android - Flutter 中 InAppWebView 插件中的 Google 地图问题
问题描述
嗨朋友们,我正在使用谷歌地图网络网址(https://www.google.co.in/maps/)作为 InAppWebView 作为初始网址,我的问题是如果我点击获取当前位置按钮,它会显示类似这样的内容
Google Maps could not determine your precise location
它说导航到下面的网址,
请给我一个如何访问 RunTimeLocation 权限的解决方案
解决方案
您可以在下面复制粘贴运行完整代码
以下代码已经过测试Emulator
并且运行良好
第1步:添加权限AndroidManifest.xml
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
第 2 步:使用package:permission_handler
void requestPermission() async {
Map<Permission, PermissionStatus> statuses =
await [Permission.location].request();
}
第 3 步:您可以使用androidOnGeolocationPermissionsShowPrompt
您可以显示对话框来询问用户允许或拒绝
,并GeolocationPermissionShowPromptResponse
根据选择
代码段返回
InAppWebView(
...
androidOnGeolocationPermissionsShowPrompt:
(InAppWebViewController controller, String origin) async {
bool result = await showDialog<bool>(
context: context,
barrierDismissible: false, // user must tap button!
builder: (BuildContext context) {
return AlertDialog(
title: Text('Allow access location $origin'),
content: SingleChildScrollView(
child: ListBody(
children: <Widget>[
Text('Allow access location $origin'),
],
),
),
actions: <Widget>[
TextButton(
child: Text('Allow'),
onPressed: () {
Navigator.of(context).pop(true);
},
),
TextButton(
child: Text('Denied'),
onPressed: () {
Navigator.of(context).pop(false);
},
),
],
);
},
);
if (result) {
return Future.value(GeolocationPermissionShowPromptResponse(
origin: origin, allow: true, retain: true));
} else {
return Future.value(GeolocationPermissionShowPromptResponse(
origin: origin, allow: false, retain: false));
}
},
完整代码
import 'dart:io';
import 'package:permission_handler/permission_handler.dart';
import 'package:flutter/material.dart';
import 'package:flutter_inappwebview/flutter_inappwebview.dart';
import 'package:url_launcher/url_launcher.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Isolate Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: InAppWebViewExampleScreen(),
);
}
}
class InAppWebViewExampleScreen extends StatefulWidget {
@override
_InAppWebViewExampleScreenState createState() =>
new _InAppWebViewExampleScreenState();
}
class _InAppWebViewExampleScreenState extends State<InAppWebViewExampleScreen> {
InAppWebViewController webView;
ContextMenu contextMenu;
String url = "";
double progress = 0;
CookieManager _cookieManager = CookieManager.instance();
void requestPermission() async {
Map<Permission, PermissionStatus> statuses =
await [Permission.location].request();
}
@override
void initState() {
super.initState();
requestPermission();
contextMenu = ContextMenu(
menuItems: [
ContextMenuItem(
androidId: 1,
iosId: "1",
title: "Special",
action: () async {
print("Menu item Special clicked!");
print(await webView.getSelectedText());
await webView.clearFocus();
})
],
options: ContextMenuOptions(hideDefaultSystemContextMenuItems: true),
onCreateContextMenu: (hitTestResult) async {
print("onCreateContextMenu");
print(hitTestResult.extra);
print(await webView.getSelectedText());
},
onHideContextMenu: () {
print("onHideContextMenu");
},
onContextMenuActionItemClicked: (contextMenuItemClicked) async {
var id = (Platform.isAndroid)
? contextMenuItemClicked.androidId
: contextMenuItemClicked.iosId;
print("onContextMenuActionItemClicked: " +
id.toString() +
" " +
contextMenuItemClicked.title);
});
}
@override
void dispose() {
super.dispose();
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text("InAppWebView")),
//drawer: myDrawer(context: context),
body: SafeArea(
child: Column(children: <Widget>[
Container(
padding: EdgeInsets.all(20.0),
child: Text(
"CURRENT URL\n${(url.length > 50) ? url.substring(0, 50) + "..." : url}"),
),
Container(
padding: EdgeInsets.all(10.0),
child: progress < 1.0
? LinearProgressIndicator(value: progress)
: Container()),
Expanded(
child: Container(
margin: const EdgeInsets.all(10.0),
decoration:
BoxDecoration(border: Border.all(color: Colors.blueAccent)),
child: InAppWebView(
// contextMenu: contextMenu,
initialUrl: "https://www.google.co.in/maps/",
// initialFile: "assets/index.html",
initialHeaders: {},
initialOptions: InAppWebViewGroupOptions(
crossPlatform: InAppWebViewOptions(
debuggingEnabled: true,
useShouldOverrideUrlLoading: true,
),
android: AndroidInAppWebViewOptions(
//useHybridComposition: true
)),
androidOnGeolocationPermissionsShowPrompt:
(InAppWebViewController controller, String origin) async {
bool result = await showDialog<bool>(
context: context,
barrierDismissible: false, // user must tap button!
builder: (BuildContext context) {
return AlertDialog(
title: Text('Allow access location $origin'),
content: SingleChildScrollView(
child: ListBody(
children: <Widget>[
Text('Allow access location $origin'),
],
),
),
actions: <Widget>[
TextButton(
child: Text('Allow'),
onPressed: () {
Navigator.of(context).pop(true);
},
),
TextButton(
child: Text('Denied'),
onPressed: () {
Navigator.of(context).pop(false);
},
),
],
);
},
);
if (result) {
return Future.value(GeolocationPermissionShowPromptResponse(
origin: origin, allow: true, retain: true));
} else {
return Future.value(GeolocationPermissionShowPromptResponse(
origin: origin, allow: false, retain: false));
}
},
onWebViewCreated: (InAppWebViewController controller) {
webView = controller;
print("onWebViewCreated");
},
onLoadStart: (InAppWebViewController controller, String url) {
print("onLoadStart $url");
setState(() {
this.url = url;
});
},
shouldOverrideUrlLoading:
(controller, shouldOverrideUrlLoadingRequest) async {
var url = shouldOverrideUrlLoadingRequest.url;
var uri = Uri.parse(url);
if (![
"http",
"https",
"file",
"chrome",
"data",
"javascript",
"about"
].contains(uri.scheme)) {
if (await canLaunch(url)) {
// Launch the App
await launch(
url,
);
// and cancel the request
return ShouldOverrideUrlLoadingAction.CANCEL;
}
}
return ShouldOverrideUrlLoadingAction.ALLOW;
},
onLoadStop:
(InAppWebViewController controller, String url) async {
print("onLoadStop $url");
setState(() {
this.url = url;
});
},
onProgressChanged:
(InAppWebViewController controller, int progress) {
setState(() {
this.progress = progress / 100;
});
},
onUpdateVisitedHistory: (InAppWebViewController controller,
String url, bool androidIsReload) {
print("onUpdateVisitedHistory $url");
setState(() {
this.url = url;
});
},
onConsoleMessage: (controller, consoleMessage) {
print(consoleMessage);
},
),
),
),
ButtonBar(
alignment: MainAxisAlignment.center,
children: <Widget>[
RaisedButton(
child: Icon(Icons.arrow_back),
onPressed: () {
if (webView != null) {
webView.goBack();
}
},
),
RaisedButton(
child: Icon(Icons.arrow_forward),
onPressed: () {
if (webView != null) {
webView.goForward();
}
},
),
RaisedButton(
child: Icon(Icons.refresh),
onPressed: () {
if (webView != null) {
webView.reload();
}
},
),
],
),
])));
}
}
推荐阅读
- javascript - 当我“复制”一个文件时,我在哪里检索文件名和路径?
- jquery - 轮播控制按钮仅适用于一页
- algorithm - 将 StartIndex/EndIndex 转换为 PageNumber/PageSize
- python - 如何在每行的不同列号处对数据框进行切片?
- python - 如何从 Instagram 检索其 API 中不存在的数据
- azure-devops - 针对 Windows 运行 ansible playbook,然后启动另一个 Playbook
- php - 使用 laravel 分页时抛出 SQL 错误
- node.js - JSONP 回调似乎不起作用
- python - 将 Pandas 具有相同名称的重复列合并到数据框中的新行
- javascript - 在jquery中上传文件后设置当前选项卡处于活动状态