Androidビーコンライブラリを使用しています。マシュマロ以来、予想どおり、文書化されているように、次のエラーが表示されます。
権限の拒否:スキャン結果を取得するには、ACCESS_COARSE_LOCATIONまたはACCESS_FINE_LOCATION権限が必要です
フラグメントにレンジングコードがあり、許可を求めていないので、期待どおり、フラグメントが画面に表示されているときにRuntimeExceptionがスローされます。ホームボタンを押すと、Pauseが呼び出され、beaconManagerのバインドが解除され、期待どおりに例外が再度スローされなくなります。前のアプリリストからアクティビティに戻ると、スキャンごとにRuntimeExceptionが再度スローされます。
AndroidManifestにアクセス許可を追加したのに、フォアグラウンドで例外がスローされるのはなぜですか?
ドキュメントによると [〜#〜] here [〜#〜] 、バックグラウンドでスキャンを実行している場合にのみ、ユーザーに位置情報の許可を求める必要がありますか?
バックグラウンドでBluetoothスキャンを実行しようとすると、LogCatで次のエラーが発生し、ビーコンは検出されません。
これは、[〜#〜]のみ[〜#〜]のバックグラウンドスキャンを意味しますか、それともドキュメントを誤って解釈しているのでしょうか。余分なものを避けたい(おそらく神経質なユーザーに不快感を与える)回避可能な場合は、アプリ内で許可を求めます!!
私のマニフェストには-
<uses-permission-sdk-23 Android:name="Android.permission.ACCESS_COARSE_LOCATION"/>
フラグメントからの私の切り取ったコードは-
public class NearMeNowFragment extends Fragment implements BeaconConsumer {
//Beacon manager stuff
private BeaconManager beaconManager;
<SNIP>
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
beaconManager = BeaconManager.getInstanceForApplication(getActivity());
beaconManager.getBeaconParsers().add(new BeaconParser().
setBeaconLayout("m:2-3=0215,i:4-19,i:20-21,i:22-23,p:24-24"));
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
View rootView = inflater.inflate(R.layout.near_me_now, container, false);
//Set up beacon stuff if Bluetooth available
if (verifyBluetooth(false)) {
beaconManager.bind(this);
}
<SNIP>
return rootView;
}
/***************************
Beacon config methods
****************************
*/
@Override
public void onBeaconServiceConnect() {
//update all scan periods
beaconManager.setForegroundScanPeriod(1100l);
beaconManager.setForegroundBetweenScanPeriod(8900l);
beaconManager.setAndroidLScanningDisabled(true);
try {
beaconManager.updateScanPeriods();
} catch (RemoteException e) {
e.printStackTrace();
}
beaconManager.setRangeNotifier(new RangeNotifier() {
@Override
public void didRangeBeaconsInRegion(Collection<Beacon> beacons, Region region) {
if (beacons.size() > 0) {
<SNIP>
//handling beacons here
...
} else {
Log.i(TAG, "ZERO BEACONS IN SCAN");
}
}
});
try {
beaconManager.startRangingBeaconsInRegion(new Region(TAG, null, null, null));
} catch (RemoteException e) {
e.printStackTrace();
}
}
@Override
public Context getApplicationContext() {
return getActivity().getApplicationContext();
}
@Override
public void unbindService(ServiceConnection serviceConnection) {
getActivity().unbindService(serviceConnection);
}
@Override
public boolean bindService(Intent intent, ServiceConnection serviceConnection, int mode) {
return getActivity().bindService(intent, serviceConnection, mode);
}
@Override
public void onPause() {
super.onPause();
if(beaconManager.isBound(this)){
beaconManager.unbind(this);
}
}
@Override
public void onResume() {
super.onResume();
beaconManager.bind(this);
}
@Override
public void onDestroy() {
super.onDestroy();
if(beaconManager.isBound(this)){
beaconManager.unbind(this);
}
}
}
私の実際のLogcatエラーは
W/Binder:バインダースタブ実装からRuntimeExceptionをキャッチしました。 Java.lang.SecurityException:スキャン結果を取得するには、ACCESS_COARSE_LOCATIONまたはACCESS_FINE_LOCATION権限が必要です
明確にするために、build.gradleファイルでtargetSdkVersion 23
を設定するかどうかによって、要件は異なります。
SDK 23(マシュマロ)以降をターゲットにしている場合:
SDK 22以下をターゲットにしている場合:
マシュマロデバイスでテストしたときに、アプリで同じ問題が発生しました。ユーザーに許可を求めないようにするために、targetSdkVersionを22に変更しました。compileSdkVersionは23のままにすることができます。build.gradleを変更した後、ツールを実行する必要がある場合があります> Android> Sync Project Gradleファイルを使用します。Eclipseを使用する場合、targetSdkVersionはマニフェストファイルにあります。