【问题标题】:Use PhoneGap to Check if GPS is enabled使用 PhoneGap 检查 GPS 是否启用
【发布时间】:2012-10-22 07:06:34
【问题描述】:

我正在使用 PhoneGap 构建一个应用程序。在使用 phonegap 的 Geolocation API 时,我意识到 API 超时有两个原因,并且抛出了相同的错误: 1. 如果用户设备上没有启用 GPS 2.如果开启了GPS,却无法获取到用户的位置(可能有多种原因,GPS故障,天气不明等)

我在区分原因时遇到问题?有什么想法吗?

我想知道是否有任何方法,我可以使用 Phonegap 检查用户设备上的 GPS 是否处于活动状态,这样我就可以单独检查并将用户引导到通常放置 GEO 设置的设置窗口。不知道该怎么做?可能是自定义 phonegap 插件?

【问题讨论】:

    标签: cordova mobile


    【解决方案1】:

    您可以在调用getCurrentPosition 时检查geolocationErrorPositionError 参数中的错误代码。我猜当 gps 未启用时它将是 PositionError.PERMISSION_DENIED,而当 gps 启用时它将是 PositionError.POSITION_UNAVAILABLE 或 PositionError.TIMEOUT 但还有其他问题。

    请注意,这取决于平台。您可能不得不编写一条人为的错误消息,显示“无法获取当前位置。GPS 信号较弱或 GPS 已关闭”。

    您可以尝试的一件事是调用 getCurrentPosition 时的超时非常小,比如 1 毫秒。如果它说权限被拒绝,您可以断定 gps 已禁用,如果超时,您可以假定 gps 已启用。我没有时间对此进行测试,您可以根据测试结果编辑此答案。

    您可以尝试的另一件事是使用diagnostic phonegap plugin for android。你必须确保你也使用其他平台的插件,但它们也大多都在那里。

    【讨论】:

    • 感谢 Kinjal,不同的错误代码肯定会解决问题,但这里的问题是我得到相同的错误代码 - PositionError.TIMEOUT 在两种情况下,即当 GPS 未启用和 GPS 返回时无法定位我的位置。顺便说一句,我正在运行 Android 2.3 的 HTC 手机上测试它,我还没有在其他设备上测试它
    • 对此有一个简短的提醒。根据设备和操作系统版本,错误回调将不会触发。例如,在我的 Galaxy S2 上,当 GPS 被禁用时,我立即收到错误消息。另一方面,到目前为止,我测试过的每个 S3 和 S4 都从未触发错误回调(仅在超时后),即使 GPS 完全禁用。不过,PhoneGap 团队意识到了这一点。
    • @Prinzhorn 您的评论非常有用。您是否介意准确指定在 Galaxy S2 上禁用 GPS 时收到的错误(即错误消息)。对于 S3 和 S4,似乎很短的超时就可以解决您的问题,对吗?
    • @StevenWexler 抱歉,我已经三个月没用过PhoneGap了,以后几个月也不打算用了
    【解决方案2】:

    为了最优雅地处理这种情况,您可以使用cordova.plugins.diagnostic 检查是否启用了 GPS 设置并(在 Android 6+ 上)检查应用程序是否具有运行时授权,以及(如果未启用),使用 @987654322 @ 通过本机对话框自动打开 GPS,无需用户通过设置页面手动打开。但是,由于后者依赖于设备上最新的 Google Play 服务库,因此如果自动切换失败,最好回退到手动切换。

    首先将所需的插件添加到您的项目中:

    cordova plugin add cordova.plugins.diagnostic --save
    cordova plugin cordova-plugin-request-location-accuracy --save
    

    然后你会这样做:

    function checkAvailability(){
        cordova.plugins.diagnostic.isGpsLocationAvailable(function(available){
            console.log("GPS location is " + (available ? "available" : "not available"));
            if(!available){
               checkAuthorization();
            }else{
                console.log("GPS location is ready to use");
            }
        }, function(error){
            console.error("The following error occurred: "+error);
        });
    }
    
    function checkAuthorization(){
        cordova.plugins.diagnostic.isLocationAuthorized(function(authorized){
            console.log("Location is " + (authorized ? "authorized" : "unauthorized"));
            if(authorized){
                checkDeviceSetting();
            }else{
                cordova.plugins.diagnostic.requestLocationAuthorization(function(status){
                    switch(status){
                        case cordova.plugins.diagnostic.permissionStatus.GRANTED:
                            console.log("Permission granted");
                            checkDeviceSetting();
                            break;
                        case cordova.plugins.diagnostic.permissionStatus.DENIED:
                            console.log("Permission denied");
                            // User denied permission
                            break;
                        case cordova.plugins.diagnostic.permissionStatus.DENIED_ALWAYS:
                            console.log("Permission permanently denied");
                            // User denied permission permanently
                            break;
                    }
                }, function(error){
                    console.error(error);
                });
            }
        }, function(error){
            console.error("The following error occurred: "+error);
        });
    }
    
    function checkDeviceSetting(){
        cordova.plugins.diagnostic.isGpsLocationEnabled(function(enabled){
            console.log("GPS location setting is " + (enabled ? "enabled" : "disabled"));
            if(!enabled){
                cordova.plugins.locationAccuracy.request(function (success){
                    console.log("Successfully requested high accuracy location mode: "+success.message);
                }, function onRequestFailure(error){
                    console.error("Accuracy request failed: error code="+error.code+"; error message="+error.message);
                    if(error.code !== cordova.plugins.locationAccuracy.ERROR_USER_DISAGREED){
                        if(confirm("Failed to automatically set Location Mode to 'High Accuracy'. Would you like to switch to the Location Settings page and do this manually?")){
                            cordova.plugins.diagnostic.switchToLocationSettings();
                        }
                    }
                }, cordova.plugins.locationAccuracy.REQUEST_PRIORITY_HIGH_ACCURACY);
            }
        }, function(error){
            console.error("The following error occurred: "+error);
        });
    }
    
    checkAvailability(); // start the check
    

    【讨论】:

    • 但是代码中的“cordova”是从哪里来的呢?似乎它只是在代码中被扔掉了。我应该使用任何依赖注入吗?
    【解决方案3】:

    我在某些设备上遇到了类似的问题。设法用下面的代码解决它:

    var options = {maximumAge: 0, timeout: 10000, enableHighAccuracy:true};
    navigator.geolocation.getCurrentPosition(onSuccess, onError, options);
    

    【讨论】:

      【解决方案4】:

      我在上面尝试了 DaveAlden 的解决方案,但没有成功,部分原因是他调用的第一个函数 cordova.plugins.diagnostic.isGpsLocationAvailable() 是 Android 专用的 plugin docs

      如他所说,先添加两个插件:

      cordova plugin add cordova.plugins.diagnostic --save
      cordova plugin cordova-plugin-request-location-accuracy --save
      

      然后添加以下函数:

      // Checks to see if GPS is enabled AND if the app is authorized
      checkEnabled(){
          cordova.plugins.diagnostic.isLocationAvailable(
            (available) => { onSuccess(available); },
            (error) => { goToSettings(error); }
          );
      }
      
      onSuccess(available) {
        if(available) { // do something };
        else goToSettings(available);
      }
      
      // Output error to console
      // Prompt user to enable GPS, on OK switch to phone settings
      goToSettings(error) {
        console.log("error: ", error);
        if(window.confirm("You need to enable location settings to use the geolocation feature.")) {
          cordova.plugins.diagnostic.switchToSettings();
        }
      }
      
      checkEnabled(); // Run check
      

      希望这可以帮助其他提出此答案的人。

      【讨论】:

        【解决方案5】:

        使用 apache cordova 3 安卓平台

        在 GeoBroker.java 文件中的执行方法中,在 locationManager 实例化后添加以下操作。

        if(action.equals("isGPSEnabled")){
                    PluginResult result;
                    if ( locationManager.isProviderEnabled( LocationManager.GPS_PROVIDER )){
                        result = new PluginResult(PluginResult.Status.OK);
                    }else{
                        result = new PluginResult(PluginResult.Status.ERROR);
                    }
                    callbackContext.sendPluginResult(result);
                }
        

        然后在你的资产插件文件夹中的 geolocation.js 文件中添加公开新功能

         /**
             * Asynchronously checks if gps is enabled.
             *
             * @param {Function} successCallback    The function to call when gps is enabled.
             * @param {Function} errorCallback      The function to call when gps is not enabled. (OPTIONAL)
             */
            isGPSEnabled:function(successCallback, errorCallback){
                exec(successCallback, errorCallback, "Geolocation", "isGPSEnabled", []);
            }
        

        希望对你有帮助

        【讨论】:

        • 我找不到这个文件...或者我必须创建这个文件如果是的话在哪里创建它?
        • @quicklearner 请注意,该解决方案适用于 apache cordova 版本 3。也许它在您的版本中被重命名。无论如何,您应该在使用 PluginResult 的插件文件夹下找到一个 java 文件,并在 www 文件夹中找到一个 js 文件
        • 非常感谢您的关注,但我想知道您说的是哪个插件?没有安装任何
        【解决方案6】:

        仅针对重定向到此处的新用户,有一个名为 Cordova diagnostic plugin 的插件(大约在 2014 年年中开始):

        这个适用于 iOS、Android 和 Windows 10 Mobile 的 Cordova/Phonegap 插件是 用于管理设备设置,例如位置、蓝牙和 WiFi。 它可以管理运行时权限、设备硬件和 核心操作系统功能。 ref

        【讨论】:

        • 但是代码中的“cordova”是从哪里来的呢?似乎它只是在代码中被扔掉了。我应该使用任何依赖注入吗?
        • @luizfzs 你说的注入是什么意思?当您将一些插件添加到您的 Cordova 应用程序时,它将被添加为一个全局变量或另一个全局变量(主要是 Cordova 本身)。
        • 这很奇怪,因为我已经安装了 cordova-diagnostic 但是每当我编译时,我都会收到“找不到名称 'cordova'”的消息。
        • 我相信您在其他地方犯了错误。您应该使用 chrome 检查器 chrome://inspect/device#devices 再次检查您的代码
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2016-07-07
        • 2014-09-10
        • 2011-08-27
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多