You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.14 13:20:35