web-dev-qa-db-ja.com

バックグラウンドで監視していないときに位置情報の許可を求めますか?

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権限が必要です

8
WallyHale

明確にするために、build.gradleファイルでtargetSdkVersion 23を設定するかどうかによって、要件は異なります

SDK 23(マシュマロ)以降をターゲットにしている場合:

  • マニフェストでAndroid.permission.ACCESS_COARSE_LOCATIONまたはAndroid.permission.ACCESS_FINE_LOCATIONを宣言する必要があります。
  • 私のブログ投稿で説明されているように、ユーザーに許可を求める必要があります ここ
  • ユーザーはこの権限を受け入れる必要があり、オフにしないでください。
  • 上記の要件のいずれかが満たされていない場合、フォアグラウンドまたはバックグラウンドでビーコンを検出することはできません。

SDK 22以下をターゲットにしている場合:

  • オプションで、マニフェストでAndroid.permission.ACCESS_COARSE_LOCATIONまたはAndroid.permission.ACCESS_FINE_LOCATIONを宣言できます。
  • ユーザーは、設定に移動して権限をオンまたはオフにすることができます。
  • 権限の1つが付与されていない場合でも、フォアグラウンドでビーコンを検出できますが、バックグラウンドでは検出できません。

詳細については、 ここ および ここ を参照してください。

22
davidgyoung

マシュマロデバイスでテストしたときに、アプリで同じ問題が発生しました。ユーザーに許可を求めないようにするために、targetSdkVersionを22に変更しました。compileSdkVersionは23のままにすることができます。build.gradleを変更した後、ツールを実行する必要がある場合があります> Android> Sync Project Gradleファイルを使用します。Eclipseを使用する場合、targetSdkVersionはマニフェストファイルにあります。

1
Andrew F.