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();
相关推荐
Leo655351 小时前
JDK8 的排序、分组求和,转换为Map
java·开发语言
磨十三2 小时前
C++ 标准库排序算法 std::sort 使用详解
开发语言·c++·排序算法
书源丶4 小时前
二十八、API之《System 类》——与系统交互的“桥梁”
java·交互
两只程序猿4 小时前
数据可视化 | Violin Plot小提琴图Python实现 数据分布密度可视化科研图表
开发语言·python·信息可视化
Pluchon4 小时前
硅基计划4.0 算法 字符串
java·数据结构·学习·算法
折翅鵬4 小时前
Android 程序员如何系统学习 MQTT
android·学习
野生技术架构师4 小时前
1000 道 Java 架构师岗面试题
java·开发语言
搬砖的小码农_Sky4 小时前
如何将安卓应用迁移到鸿蒙?
android·华为·harmonyos
搬砖的小码农_Sky4 小时前
鸿蒙应用开发和安卓应用开发的区别
android·华为·harmonyos
青柠编程4 小时前
基于Spring Boot的选课管理系统架构设计
java·spring boot·后端