在Android开发中,检测SD卡的读写权限是一个常见需求,由于不同版本的Android系统对SD卡权限的管理有所不同,开发者需要根据具体情况进行适配,下面将详细介绍如何在Android应用中检测SD卡的读写权限。
Android SD卡读写权限
一、Android版本与SD卡权限
1、Android 4.4(KitKat)及之前:在这些版本中,SD卡的读写权限并未细分,通常使用android.permission.WRITE_EXTERNAL_STORAGE
权限即可访问SD卡。
2、Android 5.0(Lollipop)及以上:从这一版本开始,Google对SD卡的读写权限进行了分离和限制,读权限被分为了READ_EXTERNAL_STORAGE
,而写权限则保留为WRITE_EXTERNAL_STORAGE
,对于某些特定的文件夹或文件,还需要用户手动授权才能访问。
3、Android 13(API 33)及之后:在Android 13中,SD卡的读权限进一步细化为三个子权限:READ_MEDIA_AUDIO
、READ_MEDIA_IMAGES
和READ_MEDIA_VIDEO
,如果应用的targetSDK小于33,申请READ_EXTERNAL_STORAGE
权限时会自动转化为对这三个子权限的申请;如果targetSDK大于等于33,则需要单独申请这三个子权限。
二、权限检测与请求流程
1、定义权限变量:定义两个Map来存储允许和禁止后的Runnable操作。
private Map<Integer, Runnable> allowablePermissionRunnables = new HashMap<>(); private Map<Integer, Runnable> disallowablePermissionRunnables = new HashMap<>();
2、编写权限请求方法:实现一个通用的权限请求方法,该方法接受权限ID、权限名称、允许后的Runnable和禁止后的Runnable作为参数。
protected void requestPermission(int id, String permission, Runnable allowableRunnable, Runnable disallowableRunnable) { if (allowableRunnable != null) { allowablePermissionRunnables.put(id, allowableRunnable); } if (disallowableRunnable != null) { disallowablePermissionRunnables.put(id, disallowableRunnable); } // API版本判断 if (Build.VERSION.SDK_INT >= 23) { // 检查是否拥有权限 int checkCallPhonePermission = ContextCompat.checkSelfPermission(getApplicationContext(), permission); if (checkCallPhonePermission != PackageManager.PERMISSION_GRANTED) { // 弹出对话框接收权限 ActivityCompat.requestPermissions(TakeCameraActivity.this, new String[]{permission}, id); return; } else { if (allowableRunnable != null) { allowableRunnable.run(); } } } else { // 对于低于Android 6.0的版本,直接执行允许后的操作 if (allowableRunnable != null) { allowableRunnable.run(); } } }
3、调用权限请求方法:根据实际需求调用上述方法,传入相应的参数,为了请求SD卡写入权限,可以这样调用:
requestPermission(HDCivilizationConstants.SD_CARD_REQUEST_CODE, "android.permission.WRITE_EXTERNAL_STORAGE", new Runnable() { @Override public void run() { // 权限允许后的业务逻辑 if (type == 1) { FileUtils.saveBitmapPng(rectBitmap, pathList, 80); } else { try { FileUtils.saveBitmapJPG(rectBitmap, pathList, 70); } catch (ContentException e) { e.printStackTrace(); } } } }, new Runnable() { @Override public void run() { // 权限禁止后的业务逻辑 OKPopup.getInstance().showPopup(TakeCameraActivity.this, new OKPopup.BtnClickListener() { @Override public void btnOk() { OKPopup.getInstance().dismissDialog(); } }, false, HDCivilizationConstants.SDCARD_PERMISSION); } });
4、处理权限请求结果:重写onRequestPermissionsResult
方法,以处理用户对权限请求的响应。
@Override public void onRequestPermissionsResult(int requestCode, int[] permissions, int[] grantResults) { super.onRequestPermissionsResult(requestCode, permissions, grantResults); if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) { // 权限被允许,执行允许后的操作 if (allowablePermissionRunnables.containsKey(requestCode)) { allowablePermissionRunnables.get(requestCode).run(); } } else { // 权限被拒绝,执行禁止后的操作 if (disallowablePermissionRunnables.containsKey(requestCode)) { disallowablePermissionRunnables.get(requestCode).run(); } } }
Android SD卡读写权限检测与请求示例代码
以下是一个完整的示例代码,展示了如何在Android应用中检测并请求SD卡的读写权限。
import android.Manifest; import android.content.pm.PackageManager; import android.os.Build; import android.os.Bundle; import androidx.annotation.NonNull; import androidx.appcompat.app.AppCompatActivity; import androidx.core.app.ActivityCompat; import androidx.core.content.ContextCompat; import java.util.HashMap; import java.util.Map; public class TakeCameraActivity extends AppCompatActivity { private static final int SD_CARD_REQUEST_CODE = 1; // 请求码唯一标识即可 private Map<Integer, Runnable> allowablePermissionRunnables = new HashMap<>(); // 允许后的Runnable操作集合 private Map<Integer, Runnable> disallowablePermissionRunnables = new HashMap<>(); // 禁止后的Runnable操作集合 @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_take_camera); // 假设这里有一个按钮用于触发SD卡写入操作 findViewById(R.id.button_write_sd).setOnClickListener(v -> requestWriteExternalStoragePermission()); } private void requestWriteExternalStoragePermission() { requestPermission(SD_CARD_REQUEST_CODE, Manifest.permission.WRITE_EXTERNAL_STORAGE, new Runnable() { @Override public void run() { // 权限允许后的业务逻辑,如保存图片到SD卡 FileUtils.saveBitmapPng(rectBitmap, pathList, 80); } }, new Runnable() { @Override public void run() { // 权限禁止后的业务逻辑,如提示用户开启权限 OKPopup.getInstance().showPopup(TakeCameraActivity.this, new OKPopup.BtnClickListener() { @Override public void btnOk() { OKPopup.getInstance().dismissDialog(); } }, false, "请查看SD卡的读写权限"); } }); } protected void requestPermission(int id, String permission, Runnable allowableRunnable, Runnable disallowableRunnable) { if (allowableRunnable != null) { allowablePermissionRunnables.put(id, allowableRunnable); } if (disallowableRunnable != null) { disallowablePermissionRunnables.put(id, disallowableRunnable); } // API版本判断 if (Build.VERSION.SDK_INT >= 23) { int checkCallPhonePermission = ContextCompat.checkSelfPermission(getApplicationContext(), permission); if (checkCallPhonePermission != PackageManager.PERMISSION_GRANTED) { ActivityCompat.requestPermissions(TakeCameraActivity.this, new String[]{permission}, id); return; } else { if (allowableRunnable != null) { allowableRunnable.run(); } } } else { if (allowableRunnable != null) { allowableRunnable.run(); } } } @Override public void onRequestPermissionsResult(int requestCode, int[] permissions, int[] grantResults) { super.onRequestPermissionsResult(requestCode, permissions, grantResults); if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) { if (allowablePermissionRunnables.containsKey(requestCode)) { allowablePermissionRunnables.get(requestCode).run(); } } else { if (disallowablePermissionRunnables.containsKey(requestCode)) { disallowablePermissionRunnables.get(requestCode).run(); } } } }
在这个示例中,我们通过点击按钮来触发SD卡写入权限的请求,如果用户授予了权限,则执行保存图片的操作;否则,提示用户开启权限,注意,这里的FileUtils.saveBitmapPng
和OKPopup
是假设存在的工具类和方法,实际应用中需要根据具体情况进行替换。
相关问题与解答栏目
问题1:在Android 13中,如何正确请求SD卡的读写权限?
答:在Android 13中,SD卡的读权限被细化为三个子权限:READ_MEDIA_AUDIO
、READ_MEDIA_IMAGES
和READ_MEDIA_VIDEO
,如果你的应用targetSDK小于33,申请READ_EXTERNAL_STORAGE
权限时会自动转化为对这三个子权限的申请;如果targetSDK大于等于33,则需要单独申请这三个子权限,写权限仍然保持不变,为WRITE_EXTERNAL_STORAGE
,你需要根据你的应用需求来决定是否需要申请这些权限。
问题2:如何处理用户拒绝SD卡读写权限的情况?
答:当用户拒绝SD卡读写权限时,你可以通过弹窗或其他方式提示用户前往设置中手动开启相关权限,你可以在disallowablePermissionRunnables
中存储拒绝后的Runnable操作,以便在用户拒绝权限后执行相应的业务逻辑,你可以显示一个对话框引导用户前往设置页面开启权限,或者禁用与SD卡相关的功能。
各位小伙伴们,我刚刚为大家分享了有关“android检测SD卡读写权限”的知识,希望对你们有所帮助。如果您还有其他相关问题需要解决,欢迎随时提出哦!
原创文章,作者:K-seo,如若转载,请注明出处:https://www.kdun.cn/ask/632346.html