React-native: Android上的地理位置“ enableHighAccuracy”始终超时

创建于 2016-05-10  ·  239评论  ·  资料来源: facebook/react-native

开发Android应用程序,同时在运行于6.1的Android设备上进行调试时,geolocation api始终会返回错误回调,并显示消息Location request timed out

navigator.geolocation.getCurrentPosition(
      (position) => {
        console.log(position);
       },
       (error) => {
        console.log(error)
      },
      {enableHighAccuracy: true, timeout: 20000, maximumAge: 10000}
);

如果我将enableHighAccuracy选项切换为false,则api可以正常工作。 在高精度模式下,超时时间总是与我在超时选项中指定的时间一样长,即20秒。

我尝试在关闭开发模式的情况下运行。

高精度模式是否可以在Android中使用?

Geolocation Bug Help Wanted Android Ran Commands Locked

最有用的评论

enableHighAccuracy设置为truefalse对我不起作用。
省略getCurrentPosition的第三个参数以使用本机模块的默认值对我来说很有效。

所有239条评论

@ acapop77忘了还提及使用以下命令启用权限:

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

我在RN 0.25.1上有相同的问题,不同之处在于,对我来说,问题的高低精度仍然存在。 最终,我找到了使它起作用的方法,但不是解决方案。

这对我有用-假设您使用普通android avd-模拟器:

  1. 在Android模拟器设备中,转到“设置>位置”(就像在实际设备上一样),然后将“模式”设置为“高精度”。
  2. 返回应用程序。
  3. 按下“扩展控件”按钮(以“ ...”表示)。 在“位置”部分的下一步,您将在下面看到GPS数据点数据和“发送”按钮。 只需单击“发送”,然后关闭扩展控件菜单。
  4. 重新加载应用程序。

这对我有效-基于“仅一次”。 每次我想重新加载应用程序时,我都需要再次执行3-4步。 但是至少通过这种方式,我可以使Geolocation正常工作,并且不会出现超时错误。

我在0.24中遇到了类似的情况。 即使<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />在我的AndroidManifest.xml中,我仍然收到红色错误,指出:

“看来该应用没有访问位置的权限。请添加以下行...”

我没有使用仿真器,而是直接构建到设备上。

编辑-这也发生在0.25.1中

@ acapop77 @rossthedevigner我也正在直接构建到三星S6设备。

@Findiglay这里也是。 我什至尝试执行手动.apk安装,但仍然收到错误。

我正在尝试一种变通方法,其中遍历权限清单并查看是否启用了android.permission.ACCESS_FINE_LOCATION

是否有人拥有navigator.geolocation ==未定义?

我当前在设备上遇到此问题。

这里报告了各种问题。 我不确定是否都与enableHighAccuracy的特定问题相关。

我没有Android开发方面的经验,但是我发现,如果我编辑LocationModule.java来对LocationOptions boolean highAccuracy = true;进行硬编码并重建,那么我的位置将正确返回。 我不确定结果是否与React-Native地理位置API中的设置enableHighAccuracy: false所收到的结果有所不同,但是可以安全地假设它在highAccuracy模式下运行。

这是否意味着错误发生在Geolocation API和LocationModule之间的桥梁中?

我遇到了同样的问题。 我按照@Findiglay的建议进行了相同的操作,并工作了几次,但后来我只有超时。

