Android Q 作用域规则
如果我们要读取SD卡上非图片、音频、视频类的文件,比如说先选择一个doc文件,这个时候就不能再使用MediaStore API了,而是要使用系统自带的文件选择器。直接上代码。
//选择文件
private void performFileSearch() {
Intent intent = new Intent(Intent.ACTION_OPEN_DOCUMENT);
intent.addCategory(Intent.CATEGORY_OPENABLE);
//允许多选 长按多选
intent.putExtra(Intent.EXTRA_ALLOW_MULTIPLE, true);
//不限制选取类型
intent.setType("*/*");
startActivityForResult(intent, -1);
}
//接收返回值
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
switch (requestCode) {
case -1:
if (resultCode == Activity.RESULT_OK && data != null) {
//当单选选了一个文件后返回
if (data.getData() != null) {
handleSingleDocument(data);
} else {
//多选
ClipData clipData = data.getClipData();
if (clipData != null) {
Uri[] uris = new Uri[clipData.getItemCount()];
for (int i = 0; i < clipData.getItemCount(); i++) {
uris[i] = clipData.getItemAt(i).getUri();
}
}
}
}
break;
}
}
//将uri转换为我们需要的path,多选类似
private void handleSingleDocument(Intent data) {
Uri uri = data.getData();
String filePath = FileUtils.getRealPath(this, uri);
}
FileUtils.java文件 (根据Uri获取Path)
网上流传的很多Uri获取Path的方法虽然都适配到了Android 4.4,但是到了Android 8.0又不好使了,下面是在Android 10.0上测试通过的版本。
public class FileUtils {
public static String getRealPath(Context context, Uri fileUri) {
String realPath;
// SDK < API11
if (Build.VERSION.SDK_INT < 11) {
realPath = FileUtils.getRealPathFromURI_BelowAPI11(context, fileUri);
}
// SDK >= 11 && SDK < 19
else if (Build.VERSION.SDK_INT < 19) {