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

Android 6.0多权限申请问题:仅弹出首个权限弹窗求助

解决Android多权限申请仅弹出第一个弹窗的问题

嘿,我来帮你搞定这个权限申请的坑!你遇到的问题大概率是因为权限类型不匹配导致的——你申请的权限里混了普通危险权限和特殊权限,而Android对这两类权限的申请逻辑完全不一样,系统只会处理第一个符合普通申请逻辑的权限,后面的特殊权限根本不会触发弹窗。

先搞清楚你申请的权限类型

你列出的四个权限里:

  • MODIFY_AUDIO_SETTINGS、WRITE_EXTERNAL_STORAGE:属于危险权限,可以通过requestPermissions()弹窗申请;
  • WRITE_SETTINGS:属于特殊权限,不能用弹窗申请,必须跳转到系统设置页面让用户手动开启;
  • CHANGE_CONFIGURATION:更特殊,属于系统级权限,只有系统应用或拥有系统签名的应用才能获取,普通应用根本没法通过常规方式申请到!

解决方案:拆分权限申请逻辑

我们需要把危险权限和特殊权限分开处理,先申请危险权限,再单独处理特殊权限。下面是完整的代码示例:

import android.Manifest;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.net.Uri;
import android.os.Build;
import android.provider.Settings;
import android.widget.Toast;
import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
import android.os.Bundle;
import androidx.core.app.ActivityCompat;
import androidx.core.content.ContextCompat;
import java.util.ArrayList;
import java.util.List;

public class MainActivity extends AppCompatActivity {

    // 危险权限数组(可弹窗申请的)
    private static final String[] DANGEROUS_PERMISSIONS = {
            Manifest.permission.MODIFY_AUDIO_SETTINGS,
            Manifest.permission.WRITE_EXTERNAL_STORAGE
    };

    // 请求码
    private static final int REQUEST_CODE_DANGEROUS = 100;
    private static final int REQUEST_CODE_WRITE_SETTINGS = 101;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
            checkPermissions();
        }
    }

    // 先检查并申请危险权限
    private void checkPermissions() {
        List<String> needRequestPerms = new ArrayList<>();
        for (String perm : DANGEROUS_PERMISSIONS) {
            if (ContextCompat.checkSelfPermission(this, perm) != PackageManager.PERMISSION_GRANTED) {
                needRequestPerms.add(perm);
            }
        }

        if (!needRequestPerms.isEmpty()) {
            // 批量申请危险权限
            ActivityCompat.requestPermissions(this, needRequestPerms.toArray(new String[0]), REQUEST_CODE_DANGEROUS);
        } else {
            // 危险权限都拿到了,处理特殊权限
            checkSpecialPermissions();
        }
    }

    // 处理特殊权限(WRITE_SETTINGS)
    private void checkSpecialPermissions() {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
            // 检查WRITE_SETTINGS权限
            if (!Settings.System.canWrite(this)) {
                Intent intent = new Intent(Settings.ACTION_MANAGE_WRITE_SETTINGS);
                intent.setData(Uri.parse("package:" + getPackageName()));
                startActivityForResult(intent, REQUEST_CODE_WRITE_SETTINGS);
            } else {
                Toast.makeText(this, "所有必要权限已获取", Toast.LENGTH_SHORT).show();
                // 这里可以执行需要权限的操作
            }
        }
    }

    // 处理危险权限申请结果
    @Override
    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults);
        if (requestCode == REQUEST_CODE_DANGEROUS) {
            boolean allGranted = true;
            for (int result : grantResults) {
                if (result != PackageManager.PERMISSION_GRANTED) {
                    allGranted = false;
                    break;
                }
            }

            if (allGranted) {
                checkSpecialPermissions();
            } else {
                Toast.makeText(this, "部分危险权限未授予,应用功能可能受限", Toast.LENGTH_SHORT).show();
            }
        }
    }

    // 处理特殊权限的跳转结果
    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        if (requestCode == REQUEST_CODE_WRITE_SETTINGS) {
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
                if (Settings.System.canWrite(this)) {
                    Toast.makeText(this, "WRITE_SETTINGS权限已开启", Toast.LENGTH_SHORT).show();
                } else {
                    Toast.makeText(this, "WRITE_SETTINGS权限未开启,相关功能无法使用", Toast.LENGTH_SHORT).show();
                }
            }
        }
    }
}

额外注意事项

  1. 关于CHANGE_CONFIGURATION权限:
    这个权限普通应用根本拿不到,如果你不是开发系统应用,建议先确认是否真的需要它——大概率可以用其他方式替代需求,比如通过AccessibilityService来实现配置调整的功能。

  2. Android 10+的存储权限:
    WRITE_EXTERNAL_STORAGE在Android 10及以上版本已经被限制,如果需要访问设备上的所有文件,应该申请MANAGE_EXTERNAL_STORAGE权限,同样需要跳转到系统设置页面申请。

内容的提问来源于stack exchange,提问作者WhySoBizarreCode

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.25 08:20:15