Phonegap在安卓系统上定位有时无法正常工作。

15

我正在使用Cordova v3.4.1构建Android和iOS应用程序,在iOS上,地理定位功能返回非常快,并始终正常工作,但在Android上,有时它无法工作。

奇怪的是,当我重新启动我的Android手机后,它就能正常运行了。在几个小时内,地理定位功能可以非常快速地获取位置信息,无论是在WiFi还是3G环境下。

但是在几个小时之后,当我再次打开应用时,地理定位就无法工作了。有时候当我在户外时,它可以通过GPS卫星获取位置信息,但速度非常慢,经常出现超时错误。

我尝试删除并重新安装应用程序,但问题仍然存在,除非重新启动我的Android手机。当我重新启动我的Android手机时,未来几个小时内地理定位功能又可以正常工作了。

我已经测试了几款Android手机,如三星Note2、Galaxy4等,它们都有同样的问题。只有当我重新启动它们时,它们才能非常快速地获取位置信息。

这个问题已经困扰我很长时间了,所以有人能帮帮我吗?

以下是我的代码:

navigator.geolocation.getCurrentPosition(function(pos){
                cb(null,pos)
            },function(errMsg){
    navigator.geolocation.getCurrentPosition(function(pos){  
            cb(null,pos)
    },function(errMsg){
    cb(errMsg)
    }, {
    enableHighAccuracy: true,
    timeout: 60*1000*2,
    maximumAge: 1000*60*10
   });
}, {
    enableHighAccuracy: false,
    timeout: 10*1000,
    maximumAge: 1000*60*10
});

我的config.xml文件:

<feature name="Geolocation">
    <param name="android-package" value="org.apache.cordova.geolocation.GeoBroker" />
</feature>
2个回答

16

我终于解决了问题,现在我的安卓手机上getCurrentPosition函数每次都可以快速返回位置信息了,再也不需要重新启动手机了!我不确定cordova v3.4.1的地理位置插件是否有bug。

导致这个问题发生的原因是我们一直使用浏览器的navigator.geolocation.getCurrentPosition函数来定位位置,所以我们必须让应用程序使用cordova本地实现代替html5。

这里是cordova v3.4.1的解决方案,希望它能帮到你,事实上,它已经解决了我的问题。

解决步骤:

1. 删除org.apache.cordova.geolocation

$ cordova plugin rm org.apache.cordova.geolocation

2.重新安装一个新的org.apache.cordova.geolocation插件。

$ cordova plugin add org.apache.cordova.geolocation

3. 将插件复制到 E:\

进入插件文件夹,例如 'YOUR_APP_FOLDER\plugins\'

将整个 org.apache.cordova.geolocation 文件夹复制到 E:\org.apache.cordova.geolocation

4. 再次移除插件

$ cordova plugin rm org.apache.cordova.geolocation

5. 编辑 E:\org.apache.cordova.geolocation\plugin.xml 中的 plugin.xml 文件。

编辑 plugin.xml 文件如下:

... ...
<name>Geolocation</name>
<description>Cordova Geolocation Plugin</description>
<license>Apache 2.0</license>
<keywords>cordova,geolocation</keywords>
<repo>https://git-wip-us.apache.org/repos/asf/cordova-plugin-geolocation.git</repo>
<issue>https://issues.apache.org/jira/browse/CB/component/12320638</issue>

<!-- android Code Comments
<platform name="android">

    <config-file target="AndroidManifest.xml" parent="/*">
        <uses-permissionandroid android:name="android.permission.ACCESS_COARSE_LOCATION" />
        <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
        <uses-permission android:name="android.permission.ACCESS_LOCATION_EXTRA_COMMANDS" />
    </config-file>

</platform>
-->

 <!-- amazon-fireos change to android-->
<platform name="android"> 

    <js-module src="www/Coordinates.js" name="Coordinates">
        <clobbers target="Coordinates" />
    </js-module>

    <js-module src="www/PositionError.js" name="PositionError">
        <clobbers target="PositionError" />
    </js-module>

    <js-module src="www/Position.js" name="Position">
        <clobbers target="Position" />
    </js-module>

    <js-module src="www/geolocation.js" name="geolocation">
        <clobbers target="navigator.geolocation" />
    </js-module>

    <config-file target="res/xml/config.xml" parent="/*">
        <feature name="Geolocation">
            <param name="android-package" value="org.apache.cordova.geolocation.GeoBroker"/>
        </feature>
    </config-file>

    <config-file target="AndroidManifest.xml" parent="/*">
        <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
        <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
        <uses-permission android:name="android.permission.ACCESS_LOCATION_EXTRA_COMMANDS" />
    </config-file>

    <source-file src="src/amazon/GeoBroker.java" target-dir="src/org/apache/cordova/geolocation" />
    <source-file src="src/amazon/GPSListener.java" target-dir="src/org/apache/cordova/geolocation" />
    <source-file src="src/amazon/NetworkListener.java" target-dir="src/org/apache/cordova/geolocation" />
    <source-file src="src/amazon/CordovaLocationListener.java" target-dir="src/org/apache/cordova/geolocation" />

