Android 7.1.1无Google API环境下BlackBox应用权限撤销方案咨询
Android 7.1.1 下应用关闭自动撤销位置权限及替代方案
一、自动撤销权限的可行实现方式
Android 7.1.1(API 25)中,普通应用无法直接自行撤销已授予的权限,需借助以下两种方式实现:
1. 借助设备所有者(Device Owner)权限
通过设备所有者身份,可调用系统API直接修改权限状态,步骤如下:
- 第一步:注册设备管理员接收器
创建继承自DeviceAdminReceiver的类,并在Manifest中声明:public class BlackBoxDeviceAdmin extends DeviceAdminReceiver {}<receiver android:name=".BlackBoxDeviceAdmin" android:permission="android.permission.BIND_DEVICE_ADMIN"> <meta-data android:name="android.app.device_admin" android:resource="@xml/device_admin" /> <!-- 需在res/xml下创建device_admin.xml,内容为<device-admin/> --> <intent-filter> <action android:name="android.app.action.DEVICE_ADMIN_ENABLED" /> </intent-filter> </receiver> - 第二步:设置应用为设备所有者
通过ADB命令完成激活(需用户配合):dpm set-device-owner com.your.blackbox.package/.BlackBoxDeviceAdmin - 第三步:监听应用关闭事件并撤销权限
在onTaskRemoved()回调中(应用被从最近任务列表移除时触发)执行权限撤销:
注意:设备所有者权限属于系统级权限,仅适用于企业设备或用户愿意配合激活的场景。@Override public void onTaskRemoved(Intent rootIntent) { super.onTaskRemoved(rootIntent); DevicePolicyManager dpm = (DevicePolicyManager) getSystemService(Context.DEVICE_POLICY_SERVICE); ComponentName adminComponent = new ComponentName(this, BlackBoxDeviceAdmin.class); if (dpm.isAdminActive(adminComponent)) { // 撤销精确定位权限 dpm.setPermissionGrantState(adminComponent, getPackageName(), Manifest.permission.ACCESS_FINE_LOCATION, DevicePolicyManager.PERMISSION_GRANT_STATE_DENIED); // 撤销粗略定位权限(如果需要) dpm.setPermissionGrantState(adminComponent, getPackageName(), Manifest.permission.ACCESS_COARSE_LOCATION, DevicePolicyManager.PERMISSION_GRANT_STATE_DENIED); } finish(); }
2. 基于Root权限执行Shell命令
若设备已Root,可通过执行系统Shell命令撤销权限:
- 在应用关闭回调中执行以下代码:
可在private void revokeLocationPermissions() { String pkgName = getPackageName(); try { // 撤销精确定位权限 Process process = Runtime.getRuntime().exec("su -c pm revoke " + pkgName + " android.permission.ACCESS_FINE_LOCATION"); process.waitFor(); // 撤销粗略定位权限 Process process2 = Runtime.getRuntime().exec("su -c pm revoke " + pkgName + " android.permission.ACCESS_COARSE_LOCATION"); process2.waitFor(); } catch (IOException | InterruptedException e) { e.printStackTrace(); } }onDestroy()或onTaskRemoved()中调用此方法完成权限撤销。
二、无需撤销权限的替代解决方案
考虑到权限撤销依赖特殊权限,优先推荐以下方案解决冲突崩溃问题:
彻底释放位置服务资源
授予权限后其他应用崩溃,大概率是你的应用未正确释放位置服务占用的资源。可在应用退后台或关闭时,停止位置监听并释放相关对象:
private LocationManager locationManager; private LocationListener locationListener; @Override protected void onPause() { super.onPause(); // 退后台时停止位置更新 if (locationManager != null && locationListener != null) { locationManager.removeUpdates(locationListener); } } @Override public void onTaskRemoved(Intent rootIntent) { super.onTaskRemoved(rootIntent); // 应用关闭时彻底释放资源 if (locationManager != null && locationListener != null) { locationManager.removeUpdates(locationListener); locationManager = null; locationListener = null; } finish(); }
通过释放资源,即使权限仍处于授予状态,也不会占用位置服务资源导致其他应用崩溃。
三、总结
- 若必须实现自动撤销权限:优先选择设备所有者方案(无需Root),或Root设备下执行Shell命令;
- 若无需强制撤销权限:通过释放位置服务资源即可解决其他应用崩溃问题,无需依赖特殊权限。
内容的提问来源于stack exchange,提问作者JNMP
相关产品推荐
相关产品推荐