知道为什么在真实设备上会发生这种情况吗? :(

有同样的问题。 我目前正在使用RN 0.25.1在真实设备上运行该应用程序。

我应该补充一点,我已经在权限清单中添加了必要的Android权限。 但是仍然超时。

作为一种解决方法,我在android设置中启用了“允许模拟位置”,并安装了可模拟gps的应用(在商店中查找假gps)。 至少在解决此问题之前,开发不会受到阻碍

伙计们
我遇到了同样的错误,但是在与同事进行了几次重试之后,我们发现了一些奇怪的东西(但是如果您对GPS感兴趣的话,这是正常的)。

如果使用物理设备在办公室“内部”执行测试,则GPS定位器可能会受到诸如墙壁之类的外部事物的干扰,或者由于您试图在“室内”执行此操作的简单原因而受到干扰,通常应在室外执行。

好吧,这之后我们从办公室出去了,我们重新执行了测试,并且设备按计划进行了响应(我们没有收到“请求超时”错误)。

我的建议是:尝试使用设置为true的“ enableHighAccuracy”进行地理定位,如果失败(在办公室中可能失败),请重试为false,在我的情况下应该可以。

希望这可以有所帮助。

+1

此处是否将enableHighAccuracy设置为truefalse
它可以在GenyMotion模拟器上使用,但不能在任何实际设备上(在Samsung,Nexus,Mi上测试)。
在AndroidManifest.xml中启用了权限
码:

                navigator.geolocation.getCurrentPosition(
                    (position) => {
                        console.log(position);
                    },
                    (error) => console.log(new Date(), error),
                    {enableHighAccuracy: true, timeout: 10000, maximumAge: 3000}
                );  

enableHighAccuracy设置为truefalse对我不起作用。
省略getCurrentPosition的第三个参数以使用本机模块的默认值对我来说很有效。

LGE Nexus 5(Android 6.0)在这里也存在同样的问题。
在Android 5.1.1和4.3上没有此问题。
在具有Android 6.0的模拟器中,没有这样的问题。
boolean highAccuracy = false;不起作用。
RN 0.28.0。

大家好,我发现了临时修复程序-此程序包https://github.com/lucasferreira/react-native-android-permissions

有任何更新或修复吗? 在仅超时的情况下,在Simulator和5.0之前的设备上一切正常,而我迫切需要一个已可用应用程序的修复程序!

+1

此问题受设备上的locationMode设置影响。 当定位模式设置为高精度或仅设备时,地理定位将超时。 当位置模式设置为省电时,它可以正常工作

我遇到了同样的问题,我打了个平底锅,删除了第三个参数。 它现在正在工作。

navigator.geolocation.getCurrentPosition( (position) => { console.log(position); }, (error) => console.log(new Date(), error), {enableHighAccuracy: true, timeout: 10000, maximumAge: 3000} //removed this );

我假设这与以下内容有关: https :

对?

不,那是因为位置超时问题

是的,我刚刚发现删除第三个参数似乎可以解决。

我们尚未对设备进行全面的测试,但是当包含第3个参数(无论设置如何)时,将设备模式设置为高精度或仅设备的android 22版似乎会导致位置超时。 它似乎不会影响android版本23。

同样的经历,除了android 23版仅在enableHighAccuracy设置为false时,第3个参数有效( true导致位置超时)。 还对Android 22、21、20和19版进行了测试,似乎第3个参数的存在在所有情况下都会导致超时。 删除该参数似乎是唯一可靠的解决方案。

删除第3个参数只是让我立即弹出“位置请求超时”弹出窗口,而不必等到超时完成。 将enableHighAccuracy为false也不起作用。

在我的模拟器上,仅当我打开模拟器设置并发送位置(查看屏幕截图)时,“位置”才可用。

有没有办法自动获取它?

screen shot 2016-08-21 at 6 42 52 pm

在我的情况下,将enableHighAccuracyfalse解决问题。

在模拟器和设备上都存在相同的问题,并为true和false尝试了enableHighAccuracy

我只是直接得到“未定义不是对象(正在评估'navigator.geolocation.getCurrentPosition')”

我尝试检查if(navigator)是否返回true,
但是if(navigator.geolocation)返回false。

另外,在Android 5.1 OnePlus One上的设备上执行此操作。 已启用开发人员模式,包括AndroidManifest权限,开/关模拟位置,所有功能。

此外,它似乎并没有向我询问位置权限🤔尽管我删除了设备上的应用程序并删除了Mac上的输出文件夹。

自从我使用React Realm以来,我实际上都无法进行远程调试,并且该问题存在巨大的问题,使chrome远程调试器无法自拔。

我有一个类似的问题,也许每次有RN的地理位置定位非常差的应用程序时,其他地理位置应用程序都可以正常工作,但应用程序并不一定总是超时,但是它确实可以做到很多。
我使用的是RN 0.32,但每个版本都存在相同的问题,由于某种原因,RN中的地理位置非常奇怪和糟糕(至少在Android上)

同样的问题,在真实设备上进行测试。

碰到这个,这真的很烦:/

我在Android 6.0上遇到相同的问题。

+1

我发现一个解决方案是不添加第3个参数,并使用上面链接的库(https://github.com/lucasferreira/react-native-android-permissions)在android版本> = 23上请求android M权限。

刚刚发现的PermissionsAndroid现在已添加到RN。 所以使用它来请求是否在android> = 23上

https://facebook.github.io/react-native/docs/permissionsandroid.html

但是我的设备上有Android 5.1.1。 在此android版本上,Geolocation必须工作正常,不是吗?

23是6.0及更高版本。 我还发现我不需要添加第3个参数即可使它在所有内容上都能正常工作。

我设法使它起作用,但对您来说可能有所不同。 较新版本的RN(我的是0.32.1)包括一个名为MainApplication.java的文件(除了MainActivity.java)。 React Native Mapbox GL Docs说您必须将ReactNativeMapboxGLPackage包含到MainActivity.java中,但是您必须在MainApplication.java中这样做,所以它看起来像这样:

MainApplication.java

`。 。 。

<strong i="8">@Override</strong>
protected List<ReactPackage> getPackages() {
  return Arrays.<ReactPackage>asList(
      new MainReactPackage(),
      new ReactNativeMapboxGLPackage()
  );
}

};
`

而且MainActivity.java将保持不变。

我的Android版本是23,所以我仍在使用清单XML的权限

在设备上激活GPS的情况下,App可以很好地返回位置,但是如果我将其关闭,则可以返回位置: error: No available location provider.

我如何强制设备进入有效GPS位置?

这很疯狂= /

在过去的几周里,我有getCurrentPosition在我的Genymotion Android模拟器上工作,但现在又失败了。

我正在使用Genymotion的GPS小部件来设置位置。 我已经在模拟器上安装了Google Maps,Google Maps可以很好地读取我的位置。

我拥有所有必要的权限,甚至使用了@sattaman建议的PermissionsAndroid模块。 行为似乎是不确定的,因为它一天有效,第二天坏了。

我在RN 0.31上,删除第三个参数也对我有用! 真实设备,Nexus 5X,Android 6。

我在RN 0.34.1上有同样的问题,但是删除第三个参数可以解决它
将enableHighAccuracy设置为false不能解决此问题

我在RN 0.32上遇到了同样的问题,并在Android 22和23上进行了尝试,

enableHighAccuracy为真或假,对我不起作用
删除第三个参数会立即导致“位置请求超时”
但是,重新启动我的设备即可正常工作,但一段时间后会损坏,

现在,要获取用户位置,我只需使用以下命令:
https://github.com/mauron85/react-native-background-geolocation

@acondense ,您在哪里设置背景地理定位的代码,因为它似乎没有运行定位功能

我在RN 0.35的Android 23和24上遇到了相同的问题,但是在Android 22上工作正常。
它可能与Android 6.0运行时权限系统有关:
http://stackoverflow.com/questions/32224534/access-fine-location-permission-error-emulator-only

我使用该库来避免此问题,并且可以正常工作!
https://github.com/yonahforst/react-native-permissions

删除第三个参数也为我固定了它

删除第三个有效的参数

从一开始还不清楚每个人都在谈论哪个参数,方法参数或options对象的第三个参数。

确切地说,它是getCurrentPosition方法的第三个参数,其结尾看起来像这样:

navigator.geolocation.getCurrentPosition(
    (position) => {
       ...
    },
    (error) => alert(error.message)
)

最后,我提供了以下解决方案(与上述相同的想法):

export const detectCurrentLocation = (successCallback, errorCallback) => {
    let navigatorOptions = {}
    if (Platform.OS === 'android' && Platform.Version === 23) {
        navigatorOptions = {
            enableHighAccuracy: false,
            timeout: 10000,
            maximumAge: 0
        }
    }

    navigator.geolocation.getCurrentPosition(
        position => successCallback(detectedLocation),
        error => errorCallback(error),
        navigatorOptions
    )
}

它可以在设备上运行(已在Android 21、22和23上测试),但对于Android 23来说,它的运行速度非常慢:5-10秒。

是否有人在React-native(使用Android的Java代码本地实现)中将LocationServices.FusedLocationApi用作此目的的解决方法?

enableHighAccuracy: true根本无法在android上使用

我正在使用此代码检查Android 6上的位置权限

requestLocationPermission = async () => {
    try {
      const granted = await PermissionsAndroid.requestPermission(
        PermissionsAndroid.PERMISSIONS.ACCESS_FINE_LOCATION,
        {
          'title': 'Enable location',
          'message': 'Location is good \o/',
        },
      );

      if (granted) {
        console.log('You can use the location');
        this.getLocation();
      } else {
        console.log('Location permission denied');
      }
    } catch (err) {
      console.warn(err);
    }
  };

@sibelius这样可以防止Location request timed out错误?

使用我的代码段以及这个代码段https://github.com/facebook/react-native/issues/7495#issuecomment -259753488

仍然没有解决办法吗? 我已经在该线程上尝试了所有内容,但对我没有任何帮助,无论是立即还是几秒钟后,始终都是超时错误。

同样, @ sattaman注释已为我的设备修复了该问题(将位置模式设置为省电),但是如何告诉应用程序用户执行此操作!

禁用enableHighAccuracy或省略第3个参数都对我有用。 不过,该位置看起来仍然非常准确。
在iOS上没有问题。 (RN 0.39)

RN 0.40同样的问题。 删除第三个参数即可解决。
(但是您得不到高精度)

同样的问题,删除第三个参数即可解决。

在模拟器上,我必须设置enableHighAccuracy: true并确保将定位模式设置为“高精度”。 否则超时。 在任何情况下,我都无法在模拟器上节省电池才能正常工作。

在设备上,我根本不传递任何选项。 如果您像我一样正在为此而苦苦挣扎-建议您在实际设备上尝试一下。 我在Pixel C(Android 7.1)和Note 4(Android 6.0.1)上进行了测试

在iOS上,我必须将“高精度”设置为True。 您可以想象此时我的获取位置功能...

我正在使用RN 0.40并使用真实设备(Nexus 5),但仍然遇到问题。

我尝试了本期所有评论中的任何内容。

有人以其他方式解决了这个问题,这里没有提到吗?

//更新:

似乎navigator.geolocation.watchPosition有效。 因此,在固定navigator.geolocation.getCurrentPosition之前,可以使用该解决方案。

现在,我将编写一个本机模块并直接与本机API对话,因为使用高精度对我很重要。
目前,RN的地理定位API似乎不稳定。

在我的项目中,我弄清楚了一些规则。

  1. Android设备设置-定位是设备而已,你应该设置enableHighAccuracy: true到getCurrentPosition
  2. 设置-位置精度高,应将enableHighAccuracy: true为getCurrentPosition

按照这两个规则,在我的项目中一切正常

@kimochg您的测试设置是什么?

在我的测试中,无论地理位置enableHighAccuracy是什么,将“位置”的设备设置仅设置为“设备”都会导致timeOut。

无论将enableHighAccuracy设置为什么,将设备设置设置为“高精度”都会给我一个有效的位置。

编辑
在我看来,如果我将enableHighAccuracy: false和设备位置设置设为高精度,则地理位置只会获取一个新位置。 使用enableHighAccuracy: true它将获取缓存的位置,但是新的获取将超时。

这是在React Native 0.40上,在运行Android 7.1.1的Nexus 5X上进行测试

@kulmajaba,当您反应Native 0.40时,在运行Android 7.1.1的Nexus 5X上进行了测试
但是这里的android模拟器不是真正的android设备

如果您使用模拟器,
单击仿真器右侧栏上的“扩展控件”按钮,然后发送GPS数据?
(按钮)

@kimochg好的。 我使用的是真实的设备进行测试,因此我需要将仿真器行为与下一次处理项目时的行为进行比较。

@Ascendance @ Daniel-ltw我遵循了该线程中的所有解决方案,无法摆脱可怕的navigator.geolocation未定义问题。 然后我登录了navigator

这是我回来的东西:

ProxyComponent
_attachGesture
_cleanScenesPastIndex
_clearTransformations
_completeTransition
_deltaForGestureAction
_detachGesture
_disableScene
_disableTVEventHandler
_doesGestureOverswipe
_eligibleGestures
...

然后我意识到这是来自导航器组件的。 渲染路线时使用(route, navigator) 。 果然,删除navigator变量并再次登录将产生:

WorkerNavigator
appCodeName
appName
appVersion
geolocation (...)
get geolocation
getValue()
set geolocation
setValue(newValue)
hardwareConcurrency

希望这可以帮助其他人-花费了我很多时间来了解问题所在。 :/

@kulmajabamaximumAge参数为我解决了任何缓存问题。 将其设置为0将强制其始终获得新位置。

对于其他在超时问题上苦苦挣扎的人来说,我读到有时候高精度的GPS通话可能需要一段时间(一分钟以上),尤其是在室内-如@RoBYCoNTe上面指出的。

从一开始就依靠高精度的呼叫可能不是最好的方法,也许首先获取低精度的呼叫,然后在后台启动高精度的呼叫将是更好的方法。 当然,这取决于您的需求,等待一分钟以上的电话并不适合所有人:)

同样,鉴于RN扩展了有关地理定位的网络规范,您可以在网络上找到与其相关的答案,例如恰当地命名为http://stackoverflow.com/questions/3752383/geolocation-is-so-slow-what-im-做错了

有谁能解决这个问题? 由于部分注册要求他们设置地理位置,因此某些用户甚至无法注册我的应用程序。 该问题仅在某些Android设备上发生,并且我没有使用3rd参数。 使我抓狂。 人们只是自动给我的应用1星评价,因为他们无法设置地理位置,哈哈哈。 >。>

@booboothefool尝试使用options参数并将highAccuracy传递为
假。 这样结果更快。

2017年2月20日星期一,上午9:50 booboothefool [email protected]
写道:

有谁能解决这个问题? 有些用户甚至无法注册我的
应用程序(由于注册的一部分)要求他们设置地理位置。
该问题仅在某些Android设备上发生,我没有
使用第三个参数。 使我抓狂。

-
您收到此邮件是因为您发表了评论。
直接回复此电子邮件,在GitHub上查看
https://github.com/facebook/react-native/issues/7495#issuecomment-281142941
或使线程静音
https://github.com/notifications/unsubscribe-auth/ADJE_BC-osVA45bcpejEI_paDEBykBs1ks5redJtgaJpZM4Ibete

@greyvugrin好吧,我会

也基于此: https :

似乎这些是默认选项。 enableHighAccuracy: falsetimeout: Infinity ,所以如果我不提供第三个参数,它是否应该已经这样做了?

@booboothefool,您对这个线程令人困惑是正确的。 据我所知,省略options参数的人可能已经解决了他们的问题,因为设置中的其他内容正在影响事情。

将enableHighAccuracy设置为true或false对我不起作用。
省略getCurrentPosition的第3个参数以使用本机模块中的默认值对我而言有效。

因此,问题可能出在timeout 。 地理定位有很多因素,从坠毁人员那里获得尽可能多的信息将有所帮助。

如果您已经删除了这些选项,并且RN实际上默认使用与web相同的参数,那么一切应该正常进行。 如果您仍然遇到问题,请查看用户是否已启用位置权限(并且您正在应用程序中进行检查)。

@greyvugrin

感谢您提供有关权限的重要提示。 我认为那是我所缺少的。 在实现https://github.com/lucasferreira/react-native-android-permissions之后(我更喜欢此API而不是https://facebook.github.io/react-native/docs/permissionsandroid.html),并指定enableHighAccuracy: false并设置timeout ,现在似乎对每个人都有效。

我的应用从Google Play商店上的1星开始,所有人都因为地理定位问题而将其丢弃到3.6星,哈哈哈! 👍

@booboothefool真是个好消息,很高兴听到!!!

我尝试了这里建议的所有方法。 无法从getCurrentPosition获得任何信息,但模拟器或Android设备上的超时。 watchPosition可以工作,但实际上并不能为用户提供最佳的用户体验,我只需要一次定位用户,就不需要让GPS浪费他们的电池。

我试过了:

  • enableHighAccuracy:否
  • 删除选项参数
  • 检查并询问权限android> = 23
  • 清单中的FINE和COARSE均显示。

没有更改getCurrentPosition的超时

这只是Android Studio仿真器开发人员将来有机会时必须修复/实现的东西。

但是,与此同时...您可以导入大的GPX跟踪文件,并使其以“ 1x”速度播放。 我从这里抓起了GPX ... ExpertGPS.com-> ca-trails.gpx
...此文件以“ 5x”的速度持续约8分钟,因此,以“ 1x”的速度应持续约40分钟。

将它(或另一个可能更大的GPX文件)加载到扩展选项->位置(右下角的加载GPS / KML按钮),点击播放按钮,然后关闭窗口...它将继续播放直到结束。 不幸的是,没有自动重复功能,这是Android Studio程序员的另一项功能要求。 :-)

这不是真的。 我在真实设备上遇到了相同的超时。
getCurrentPosition总是超时。 手表工作正常。 测试Z5,Nexus 5X
&Pixel,首次调用getCurrentPosition时所有超时。

2017年3月4日星期六,19:49 Deen Foxx, notifications@ github.com写道:

这只是Android Studio仿真器开发人员要做的事情
他们有机会时必须在将来修复/实施。

但是,与此同时...您可以导入大型GPX跟踪文件,然后
它以“ 1x”速度播放。 我从这里抓起了GPX ... ExpertGPS.com->
ca-trails.gpx
https://www.expertgps.com/data/downloading.asp?file=ca/ca-trails.gpx
...此文件以“ 5x”的速度持续了大约8分钟,因此它以“ 1x”的速度进行了
应该持续约40分钟。

将其(或另一个可能更大的GPX文件)加载到扩展中
选项->位置(右下角的加载GPS / KML按钮),点击播放
按钮,然后关闭窗口...它将一直播放,直到碰到
结束。 太糟糕了,没有自动重复功能-Android的另一个功能要求
Studio程序员。 :-)

-
您收到此邮件是因为您发表了评论。
直接回复此电子邮件,在GitHub上查看
https://github.com/facebook/react-native/issues/7495#issuecomment-284172310
或使线程静音
https://github.com/notifications/unsubscribe-auth/AACQ6AoZYXJ02DCmevcLmmF3tuOdg_SEks5ribJHgaJpZM4Ibete

删除第三个参数getCurrentLocation在模拟器上对我有用。

{
   timeout: 20000,
    maximumAge: 1000
}

我只是编码了三遍的可能性。 也许有点矫kill过正,但是哦。 这是代码段(带有注释)...

class FindNearMe extends Component {

  constructor(props) {
    super(props);

    this.state = {
      prevLatitude: 0.0,
      prevLongitude: 0.0,
      gotLocation: false,
      locating: false,
      loading: false
    };
  }

