我正在使用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文件中。