Android 动态申请 REQUEST_INSTALL_PACKAGES 权限问题:申请权限失败

xml 复制代码
<uses-permission android:name="android.permission.REQUEST_INSTALL_PACKAGES" />
java 复制代码
private static final int REQUEST_CODE_INSTALL_PERMISSION = 1;
java 复制代码
ActivityResultLauncher<String> activityResultLauncher = registerForActivityResult(
        new ActivityResultContracts.RequestPermission(),
        isGranted -> {
            if (!isGranted) {
                Toast.makeText(this, "权限申请失败", Toast.LENGTH_SHORT).show();
                finish();
                return;
            }

            next();
        }
);

activityResultLauncher.launch(Manifest.permission.REQUEST_INSTALL_PACKAGES);
  • 在 Android 开发中,执行上述权限申请的代码,权限申请失败
问题描述
  1. Manifest.permission.REQUEST_INSTALL_PACKAGES 是一个特殊权限,不能通过常规的运行时权限请求方式(ActivityResultContracts.RequestPermission)来申请

  2. Manifest.permission.REQUEST_INSTALL_PACKAGES 必须通过跳转到系统设置页面让用户手动授权

  3. 正确的申请方式:检查是否已有权限,如果没有权限,引导用户前往系统设置

  4. Manifest.permission.REQUEST_INSTALL_PACKAGES 在 Android 8.0 引入,低版本无需处理

处理策略
  1. AndroidManifest.xml 中声明权限
xml 复制代码
<uses-permission android:name="android.permission.REQUEST_INSTALL_PACKAGES" />
  1. 跳转请求权限(过时写法)
java 复制代码
private static final int REQUEST_CODE_INSTALL_PERMISSION = 1;
java 复制代码
boolean canInstall = checkInstallPermission();

Log.i(TAG, "canInstall = " + canInstall);

if (!canInstall) {
    Intent intent = new Intent(Settings.ACTION_MANAGE_UNKNOWN_APP_SOURCES)
            .setData(Uri.parse("package:" + getPackageName()));
    startActivityForResult(intent, REQUEST_CODE_INSTALL_PERMISSION);
    return;
}

next();
java 复制代码
private boolean checkInstallPermission() {
    return Build.VERSION.SDK_INT >= Build.VERSION_CODES.O ? getPackageManager().canRequestPackageInstalls() : true;
}
java 复制代码
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    super.onActivityResult(requestCode, resultCode, data);

    if (requestCode == REQUEST_CODE_INSTALL_PERMISSION) {
        boolean canInstall = checkInstallPermission();

        Log.i(TAG, "now, canInstall = " + canInstall);

        if (!canInstall) {
            Toast.makeText(this, "权限申请失败", Toast.LENGTH_SHORT).show();
            return;
        }
        next();
    }
}
  • 使用 ActivityResultLauncher 来替代(现代写法)
java 复制代码
private boolean checkInstallPermission() {
    return Build.VERSION.SDK_INT >= Build.VERSION_CODES.O ? getPackageManager().canRequestPackageInstalls() : true;
}
java 复制代码
boolean canInstall = checkInstallPermission();

Log.i(TAG, "canInstall = " + canInstall);

if (!canInstall) {
    ActivityResultLauncher<Intent> activityResultLauncher = registerForActivityResult(
            new ActivityResultContracts.StartActivityForResult(),
            result -> {
                boolean canInstall_ = checkInstallPermission();

                Log.i(TAG, "now, canInstall = " + canInstall_);

                if (!canInstall_) {
                    Toast.makeText(this, "权限申请失败", Toast.LENGTH_SHORT).show();
                    return;
                }
                next();
            }
    );

    Intent intent = new Intent(Settings.ACTION_MANAGE_UNKNOWN_APP_SOURCES)
            .setData(Uri.parse("package:" + getPackageName()));

    activityResultLauncher.launch(intent);

    return;
}
next();
相关推荐
用户41659673693551 分钟前
深度解码:记一次视频时间戳(PTS)异常导致的播放故障排查
android
风吹迎面入袖凉2 分钟前
【Redis】Redisson分布式锁原理
java·服务器·开发语言
A.A呐2 分钟前
【QT第五章】系统相关
开发语言·qt
QCzblack2 分钟前
BugKu BUUCTF ——Reverse
java·前端·数据库
Ww.xh4 分钟前
Android Studio AI插件推荐
android studio
Orange_sparkle6 分钟前
learn claude code学习记录-S02
java·python·学习
李白你好7 分钟前
Java GUI-未授权漏洞检测工具
java·开发语言
leo__52022 分钟前
拉丁超立方抽样(Latin Hypercube Sampling, LHS)MATLAB实现
开发语言·matlab
sycmancia25 分钟前
Qt——Qt中的标准对话框
开发语言·qt
aq553560027 分钟前
四大编程语言对比:PHP、Python、Java、易语言
java·python·php