</platform>

<!-- ios -->
<platform name="ios">
... ...

6. 再次添加插件

$ cordova plugin add E:\org.apache.cordova.geolocation

7、运行构建命令

$ cordova build android

8.检查是否正常运行

检查YOUR_APP\plugins\android.json文件中是否包含:

{
   "xml": "<feature name=\"Geolocation\"><param name=\"android-package\" value=\"org.apache.cordova.geolocation.GeoBroker\" /></feature>",
   "count": 1
},
... ...
{
  "xml": "<uses-permission android:name=\"android.permission.ACCESS_COARSE_LOCATION\" />",
  "count": 4
},
{
   "xml": "<uses-permission android:name=\"android.permission.ACCESS_FINE_LOCATION\" />",
    "count": 4
},
{
  "xml": "<uses-permission android:name=\"android.permission.ACCESS_LOCATION_EXTRA_COMMANDS\" />",
  "count": 1
 }

请检查YOUR_APP\platforms\android\AndroidManifest.xml文件中是否包含以下内容:

<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.ACCESS_LOCATION_EXTRA_COMMANDS" />

检查YOUR_APP\platforms\android\res\xml\config.xml必须包含:

<feature name="Geolocation">
    <param name="android-package" value="org.apache.cordova.geolocation.GeoBroker" />
</feature>

9.运行应用程序

编写Geolocation代码以获取纬度和经度:

navigator.geolocation.getCurrentPosition(function(pos){
            alert('suc')
            alert(JSON.stringify(pos))
        },function(errMsg){
               alert(JSON.stringify(errMsg))
               navigator.geolocation.getCurrentPosition(function(pos){  
                 alert('suc')
                 alert(JSON.stringify(pos))
               },function(errMsg){
                 alert(JSON.stringify(errMsg))
               }, {
               enableHighAccuracy: true,
               timeout: 60*1000*2,
               maximumAge: 1000*60*10
               });
          }, {
enableHighAccuracy: false,
timeout: 60*1000,
maximumAge: 1000*60*10

});

如果您的手机支持使用wifi/3G定位,我们将立即获取位置,否则您将看到errMsg timeout,然后geolocation会使用本地实现的GPS来定位位置。

现在我们已经获得了纬度和经度,再也不需要重新启动安卓手机,谢天谢地。

如果您仍然有问题,请尝试安装清除Webview缓存的插件:

https://github.com/moderna/cordova-plugin-cache


这个问题在PG 3.5上仍然存在,你的解决方案仍然有效! - rodripf
1
我们在PG 5.1.1中仍然需要做所有这些吗?大多数情况下,navigator.geolocation.getCurrentPosition() 在我的Android设备上根本不起作用。重新启动也没有帮助。 - novalain
抱歉再次提及此话题 - 在进行PhoneGap构建时,我们该如何解决这个问题。更改是否仍然有效?我没有看到任何区别,因此想问一下。 - sabkaraja
1
将插件复制到e:\。这里的“e”是什么?我正在使用Ionic。 - Manish Kumar

0

在cordova v5.3.3中,您需要执行以下操作:

1、cordova plugin remove cordova-plugin-geolocation

2、cordova plugin add cordova-plugin-geolocation

3、将您的cordova-plugin-geolocation目录复制到插件目录下的e:\

4、编辑plugin.xml,添加以下内容:

<js-module src="www/Coordinates.js" name="Coordinates">
    <clobbers target="Coordinates" />
</js-module>

<js-module src="www/PositionError.js" name="PositionError">
    <clobbers target="PositionError" />
</js-module>

<js-module src="www/Position.js" name="Position">
    <clobbers target="Position" />
</js-module>

<js-module src="www/geolocation.js" name="geolocation">
    <clobbers target="navigator.geolocation" />
</js-module>

<config-file target="res/xml/config.xml" parent="/*">
    <feature name="Geolocation">
        <param name="android-package" value="org.apache.cordova.geolocation.GeoBroker"/>
    </feature>
</config-file>

<config-file target="AndroidManifest.xml" parent="/*">
    <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
    <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
    <uses-permission android:name="android.permission.ACCESS_LOCATION_EXTRA_COMMANDS" />
</config-file>

5、移除cordova插件cordova-plugin-geolocation

6、添加cordova插件e:\cordova-plugin-geolocation

7、运行cordova安卓应用程序,现在我成功获取了GPS位置。感谢WuZhonghua的帮助。


我在Mac上安装了Cordova 5.4.1。我已经按照您描述的更改进行了操作,但是当我发出navigator.geolocation.getCurrentPosition(onSuccess, onError)时,onSuccess或onError方法从未被调用。有什么想法吗? - Luc
@Luc,使用value="org.apache.cordova.geolocation.GeoBroker"而不是value="org.apache.cordova.geolocation.Geolocation"会导致我的getCurrentPosition也出现问题。你解决了吗? - FuzzyTree

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接