Невозможно получить текущую позицию без GPS на react-native с навигатором.геолокация

краткое резюме после обсуждения и ответов:

используя EXPO sdk, вы не можете получить местоположение устройства без предоставления FINE_LOCATION в android. FINE_LOCATION-единственный способ получить местоположение, поэтому вы не можете получить оборудование.сеть.местоположение. Это означает: с android > 6 Вы не можете получить текущее местоположение с помощью WIFI / мобильных сетей, вы должны включить местоположение.

Expo GitHub обсуждение: https://github.com/expo/expo/issues/1339

исходная задача:

im работает над реагировать-уроженца приложения использование expo и react-native-maps, и мне нужно получить широту и longitud текущей позиции пользователя.

Im с помощью навигатор.API геолокации для этого

С включенным GPS у меня нет проблем, но мне нужно получить текущую позицию без GPS, на основе сетевого провайдера.

проблема в том, что при запуске приложения С ЭКСПО на androiod > 6 Я получаю эту ошибку:

21: 50: 53: законченный пакет JavaScript здания в 449ms 21:50: 55: Службы геолокации отключены - node_modulesreact-nativeLibrariesBatchedBridgeNativeModules.js: 80:57 в - node_modulesreact-nativeLibrariesBatchedBridgeMessageQueue.js: 347: 19 in _ _ invokeCallback - ... Еще 4 стека кадры из framework internals

в IOs и android

вот код компонента:

class MyComponent extends Component {

    componentWillMount = () => {    
            this.getCurrentLocation();    
    }
    getCurrentLocation = () =>
         navigator.geolocation.getCurrentPosition(
            (position) => {
                let currentUserPosition = position.coords;
                alert(JSON.stringify(currentUserPosition));
            },
            (error) => {
                console.log(error);
            },
            {
                enableHighAccuracy: false,
                timeout: 20000,
                maximumAge: 0,
                distanceFilter: 10
            }
        );

}

и это мой пакет.в JSON depencendies:

"dependencies": {
    "expo": "23.0.4",
    "native-base": "^2.3.5",
    "react": "16.0.0",
    "react-native": "0.50.4",
    "react-native-extend-indicator": "^0.1.2",
    "react-native-maps": "^0.19.0",
    "react-native-maps-directions": "^1.3.0",
    "react-native-router-flux": "4.0.0-beta.21",
    "react-navigation": "1.0.0-beta.21",
    "react-navigation-redux-debouncer": "^0.0.2",
    "react-redux": "^5.0.6",
    "redux": "^3.7.2",
  }

Я ожидаю, что навигатор.геолокация получить местоположение на основе поставщика сети в этой ситуации (без gps), спецификация говорит, что..

