Android 6.0 动态申请权限无效问题

本文介绍Android应用中如何正确实现动态权限请求的过程,并针对权限请求失败、回调参数为空的问题提供了检查和解决方法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Android动态权限添加的流程一般如下:
  1.在AndroidManifest.xml文件中添加相应的权限,如下:
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>


2.在需要使用权限的地方或者直接应用启动后直接申请权限,如下:

if(Build.VERSION.SDK_INT >= 23){
    if(checkSelfPermission(Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED){
        if(!shouldShowRequestPermissionRationale(Manifest.permission.ACCESS_FINE_LOCATION)){
            requestPermissions(new String[]{Manifest.permission.ACCESS_FINE_LOCATION},1);
        }
    }
}
3.添加权限申请回调
@Override
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
    super.onRequestPermissionsResult(requestCode, permissions, grantResults);
    if (requestCode == 1) {
        for (int i = 0; i < permissions.length; i++) {
            if (grantResults[i] != PackageManager.PERMISSION_GRANTED) {
                Toast.makeText(MainActivity.this,permissions[i] + "未授权",Toast.LENGTH_SHORT).show();
                continue;
            }
            Toast.makeText(MainActivity.this,permissions[i] + "已授权",Toast.LENGTH_SHORT).show();
        }
    }
}
问题:有可能虽然是这么做了,但是权限申请无效,申请框依然没有弹出来,回调到的方法中permissions和grantResults的长度均为0.

解决方案:

确认AndroidManifest.xml文件中目标SDK是否有设置和设置版本问题。
<uses-sdk android:minSdkVersion="11"
          android:targetSdkVersion="23" /> 
