英文:
Flutter | inappwebview - GeoLocation Error
问题
我对在Flutter中构建应用程序还不太熟悉,但到目前为止,我已经开发了一个具有全屏"inappwebview"的应用程序。
它指向的页面是一个网页,我也使用JavaScript制作了该网页,该网页请求使用Geolocation API的权限。也就是说,我复制并粘贴了在这里找到的JavaScript代码:https://www.w3schools.com/html/tryit.asp?filename=tryhtml5_geolocation_error
我的问题是,当我将我的webview指向上述URL时,地理位置定位完全正常,如预期的那样工作...但是当我将其指向我的网页(https://)时...它说用户拒绝了权限请求-尽管我没有拒绝-而且它与w3schools页面上的JS代码相同。
我的Flutter应用程序的代码如下:
main.dart
import 'package:flutter/material.dart';
import 'package:permission_handler/permission_handler.dart';
import 'package:flutter_inappwebview/flutter_inappwebview.dart';
void main() async {
WidgetsFlutterBinding.ensureInitialized();
var status = await Permission.location.request();
if (status.isGranted) {
runApp(MyApp());
} else {
if (status.isPermanentlyDenied) {
openAppSettings();
}
}
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Fullscreen WebView App',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: FullScreenWebView(),
);
}
}
class FullScreenWebView extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
body: SafeArea(
child: Column(
children: [
Expanded(
child: InAppWebView(
initialUrlRequest: URLRequest(
url: Uri.parse(
'https://www.w3schools.com/html/html5_geolocation.asp'),
),
initialOptions: InAppWebViewGroupOptions(
android: AndroidInAppWebViewOptions(
useWideViewPort: true,
geolocationEnabled: true,
),
ios: IOSInAppWebViewOptions(
allowsInlineMediaPlayback: true,
),
),
),
),
],
),
),
);
}
}
我还在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"/>
我花了一整天的时间来解决这个问题。即使ChatGPT也不知道原因。我希望这里有人能帮助我。非常感谢。
如果我遗漏了任何信息,或者您想了解更多信息,请告诉我。我已尽力尽可能详细地描述,因为我知道较少的信息似乎会得到负面回应。
编辑
这是执行Geolocation请求的网页的代码:
<!DOCTYPE html>
<html>
<style>
div {display:grid; place-items:center; scale: 1.1;}
</style>
<body>
<div>
<p>Click the button to get your coordinates.</p>
<button onclick="getLocation()">Try It</button>
<p id="demo"></p>
<button onclick="location.reload()">reload</button>
</div>
<script>
var x = document.getElementById("demo");
document.write("     "+document.URL)
function getLocation() {
if (navigator.geolocation) {
navigator.geolocation.getCurrentPosition(showPosition, showError);
} else {
x.innerHTML = "Geolocation is not supported by this browser.";
}
}
function showPosition(position) {
x.innerHTML = "Latitude: " + position.coords.latitude +
"<br>Longitude: " + position.coords.longitude;
}
function showError(error) {
switch(error.code) {
case error.PERMISSION_DENIED:
x.innerHTML = "User denied the request for Geolocation."
break;
case error.POSITION_UNAVAILABLE:
x.innerHTML = "Location information is unavailable."
break;
case error.TIMEOUT:
x.innerHTML = "The request to get user location timed out."
break;
case error.UNKNOWN_ERROR:
x.innerHTML = "An unknown error occurred."
break;
}
}
</script>
</body>
</html>
英文:
I'm pretty new to building apps in Flutter but I've developed so far an app that has a fullscreen "inappwebview".
The page that it points to is a webpage that I also made using JavaScript that requests permission to use the Geolocation API. Namely, i've copied and pasted the JavaScript found here: https://www.w3schools.com/html/tryit.asp?filename=tryhtml5_geolocation_error
My problem is, when I point my webview at the above URL, the geolocation works absolutely fine as intended... but when I point it to my web page (which is https:// might I add)... it says the user denied the permission request - even though I didn't - AND it's the same JS as that of the w3schools page.
The code for my Flutter App is as follows:
main.dart
import 'package:flutter/material.dart';
import 'package:permission_handler/permission_handler.dart';
import 'package:flutter_inappwebview/flutter_inappwebview.dart';
void main() async {
WidgetsFlutterBinding.ensureInitialized();
var status = await Permission.location.request();
if (status.isGranted) {
runApp(MyApp());
} else {
if (status.isPermanentlyDenied) {
openAppSettings();
}
}
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Fullscreen WebView App',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: FullScreenWebView(),
);
}
}
class FullScreenWebView extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
body: SafeArea(
child: Column(
children: [
Expanded(
child: InAppWebView(
initialUrlRequest: URLRequest(
url: Uri.parse(
'https://www.w3schools.com/html/html5_geolocation.asp'),
),
initialOptions: InAppWebViewGroupOptions(
android: AndroidInAppWebViewOptions(
useWideViewPort: true,
geolocationEnabled: true,
),
ios: IOSInAppWebViewOptions(
allowsInlineMediaPlayback: true,
),
),
),
),
],
),
),
);
}
}
I also have the following in the 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"/>
I've spent the best part of a day pulling my hair out about this. Not even ChatGPT knows why. I'm hoping someone here can come to my rescue. I would greatly appreciate it.
If i've missed any information, or you'd like to know more, please let me know. I've done my best to be as descriptive as possible as I know lesser ones seem to get a negative response.
EDIT
Here's the code for the web page that's doing the Geolocation request:
<!-- begin snippet: js hide: false console: true babel: false -->
<!-- language: lang-html -->
<!DOCTYPE html>
<html>
<style>
div {display:grid; place-items:center; scale: 1.1;}
</style>
<body>
<div>
<p>Click the button to get your coordinates.</p>
<button onclick="getLocation()">Try It</button>
<p id="demo"></p>
<button onclick="location.reload()">reload</button>
</div>
<script>
var x = document.getElementById("demo");
document.write("&emsp;&emsp;&emsp;&emsp;&emsp;"+document.URL)
function getLocation() {
if (navigator.geolocation) {
navigator.geolocation.getCurrentPosition(showPosition, showError);
} else {
x.innerHTML = "Geolocation is not supported by this browser.";
}
}
function showPosition(position) {
x.innerHTML = "Latitude: " + position.coords.latitude +
"<br>Longitude: " + position.coords.longitude;
}
function showError(error) {
switch(error.code) {
case error.PERMISSION_DENIED:
x.innerHTML = "User denied the request for Geolocation."
break;
case error.POSITION_UNAVAILABLE:
x.innerHTML = "Location information is unavailable."
break;
case error.TIMEOUT:
x.innerHTML = "The request to get user location timed out."
break;
case error.UNKNOWN_ERROR:
x.innerHTML = "An unknown error occurred."
break;
}
}
</script>
</body>
</html>
<!-- end snippet -->
答案1
得分: 0
我成功解决了这个问题,对于任何感兴趣的人,这是我所做的:
InAppWebView(
initialUrlRequest:
URLRequest(url: Uri.parse('https://www.w3schools.com/html/html5_geolocation.asp')),
androidOnGeolocationPermissionsShowPrompt:
(InAppWebViewController controller, String origin) async {
return GeolocationPermissionShowPromptResponse(
origin: origin, allow: true, retain: true);
},
initialOptions: InAppWebViewGroupOptions(
android: AndroidInAppWebViewOptions(
useWideViewPort: true,
geolocationEnabled: true,
),
ios: IOSInAppWebViewOptions(
allowsInlineMediaPlayback: true,
),
),
androidOnPermissionRequest: (InAppWebViewController controller,
String origin, List<String> resources) async {
return PermissionRequestResponse(
resources: resources,
action: PermissionRequestResponseAction.GRANT);
})
感谢Mauro的帮助。
英文:
I managed to resolve the issue, for anyone interested, here's what I did:
InAppWebView(
initialUrlRequest:
URLRequest(url: Uri.parse('https://www.w3schools.com/html/html5_geolocation.asp')),
androidOnGeolocationPermissionsShowPrompt:
(InAppWebViewController controller, String origin) async {
return GeolocationPermissionShowPromptResponse(
origin: origin, allow: true, retain: true);
},
initialOptions: InAppWebViewGroupOptions(
android: AndroidInAppWebViewOptions(
useWideViewPort: true,
geolocationEnabled: true,
),
ios: IOSInAppWebViewOptions(
allowsInlineMediaPlayback: true,
),
),
androidOnPermissionRequest: (InAppWebViewController controller,
String origin, List<String> resources) async {
return PermissionRequestResponse(
resources: resources,
action: PermissionRequestResponseAction.GRANT);
})
Thanks to Mauro for the help though.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论