ディスカッションと回答後の概要:
eXPO SDKを使用すると、AndroidでFINE_LOCATIONを付与しないとデバイスの位置を取得できません。 FINE_LOCATIONは位置を取得する唯一の方法であるため、hardware.network.locationを取得することはできません。つまり、Android> 6では、WIFI /モバイルネットワークを使用して現在の場所を取得できないため、場所を有効にする必要があります。
Expo githubディスカッション:https://github.com/expo/expo/issues/1339
最初の問題:
react-nativeアプリケーションで作業中のim、expoとreact-native-mapsを使用、ユーザーの現在位置の緯度と経度を取得する必要があります。
navigator.geolocation API を使用している
gPSをオンにすると問題はありませんが、ネットワークプロバイダーに基づいて、GPSなしで現在の位置を取得する必要があります。
問題は、アプリケーションの実行時にandroiodでの博覧会> 6このエラーが発生することです:
21:50:53:449msでJavaScriptバンドルの構築を終了21:50:55:位置情報サービスは無効-node_modules\react-native\Libraries\BatchedBridge\NativeModules.js:80:57 in-node_modules\react-native\Libraries\__invokeCallbackのBatchedBridge\MessageQueue.js:347:19-...フレームワーク内部からのさらに4つのスタックフレーム
IOとAndroid <= 5でうまく動作します。
コンポーネントのコードは次のとおりです。
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
}
);
}
そして、これは私のpackage.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",
}
Navigator.geolocationは、その状況のネットワークプロバイダーに基づいて(gpsを使用せずに)場所を取得することを期待しています、と仕様書は述べています。
また、expoのGeolocation API(この例を試しました: https://snack.expo.io/@schazers/expo-map-and-location-example )とGPSを有効にしてOFF位置情報を取得できません。
だから..私が欲しいものを達成する方法はありますか?私は何かが欠けていますか?
編集(EXPO貢献者の回答):
私は同じことをexpo githubに投稿しました( https://github.com/expo/expo/issues/1339 )、彼らによると、navigator.geolocationを使用せずに現在の位置を取得することは不可能ですAndroidデバイスで有効になっている場所のレベル.。.唯一起こりうることは、Android 5よりも古いバージョンではデフォルトで場所が有効になっており、 GPSのみをオンにすることができます。バージョン6以降では、位置レベルを指定する必要があります..
何か案は?
EDIT2(重要!!):
私はこれを確認しました:
これは、Android 6デバイスのセキュリティ設定です。デフォルトではGPSを使用します。Android 5以下はそうではないので、それが問題です。 2番目のオプションを使用すると、場所が取得されます!
実際には、ユーザーにロケーションの有効化を強制することは「ちょっと、GPSを使う!」のようなものであり、ロケーションをオンにせずに近接位置を提供するアプリケーションがたくさんあります(たとえばUberなど)。 wifiのみを使用して、このAPIで位置を取得する方法はありますか?
Android 5(API 21)の後にロケーションリクエストAPIが変更されたため、ここで扱っている問題はEXPOにあります。
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>
ただし、Androidマニフェストに含まれる新しい許可は、博覧会の参加者のみに含まれているようです。そのため、Androidマニフェストを変更する必要があります。ただし、expoはプログラムの純粋なJS部分にのみアクセスし、ネイティブコードにはアクセスできません。そのため、ネイティブモジュールまたは変更を追加するには、EXPOからデタッチする必要があります。
Expoのドキュメントでは、分離プロセスは このリンク で説明されています。手順は簡単です:
npmを使用してexpoパッケージをグローバルにインストールします。
npm install -g exp
プロジェクトディレクトリ内でデタッチメントコードを実行すると、プロジェクトディレクトリにAndroidおよびiosフォルダーが構築されます。
exp detach
その後、Androidマニフェストファイルで必要な変更を加えることができます。
Androidの一般的なバグ。 3番目のパラメーターを使用せずに試してください。
getCurrentLocation = () =>
navigator.geolocation.getCurrentPosition(
(position) => {
let currentUserPosition = position.coords;
alert(JSON.stringify(currentUserPosition));
},
(error) => {
console.log(error);
}
);
したがって、コードを少し掘り下げただけで、基本的にLocationModuleが行うことは、Androidに直接リクエストを送信することだけです。
このメソッドを呼び出すだけです:
今、あなたがそれを読んだ場合、場所はFINE_LOCATIONまたはCOARSE_LOCATIONと言います。
通常、ロケーションの許可を追加するだけですが、Wifiの場所にアクセスするには、アプリに粗い許可を追加する必要があると思います。両方ありますか?
https://developer.Android.com/reference/Android/Manifest.permission.html#ACCESS_COARSE_LOCATION
そうでない場合は、その許可をアプリに追加して、再試行します。
私の場合、AndroidManifest.xmlに以下を追加して問題を解決しました。
<uses-permission Android:name="Android.permission.ACCESS_FINE_LOCATION" />
まず、アプリに権限を付与しますIosの場合:Info.plistにNSLocationWhenInUseUsageDescription
キーを含める必要があります
アンドロイド用:
<uses-permission Android:name="Android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission Android:name="Android.permission.ACCESS_FINE_LOCATION" />
ここから緯度経度経度を取得しますCODE ==>
navigator.geolocation.getCurrentPosition(
(position) => {
const initialPosition = JSON.stringify(position);
// console.log(initialPosition);
this.setState({ initialPosition });
},
//(error) => alert(error.message),
{ enableHighAccuracy: true, timeout: 20000, maximumAge: 1000 }
);
this.watchID = navigator.geolocation.watchPosition((position) => {
const lastPosition = JSON.stringify(position);
//this.setState({ longitude: position.coords.longitude, latitude: position.coords.latitude });
//this._getWheaterData();
AsyncStorage.setItem('latitude',position.coords.latitude.toString())
AsyncStorage.setItem('longitude',position.coords.longitude.toString())
},
// (error) => alert(error.message),
// console.log(error),
{ enableHighAccuracy: true, timeout: 20000, maximumAge: 1000 });