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();
相关推荐
i***13242 分钟前
SpringCloud实战十三:Gateway之 Spring Cloud Gateway 动态路由
java·spring cloud·gateway
计算机徐师兄4 分钟前
Java基于微信小程序的食堂线上预约点餐系统【附源码、文档说明】
java·微信小程序·食堂线上预约点餐系统小程序·食堂线上预约点餐微信小程序·java食堂线上预约点餐小程序·食堂线上预约点餐小程序·食堂线上预约点餐系统微信小程序
无心水1 小时前
【分布式利器:腾讯TSF】10、TSF故障排查与架构评审实战:Java架构师从救火到防火的生产哲学
java·人工智能·分布式·架构·限流·分布式利器·腾讯tsf
TA远方3 小时前
【Android】adb常用的命令用法详解
android·adb·管理·控制·命令
Boilermaker19928 小时前
[Java 并发编程] Synchronized 锁升级
java·开发语言
Cherry的跨界思维8 小时前
28、AI测试环境搭建与全栈工具实战:从本地到云平台的完整指南
java·人工智能·vue3·ai测试·ai全栈·测试全栈·ai测试全栈
MM_MS8 小时前
Halcon变量控制类型、数据类型转换、字符串格式化、元组操作
开发语言·人工智能·深度学习·算法·目标检测·计算机视觉·视觉检测
꧁Q༒ོγ꧂9 小时前
LaTeX 语法入门指南
开发语言·latex
njsgcs9 小时前
ue python二次开发启动教程+ 导入fbx到指定文件夹
开发语言·python·unreal engine·ue
alonewolf_999 小时前
JDK17新特性全面解析:从语法革新到模块化革命
java·开发语言·jvm·jdk