<think>我们正在讨论Android动态申请运行时权限,解决文件操作时的EACCESPermissiondenied问题。参考引用内容,我们可以总结以下步骤:1.AndroidManifest.xml中声明权限(WRITE_EXTERNAL_STORAGE和READ_EXTERNAL_STORAGE)。2.对于Android10及以上版本,在<application>标签中添加android:requestLegacyExternalStorage="true"以启用旧版存储模式。3.在代码中动态申请权限(针对Android6.0及以上版本)。4.对于Android11(API30)及更高版本,如果需要访问所有文件(管理外部存储),则必须请求MANAGE_EXTERNAL_STORAGE权限,并引导用户到设置页面开启。下面详细说明动态申请运行时权限的步骤:###步骤1:在AndroidManifest.xml中声明权限```xml<uses-permissionandroid:name="android.permission.READ_EXTERNAL_STORAGE"/><uses-permissionandroid:name="android.permission.WRITE_EXTERNAL_STORAGE"/><!--针对Android11及以上,如果需要管理所有文件,还需要声明以下权限--><uses-permissionandroid:name="android.permission.MANAGE_EXTERNAL_STORAGE"android:minSdkVersion="30"/>```###步骤2:为Android10及以上应用启用旧版存储模式在`<application>`标签中添加:```xml<application...android:requestLegacyExternalStorage="true"...>...</application>```###步骤3:动态申请权限(针对Android6.0+)在需要访问存储的地方,检查权限申请。```java//定义权限请求码privatestaticfinalintREQUEST_STORAGE_PERMISSION=1;//需要申请权限数组privateString[]permissions={Manifest.permission.READ_EXTERNAL_STORAGE,Manifest.permission.WRITE_EXTERNAL_STORAGE};//检查并申请权限privatevoidcheckStoragePermissions(){//检查是否已经授予权限if(ContextCompat.checkSelfPermission(this,Manifest.permission.WRITE_EXTERNAL_STORAGE)!=PackageManager.PERMISSION_GRANTED){//没有权限申请权限ActivityCompat.requestPermissions(this,permissions,REQUEST_STORAGE_PERMISSION);}else{//已经有权限,执行文件操作doFileOperation();}}//处理权限申请结果@OverridepublicvoidonRequestPermissionsResult(intrequestCode,@NonNullString[]permissions,@NonNullint[]grantResults){super.onRequestPermissionsResult(requestCode,permissions,grantResults);if(requestCode==REQUEST_STORAGE_PERMISSION){//检查是否所有权限都被授予if(grantResults.length>0&&grantResults[0]==PackageManager.PERMISSION_GRANTED&&grantResults[1]==PackageManager.PERMISSION_GRANTED){doFileOperation();}else{//权限被拒绝,提示用户Toast.makeText(this,"权限被拒绝,无法访问文件",Toast.LENGTH_SHORT).show();}}}```###步骤4:处理Android11(API30)及以上版本的管理所有文件权限Android11开始,普通存储权限(READ/WRITE_EXTERNAL_STORAGE)不能访问所有文件,如果需要管理所有文件,则必须使用MANAGE_EXTERNAL_STORAGE权限。```java//检查是否为Android11及以上if(Build.VERSION.SDK_INT>=Build.VERSION_CODES.R){if(!Environment.isExternalStorageManager()){//引导用户到设置页面开启所有文件管理权限Intentintent=newIntent(Settings.ACTION_MANAGE_APP_ALL_FILES_ACCESS_PERMISSION);intent.setData(Uri.parse("package:"+getPackageName()));startActivityForResult(intent,REQUEST_MANAGE_EXTERNAL_STORAGE);}else{//已经获得管理所有文件的权限doFileOperation();}}else{//Android11以下版本,使用之前的动态权限申请checkStoragePermissions();}```然后在`onActivityResult`中处理结果:```java@OverrideprotectedvoidonActivityResult(intrequestCode,intresultCode,@NullableIntentdata){super.onActivityResult(requestCode,resultCode,data);if(requestCode==REQUEST_MANAGE_EXTERNAL_STORAGE){if(Build.VERSION.SDK_INT>=Build.VERSION_CODES.R){if(Environment.isExternalStorageManager()){doFileOperation();}else{Toast.makeText(this,"未授予所有文件访问权限,功能受限",Toast.LENGTH_SHORT).show();}}}}```###注意事项1.动态申请权限时,需要处理用户拒绝权限的情况,可以提示用户该权限的必要性,并再次申请。2.Android11及以上,使用MANAGE_EXTERNAL_STORAGE权限时,需要在GooglePlay中声明该权限的使用目的,否则可能被拒绝上架。3.对于Android10的旧版存储模式,它只是一个过渡方案,在Android11及以上,如果targetSdkVersion为30或更高,则旧版存储模式无效,需要迁移到分区存储(ScopedStorage)模式。通过以上步骤,我们可以根据不同的Android版本动态申请权限,解决文件操作时的权限问题[^1][^2][^5]。§§相关问题§§1.Android权限机制有哪几种?例如普通权限和危险权限等2.如何迁移应用到Android11的分区存储模式?3.如何自定义权限申请对话框以提高用户授权率?</think> ### Android动态申请运行时权限解决文件操作权限异常 在Android中解决`EACCES (Permission denied)`文件操作失败问题,需按系统版本动态处理权限。以下是完整流程: --- #### **1. 基本权限声明** 在`AndroidManifest.xml`中声明权限(所有版本必需): ```xml <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" /> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /> ``` --- #### **2. Android 5.0~9.0 (API 21~28) 动态权限申请** 使用运行时请求,需处理用户授权结果: ```java // 检查权限状态 if (ContextCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) { // 弹出权限请求对话框 ActivityCompat.requestPermissions( this, new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, REQUEST_CODE_STORAGE // 自定义请求码(如100) ); } // 处理授权结果 @Override public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) { if (requestCode == REQUEST_CODE_STORAGE) { if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) { // 权限已授予,执行文件操作 writeToFile(); } else { // 权限被拒绝,提示用户 Toast.makeText(this, "存储权限被拒绝,无法保存文件", Toast.LENGTH_SHORT).show(); } } } ``` --- #### **3. Android 10+ (API 29+) 特殊处理** 添加`requestLegacyExternalStorage`属性绕过分区存储限制: ```xml <application android:requestLegacyExternalStorage="true" ... > </application> ``` > **注意**:Android 11及更高版本中此属性作用受限,需额外处理[^1][^2]。 --- #### **4. Android 11+ (API 30+) 管理所有文件权限** 对完整存储访问需引导用户至系统设置页: ```java if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) { if (!Environment.isExternalStorageManager()) { // 跳转系统设置页 Intent intent = new Intent(Settings.ACTION_MANAGE_APP_ALL_FILES_ACCESS_PERMISSION); intent.setData(Uri.parse("package:" + getPackageName())); startActivityForResult(intent, REQUEST_CODE_MANAGE_STORAGE); } else { // 已有权限 } } ``` --- #### **5. 最佳实践建议** 1. **兼容性检查**: ```java if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { // 动态请求逻辑 } ``` 2. **解释必要性**(可选): 在请求权限前调用`shouldShowRequestPermissionRationale()`解释为何需要权限。 3. **降级处理**: 捕获文件操作异常并提示友好错误: ```java try { FileOutputStream fos = new FileOutputStream(filePath); } catch (FileNotFoundException e) { Log.e("FileError", "文件访问失败: " + e.getMessage()); // 检查权限状态并重试请求 } ``` --- **关键点总结**: 1. 声明基础读写权限 2. 动态请求运行时权限(API 23+) 3. Android 10+启用`requestLegacyExternalStorage` 4. Android 11+引导用户开启「所有文件访问」[^5] 5. 按需处理降级场景 通过分版本阶梯式处理,可彻底解决`EACCES (Permission denied)`文件访问问题[^1][^2][^5]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值