  handleGeolocationSuccess = (position) => {

    // Get a response, say we are done locating, even if it is still looking for a fine result.
    this.setState({ locating: false });

    // If we previously failed, we can clear the error if it just happens to still be visible.
    if (!this.state.gotLocation) {
      this.props.navigator.hideLocalAlert();  // Hide possibly open alert.
      this.setState({ gotLocation: true });  // Remove the previous failure state.
    }

    // Only proceed if there is an actual change in location.
    if (this.state.prevLatitude != position.coords.latitude ||
        this.state.prevLongitude != position.coords.longitude) {

      // Overwrite the old location with the new location.
      this.setState({
        prevLatitude: position.coords.latitude,
        prevLongitude: position.coords.longitude,
        loading: true // Only needed if you plan to get content from server.
      });

      // ... DO SOMETHING WITH THE UPDATED LOCATION ...
      // If you used a callback function (success or failure) be sure to include this...
      this.setState({ loading: false });
 };

  // This first, RoughError, means the "enableHighAccuracy: false" time-out occurred.
  handleGeolocationRoughError = (error) => {
    this.props.navigator.showLocalAlert('Attempting to pinpoint your location...', config.errorStyles);
    // Invalidate our current location
    this.setState({ gotLocation: false });
  };

  // This second, FineError, means the "enableHighAccuracy: true" time-out occurred.
  handleGeolocationFineError = (error) => {
    // If we got Rough location, I'm ignoring this. But, if neither rough nor fine succeeded...
    if (!this.state.gotLocation) {
      // ...try once more without the options.
      navigator.geolocation.getCurrentPosition(
        this.handleGeolocationSuccess,
        this.handleGeolocationFinalError
      );
    }
  };

  // This last, FinalError, means nothing worked and we're giving up.
  handleGeolocationFinalError = (error) => {
    if (!this.state.gotLocation) {
      this.props.navigator.showLocalAlert('Could not determine your location, sorry!', config.errorStyles);

      // Let our app know that we are not trying anymore.
      this.setState({ locating: false });
    }
  };

  goToNearMe = () => {
      // Track when we are attempting to get a location update.
      this.setState({ locating: true });

      // Try to get the rough location quickly.
      navigator.geolocation.getCurrentPosition(
        this.handleGeolocationSuccess,
        this.handleGeolocationRoughError,
        {
          enableHighAccuracy: false,
          timeout: 500,  // I have this set for half-second before popping up the alert.
          maximumAge: 0
        }
      );

      // But, also, simultaneously try to get the fine location.
      navigator.geolocation.getCurrentPosition(
        this.handleGeolocationSuccess,
        this.handleGeolocationFineError,
        {
          enableHighAccuracy: true,
          timeout: 7500,  // I have this set for 7.5 seconds, about the length of the first alert's visibility.
          maximumAge: 0
        }
      );
  };

  render() {
    return (
        <Container>
          <LocateMeButton
              onPress={this.goToNearMe}
              loading={this.state.loading || this.state.locating}
          />
          <Header>
            Use Current Location
          </Header>
        </Container>
    );
  }
}

export default FindNearMe;

我仅在本地开发仿真器上进行了测试,而未在生产中进行测试。 让我知道这是否对您有帮助。

我只是在想...如果您的rawError调用仅使用无选项版本,那么它可以作为两次通过完美地运行...

  goToNearMe = () => {
      // Track when we are attempting to get a location update.
      this.setState({ locating: true });

      // Try to get the rough location quickly.
      navigator.geolocation.getCurrentPosition(
        this.handleGeolocationSuccess,
        this.handleGeolocationRoughError,
// Just leave this off entirely (but default timeout is Infinity, so you'd never get the first alert!)...
//        {
//          enableHighAccuracy: false,
//          timeout: 500,  // I have this set for half-second before popping up the alert.
//          maximumAge: 0
//        }
// ...or try ujwal-setlur's method of leaving off the enableHighAccuracy portion...
        {
          timeout: 500,
          maximumAge: 0
        }
// NOTE: ujwal-setlur's method did NOT work for my Android emulator.
//             I had to comment out the options object completely for it to not time-out.
      );

      // But, also, simultaneously try to get the fine location.
      navigator.geolocation.getCurrentPosition(
        this.handleGeolocationSuccess,
//        this.handleGeolocationFineError,  // Wouldn't need this, make it your FinalError instead.
        this.handleGeolocationFinalError,
        {
          enableHighAccuracy: true,
          timeout: 7500,  // I have this set for 7.5 seconds, about the length of the first alert's visibility.
          maximumAge: 0
        }
      );
  };

这将使有问题的Android手机不再有延迟,但仍会尝试高精度。 然后,您将不再需要FineError,可以删除该代码。

