如何正确获取安卓设备的存储权限?

在Android开发中,获取存储权限是一个常见的需求,下面将详细介绍如何在Android应用中获取存储权限,包括权限的申请和文件的创建与存储。

如何正确获取安卓设备的存储权限?

一、获取存储权限

1. 配置静态权限

需要在AndroidManifest.xml文件中添加存储相关的权限声明:

<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>

2. 动态获取权限

从Android 6.0(API级别23)开始,一些危险权限(如存储权限)需要动态获取,以下是使用XXPermissions库来请求存储权限的示例代码:

import com.hjq.permissions.OnPermissionCallback;
import com.hjq.permissions.Permission;
import com.hjq.permissions.XXPermissions;
// 在任意能够执行的地方添加以下代码
XXPermissions.with(this)
    .permission(Permission.MANAGE_EXTERNAL_STORAGE) // 适配 Android 11 需要这样写
    .request(new OnPermissionCallback() {
        @Override
        public void onGranted(List<String> permissions, boolean all) {
            if (all) {
                Toast.makeText(MainActivity.this, "获取存储权限成功", Toast.LENGTH_SHORT).show();
            }
        }
        @Override
        public void onDenied(List<String> permissions, boolean never) {
            if (never) {
                Toast.makeText(MainActivity.this, "永久获取存储权限失败", Toast.LENGTH_SHORT).show();
                // 如果是被永久拒绝就跳转到应用权限系统设置页面
                XXPermissions.startPermissionActivity(MainActivity.this, permissions);
            } else {
                Toast.makeText(MainActivity.this, "获取存储权限失败", Toast.LENGTH_SHORT).show();
            }
        }
    });

引入库:

implementation 'com.github.getActivity:XXPermissions:18.6'

如果项目的targetSdkVersion >= 29,还需要在清单文件中添加以下属性:

如何正确获取安卓设备的存储权限?

<application
    android:requestLegacyExternalStorage="true">
</application>

二、创建、存储文件

1. 查找路径

可以使用以下方法获取外部存储的根目录路径:

String externalStorageDirectory = Environment.getExternalStorageDirectory().getAbsolutePath();

2. 创建目录和文件

以下是在外部存储路径下创建一个文件夹并保存文件的示例代码:

import java.io.File;
import java.io.PrintWriter;
public class MainActivity extends AppCompatActivity {
    private static final int REQUEST_EXTERNAL_STORAGE = 1;
    private static String[] PERMISSIONS_STORAGE = {
        "android.permission.READ_EXTERNAL_STORAGE",
        "android.permission.WRITE_EXTERNAL_STORAGE"
    };
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        checkPermission();
    }
    private void checkPermission() {
        try {
            int permission = ActivityCompat.checkSelfPermission(this,
                    "android.permission.WRITE_EXTERNAL_STORAGE");
            if (permission != PackageManager.PERMISSION_GRANTED) {
                ActivityCompat.requestPermissions(this, PERMISSIONS_STORAGE, REQUEST_EXTERNAL_STORAGE);
            } else {
                createAndStoreFile("exampleDir", "exampleFile.txt");
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    private void createAndStoreFile(String dirName, String fileName) {
        String absolutePath = Environment.getExternalStorageDirectory().getAbsolutePath() + File.separator + dirName;
        File dir = new File(absolutePath);
        if (!dir.exists()) {
            dir.mkdirs();
            System.out.println("Directory created: " + absolutePath);
        } else {
            System.out.println("Directory already exists: " + absolutePath);
        }
        String filePath = absolutePath + File.separator + fileName;
        try (PrintWriter out = new PrintWriter(filePath)) {
            out.println("This is a test file.");
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

三、相关问题与解答

Q1: 如果用户拒绝了存储权限,如何再次请求?

A1: 如果用户拒绝了存储权限,可以通过提示用户前往应用设置页面手动开启权限。

如何正确获取安卓设备的存储权限?

if (never) {
    Toast.makeText(MainActivity.this, "永久获取存储权限失败", Toast.LENGTH_SHORT).show();
    XXPermissions.startPermissionActivity(MainActivity.this, permissions); // 跳转到应用权限系统设置页面
} else {
    Toast.makeText(MainActivity.this, "获取存储权限失败", Toast.LENGTH_SHORT).show();
}

Q2: Android 11及以上版本如何处理存储权限?

A2: Android 11及以上版本对存储权限进行了更严格的管理,需要使用MANAGE_EXTERNAL_STORAGE权限,还需要在AndroidManifest.xml中添加requestLegacyExternalStorage="true"属性,以确保兼容性。

小伙伴们,上文介绍了“安卓获取存储权限”的内容,你了解清楚吗?希望对你有所帮助,任何问题可以给我留言,让我们下期再见吧。