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();
相关推荐
爱写代码的小朋友16 小时前
从零开始学 Win32 API:C++ 窗口编程实战(VS Code + MinGW-w64 命令行详解)
开发语言·c++
果汁华16 小时前
Function Calling 与 Python 实战完整指南
开发语言·网络·python
小小晓.16 小时前
C++:语句和作用域
开发语言·c++
雨白16 小时前
深入理解 Kotlin 协程 (八):拾遗补阙,探秘官方框架的调度细节与取消闭环
android·kotlin
都叫我大帅哥17 小时前
从Python到Java:为什么企业级Agent最终会选择Java?
java·ai编程
wanderist.17 小时前
Lambda表达式在算法竞赛中的应用
java·开发语言·算法
海天鹰18 小时前
PHP上传文件
android·开发语言·php
腻害兔18 小时前
【若依项目-产品经理视角】RuoYi-Vue-Pro 源码拆解:IM 即时通讯模块,一个被低估的「全功能聊天系统」
java·前端·vue.js·产品经理·ai编程
心念枕惊19 小时前
.NET CORE 授权进阶-角色、策略与动态权限实现
java·前端·.netcore
2501_9159184119 小时前
详解iOS App上架至App Store的全流程步骤与注意事项
android·macos·ios·小程序·uni-app·cocoa·iphone