Flutter | inappwebview – 地理位置错误

huangapple go评论99阅读模式
英文:

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("&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>

英文:

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 &#39;package:flutter/material.dart&#39;;
import &#39;package:permission_handler/permission_handler.dart&#39;;
import &#39;package:flutter_inappwebview/flutter_inappwebview.dart&#39;;

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: &#39;Fullscreen WebView App&#39;,
      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(
                      &#39;https://www.w3schools.com/html/html5_geolocation.asp&#39;),
                ),
                initialOptions: InAppWebViewGroupOptions(
                  android: AndroidInAppWebViewOptions(
                    useWideViewPort: true,
                    geolocationEnabled: true,
                  ),
                  ios: IOSInAppWebViewOptions(
                    allowsInlineMediaPlayback: true,
                  ),
                ),
              ),
            ),
          ],
        ),
      ),
    );
  }
}

I also have the following in the AndroidManifest.xml

&lt;uses-permission android:name=&quot;android.permission.INTERNET&quot;/&gt;
&lt;uses-permission android:name=&quot;android.permission.ACCESS_FINE_LOCATION&quot;/&gt;
&lt;uses-permission android:name=&quot;android.permission.ACCESS_COARSE_LOCATION&quot;/&gt;

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 -->

&lt;!DOCTYPE html&gt;
&lt;html&gt;
&lt;style&gt;
div {display:grid; place-items:center; scale: 1.1;}
&lt;/style&gt;

&lt;body&gt;
    &lt;div&gt;
    &lt;p&gt;Click the button to get your coordinates.&lt;/p&gt;
    &lt;button onclick=&quot;getLocation()&quot;&gt;Try It&lt;/button&gt;
    &lt;p id=&quot;demo&quot;&gt;&lt;/p&gt;
    
    &lt;button onclick=&quot;location.reload()&quot;&gt;reload&lt;/button&gt;
    &lt;/div&gt;
    
    &lt;script&gt;
    var x = document.getElementById(&quot;demo&quot;);
    document.write(&quot;&amp;emsp;&amp;emsp;&amp;emsp;&amp;emsp;&amp;emsp;&quot;+document.URL)
    function getLocation() {
      if (navigator.geolocation) {
        navigator.geolocation.getCurrentPosition(showPosition, showError);
      } else { 
        x.innerHTML = &quot;Geolocation is not supported by this browser.&quot;;
      }
    }
    
    function showPosition(position) {
      x.innerHTML = &quot;Latitude: &quot; + position.coords.latitude + 
      &quot;&lt;br&gt;Longitude: &quot; + position.coords.longitude;
    }
    
    function showError(error) {
      switch(error.code) {
        case error.PERMISSION_DENIED:
          x.innerHTML = &quot;User denied the request for Geolocation.&quot;
          break;
        case error.POSITION_UNAVAILABLE:
          x.innerHTML = &quot;Location information is unavailable.&quot;
          break;
        case error.TIMEOUT:
          x.innerHTML = &quot;The request to get user location timed out.&quot;
          break;
        case error.UNKNOWN_ERROR:
          x.innerHTML = &quot;An unknown error occurred.&quot;
          break;
      }
    }
    &lt;/script&gt;

&lt;/body&gt;
&lt;/html&gt;

<!-- 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(&#39;https://www.w3schools.com/html/html5_geolocation.asp&#39;)),
    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&lt;String&gt; resources) async {
    return PermissionRequestResponse(
        resources: resources,
        action: PermissionRequestResponseAction.GRANT);
})

Thanks to Mauro for the help though.

huangapple
  • 本文由 发表于 2023年8月8日 22:07:29
  • 转载请务必保留本文链接:https://go.coder-hub.com/76860351.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定