如何检测安卓设备中SD卡的读写权限?

在Android开发中,检测SD卡的读写权限是一个常见需求,由于不同版本的Android系统对SD卡权限的管理有所不同,开发者需要根据具体情况进行适配,下面将详细介绍如何在Android应用中检测SD卡的读写权限。

如何检测安卓设备中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_AUDIOREAD_MEDIA_IMAGESREAD_MEDIA_VIDEO,如果应用的targetSDK小于33,申请READ_EXTERNAL_STORAGE权限时会自动转化为对这三个子权限的申请;如果targetSDK大于等于33,则需要单独申请这三个子权限。

二、权限检测与请求流程

1、定义权限变量:定义两个Map来存储允许和禁止后的Runnable操作。

如何检测安卓设备中SD卡的读写权限?

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.saveBitmapPngOKPopup是假设存在的工具类和方法,实际应用中需要根据具体情况进行替换。

如何检测安卓设备中SD卡的读写权限?

相关问题与解答栏目

问题1:在Android 13中,如何正确请求SD卡的读写权限?

:在Android 13中,SD卡的读权限被细化为三个子权限:READ_MEDIA_AUDIOREAD_MEDIA_IMAGESREAD_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

Like (0)
Donate 微信扫一扫 微信扫一扫
K-seo的头像K-seoSEO优化员
Previous 2024-11-08 00:01
Next 2024-11-08 00:07

相关推荐

  • linux中gedit的用法

    什么是htdigest?htdigest是一种基于HTTP基本认证的加密机制,它允许用户在不泄露密码的情况下访问受保护的资源,htdigest是Apache HTTP服务器的一个扩展模块,它使用MD5算法对用户的密码进行加密,然后将加密后的密码与用户名一起存储在一个名为.htdigest的文件中,这样,当用户尝试访问受保护的资源时,服……

    2023-12-19
    0142
  • 服务器自带的程序能做什么用

    服务器自带的程序能做什么服务器是现代计算环境中不可或缺的组成部分,它们通常预装了操作系统和一系列基本的软件工具,以便执行各种任务,以下是一些服务器自带程序的常见功能和用途:操作系统基础功能每个服务器都装有一个操作系统(OS),如Windows Server、Linux发行版或UNIX等,这些操作系统提供了服务器运行的基本平台,并且具备……

    2024-04-06
    0143
  • linux如何修改主机名(linux如何修改主机名称)

    在Linux中,可以通过编辑/etc/hostname文件来修改主机名。然后使用hostnamectl set-hostname命令使更改生效。

    2024-04-29
    090
  • 游戏云服务器配置要求

    高频游戏云服务器是专为处理高性能要求的游戏应用而设计的计算资源,它们通常具备高频率的中央处理器(CPU)、高性能图形处理器(GPU)以及快速的存储和网络连接,旨在为游戏开发者提供所需的技术能力,以创建、测试和部署游戏,特别是那些需要大量实时计算和数据处理的游戏,以下是高频游戏云服务器对游戏开发者所提供的一些关键优势:强大的计算性能高频……

    2024-02-08
    0199
  • redis常用命令总结

    Redis是一个开源的使用ANSI C编写、遵守BSD协议、支持网络、可基于内存亦可持久化的日志型、Key-Value数据库,并提供多种语言的API,它常被用作数据库、缓存和消息中间件,以下是一些常用的Redis命令:1、SET命令:这是最基本的命令,用于设置键值对,如果键已经存在,那么它的值将被覆盖,SET key value。2、……

    2024-02-29
    0179
  • 手表网站设计

    简洁高效的手表网站设计,注重用户体验与品牌形象。

    2024-02-08
    0214

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

免备案 高防CDN 无视CC/DDOS攻击 限时秒杀,10元即可体验  (专业解决各类攻击)>>点击进入