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);}//接收返回值@Overrideprotected 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) {            realPath = FileUtils.getRealPathFromURI_API11to18(context, fileUri);        }        // SDK > 19 (Android 4.4) and up        else {            realPath = FileUtils.getRealPathFromURI_API19(context, fileUri);        }        return realPath;    }    @SuppressLint("NewApi")    public static String getRealPathFromURI_API11to18(Context context, Uri contentUri) {        String[] proj = {MediaStore.Images.Media.DATA};        String result = null;        CursorLoader cursorLoader = new CursorLoader(context, contentUri, proj, null, null, null);        Cursor cursor = cursorLoader.loadInBackground();        if (cursor != null) {            int column_index = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);            cursor.moveToFirst();            result = cursor.getString(column_index);            cursor.close();        }        return result;    }    public static String getRealPathFromURI_BelowAPI11(Context context, Uri contentUri) {        String[] proj = {MediaStore.Images.Media.DATA};        Cursor cursor = context.getContentResolver().query(contentUri, proj, null, null, null);        int column_index = 0;        String result = "";        if (cursor != null) {            column_index = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);            cursor.moveToFirst();            result = cursor.getString(column_index);            cursor.close();            return result;        }        return result;    }    @SuppressLint("NewApi")    public static String getRealPathFromURI_API19(final Context context, final Uri uri) {        final boolean isKitKat = Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT;        // DocumentProvider        if (isKitKat && DocumentsContract.isDocumentUri(context, uri)) {            // ExternalStorageProvider            if (isExternalStorageDocument(uri)) {                final String docId = DocumentsContract.getDocumentId(uri);                final String[] split = docId.split(":");                final String type = split[0];                // This is for checking Main Memory                if ("primary".equalsIgnoreCase(type)) {                    if (split.length > 1) {                        return Environment.getExternalStorageDirectory() + "/" + split[1];                    } else {                        return Environment.getExternalStorageDirectory() + "/";                    }                    // This is for checking SD Card                } else {                    return "storage" + "/" + docId.replace(":", "/");                }            }            // DownloadsProvider            else if (isDownloadsDocument(uri)) {                String fileName = getFilePath(context, uri);                if (fileName != null) {                    return Environment.getExternalStorageDirectory().toString() + "/Download/" + fileName;                }                String id = DocumentsContract.getDocumentId(uri);                if (id.startsWith("raw:")) {                    id = id.replaceFirst("raw:", "");                    File file = new File(id);                    if (file.exists())                        return id;                }                final Uri contentUri = ContentUris.withAppendedId(Uri.parse("content://downloads/public_downloads"), Long.valueOf(id));                return getDataColumn(context, contentUri, null, null);            }            // MediaProvider            else if (isMediaDocument(uri)) {                final String docId = DocumentsContract.getDocumentId(uri);                final String[] split = docId.split(":");                final String type = split[0];                Uri contentUri = null;                if ("image".equals(type)) {                    contentUri = MediaStore.Images.Media.EXTERNAL_CONTENT_URI;                } else if ("video".equals(type)) {                    contentUri = MediaStore.Video.Media.EXTERNAL_CONTENT_URI;                } else if ("audio".equals(type)) {                    contentUri = MediaStore.Audio.Media.EXTERNAL_CONTENT_URI;                }                final String selection = "_id=?";                final String[] selectionArgs = new String[]{                        split[1]                };                return getDataColumn(context, contentUri, selection, selectionArgs);            }        }        // MediaStore (and general)        else if ("content".equalsIgnoreCase(uri.getScheme())) {            // Return the remote address            if (isGooglePhotosUri(uri))                return uri.getLastPathSegment();            return getDataColumn(context, uri, null, null);        }        // File        else if ("file".equalsIgnoreCase(uri.getScheme())) {            return uri.getPath();        }        return null;    }    public static String getDataColumn(Context context, Uri uri, String selection,                                       String[] selectionArgs) {        Cursor cursor = null;        final String column = "_data";        final String[] projection = {                column        };        try {            cursor = context.getContentResolver().query(uri, projection, selection, selectionArgs,                    null);            if (cursor != null && cursor.moveToFirst()) {                final int index = cursor.getColumnIndexOrThrow(column);                return cursor.getString(index);            }        } finally {            if (cursor != null)                cursor.close();        }        return null;    }    public static String getFilePath(Context context, Uri uri) {        Cursor cursor = null;        final String[] projection = {                MediaStore.MediaColumns.DISPLAY_NAME        };        try {            cursor = context.getContentResolver().query(uri, projection, null, null,                    null);            if (cursor != null && cursor.moveToFirst()) {                final int index = cursor.getColumnIndexOrThrow(MediaStore.MediaColumns.DISPLAY_NAME);                return cursor.getString(index);            }        } finally {            if (cursor != null)                cursor.close();        }        return null;    }    /**     * @param uri The Uri to check.     * @return Whether the Uri authority is ExternalStorageProvider.     */    public static boolean isExternalStorageDocument(Uri uri) {        return "com.android.externalstorage.documents".equals(uri.getAuthority());    }    /**     * @param uri The Uri to check.     * @return Whether the Uri authority is DownloadsProvider.     */    public static boolean isDownloadsDocument(Uri uri) {        return "com.android.providers.downloads.documents".equals(uri.getAuthority());    }    /**     * @param uri The Uri to check.     * @return Whether the Uri authority is MediaProvider.     */    public static boolean isMediaDocument(Uri uri) {        return "com.android.providers.media.documents".equals(uri.getAuthority());    }    /**     * @param uri The Uri to check.     * @return Whether the Uri authority is Google Photos.     */    public static boolean isGooglePhotosUri(Uri uri) {        return "com.google.android.apps.photos.content".equals(uri.getAuthority());    }}

最后,如果想给选择器添加过滤的文件类型,只需要添加如下代码就可以了

String[] mimeTypes = {MimeType.DOC, MimeType.DOCX, MimeType.PDF, MimeType.PPT, MimeType.PPTX, MimeType.XLS, MimeType.XLSX};intent.putExtra(Intent.EXTRA_MIME_TYPES, mimeTypes);//存放需要过滤的类型的类public class MimeType {    public static final String DOC = "application/msword";    public static final String DOCX = "application/vnd.openxmlformats-officedocument.wordprocessingml.document";    public static final String XLS = "application/vnd.ms-excel";    public static final String XLSX = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet";    public static final String PPT = "application/vnd.ms-powerpoint";    public static final String PPTX = "application/vnd.openxmlformats-officedocument.presentationml.presentation";    public static final String PDF = "application/pdf";}

 

更多相关文章

  1. Android(安卓)Lint
  2. Android(安卓)MediaScannerConnection,Android(安卓)MediaScanner
  3. Android(安卓)自定义Notification字体颜色适配
  4. 系统定义弹窗以及自定义弹窗
  5. Android之CheckBox(多选按钮)
  6. Mac OS 上配置Android(安卓)studio的真机调试环境
  7. Android(安卓)Fragment学习笔记(一)
  8. Android(安卓)boot.img 结构
  9. 解决Android(安卓)studio 2.3升级到Android(安卓)studio 3.0 后a

随机推荐

  1. Android通知栏详解
  2. Android AudioFlinger
  3. ios手机getTime不兼容的问题(安卓正常)
  4. Android实时绘制效果(二)
  5. Android实现 ScrollView + ListView无滚
  6. as随笔
  7. 简单实用 layoutAnimation
  8. Android给第三方应用添加系统签名的两种
  9. adb devices 找不到设备的解决方法
  10. android 循环滚动实现