Я также пробовал с API геолокации expo (пробовал этот пример: https://snack.expo.io/@schazers/expo-map-and-location-example), и с выключенным GPS я не могу получить свое местоположение..

так.. есть ли способ достичь того, чего я хочу? я что-то пропустил?

EDIT (EXPO CONTRIBUTOR ANSWER):

Я разместил то же самое на expo github (https://github.com/expo/expo/issues/1339), согласно им, невозможно получить текущую позицию с помощью навигатора.геолокация без какого-либо уровня местоположения включен в устройстве android.. так. . единственное, что может произойти, это то, что android версии старше 5 имеет местоположение включено по умолчанию, и вы можете включить только GPS, а версии 6 и вперед вы должны указать уровень местоположения ..

какие идеи?

EDIT2 (ВАЖНО !!):

Я подтвердил это:

enter image description here

Это настройки безопасности Android 6 устройство, по умолчанию он использует GPS, я думаю, что android 5 или ниже не делает, так что это вещь.. когда я использую 2-й вариант, он дает мне место !

дело в том, что принуждение пользователя включить местоположение похоже на "эй, используйте свой GPS!", и есть много приложений, которые дают вам апроксимированную позицию без включения местоположения (например, Uber), поэтому вопрос в том,есть ли способ, который только с помощью wifi получить местоположение с этим API-интерфейс?

3 ответов


проблема, с которой Вы имеете дело здесь, связана с EXPO, потому что API запроса местоположения изменился после Android 5(API 21).

перед API 21 вам нужно было добавить в ACCESS_FINE_LOCATION (как Wifi/сеть, так и GPS-провайдеры) и ACCESS_COARSE_LOCATION (только разрешение GPS) разрешения местоположения. Однако, начиная с Android 5, API изменяется на android.hardware.location.network и android.hardware.location.gps.

когда ваши целевые пользователи включают как Android 5 +/ -. вам нужно добавить оба типа разрешений в манифест android, для пример:

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

    <!-- for Android 5.0 (API level 21) or higher. -->
    <uses-feature android:name="android.hardware.location.gps" />
    <uses-feature android:name="android.hardware.location.network" />
</manifest>

однако, похоже, что люди в expo, только включены, новое разрешение в манифесте android. Итак, что вам нужно сделать, это изменить манифест android. Однако expo предоставляет доступ только к чистой JS-части программы, а не к собственным кодам. В результате вам нужно отсоединиться от EXPO, чтобы добавить собственные модули или изменения.

в документации expo процесс отсоединения объясняется в этой ссылке процедура просто:

  1. установите пакет expo глобально с помощью npm:

    npm install -g exp

  2. внутри каталога проекта запустите код отделения, он будет создавать папки android и ios в каталоге проекта:

    exp detach

затем вы можете внести необходимые изменения в файл манифеста android.


распространенная ошибка в Android. Попробуйте без использования третьего параметра:

getCurrentLocation = () =>
         navigator.geolocation.getCurrentPosition(
            (position) => {
                let currentUserPosition = position.coords;
                alert(JSON.stringify(currentUserPosition));
            },
            (error) => {
                console.log(error);
            }
        );

Итак, я просто немного покопался в коде, и в основном все LocationModule делает, это отправить запрос непосредственно на Android.

Это просто вызывает этот метод:

https://developer.android.com/reference/android/location/LocationManager.html#getLastKnownLocation(java.lang.String)

теперь, если Вы читаете это, местоположение говорит FINE_LOCATION или COARSE_LOCATION.

обычно просто добавьте разрешения на точное местоположение, но я думаю, что, возможно, для доступа к местоположению Wifi вам нужно добавить грубые разрешения в приложение. У тебя есть оба?

https://developer.android.com/reference/android/Manifest.permission.html#ACCESS_COARSE_LOCATION

если нет, я бы добавил Эти разрешения в приложение и повторите попытку.


у меня была такая же проблема, и я попробовал много библиотек, чтобы получить местоположение пользователя. навигатор.API геолокации не дал мне местоположение каждый раз на android, вместо этого он просто дает в основном ошибку тайм-аута. Так что я попробовал реагировать родной фон геолокации что начать использовать gps непрерывно, то я нахожу реагировать родной Службы геолокации и автор явно указано что:

С этого момента библиотека должна была быть drop-in замена для р-н API геолокации, использование довольно прямолинейно, с некоторыми дополнительными ошибки в обращении.

это то, что мне нужно всегда, и я думаю, что вы также должны попробовать это.

посмотрите на это AndroidManifest файл, автор использует все типы местоположения.

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.agontuk.RNFusedLocation">

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

для примера теста вы просто будете следовать той же инструкции, что и RN Геолокация API предлагает. Вот простой пример использования Службы геолокации react native:

import Geolocation from 'react-native-geolocation-service';

componentDidMount() {
    // Instead of navigator.geolocation, just use Geolocation.
    if (hasLocationPermission) {
        Geolocation.getCurrentPosition(
            (position) => {
                console.log(position);
            },
            (error) => {
                // See error code charts below.
                console.log(error.code, error.message);
            },
            { enableHighAccuracy: true, timeout: 15000, maximumAge: 10000 }
        );
    }
}

Итак, в третьем параметре getCurrentPosition использовать enableHighAccuracy false использовать сеть, чтобы получить местоположение пользователя и true, чтобы получить более точное местоположение с помощью gps. См.эта опция документация.

автор этого РЕПО также предоставил пример проекта вы можете попробовать его с enableHighAccuracy false и превратить локацию в первый раз, но когда вы запустите приложение, оно попросит разрешения местоположения, которое покажет приложение, которое хочет получить доступ к wifi или сотовой сети.

как вы используете expo вы не можете использовать реагировать родной Службы геолокации для этого вам нужно следовать Mojtaba ответ для отделения и получить проект android и iOS, так что вы можете настроить оба проекта. Дайте мне знать, если вам понадобится больше информации.