  • 是的,我知道“ enableHighAccuracy:true”尝试在其他异步“粗糙”结果(特别是超时为Infinity)之前返回的可能性很小,因此会丢失/覆盖...但是我对此表示怀疑。 如果您真的想保持谨慎,则可以更改代码以测试该特定情况。

在这方面有什么进展吗?

Alex,此线程上有一些解决方案。 你尝试了什么? 它
一旦您有更多详细信息,可能还值得创建新票证,因为
如果上述解决方案均无效,则此线程很长。

2017年3月17日星期五,上午10:29 Alex Sinelnikov [email protected]
写道:

在这方面有什么进展吗?

-
您收到此邮件是因为有人提到您。
直接回复此电子邮件,在GitHub上查看
https://github.com/facebook/react-native/issues/7495#issuecomment-287419487
或使线程静音
https://github.com/notifications/unsubscribe-auth/ADJE_HLDGQEplAduqm3Zx5L74dv99mnhks5rmsLjgaJpZM4Ibete

喜欢你。 以上建议均无效。 我唯一的解决方案
在Android上获取位置是使用手表并更新UI来通知
用户,如果您的应用程序功能在locat上回复,那将会是什么情况。 别
麻烦getCurrentPosition在10个真实测试中的任何一个上都不起作用
我们运行各种Android版本的设备4+

2017年3月17日星期五,17:48灰色Vugrin, notifications @github.com写道:

Alex,此线程上有一些解决方案。 你尝试了什么? 它
一旦您有更多详细信息,可能还值得创建新票证,因为
如果上述解决方案均无效,则此线程很长。

2017年3月17日星期五,上午10:29 Alex Sinelnikov [email protected]
写道:

在这方面有什么进展吗?

-
您收到此邮件是因为有人提到您。
直接回复此电子邮件,在GitHub上查看
<
https://github.com/facebook/react-native/issues/7495#issuecomment -287419487

或使线程静音
<
https://github.com/notifications/unsubscribe-auth/ADJE_HLDGQEplAduqm3Zx5L74dv99mnhks5rmsLjgaJpZM4Ibete

-
您收到此邮件是因为您发表了评论。
直接回复此电子邮件,在GitHub上查看
https://github.com/facebook/react-native/issues/7495#issuecomment-287424598
或使线程静音
https://github.com/notifications/unsubscribe-auth/AACQ6DgWuUzw4hj7rmr8LDzcRHjEheIcks5rmsdSgaJpZM4Ibete

有时它起作用,有些则不起作用。 我已经尝试了上述所有解决方案,到目前为止还没有可靠的解决方案。 这真的让我发疯了:(

是否有任何本机模块可复制诸如getCurrentPosition之类的功能? 我正在寻找其他仓库,因为我无法编写Java代码。

未启用位置信息时, watchPosition有问题。 尽管我将超时设置为1000,但它从未抛出超时

在“ getCurrentPosition”上,它将引发超时,因此我可以触发“位置”对话框以启用GPS。 但是现在我从“ getCurrentPosition”继续

编辑:
我已经尝试了所有变体,现在知道了问题所在。 我可以让它工作,如果删除第三PARAMS设置位置模式设置为高精度或节省电池。 否则,它将无法正常工作。 我不知道如何告诉用户选择“高精度”或“省电”而不是“仅设备”,因为它对每个供应商都有不同的访问此菜单的方式。

上面有一条评论,在第三个参数中添加了enableHighAccuracy: false ,但不适用于“高精度”,“省电”或“仅设备”选项。 我认为地理定位的第三个参数对实际设备毫无用处。

location-mode-100621707-large

在我的情况下,删除maximumAge解决了该问题。

删除maximumAge

@nigelnindo是什么意思本机实现? 在RN中还是直接在Android中进行?

@ L3V147H4N直接在Android中。 您可以使用几个库,但是我已经看到大多数库与最新版本的RN不兼容。 如果对此有足够的兴趣,我不介意花费一些时间来创建一个简单的模块来帮助解决此线程中概述的Android上的地理位置问题。

也许您可以检查https://github.com/mauron85/react-native-background-geolocation#getlocationssuccess -fail

这是本机实现,对我来说效果很好。

我认为这个线程上的几乎每个人都会非常感激@nigelnindo
https://github.com/nigelnindo

在2017年4月3日星期一17:34奈杰尔·宁多[email protected]写道:

@ L3V147H4N https://github.com/L3V147H4N直接在Android中。 有
您可以使用几个库,但是我看过大多数
与最新版本的RN不兼容。 如果足够的话
对此感兴趣,我不介意花一些时间来创建一个简单的模块
以帮助解决此线程中概述的Android上的地理位置问题。

-
您收到此邮件是因为您发表了评论。
直接回复此电子邮件,在GitHub上查看
https://github.com/facebook/react-native/issues/7495#issuecomment-291198134
或使线程静音
https://github.com/notifications/unsubscribe-auth/AACQ6BwArzmfCk3TXfiRMp7kpdwMLM81ks5rsR-hgaJpZM4Ibete

无奈...我正在尝试使用navigator.geolocation.getCurrentPosition,但我不断收到错误消息:
位置请求超时。 对于Android,iOS可以正常运行。
我尝试将enableHighAccuracy设置为True / False,删除了第3个参数,并在AndroidManifest中添加了COURSE和FINE位置权限。

Android SDK 23,构建工具25.0.0
反应16.0.0-alpha.6
RN 0.43.3

谢谢你的帮助!

欢迎来到话题道格拉斯,很遗憾, getCurrentPosition不是
如您所见,在Android上可靠。
看看线程前面使用的一些解决方案
watchPosition代替

谢谢@raldred。
watchPosition似乎正在正常工作,感谢您的帮助!

@douglaswissett ,不客气。 希望不久将有针对getCurrentPosition强大解决方案。

获取地理位置后,我可以立即使用watchPosition然后clearWatch吗? 我有麻烦就这样做,是因为clearWatch只能被称为componentDidMount

@pewh是的。 我就是做这个的。
navigator.geolocation.clearWatch也可以随时调用。
只需保留对您组件上watchID的引用,该引用由对watchPosition的调用返回

从我在https://facebook.github.io/react-native/docs/geolocation.html上阅读的文档中,我不知道如何在watchPosition回调中获取this.watchID 。 我的用例是在收到新值后立即触发clearWatch

@pewh这是我的实现。 这不是完美的,但可以。
https://gist.github.com/raldred/b08cf60712eb87d81f05437444dff4ae

@raldred尝试了您的解决方案,其他人都没有解决

有什么解决办法吗? 在这里尝试一切,似乎什么也没有用,请帮助! 如果您可以分享一些摘要或其他内容

@ gerard0315您可以成功解决此问题?

它似乎可以在我真正的Android手机上使用

获取iOS的Outlook https://aka.ms/o0ukef


来自:豪尔赫Almonacid [email protected]
发送:2017年5月9日,星期二2:29:56 PM
收件人:facebook / react-native
抄送:Ujwal Setlur; 评论
主题:回复:[facebook / react-native] Android上的地理位置'enableHighAccuracy'总是超时(#7495)

有什么解决办法吗? 在这里尝试一切,似乎什么也没有用,请帮助! 如果您可以分享一些摘要或其他内容

-
您收到此邮件是因为您发表了评论。
直接回复此电子邮件,在GitHub https://github.com/facebook/react-native/issues/7495#issuecomment-300307037上查看,或忽略线程https://github.com/notifications/unsubscribe-auth/ AFkMXWcokXoYDpsw28UaiUSDtCvRpE3Rks5r4NrUgaJpZM4Ibete

我已经分享了一些片段,它们可以在运行中的真实设备上运行
Android 4-7。

在2017年5月9日,星期二22:29 Jorge Almonacid上, notifications@ github.com写道:

有什么解决办法吗? 在这里尝试一切,似乎没有任何效果,
请帮忙! 如果您可以分享一些摘要或其他内容

-
您收到此邮件是因为有人提到您。
直接回复此电子邮件,在GitHub上查看
https://github.com/facebook/react-native/issues/7495#issuecomment-300307037
或使线程静音
https://github.com/notifications/unsubscribe-auth/AACQ6HSlN8YS_jE6NY9w2vuk7Hv4Wjwfks5r4NrSgaJpZM4Ibete

当前,只有同时更改所有参数(经度,纬度,海拔)时,才有可能获得更新(在android仿真器中)。 如果仅更改一个或两个- nothing works

React-Native在Android上处理位置的方式存在先天缺陷。 (iOS似乎缺少此问题,iirc)

String provider = highAccuracy ? LocationManager.GPS_PROVIDER : LocationManager.NETWORK_PROVIDER;

LocationManager.GPS_PROVIDER is best for outdoors when you have a clear view of the sky

LocationManager.NETWORK_PROVIDER is best for indoors, since it uses networks (and cell towers?)

实际上,如果您想要超精确的位置,则需要同时使用所有/所有提供商。 然后,您想比较准确性,时间戳并接受更准确和新鲜的位置。

有两种方法可以执行此操作:

在React中:

设置两个watchID变量-> watchIDGPSwatchIDNetwork 。 然后设置两个观察者,一个带有enableHighAccuracy=trueenableHighAccuracy=false观察者,这将同时返回GPS提供者和网络提供者(室内的网络将更加准确)

React方式的问题在于它是在JS线程上完成的。 这可能会冻结资源不足设备上的应用程序。 尽管如此,它确实有效。

在本机中:

您将需要重写LocationModule.java作为自定义模块,以处理您选择的提供程序,并将位置报告回mLocationListener而不管它是哪个提供程序。 直到React-Native修复此“问题”。

@ralred ,感谢您的代码段,但是AndroidPermissions对象是什么?

我尝试了所有解决方案,但都失败了。
突然想起我的应用程序有一个地图模块,百度地图,一个像谷歌地图这样的中文地图(map.baidu.com),它可以获取标记和当前位置! 终于我做到了〜

您可以通过github搜索它,react-native-baidu-map

导入{
MapView,//地图视图(我不需要)
MapTypes,//输入为2D或3D(我不需要)
地理位置//有关位置的api(我需要)
}来自“ react-native-baidu-map”;

componentDidMount(){
Geolocation.getCurrentPosition()
.then(data => {
Alert.alert(JSON.stringify(data.latitude),JSON.stringify(data.longitude))
})
}

我不知道是否可以在其他国家/地区使用,只是通过使用某些地图应用程序的思考,您可以尝试react-native-maps或其他地图...

没有任何效果,watchPosition甚至无法在Android上调用,iOS完美运行。 它已经是RN v0.45.0(我现在是0.44.0),仍然没有解决? 来吧!

@rexlow
没有任何效果,我正在使用版本0.44。 您是否尝试过更新到v0.45?

@VietDucPhan它刚刚工作,完全是随机的。 仍为0.44.0

@rexlow哦,对你有好处。 现在,我只需要运气就可以打击我。

您是否尝试过仅删除选项结构? 那是唯一对我有用的东西。

获取iOS的Outlook https://aka.ms/o0ukef


来自:viet_duc_phan [email protected]
发送:2017年6月18日星期日11:26:15 PM
收件人:facebook / react-native
抄送:Ujwal Setlur; 评论
主题:回复:[facebook / react-native] Android上的地理位置'enableHighAccuracy'总是超时(#7495)

@rexlow https://github.com/rexlow哦,对您有好处。 现在,我只需要运气就可以打击我。

-
您收到此邮件是因为您发表了评论。
直接回复此电子邮件,在GitHub https://github.com/facebook/react-native/issues/7495#issuecomment-309349488上查看,或使线程https://github.com/notifications/unsubscribe-auth/静音

@rexlow @ ujwal-setlur只想让你们知道我的运气很好。 它正在工作,而且完全是随机的。 我什么都没改变。

您是否在真实设备上尝试过?

在2017年6月20日星期二19:18 viet_duc_phan, notifications @github.com写道:

@rexlow https://github.com/rexlow @ ujwal-setlur
https://github.com/ujwal-setlur只想让你们知道
运气打击我。 它正在工作,而且完全是随机的。 我没有改变
任何东西。

-
您收到此邮件是因为有人提到您。
直接回复此电子邮件,在GitHub上查看
https://github.com/facebook/react-native/issues/7495#issuecomment-309843462
或使线程静音
https://github.com/notifications/unsubscribe-auth/AACQ6OVyeCsOgd-qevP9CrP9XJMhwaxsks5sGAz3gaJpZM4Ibete

@raldred始终在真实设备上进行测试。

@VietDucPhan您可以设置一个重现该问题的示例吗?

2017年6月20日星期二20:52 viet_duc_phan, notifications @github.com写道:

@raldred https://github.com/raldred始终在真实设备上进行测试。

-
您收到此邮件是因为有人提到您。
直接回复此电子邮件,在GitHub上查看
https://github.com/facebook/react-native/issues/7495#issuecomment-309870269
或使线程静音
https://github.com/notifications/unsubscribe-auth/AACQ6N5SVbYeDEeY9FRnTQSrvpLwKL5aks5sGCLmgaJpZM4Ibete

@raldred此链中的原始报告具有代码段:

navigator.geolocation.getCurrentPosition(
      (position) => {
        console.log(position);
       },
       (error) => {
        console.log(error)
      },
      {enableHighAccuracy: true, timeout: 20000, maximumAge: 10000}
);

对我来说也失败了。 解决它的唯一方法似乎是不包括options参数:

navigator.geolocation.getCurrentPosition(
      (position) => {
        console.log(position);
       },
       (error) => {
        console.log(error)
      }
);

@dreallday是正确的,反应本机Fused API ,该

我发现react-native-fused-location对于在Android上发出位置请求非常有用。

@raldred您好,很抱歉,最近没有检查邮件,但是它不再起作用。

@ derman232当应用程序进入后台时,react-native-fused-location是否可以工作?

@rexlow很抱歉,不知道答案,这不是我的应用程序所需的功能。

只是提供有关如何解决此问题的意见:

  • 问题是android> = 6.0要求在运行时授予权限
  • 这个计算器的问题进行了详细介绍:问题
  • 我使用React Native的PermissionsAndroid模块来获取权限

现在一切正常。

你好
没用。 我尝试了一切。
请指教。
谢谢

我真的很想帮助人们解决这个问题。
我们有3个可实时使用位置的React本机应用程序。 对30多个运行Gingerbread到Nougat的真实android设备进行质量检查。
在整个用户测试过程中,所有操作均正常进行,自此以来,我们没有任何有关实时用户问题的报告。

@adriancuco ,您能否分享您的实现和清单,以便我们进一步尝试和帮助。

  • RN版本?
  • 您遇到哪些Android版本的问题?
  • 您在哪些设备上遇到问题?

您的实现或设备配置会很复杂,这是弄清楚那是什么的问题。

集会

抱歉。 我的错!
在自杀之前,我决定检查一下手机上的位置设置,就像几天前我读到的那样,它刚刚启用了GPS。 ;(
因此我启用了GPS,Wifi等功能,现在一切正常。
真的很感激。
非常感谢

关于此问题有任何更新吗?

仍然没有解决方案。


来自:adriancuco [email protected]
发送:2017年7月4日,星期二2:44:28 PM
收件人:facebook / react-native
抄送:Marouen SAYARI; 评论
主题:回复:[facebook / react-native] Android上的地理位置'enableHighAccuracy'总是超时(#7495)

集会

抱歉。 我的错!
在自杀之前,我决定检查一下手机上的位置设置,就像几天前我读到的那样,它刚刚启用了GPS。 ;(
因此我启用了GPS,Wifi等功能,现在一切正常。
真的很感激。
非常感谢

-
您收到此邮件是因为您发表了评论。
直接回复此电子邮件,在GitHub https://github.com/facebook/react-native/issues/7495#issuecomment-312881724上查看,或使线程https://github.com/notifications/unsubscribe-auth/静音

@ m-sayari您将为我们提供更多信息以提供帮助。

  • RN版本
  • Android Build目标版本
  • Android设备版本
  • 您遇到此问题的设备。

它们将是导致问题的特定于您的实现/设置的东西。 按照我先前的说法,我们可以在多个实时应用程序中正常工作。

在这里解决! RN 0.45.1在Android 6上使用Redmi 4A。

我在componentDidMount()内部调用navigator.geolocation.getCurrentPosition()时遇到问题
代替getCurrentPosition而是使用相同的参数调用watchPosition()。

@raldred
RN版本
0.46
Android Build目标版本
API 22
Android设备版本
6.0.1
您遇到此问题的设备。
连结5

不使用第三个参数“ options”调用getCurrentLocation解决了我的问题。 将'enableHighAccuracy'设置为false对我不起作用

您好@raldred ,与RN 0.47上报告的其他问题相同。

  • RN版本:0.47
  • RN默认保留的Android构建目标版本:
    compileSdkVersion 23
    buildToolsVersion "23.0.1"

    defaultConfig {
        minSdkVersion 16
        targetSdkVersion 22
  • Android设备版本:6.0.1、7.0
  • 您在以下设备上遇到此问题的设备:

    • 配备Android 6.0.1的Nexus 5

    • 小米Redmi 3S与Android 6.0.1

    • 装有Android 7.0的Android模拟器

当我在设备设置中设置“仅设备”位置模式时, getCurrentPosition可以很好地工作,但是当模式设置为“高精度”时, Location request timed out停止工作(

我需要省略第三个参数,以使getCurrentPosition至少在“仅设备”模式下工作:

    navigator.geolocation.getCurrentPosition(setLocation);

我以为这对我有用,但是还没有测试其他情况。
因此,从我的选择来看,我发现有两个项目彼此冲突maximumAgeenableHighAccuracy ,我认为这两个选项在略有不同的方面是相同的,而最大年龄可以确保您即使准确度较低,也会根据您的设置获取最新的地理位置, enableHighAccuracy确保您获得了最新,最准确的位置,以下选项也存在相同的问题。
{enableHighAccuracy: true, timeout: 20000, maximumAge: 60000}直到我删除了最大年龄并留下enableHighAccuracy希望这对某人有帮助。

我只是从master那里构建react-native来尝试commit 7e11bad86fd21ce1a8408218e66ce85993d9db69是否可以解决此问题。 可悲的是,我仍然遇到与以前相同的错误。

@olieidel监视位置实际有效,还确保您的设备已授予对应用程序的位置访问权限,并且已启用您的位置服务。

@olieidel您可以使用以下API PermissionsAndroid检查您的应用是否有权访问位置

@mrbarde感谢您的快速回复!

啊,经过一整天的调试,这是我的发现以及相关的解决方法:
RN 0.46.4,设备:Nexus 5X,API 25

定位模式:仅设备

  • getCurrentPositionenableHighAccuracy: true :在GPS信号可用时工作,否则超时
  • getCurrentPositionenableHighAccuracy: false :不起作用(超时)。 可能需要位置服务(仅位置模式!=设备)。
  • watchPositionenableHighAccuracy: true :GPS信号可用时工作,否则超时
  • watchPositionenableHighAccuracy: false :不起作用

定位模式:高精度

  • getCurrentPositionenableHighAccuracy: true :在GPS信号可用时工作,否则超时。 可能会返回较旧的位置,具体取决于您的maximumAge设置。
  • getCurrentPositionenableHighAccuracy: false :在5-6s后工作(如前所述)。
  • watchPositionenableHighAccuracy: true :在GPS信号可用时工作,否则超时
  • watchPositionenableHighAccuracy: false :作品

概要
如果您的位置模式是仅设备,则应该期望始终有GPS信号。 在所有其他情况下,您需要定位服务(定位模式!=仅设备)。
我想这是定位API的所有预期的行为,我刚刚发现了地球的相当于不平坦的,但是,这是地狱调试,如果你有设置了定位模式的设备==设备只(一模拟器(一种新配置的设备),而您正坐在没有gps信号可用的房间里。 在这种情况下,您只会得到超时。

解决方法
如本线程中所述,我还使用了两个watchPosition侦听器,它们为enableHighAccuracy了不同的值,并简单地获取了两者的第一个值,然后将其删除。 试着用这种方法,我给人的印象是两个听众实际上都返回相同的位置,但是我当天的调试容忍度已经用尽了……
这假定您的位置模式并非仅设备。

@olieidel当然,我想知道为什么没有人直接使用react native Geolocation API,如果它没有用或者就是不起作用,我认为应该用navigator.geolocation代替它,因为这样做可以想知道,尝试用您的解决方法提出拉取请求,看看Facebook是否会喜欢。 并感谢您付出了更多的努力来进一步挖掘。

我花了一段时间才不断重现此问题。

仅当位置模式设置为“高精度”并且在室内且没有GPS信号的情况下使用当前位置API时,我才在具有Android 5.1和6.0的三星手机上遇到此问题。 即使在“高精度”模式下,它在Oppo手机上或在GPS信号清晰的户外也能正常工作。

我将很快测试此线程中建议的一些解决方案。

@mrbarde只是为了澄清:我正在使用navigator.geolocation 。 :)

@olieidel我知道,只是把它放在那里,文档应该反映navigator.geolocation而不是Geolocation Api。

嗨,大家好,您知道在Android上您可能有权访问位置,但是用户已从操作系统设置中关闭了位置。 因此,调用navigator.getCurrentPosition()仍然会超时。

这是带有两种方法的Java代码段。 checkIfLocationAvailable检查用户是否在设置中打开了位置信息。 requestUserToActivateLocation将提示用户打开位置。

package location;

import android.Manifest;
import android.app.Activity;
import android.content.BroadcastReceiver;
import android.content.Intent;
import android.content.IntentSender;
import android.content.pm.PackageManager;
import android.location.Location;
import android.os.Build;
import android.os.Bundle;
import android.provider.Settings;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.v4.content.ContextCompat;
import android.text.TextUtils;
import android.util.Log;

import com.facebook.react.bridge.Promise;
import com.facebook.react.bridge.ReactApplicationContext;
import com.facebook.react.bridge.ReactContextBaseJavaModule;
import com.facebook.react.bridge.ReactMethod;
import com.google.android.gms.common.ConnectionResult;
import com.google.android.gms.common.api.GoogleApiClient;
import com.google.android.gms.common.api.PendingResult;
import com.google.android.gms.common.api.ResultCallback;
import com.google.android.gms.common.api.Status;
import com.google.android.gms.location.LocationRequest;
import com.google.android.gms.location.LocationServices;
import com.google.android.gms.location.LocationSettingsRequest;
import com.google.android.gms.location.LocationSettingsResult;
import com.google.android.gms.location.LocationSettingsStates;
import com.google.android.gms.location.LocationSettingsStatusCodes;



/**
 * Created by nigelnindo on 11/28/16.
 */
public class LocationBridge extends ReactContextBaseJavaModule implements GoogleApiClient.ConnectionCallbacks, GoogleApiClient.OnConnectionFailedListener {
    public LocationBridge(ReactApplicationContext reactContext) {
        super(reactContext);
    }

    public GoogleApiClient googleApiClient;

    <strong i="10">@Override</strong>
    public String getName() {
        return "LocationBridge";
    }

    <strong i="11">@ReactMethod</strong>
    public void checkIfLocationAvailable(final Promise promise){

        int locationMode = 0;
        String locationProviders;
        boolean isAvailable = false;

        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT){
            try {
                locationMode = Settings.Secure.getInt(getReactApplicationContext().getContentResolver(), Settings.Secure.LOCATION_MODE);
            } catch (Settings.SettingNotFoundException e) {
                e.printStackTrace();
            }

            isAvailable = (locationMode != Settings.Secure.LOCATION_MODE_OFF);
        } else {
            locationProviders = Settings.Secure.getString(getReactApplicationContext().getContentResolver(), Settings.Secure.LOCATION_PROVIDERS_ALLOWED);
            isAvailable = !TextUtils.isEmpty(locationProviders);
        }

        boolean coarsePermissionCheck = (ContextCompat.checkSelfPermission(getReactApplicationContext(), Manifest.permission.ACCESS_COARSE_LOCATION) == PackageManager.PERMISSION_GRANTED);
        boolean finePermissionCheck = (ContextCompat.checkSelfPermission(getReactApplicationContext(), Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED);

        boolean finalResult = (isAvailable && (coarsePermissionCheck || finePermissionCheck));

        Log.e("FINAL RESULT", Boolean.toString(finalResult));

        promise.resolve(Boolean.toString(finalResult));

    }

    <strong i="12">@ReactMethod</strong>
    public void requestUserToActivateLocation(final Promise promise){

        Log.e("LOCATION_BRIDGE:", "called activate location function");

        if (googleApiClient == null) {
            Log.e("LOCATION_BRIDGE: ", "googleApiClient is null");
            googleApiClient = new GoogleApiClient.Builder(getReactApplicationContext())
                    .addApi(LocationServices.API)
                    .addConnectionCallbacks(this)
                    .addOnConnectionFailedListener(this).build();
            googleApiClient.connect();
        }

        LocationRequest locationRequest = LocationRequest.create();
        locationRequest.setPriority(LocationRequest.PRIORITY_BALANCED_POWER_ACCURACY);
        locationRequest.setInterval(30 * 1000);
        locationRequest.setFastestInterval(5 * 1000);
        LocationSettingsRequest.Builder builder = new LocationSettingsRequest.Builder()
                .addLocationRequest(locationRequest);

        //**************************
        builder.setAlwaysShow(true); //this is the key ingredient
        //**************************

        Log.e("LOCATION_BRIDGE", "Created builder");

        PendingResult<LocationSettingsResult> result =
                LocationServices.SettingsApi.checkLocationSettings(googleApiClient, builder.build());
        result.setResultCallback(new ResultCallback<LocationSettingsResult>() {
            <strong i="13">@Override</strong>
            public void onResult(LocationSettingsResult result) {
                Log.e("LOCATION_BRIDGE: ", "onResult callback invoked");
                final Status status = result.getStatus();
                final LocationSettingsStates state = result.getLocationSettingsStates();
                switch (status.getStatusCode()) {
                    case LocationSettingsStatusCodes.SUCCESS:
                        Log.e("LOCATION_BRIDGE: ", "Location settings satisfied");
                        // All location settings are satisfied. The client can initialize location
                        // requests here.
                        promise.resolve("true");
                        break;
                    case LocationSettingsStatusCodes.RESOLUTION_REQUIRED:
                        Log.e("LOCATION_BRIDGE", "Location resolution required");
                        // Location settings are not satisfied. But could be fixed by showing the user
                        // a dialog.
                        try {
                            // Show the dialog by calling startResolutionForResult(),
                            // and check the result in onActivityResult().
                            status.startResolutionForResult(
                                    getCurrentActivity(), 1000);
                            promise.resolve("awaiting");
                        } catch (IntentSender.SendIntentException e) {
                            Log.e("LOCATION_BRIDGE", "could not send intent");
                            promise.reject("LOCATION_BRIDGE", "could not send intent");
                        }
                        break;
                    case LocationSettingsStatusCodes.SETTINGS_CHANGE_UNAVAILABLE:
                        Log.e("LOCATION_BRIDGE", "location settings are unavailable");
                        // Location settings are not satisfied. However, we have no way to fix the
                        // settings so we won't show the dialog.
                        promise.reject("LOCATION_BRIDGE", "settings change is not available");
                        break;
                }
            }
        });

    }

    <strong i="14">@Override</strong>
    public void onConnected(<strong i="15">@Nullable</strong> Bundle bundle) {
        Log.e("LOCATION_BRIDGE", "CONNECTED");
    }

    <strong i="16">@Override</strong>
    public void onConnectionSuspended(int i) {
        Log.e("LOCATION_BRIDGE", "SUSPENDED");
    }

    <strong i="17">@Override</strong>
    public void onConnectionFailed(<strong i="18">@NonNull</strong> ConnectionResult connectionResult) {
        Log.e("LOCATION_BRIDGE", "CONNECTION FAILED");
        Log.e("LOCATION_BRIDGE", connectionResult.toString());
        if (connectionResult.hasResolution()){
            try {
                connectionResult.startResolutionForResult(getCurrentActivity(), 1);
            } catch (IntentSender.SendIntentException e) {
                e.printStackTrace();
            }
        }
        else{
            Log.e("LOCATION_BRIDGE","CONNECTION FAILURE HAS NO RESOLUTION");
        }
    }
}

自从我开始使用此功能以来,我就没有遇到过Android定位问题。 希望它将帮助某人。

当然,您需要将compile 'com.google.android.gms:play-services-location:x.x.x'app/build.gradle ,并按照此处所述创建本机模块。 不知道这是否足以创建独立的npm库。

@nigelnindo ,您好,实际上有一个React Native API叫做PermissionsAndroid
您可以检查以确保用户已启用该应用的位置权限
我遇到了与您指出的问题相同的问题,因此以下是我要解决的问题。

我首先检查用户是否已授予应用访问设备位置的权限

PermissionsAndroid
.check("android.permission.ACCESS_FINE_LOCATION")
.then((granted) => {
    if(granted){
        // do something
        return;
    }
    // do something else
}).catch((err) => {
    // handle error
});

然后使用下面的代码触发一个函数,这将要求用户
授予位置访问该应用的权限。

PermissionsAndroid
.request("android.permission.ACCESS_FINE_LOCATION")
.then((resp) => {
    if(resp == "granted"){
        _self._watchLocation();
    }else{
        this.props.watchLocSuccess();
    }
    // set state
    _self.setState({
        requestLocation: false
    });
    // 
}).then((err) => {
    // handle error
});

这为我解决了问题,现在我没有位置问题,希望这对外面的人有所帮助。

嗨, @mrbarde ,我要补充一点,除了上面的代码片段之外,我还使用PermissionsAndroid库。 正如我之前提到的:

嗨,大家好,您知道在Android上您可能有权访问位置,但是用户已从操作系统设置中关闭了位置。

换句话说,您的应用可以有权访问通过PermissionsAndroid获取的位置,但是如果用户通过其状态栏快捷方式或转到Settings -> Location -> Off getCurrentPosition()来关闭位置,

@nigelnindo yh在这种情况下,我真的会建议您解决方案,您是否有可能对此进行公关? 我的意思是,它确实可以节省很多时间,我使用外部程序包来处理此问题,因为我无法编写Java,尽管我真的希望自己有时间学习它。 如果这是在React中正式发布的,我宁愿这样做,我对依赖第三方库来处理诸如此类的真正核心事物表示怀疑,我担心一致性。

尝试在23(16-22)下的build.gradle(app)上更改(Android) TargetSdkVersion 。 它将起作用!

因为,我们需要AndroidManifest文件的使用许可。 和AndroidManifest文件仅在23(16-22)下的SDK处调用。

并且不要忘记添加:

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

不要删除maxAge参数!

如果这样做,GPS模块将返回上次缓存的结果,直到从卫星获取实际位置为止。 可能会将其位置缓存在远离您实际位置的另一个应用程序中。 而且,如果您尝试保存一些轨迹,则前几个点可能会显示与实际位置相距甚远的位置。

@pavelpashkovsky您可以显示一些事实或官方文档来支持您的主张吗?

@rexlow我刚刚描述了测试结果,因为大约1周前我遇到了同样的问题并找到了这个主题。

我大约进行了30次测试。 在最初的1-5秒内,我收到了3-4个位置不正确的情况(直到GPS找到卫星信号)

@pavelpashkovsky我现在也面临着同样的问题。 虽然我的配置中有maximumAge: 1000 。 就像您说的那样,它似乎在缓存先前的位置。

@rexlow你是对的。 在您的情况下,GPS保持位置持续1秒钟。

但是我用maximumAge获得的最好结果是:0,当gps不保存任何结果并且总是尝试获取实际位置时(如果无法从卫星获取位置,则报错)。

我可以确认删除最大值会在我测试过的Oppo手机上引起问题。 它将使用非常旧的缓存。

这一直在我身上发生。 原来我的地理位置许可已在“应用信息->许可”中关闭。 我不知道为什么会这样,但是这些权限似乎覆盖了我们在运行时请求的权限。 也许其他人也有这个问题

嗨(抱歉我的英语)。
我认为增加maximumAge将解决问题。

RN 0.48地理位置文档:
Geolocation API扩展了Web规范: https :

并根据:
https://developer.mozilla.org/zh-CN/docs/Web/API/PositionOptions/enableHighAccuracy

https://developer.mozilla.org/zh-CN/docs/Web/API/PositionOptions/timeout
特别是
https://developer.mozilla.org/zh-CN/docs/Web/API/PositionOptions/maximumAge

在具有此选项的方案中:
{enableHighAccuracy: true, timeout: 10000, maximumAge: 30000}

设备的GPS芯片尝试连接到卫星。 如果在超时时间段(10000 ms)中建立的连接将被返回,而没有任何错误,如@RoBYCoNTe所说: issuecomment-220580494,但是如果GPS连接失败或超时,设备将尝试返回一个缓存的经度和经度,其最大使用期限设置为选项(30000毫秒)。 如果存在某些东西将被返回,否则返回错误代码3,主题中出现超时错误。

我认为增加连接的超时时间(至少25000 ms)和特别增加maximumAge (至少3600000 ms = 1小时)是最好的解决方案!

{enableHighAccuracy: true, timeout: 25000, maximumAge: 3600000}为我工作

_emulator config_:在超时期间,您应该通过模拟器设置中的“位置”菜单发送虚拟位置信息(纬度和经度)。 (这将模拟卫星连接)

{ enableHighAccuracy: true, timeout: 60000, maximumAge: 1200 }为我工作。 对我来说,这不是最大年龄,而是我愿意等待的时间。

(仅限Android)
我认为这个问题不是错误。
在React Native中,地理定位工作如下:

  • 高精度意味着GPS定位
  • 禁用后,它将从网络提供商获取位置
  • maximumAge允许您不必每次都提取新职位(这既耗时又耗电),而是依靠缓存的职位

基本上,GPS Provider的速度比Network Provider慢,并且视您所在的位置而定,它始终无法正常运行(如果GPS无法接通电话,您将超时)。 Network Provider更快,更易访问,但作为权衡取舍,准确性较低(我最差的是2000米)。

如果使用highAccuracy超时,则意味着GPS无法联系到您。
在这种情况下,请考虑默认禁用它,并随着它变得越来越准确而更新位置。 您的用户在这种情况下不会等待。

就我而言,我实现了自己的观察者,比较位置并始终返回更精确的结果。 默认RN实现的问题在于它依赖于GPS Provider或Network Provider,但不返回两者的折衷方案。 您可能必须在JS或Native上进行处理。

希望能有所帮助。

仅在Android上测试。

我设法使其在以下情况下正常工作,并确保启用了位置:

  • 如果您通过Android模拟器运行应用程序,则必须放置选项,否则它将失败。
navigator.geolocation.getCurrentPosition(
    (position) => {
        this.setState({currentLocation: {lat: position.coords.latitude, lng: position.coords.longitude}})
    }, (error) => {
        alert("Geolocation error: "+error.message);
    },
    {enableHighAccuracy: true, timeout: 20000, maximumAge: 0}
);

我只是使用扩展控件将所需的位置发送到应用程序。

  • 如果您通过真实的手机运行应用程序,则必须忽略选项,否则它将失败。
navigator.geolocation.getCurrentPosition(
    (position) => {
        this.setState({currentLocation: {lat: position.coords.latitude, lng: position.coords.longitude}})
    }, (error) => {
        alert("Geolocation error: "+error.message);
    }
);

这将获取您的当前位置

我们遇到了同样的问题!

在不久的将来的发行版中会对此进行修复吗?

我尝试了一些建议的解决方案( exampleexampleexampleexample ),但没有一个解决了问题。 但是我需要说的是,在以下情况下我没有找到任何参考:

应用程式

  • Android 6.x
  • 反应16.1.0
  • React-Native 16.50.3

使用场景

  • Android手机没有_no SIM卡_,它们是_公司所有的_,并且只允许连接WIFI。

我仍然收到Geolocation timed out, code 3错误...

有人解决了吗?

_更新_(2017-11-13):

我通过将Settings >> Privacy >> Location >> ModeHigh accuracy解决了(至少暂时)

你好
我找到了一个很好的解决方案!
请先阅读我对此问题的先前评论: #issuecomment-331830285

解:
第一次调用navigator.geolocation.getCurrentPosition其中: {enableHighAccuracy: true, timeout: 60000, maximumAge: 0}作为PositionOptions ,这将返回实际当前头寸。
如果先前的请求超时,然后调用navigator.geolocation.getCurrentPosition并调用: {enableHighAccuracy: false, timeout: 30000, maximumAge: 3600000}作为PositionOptions ,这将返回LowAccuracy位置作为后备,并且_(我认为)_永不超时!
样例代码:

const GeoHightAccuracy = () => {
  return new Promise((resolve, reject) => {
    navigator.geolocation.getCurrentPosition(
      (locHightAccuracy)=>{
        resolve(locHightAccuracy)
      },
      (error)=>{
        GeoLowAccuracy()
        .then((locLowAccuracy)=>{resolve(locLowAccuracy)})
        .catch((err)=>{reject(err)});
      },
      {enableHighAccuracy: true, timeout: 60000, maximumAge: 0}
    )
  });
};
const GeoLowAccuracy = () => {
  return new Promise((resolve, reject) => {
    navigator.geolocation.getCurrentPosition(
      (locLowAccuracy)=>{
        resolve(locLowAccuracy)
      },
      (error)=>{
        reject(error)
      },
      {enableHighAccuracy: false, timeout: 15000, maximumAge: 3600000}
    )
  });
};



md5-4cb745c8e66bae2435e8bf78ce42a9c0



GeoHightAccuracy()
.then(locationData => console.log(locationData))
.catch(error => console.log(error));

希望有用。

我在这里有同样的问题!
我无法让navigator.geolocation在我的android真实设备上工作。

我相信这里没有什么可以固定的,地理位置正在按预期工作。 阅读我上面的帖子。

@Rewieer ,谢谢您的回复!

我正在使用此代码在我的应用程序上测试navigator.geolocation。

var options = {
  enableHighAccuracy: true,
  timeout: 5000,
  maximumAge: 5000
};

function success(pos) {
  var crd = pos.coords;
  alert(crd.latitude + " " + crd.longitude);
};

function error(err) {
  alert('ERROR(' + err.code + '): ' + err.message);
};

navigator.geolocation.getCurrentPosition(success, error, options);

我总是得到ERROR(3): Location request timed out
使用所有选项组合。
我可以在地图上看到我的位置的蓝点,并且GPS可以正常工作,但是我无法获得位置或无法通过navigator.geolocation进行编程工作。

可能的问题是:

  • 模拟器/手机配置错误
  • 不在gps覆盖的区域(例如,在建筑物中或在建筑物较大的街道中效果不佳)
  • 超时时间太早

在这种情况下,使用网络位置似乎更好。 您是否尝试在没有选项的情况下获取当前头寸? (这将使用与网络相关的基础结构来获得位置)

我正在使用真正的android设备(5.1版)
我可以使用react-native-maps确定位置(我的应用程序内部地图上正确的蓝点位置)+我可以使用google maps应用程序并转到我的位置(GPS可以工作)。
我正在使用一个很大的超时,将enableHighAccuracy切换为true和false,删除选项...等。 所有都无法通过navigator.geolocation获取数据。

您是否使用原生API在Android上弄脏了手?

2017-11-16 15:19 GMT + 01:00 Badis Merabet [email protected]

我正在使用真正的android设备(5.1版)
我可以使用react-native-maps确定我的位置(正确的蓝色
在我的应用程序内在地图上的指向位置)+我可以使用Google Maps应用程序,
转到我的位置(GPS可以正常工作)。
我正在使用较大的超时时间,将enableHighAccuracy切换为true和false,
删除选项...等。 都无法获得navigator.geolocation
数据。

-
您收到此邮件是因为有人提到您。
直接回复此电子邮件,在GitHub上查看
https://github.com/facebook/react-native/issues/7495#issuecomment-344935653
或使线程静音
https://github.com/notifications/unsubscribe-auth/ALuPm5XL1tNLCniOMR4YAMI4ZC2fKxrsks5s3ESBgaJpZM4Ibete

是的@Rewieer ,我同意,错误的原因是配置错误。

在模拟器中,我们必须在超时之前通过模拟器设置发送纬度和经度!

我的解决方案#issuecomment-331830285首先尝试通过GPS和卫星连接获取真实的当前位置,如果请求超时(或发生任何其他错误),则尝试使用与网络相关的基础结构来获取LowAccuracy位置。

@Rewieer我从未使用过android native API。 我只在做JavaScript开发。

@badis,请发送您的代码和错误日志。

@badis
RN Doc:
要请求访问位置,您需要在应用程序的AndroidManifest.xml中添加以下行:

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

使用react-Native时,您应该了解一些有关底层本机环境的信息,因为使用React-Native时,此类问题经常发生。
实际的最佳方法(从用户角度出发)是在开始时获取一个近似值,并对其进行校正,因为GPS可能需要一些时间,具体取决于您的位置和附近卫星的位置。 我知道网络位置可能看起来很粗糙,但我想并不是每个人都住在旧金山:)

@Rewieer @hoorsa
这是我进行功能测试的演示代码: https :
看看地图页面。
我只想知道代码是否正确并为其他人工作。
之后,我将尝试一边检查设备设置和位置是否有问题。

谢谢你们 !

@badis您是否将<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />到应用程序的AndroidManifest.xml?

@badis我昨天有同样的问题。 如果您只是按照https://github.com/facebook/react-native/issues/7495#issuecomment -228730196的建议删除最后一个参数(我知道这是不理想的),它确实可以工作。

android的默认选项是什么? 也许可以帮助解决这一问题

我认为我们使用了这些默认值(来自检查LocationModule.java):

{
enableHighAccuracy:否,//不要使用GPS
maximumAge:Double.POSITIVE_INFINITY,//接受任何缓存的位置
超时:Long.MAX_VALUE,
distanceFilter:100
}

同样,我们也遇到相同的位置错误,禁用第三个选项参数适用于“高精度”和“省电”模式。 但是,设备每次都只会发生故障。 无论将设备设置为哪种模式,enableHighAccuracy都必须设置为true才能失败。

这件事甚至还可以像Android Dev网站建议的那样利用

禁用第三个选项参数适用于“高精度”和“省电”模式。

@mkpietrzyk如此省略options在这两种模式下为您解决了它?

@natterstefan

是的,对于Android,我使用了默认参数...但是对于我的应用程序而言,它具有接近无限的超时时间和maximumAge,这有点像是一个应用程序杀手,因为我需要知道用户在哪里检查某些条件。

在这里使用@hoorsa解决方案检查gps是否正常。 但是无论如何,这对于gps来说是非常棘手的,并且有时不能对highAccuracy做出响应……这就是为什么我不认为它工作得很好,但是嘿,还可以。

我遇到了同样的问题,我需要将超时设置为非常高的时间才能正常工作,但是用户将需要更快地访问信息。 首次创建应用程序后,我可以在半秒内记录访问精细位置的权限是否有效。 精确定位的实现根本无法在Android上正常运行。
作为参考,我已经尝试过使用/不使用任何参数。 即使没有任何其他选项,有时仍然无法加载位置。 测试是在One Plus One上完成的

我也有这个超时问题。

RN .50.3

尝试使用和使用maximumAge参数调用API:

{enableHighAccuracy:true,超时:10000},

我还用权限请求包装了此呼叫,所以这不是问题:

PermissionsAndroid.request(
权限Android.PERMISSIONS.ACCESS_FINE_LOCATION,

设备上启用了高精度模式。
清单具有正确的权限。

在我的Galaxy S7上-它可以解决位置问题。
在我的Pixel 2上-10秒超时后在没有gps信号的位置超时。
在模拟器上-超时10秒后超时,除非我转到展开控件上的“位置”选项卡,然后单击“发送”以发送位置。

似乎在没有gps信号的情况下,navigator.geolocation.getCurrentPosition无效,即使从先前使用位置的另一个应用程序缓存了较旧的位置也是如此。

我将通过尝试高精度来解决此问题,然后像@olieidel一样

我和@jacksontbryan有相同的问题,但是如果省略maximumAgegetCurrentPosition确实会使用缓存的位置。

在Galaxy S7上似乎可以正常工作,但在我的LG G6上却不能正常工作。 在LG上,如果设置了maximumAge,它几乎总是超时。 如果未设置maximumAge,它将使用旧位置。

编辑:似乎完全省略了options参数。

我建议所有人在Android上使用自己的本机模块实现来获得稳定的结果。 实施起来非常容易,您将获得对GPS的更多控制权,无需担心您的应用程序无法在某些设备上运行。

    public Location getBestLastKnownPosition(Context context) {
        LocationManager locationManager = (LocationManager)context.getSystemService(Context.LOCATION_SERVICE);
        List<String> providers = locationManager.getProviders(true);
        Location bestLocation = null;
        for (String provider : providers) {
            Location l = locationManager.getLastKnownLocation(provider);
            if (l == null) {
                continue;
            }
            if (bestLocation == null || l.getAccuracy() < bestLocation.getAccuracy()) {
                // Found best last known location: %s", l);
                bestLocation = l;
            }
        }

        if (bestLocation == null) {
            locationManager.requestSingleUpdate(new Criteria(), this, null);
        }
        return bestLocation;
    }

    private static WritableMap locationToMap(Location location) {
        WritableMap map = Arguments.createMap();
        WritableMap coords = Arguments.createMap();
        coords.putDouble("latitude", location.getLatitude());
        coords.putDouble("longitude", location.getLongitude());
        coords.putDouble("altitude", location.getAltitude());
        coords.putDouble("accuracy", location.getAccuracy());
        coords.putDouble("heading", location.getBearing());
        coords.putDouble("speed", location.getSpeed());
        map.putMap("coords", coords);
        map.putDouble("timestamp", location.getTime());
        map.putString("provider", location.getProvider());

        if (android.os.Build.VERSION.SDK_INT >= 18) {
            map.putBoolean("mocked", location.isFromMockProvider());
        }

        return map;
    }

    <strong i="6">@ReactMethod</strong>
    public void getCurrentPosition(Callback successCallback, Callback errorCallback){
        Location l = getBestLastKnownPosition(this.getReactApplicationContext());
        if (l == null){
            errorCallback.invoke("Failed to retrieve current location");
            return;
        }
        successCallback.invoke(locationToMap(l));
    }

    private static class LocationOptions {
        private final long timeout;
        private final double maximumAge;
        private final boolean highAccuracy;
        private final float distanceFilter;

        private LocationOptions(
                long timeout,
                double maximumAge,
                boolean highAccuracy,
                float distanceFilter) {
            this.timeout = timeout;
            this.maximumAge = maximumAge;
            this.highAccuracy = highAccuracy;
            this.distanceFilter = distanceFilter;
        }

        private static LocationOptions fromReactMap(ReadableMap map) {
            // precision might be dropped on timeout (double -> int conversion), but that's OK
            long timeout =
                    map.hasKey("timeout") ? (long) map.getDouble("timeout") : Long.MAX_VALUE;
            double maximumAge =
                    map.hasKey("maximumAge") ? map.getDouble("maximumAge") : Double.POSITIVE_INFINITY;
            boolean highAccuracy =
                    map.hasKey("enableHighAccuracy") && map.getBoolean("enableHighAccuracy");
            float distanceFilter = map.hasKey("distanceFilter") ?
                    (float) map.getDouble("distanceFilter") :
                    10;

            return new LocationOptions(timeout, maximumAge, highAccuracy, distanceFilter);
        }
    }

    <strong i="7">@ReactMethod</strong>
    public void watchPosition(ReadableMap options, Callback successCallback, Callback errorCallback){
        LocationOptions opts = LocationOptions.fromReactMap(options);
        LocationManager locationManager = (LocationManager)this.getReactApplicationContext().getSystemService(Context.LOCATION_SERVICE);
        Criteria criteria = new Criteria();
        if (opts.highAccuracy) {
            criteria.setAccuracy(Criteria.ACCURACY_FINE);
        }
        String bestProvider = locationManager.getBestProvider(criteria, true);

        locationManager.requestLocationUpdates(bestProvider, 1000, opts.distanceFilter, this);
    }

    <strong i="8">@Override</strong>
    public void onLocationChanged(Location location) {
        if (location == null) return;

        this.getReactApplicationContext()
                .getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter.class)
                .emit("locationChanged", locationToMap(location));
    }

@Buthrakaur我正在尝试为您的代码段创建本机模块,但是由于构建失败,所以我无法使其工作。 我已经发布了我的要点https://gist.github.com/pewh/1fd64c8f0b3797ef2b7a7046b5a5f974 ,希望有人对我的要点进行修订。 非常感谢您,圣诞快乐!

不带任何选项调用navigator.geolocation.getCurrentPosition为我解决了这个问题。 我只传递成功和错误回调。

在具有Android 5.1的真实设备上进行了测试。

@ginex您确定数据是新的吗? 当我这样做时,有时会得到一小时的数据。 (它说我在一个小时前的位置)。

这确实需要解决!

你好

我也面临着同样的问题。 我在某些设备上收到超时错误。 我已将超时从2秒增加到10分钟,但是没有等待10分钟,这只会抛出错误。

我也尝试过enableHighAccuracy:false。 在这种情况下,我可以获取位置(在“设备模式”下除外)。

我也尝试过不传递参数。 在这种情况下,我也可以获取位置,但“设备模式”除外。

我也尝试过通过maximumAge,但是没有结果。
这是我的代码-

getCurrentPosition(){
navigator.geolocation.getCurrentPosition(
(位置)=> {
console.log('获取位置');
this.location = {
经度:position.coords.longitude,
纬度:position.coords.latitude,
错误:null,
};
},
(错误)=> {
console.log('获取位置错误',错误);
this.location = {
经度:null,
纬度:null,
错误:error.message,
};
},
{
enableHighAccuracy:是,
超时:600000
},
);
}

如果您使用的是skipPermissionsRequest并且geoLocation超时-请参阅#17487

你好

@ngandhy-不,我没有使用'skipPermissionRequests':true。 而minSdkVersion为16

我遇到了与所有人一样的问题,尝试了人们为android提及的每种组合,并使用此react-native-background-geolocation解决了

@badis
您的解决方案对我有用-谢谢!

修复之前的方法:

getUserLocationHandler() { navigator.geolocation.getCurrentPosition(position => { console.log(position.coords.latitude, position.coords.longitude); }, err => { console.log(err); } }

修复后的我的方法:

getUserLocationHandler() { navigator.geolocation.getCurrentPosition(position => { console.log(position.coords.latitude, position.coords.longitude); }, err => { console.log(err); }, {enableHighAccuracy: false, timeout: 15000, maximumAge: 3600000}); }

我只是测试此代码,它可能是一个解决方案:
https://www.abidibo.net/blog/2017/11/23/geolocation-react-native/

还有这个问题,有人解决了吗?

我已经经历了一段时间了,唯一可以持续工作的“解决方案”是禁用“ enableHighAccuracy”。 问题在于,它随后使用您的网络而不是GPS来确定您的位置,这会丢失大量的精度。

其他许多解决方案一开始似乎都可以使用,但是我发现这通常是由于使用了缓存位置,如果重新启动手机并启动应用程序,它仍然会失败。

今天,我发现此程序包使用适用于Android位置的Google融合位置API,并回退到iOS的默认React Native实现(我不是此程序包的作者,但为他创建程序而感到荣幸):

https://www.npmjs.com/package/react-native-geolocation-service

到目前为止,我仅对其进行了测试,但它似乎运行良好。

@globetro谢谢! 我也检查了一下,似乎工作正常!

@globetro谢谢。
react-native-geolocation-service是最好的解决方案。

@globetro这个插件我也很成功。 这应该合并为react-native,作为默认的地理位置功能!

react-native-geolocation-service不能帮助我:(

感谢@globetro这个包* react-native-geolocation-service *完美地工作,将它作为react native的核心组件添加应该很好。

您确实希望有两个位置侦听器(这很昂贵),一个位置侦听器具有highAccuracy,一个位置侦听器不具有。

那么您想比较哪个比“当前”位置更准确和更新。


这是一个“临时”解决方案,确实应在RN端实现,因此,如果启用了highAccuracy,则它将同时使用COARSE和FINE权限。

我解决了这个问题,这是我使用promise创建的组件:
https://gist.github.com/a3diti/5466f7309752cbb2e63ecefff6365bb9
在android中,我删除了maximumAge ,将enableHighAccuracy保留到true ,并从RN PermissionsAndroid组件添加了权限检查。

@ a3diti您是否在真实世界中进行了测试? 位置可以被缓存。

@ a3diti除非他们在最新的react-native版本中修复了某些问题,否则在Android上始终无法正常工作。 重新启动后,请尝试在真实的Android设备上启动它。 如果不只是超时,可能需要20多秒才能获得排名更新。

为什么不将https://www.npmjs.com/package/react-native-geolocation-service中使用的代码合并到核心中?

我面临同样的“请求超时问题”,在研发之后,我尝试“重新启动”设备,然后在找到位置及其工作正常之后。

请检查我的代码。

componentDidMount =()=> {
navigator.geolocation.getCurrentPosition(
(位置)=> {
const initialPosition = JSON.stringify(position);
this.setState({initialPosition});
},
(错误)=>警报(error.message),
{enableHighAccuracy:false,超时:20000,最大年龄:1000,distanceFilter:1}

  );
  this.watchID = navigator.geolocation.watchPosition((position) => {
     const lastPosition = JSON.stringify(position);
     this.setState({ lastPosition });
     Alert.alert("Location change",lastPosition);

  });

}

人们仍在为此奋斗而不使用的任何原因

https://www.npmjs.com/package/react-native-geolocation-service

如先前所建议? 它非常适合我。

它对别人不起作用吗?

将此添加到AndroidManifest.xml文件中,就可以了!

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

大家好,

我试图按照@globetro的建议使用react-native-geolocation-service ,但它导致我的应用程序立即崩溃。 有任何想法吗?

@ Patrick-Bayer我正在其可以在Google Play上的应用上使用它,但我的开发版本由于未知原因而立即崩溃。 似乎是react-native-geolocation-service也对我造成了崩溃。

Fatal Exception: java.lang.VerifyError: Verifier rejected class com.google.android.gms.location.FusedLocationProviderClient: void com.google.android.gms.location.FusedLocationProviderClient.<init>(android.app.Activity) failed to verify: void com.google.android.gms.location.FusedLocationProviderClient.<init>(android.app.Activity): [0x8] register v2 has type Precise Reference: com.google.android.gms.common.api.internal.zzg but expected Precise Reference: com.google.android.gms.common.api.internal.zzcz

让我知道您是否找到解决方案。

@oakis以下步骤对我

  1. 更新Gradle并更改其中的版本
dependencies {
        classpath 'com.android.tools.build:gradle:3.1.0'

        // NOTE: Do not place your application dependencies here; they belong
        // in the individual module build.gradle files
    }

  1. 在您的android / build.gradle中的存储库中添加“ google()”

有时即使将<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />到AndroidManifest.xml后,它仍然可能无法正常运行。
快速解决方法

  1. 您可以在用户挂载应用的第一个屏幕时明确要求用户的位置信息,如下所示
    try { const granted = await PermissionsAndroid.request( PermissionsAndroid.PERMISSIONS.ACCESS_FINE_LOCATION ) if (granted == PermissionsAndroid.RESULTS.GRANTED) { // WHATEVER WAY YOU WANT THEM TO KNOW THAT THEY HAVE GRANTED THE PERMISSION //MAY BE USING BASIC ALERT OR TOASTANDROID } else { //SAME AS ABOVE } } catch (error) { //catch the error alert(error); }
  2. 切勿将enableHighAccuracy设置为false,而是删除maximumAge并增加timeOut 。 像{enableHighAccuracy: true, timeout: 100000,}这样的东西就可以了。

希望对您有所帮助。

对我而言,将enableHighAccuracy设置为true可以在API 23上使用,尽管我需要在API 26上设置为false。
(这是我要测试的唯一对象)

编辑:我最终安装了react-native-geolocation-service ,这解决了我的问题🥁

你好

我遇到了同样的问题,这是另一个解决方案。

我在AndroidManifest.xml中添加了以下uses-feature标签,看来该应用程序可以与highAccuracy: true

<uses-feature android:name="android.hardware.location.gps" />

似乎如果您设置highAccuracy: high ,React Native将使用GPS_PROVIDER而不是NETWORK_PROVIDER。 而且,正如Android Developers文档所述,面向API 21或更高版本的应用必须在AndroidManifest.xml中包含此标记才能使用GPS_PROVIDER。

注意:如果您的应用程序针对Android 5.0(API级别21)或更高版本,则必须声明您的应用程序使用清单文件中的android.hardware.location.network或android.hardware.location.gps硬件功能,具体取决于您的应用程序应用会从NETWORK_PROVIDER或GPS_PROVIDER接收位置更新。 如果您的应用程序从这两个位置提供者来源中接收到位置信息,则需要声明该应用程序在您的应用程序清单中使用了这些硬件功能。 在运行Android 5.0(API 21)之前版本的设备上,请求ACCESS_FINE_LOCATION或ACCESS_COARSE_LOCATION权限包括对位置硬件功能的隐式请求。 但是,请求这些权限不会自动请求Android 5.0(API级别21)及更高版本上的位置硬件功能。

https://developer.android.com/guide/topics/location/strategies#Permission

我不知道为什么在设置highAccuracy: false时不需要在AndroidManifest.xml中包含android.hardware.location.network ,这意味着LocationManager使用NETWORK_PROVIDER,因此根据文档需要标记。

希望此解决方案对您有用。

我做了一些实验,看来超时可能与是否在设备上启用了Google的位置服务有关。
我注意到当我打开设备上的位置服务时,一个警告框会询问您“位置精度是否提高了?”。 文字说明Google的位置服务将在后台运行,并且还会向Google发送位置数据。 这通常发生在新设备或仿真器上,因为我们大多数人已经在常规设备上启用了此功能。

9vgfb

如果未启用此功能,则几乎每次您要求设备时都要获得一个新位置(由maximumAge设置控制)。 如果您有一段时间没有询问位置,并且timeout值不足以获取新的位置,则navigator.geolocation.getCurrentPosition只会返回超时。

我还看到通过在设备上再次打开google地图(再次获得新位置)可以解决此问题。

再说一次,不要声称这是正确的解释/解决方案,只需将我的观察结果添加到该线程中

我只能使用react-native-fused-location监视Android上的位置更改

任何人有兴趣将所建议的模块之一的变更引入上游吗?

几天前,我发布了与RN地理位置模块兼容的react-native-cross-geolocation ,但使用的是适用于Android的最高效的Google Location API。 因此,我不认为我的模块是将其集成到RN核心的备选方案,但是任何想使用它的人都可以使用。

react-native-geolocation-service此程序包使用融合的位置api,可以很好地获取位置甚至查看位置。 @hramos@reyalpsirc,请尝试一下。

@hramos的融合位置取决于Google Play服务,我想知道许可证是否还可以?

我几乎尝试了所有操作,结果发现不一致。 我发现了一些有用的东西。

启用高精度意味着通过gps + network(运营商服务)查找位置。 检查应用程序级别权限后,我的设备已禁用运营商服务的位置权限。 启用它并从navigator.geolocation.getCurrentPosition()中删除第三个参数对我而言有效。
尝试
-转到设备的设置->安全和位置->位置->应用程序级别权限
-启用运营商服务的位置权限
-从getCurrentPosition删除位置配置(第三个参数)
-重新启动设备

希望这可以帮助!

我不确定是否相关。 但是https://snack.expo.io/SkJqg8gYm的一个示例

{enableHighAccuracy: true, timeout: 10000, maximumAge: 0}
我发现如果跳过第二个参数或给出小于10000个值的错误

尝试提供上述所有三个参数,至少可以在模拟器中解决我的问题

尝试在_AndroidManifest.xml_上添加此权限:

<_uses-permission i =“ 6” />
<_uses-permission i =“ 8” />
<_permission_ i =“ 10” /> _android:name =“ android.permission.ACCESS_COARSE_LOCATION” _
_android:protectionLevel =“ signature” _ />
<_permission_ i =“ 13” /> _android:name =“ android.permission.ACCESS_FINE_LOCATION” _
_android:protectionLevel =“ signature” _ />

嗨,我遇到了同样的问题“请求超时”,我已经尝试了上面给出的所有可能的解决方案,但这些解决方案对我来说不起作用,但是最近我找到了一个可以解决该问题的模块。
https://www.npmjs.com/package/react-native-geolocation-service
这对我有用...

@vishalTechnoFreek ,也存在react-native-cross-geolocation

它与当前的RN地理位置完全兼容,但是使用了新的Google API。 使用此API,您不必担心使用哪种模式,该服务会自动检测最佳选择。

另一个好处是,当RN纠正此问题时,您可以根据需要删除它而不会影响您的应用程序。

就我而言,提到@manurana关于(下载并)打开Goog​​le Maps应用程序然后再返回Expo的事情就解决了。

我正在使用Genymotion和Android 5。

同样,对于Genymotion用户,为了正确读取位置,必须打开Genymotion的地图窗口。 否则它将起作用,但使用默认Geny的位置

enableHighAccuracy设置为truefalse对我不起作用。
省略getCurrentPosition的第三个参数以使用本机模块的默认值对我来说很有效。

救生员👍这对我有用。

伙计们
我遇到了同样的错误,但是在与同事进行了几次重试之后,我们发现了一些奇怪的东西(但是如果您对GPS感兴趣的话,这是正常的)。

如果使用物理设备在办公室“内部”执行测试,则GPS定位器可能会受到诸如墙壁之类的外部事物的干扰,或者由于您试图在“室内”执行此操作的简单原因而受到干扰,通常应在室外执行。

好吧,这之后我们从办公室出去了,我们重新执行了测试,并且设备按计划进行了响应(我们没有收到“请求超时”错误)。

我的建议是:尝试使用设置为true的“ enableHighAccuracy”进行地理定位,如果失败(在办公室中可能失败),请重试为false,在我的情况下应该可以。

希望这可以有所帮助。

我遇到了同样的问题,但是将enableHighAccuracyfalse对我不起作用。 因此,这种似乎完美的解决方案对我不起作用。

我遇到了多个请求(连续选择使用当前位置)的类似问题,我为位置请求添加了重试。 不是确切的问题,但可能会有所帮助。

import retry from 'retry'
if (granted === PermissionsAndroid.RESULTS.GRANTED) {
  const operation = retry.operation({ retries: 2 });
  operation.attempt(() => {
    navigator.geolocation.getCurrentPosition(
      (response) => { resolve(response) },
      (error) => {
        if (operation.retry(error)) {
          return;
        }
        reject(error)
     },
     { timeout: 2000, enableHighAccuracy: true, maximumAge: 100 },
   );
 })
} else {
  reject(new Error('Location access denied'))
}

https://www.npmjs.com/package/react-native-geolocation-service
这个软件包为我解决了这个问题。
几乎所有上述建议对我都不起作用。

嗨,来宾,我解决了这个难题,发生的事情是,当我们第一次请求该位置并使用“ maximunAge”时,我们没有缓存先前的位置,因此存在一个错误,请确保在第一次询问时位置没有“ maximunAge”

简单的答案是走出您所在的位置并进入开放空间,然后重试。

其简单的科学。

GPS服务会受到厚厚的墙壁和汽车的影响。

这对我有用。 无需编辑任何内容!

在我的情况下,删除maximumAge解决了该问题。

非常感谢你! 工作!

你好
这些解决方案都不适合我。
我使用navigator.geolocation,仅使用{enableHighAccuracy:false}作为第三个参数。
在iOS中,它工作正常,而在android中,它不适用于某些设备。
我已经检查了Android 7、8、9。它无法在装有Android 7的Lenovo手机中使用,但可以与装有Android 7的其他设备一起使用。

没有人有任何解决方法来解决此问题。
任何建议都是可取的。

谢谢

@akhilsanker可能尝试像react-native-fused-location这样的库

@reyalpsirc

谢谢回复。 非常感谢您的宝贵时间。
在iOS中没有问题,并且可以在大多数android设备上正常运行。 我的时间有限,您将无法使用新的库。
您还有其他解决方法来解决此问题吗?
谢谢你的时间。

谢谢。

抱歉@akhilsanker ,我所做的就是对iOS使用react native的Geolocation和对于Android使用FusedLocation。

设置maximumAge:0对我有用:
{ enableHighAccuracy: true, timeout: 60000, maximumAge:0 }
也许@GersonM是正确的...

地理定位模块已从主服务器的RN中删除,在0.60版本中不再可用。 请使用https://github.com/react-native-community/react-native-geolocation并在此处报告问题。 谢谢

这是2019年,尝试了3个不同的位置库,它们都不适用于Android。 惊人。

这是2019年,尝试了3个不同的位置库,它们都不适用于Android。 惊人。

react-native-geolocation-service工作正常。

如果软件包不起作用,请在该存储库上创建一个发行凭单。 问题无法解决,请加入社区。

请参阅iwangsyah的评论。 我需要<permission> __和__ <uses-permission>元标记

https://www.npmjs.com/package/react-native-geolocation-service
这个软件包为我解决了这个问题。
几乎所有上述建议对我都不起作用。

谢谢!

此页面是否有帮助?
0 / 5 - 0 等级