Android 6.0でのBLE、Wi-Fiのスキャンは位置情報を有効にしないといけない

More than 3 years have passed since last update.


位置情報との絡み

Android 6.0からパーミッションの仕組みや必要性が変わり、Wi-FiとBLEのスキャンに位置情報のパーミッションが必要になったことは知ってる方多いと思います。

しかし、実はパーミッションだけではなく、端末の位置情報が有効にされていないとスキャン結果を受け取れないパターンがあり、対応が必要となりそうです。


現象と原因

こちらの記事で細かくかいてあります。こちらの記事ではBLEの話だけですが、Wi-Fiの場合はWifiManager#getScanResults()の戻り値が常に空のリストになってしまいます。


targetSdkVersion

上記の記事にある通り、一見targetSdkVersionを23未満にしてしまえば動きそうな感じがしますが、手元で試した感じでは Android 6.0 ではtargetSdkVersionを下げても位置情報がオフの場合、スキャンが正常に動作しませんでした。

しかし、Android 6.0.1に更新したところ、targetSdkVersionが23未満なら、位置情報オフの状態でもスキャンを動かすことができました。

コードレベルでの確認は取れていませんが、どうやらtargetSdkVersionによって対応できるのは6.0.1でないとダメで、6.0では対処できなさそうです。


結論

Android 6.0に最適化する場合はどのみちユーザーに位置情報の有効化を促すしかなさそうです。

パーミッション周りの扱いも変わったので、アプリとしてはtargetSdkVersionを23に上げ、しっかり対応を入れていくのがいいのでしょうね。


[追記]


2016/01/27

コードを追ったところ、6.0ではtargetSdkVerionによる判定がないため動かないようです。

6.0.1からはリンク先の記事の通りです。


GattService.java

/** Determines if the given scan client has the appropriate permissions to receive callbacks. */

private boolean hasScanResultPermission(final ScanClient client) {
final boolean requiresLocationEnabled =
getResources().getBoolean(R.bool.strict_location_check);
final boolean locationEnabled = Settings.Secure.getInt(getContentResolver(),
Settings.Secure.LOCATION_MODE, Settings.Secure.LOCATION_MODE_OFF)
!= Settings.Secure.LOCATION_MODE_OFF;
return (client.hasPeersMacAddressPermission ||
(client.hasLocationPermission && (!requiresLocationEnabled || locationEnabled)));
}