不在后台监控时提示位置权限?
Prompting for location permission when NOT monitoring in background?
我正在使用 Android 信标库。自 Marshmallow 以来,我看到了以下错误,正如预期和记录的那样。
Permission denial: Need ACCESS_COARSE_LOCATION or ACCESS_FINE_LOCATION permission to get scan results
我在 Fragment 中有我的测距代码,当 Fragment 在屏幕上时抛出 RuntimeException,正如预期的那样,因为我没有提示权限。如果我按下主页按钮,将调用暂停,并且我将解除对 beaconManager 的绑定,并且不再像预期的那样抛出异常。从之前的应用程序列表回到 Activity,每次扫描都会再次抛出 RuntimeException。
即使我已经向 AndroidManifest 添加了权限,为什么在前台时仍会抛出异常?
根据文档
HERE,后台扫描只需要提示用户位置权限?
you'll get the following error in LogCat when you try to do a bluetooth scan in the background, and no beacons will be detected
这是否意味着 仅 后台扫描,或者我是否误解了文档,无论如何您都必须提示?如果可以避免,我想避免额外的(可能会让紧张的用户感到厌恶)请求许可的提示!!
我的清单包含 -
<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﹕ Caught a RuntimeException from the binder stub implementation.
java.lang.SecurityException: Need ACCESS_COARSE_LOCATION or ACCESS_FINE_LOCATION permission to get scan results
澄清一下要求有所不同,具体取决于您是否在 build.gradle 文件中设置了 targetSdkVersion 23
。
如果您的目标是 SDK 23 (Marshmallow) 或更高版本:
- 您必须在清单中声明 android.permission.ACCESS_COARSE_LOCATION 或 android.permission.ACCESS_FINE_LOCATION。
- 您必须按照我的博客中的描述提示用户授予权限 post here.
- 用户必须接受此权限并且不能将其关闭。
- 如果不满足上述任一要求,您将无法在前台或后台检测到信标。
如果您的目标是 SDK 22 或更低版本:
- 您可以选择在清单中声明 android.permission.ACCESS_COARSE_LOCATION 或 android.permission.ACCESS_FINE_LOCATION。
- 用户可以通过设置打开或关闭权限。
- 如果未授予其中一项权限,您仍然可以在前台检测到信标,但不能在后台检测。
有关详细信息,请参阅 here and 。
我在 Marshmallow 设备上测试我的应用程序时遇到了同样的问题。为了避免提示用户权限,我只是把targetSdkVersion改成22。compileSdkVersion可以保持23。改成build.gradle后,可能需要运行 Tools > Android > Sync包含 Gradle 个文件的项目。如果您使用 Eclipse,则 targetSdkVersion 在清单文件中。
我正在使用 Android 信标库。自 Marshmallow 以来,我看到了以下错误,正如预期和记录的那样。
Permission denial: Need ACCESS_COARSE_LOCATION or ACCESS_FINE_LOCATION permission to get scan results
我在 Fragment 中有我的测距代码,当 Fragment 在屏幕上时抛出 RuntimeException,正如预期的那样,因为我没有提示权限。如果我按下主页按钮,将调用暂停,并且我将解除对 beaconManager 的绑定,并且不再像预期的那样抛出异常。从之前的应用程序列表回到 Activity,每次扫描都会再次抛出 RuntimeException。
即使我已经向 AndroidManifest 添加了权限,为什么在前台时仍会抛出异常?
根据文档 HERE,后台扫描只需要提示用户位置权限?
you'll get the following error in LogCat when you try to do a bluetooth scan in the background, and no beacons will be detected
这是否意味着 仅 后台扫描,或者我是否误解了文档,无论如何您都必须提示?如果可以避免,我想避免额外的(可能会让紧张的用户感到厌恶)请求许可的提示!!
我的清单包含 -
<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﹕ Caught a RuntimeException from the binder stub implementation. java.lang.SecurityException: Need ACCESS_COARSE_LOCATION or ACCESS_FINE_LOCATION permission to get scan results
澄清一下要求有所不同,具体取决于您是否在 build.gradle 文件中设置了 targetSdkVersion 23
。
如果您的目标是 SDK 23 (Marshmallow) 或更高版本:
- 您必须在清单中声明 android.permission.ACCESS_COARSE_LOCATION 或 android.permission.ACCESS_FINE_LOCATION。
- 您必须按照我的博客中的描述提示用户授予权限 post here.
- 用户必须接受此权限并且不能将其关闭。
- 如果不满足上述任一要求,您将无法在前台或后台检测到信标。
如果您的目标是 SDK 22 或更低版本:
- 您可以选择在清单中声明 android.permission.ACCESS_COARSE_LOCATION 或 android.permission.ACCESS_FINE_LOCATION。
- 用户可以通过设置打开或关闭权限。
- 如果未授予其中一项权限,您仍然可以在前台检测到信标,但不能在后台检测。
有关详细信息,请参阅 here and
我在 Marshmallow 设备上测试我的应用程序时遇到了同样的问题。为了避免提示用户权限,我只是把targetSdkVersion改成22。compileSdkVersion可以保持23。改成build.gradle后,可能需要运行 Tools > Android > Sync包含 Gradle 个文件的项目。如果您使用 Eclipse,则 targetSdkVersion 在清单文件中。