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(); } } } } }
额外注意事项
关于CHANGE_CONFIGURATION权限:
这个权限普通应用根本拿不到,如果你不是开发系统应用,建议先确认是否真的需要它——大概率可以用其他方式替代需求,比如通过AccessibilityService来实现配置调整的功能。Android 10+的存储权限:
WRITE_EXTERNAL_STORAGE在Android 10及以上版本已经被限制,如果需要访问设备上的所有文件,应该申请MANAGE_EXTERNAL_STORAGE权限,同样需要跳转到系统设置页面申请。
内容的提问来源于stack exchange,提问作者WhySoBizarreCode
相关产品推荐
相关产品推荐

