当不在后台监控时提示位置许可



我正在使用Android Beacon Library。自Marshmallow以来,我看到以下错误,如预期和文档所示。

权限拒绝:需要ACCESS_COARSE_LOCATION或ACCESS_FINE_LOCATION权限才能获得扫描结果

我在片段中有我的范围代码,当片段在屏幕上时抛出RuntimeException,因为我没有提示权限。如果我点击home键,Pause被调用,我正在解绑定beaconManager,异常不再被抛出,像预期的那样。从上一个应用程序列表返回到Activity,每次扫描都会抛出RuntimeException。

为什么在前台抛出的异常,即使我已经添加权限到AndroidManifest?

根据文档在这里,如果您在后台执行扫描,您只需要提示用户位置权限?

当你尝试在后台进行蓝牙扫描时,你会在LogCat中得到以下错误,并且没有检测到信标

这是否意味着进行后台扫描,还是我误解了文档,而您必须提示?如果可以避免的话,我希望避免在应用程序中出现额外的许可提示(可能会让紧张的用户感到不快)!!

My Manifest contains -

<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:从Binder存根实现中捕获了一个RuntimeException。java.lang.SecurityException:需要ACCESS_COARSE_LOCATION或ACCESS_FINE_LOCATION权限来获取扫描结果

为了澄清需求是不同的取决于您是否在构建中设置了targetSdkVersion 23。gradle文件。

如果您的目标SDK 23 (Marshmallow)或更高:

    你必须声明android.permission。ACCESS_COARSE_LOCATION或android.permission。ACCESS_FINE_LOCATION在你的manifest.
  • 你必须提示一个用户的权限,在我的博客文章中描述在这里。
  • 用户必须接受这个权限,不能关闭它。
  • 如果不满足上述任何要求,您将无法检测前景或背景中的信标。

如果您的目标SDK 22或更低:

    你可以选择声明android.permission。ACCESS_COARSE_LOCATION或android.permission。ACCESS_FINE_LOCATION在你的manifest.
  • 用户可以通过settings打开或关闭权限。
  • 如果没有授予其中一个权限,您仍然可以在前台检测信标,但不能在后台检测。

当我在Marshmallow设备上测试我的应用时也遇到了同样的问题。为了避免提示用户获得许可,我只是将targetSdkVersion更改为22。compileSdkVersion可以保持为23。在您更改构建之后。你可能需要运行Tools> Android> Sync Project with gradle Files。如果您使用Eclipse, targetSdkVersion在manifest文件中。