因项目的需要,最近在做一个类似es文件管理器的app.但是在操作外置sd卡的时候碰到了各种权限的问题,现在很多的手机都没有外置sd卡,网上说的很多都是内置SD卡的权限。
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
注意在6.0后要动态申请
private static String[] PERMISSIONS_STORAGE = {
"android.permission.READ_EXTERNAL_STORAGE",
"android.permission.WRITE_EXTERNAL_STORAGE" };
//检测是否有写的权限
int permission = ActivityCompat.checkSelfPermission(activity,
"android.permission.WRITE_EXTERNAL_STORAGE");
if (permission != PackageManager.PERMISSION_GRANTED) {
// 没有写的权限,去申请写的权限,会弹出对话框
ActivityCompat.requestPermissions(activity, PERMISSIONS_STORAGE,REQUEST_EXTERNAL_STORAGE);
}
但是我需要的是外置sd,这并不是我想要的。外置SD卡的权限是
<uses-permission android:name="android.permission.WRITE_MEDIA_STORAGE" />
这个需要的系统的签名,一般的app拿不到系统的签名,如果只是在自己的系统上使用,可以考虑这个,比较省事。但是es浏览器是没有获取到系统签名的,后来发现主要是使用了DocumentFile这个类,要使用这个就要拿到一个DOCUMENT_TREE
Intent intent = new Intent(Intent.ACTION_OPEN_DOCUMENT_TREE);
startActivityForResult(intent, 1);
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (resultCode == RESULT_OK && requestCode == DIRECTORY_CHOOSE_REQ_CODE) {
//获取返回的Uri,这个uri就可以用来创建DocumentFile,在第一次使用es浏览器的时候会进入一个文件夹
Uri uri = data.getData();
Log.e(TAG, "uri ="+uri.toString());
//mkdirsOnTFCard(uri);
Log.e("onActivityResult", "没有返回的resultCode");
}
}
下面是这个类的用法
public void mkdirsOnTFCard(Uri uri) {
//创建DocumentFile,注意只能一级一级创建,不能像File那样一次创建多级目录
DocumentFile pickedDir = DocumentFile.fromTreeUri(this, uri);
/**
* 如果没有该文件夹,则创建一个新的文件并写入内容
* 查询文件是否存在时,返回的是DocumentFile对象
* 所以这里应该用try-catch来判断,出现异常则不存在此文件
*/
boolean ishasDirectory;
try {
ishasDirectory = pickedDir.findFile("sss").exists();
} catch (Exception e) {
ishasDirectory = false;
}
if (!ishasDirectory) {
try {
//创建新的一个文件夹
pickedDir.createDirectory("sss");
//找到新文件夹的路径
pickedDir = pickedDir.findFile("sss");
//创建新的文件
DocumentFile newFile = pickedDir.createDirectory("new_file");
//写入内容到新建文件
OutputStream out = getContentResolver().openOutputStream(newFile.getUri());
if (out != null) {
out.write("test".getBytes());
out.close();
}
Toast.makeText(this, "创建成功", Toast.LENGTH_SHORT).show();
} catch (Exception e) {
Toast.makeText(this, "创建失败", Toast.LENGTH_SHORT).show();
}
}
}
拿到根目录的DocumentFile 可以遍历出所有的文件,可以根据这个出创建文件夹,完成文件夹的复制功能。