Android7.0适配FileProvider分享Uri,获取

作者: MR_特殊人士 | 来源:发表于2019-07-16 20:27 被阅读7次

    当应用升级7.0之后,进程间分享Uri,Google推荐使用FileProvider;

    相应的你从适配FileProvider的第三方应用中获取Uri也需要对应的适配才行;

    如:A 应用适配FileProvider ,B应用获取到A应用分享的Uri怎么处理

    A应用的配置:

    AndroidManifest.xml

    <provider

        android:name="android.support.v4.content.FileProvider"

        android:authorities="com.xxx.xxx.fileprovider"

        android:exported="false"

        android:grantUriPermissions="true">

        <meta-data

            android:name="android.support.FILE_PROVIDER_PATHS"

            android:resource="@xml/file_paths"/>

    </provider>

    file_paths.xml

    <?xml version="1.0" encoding="utf-8"?>

    <paths xmlns:android="http://schemas.android.com/apk/res/android">

      <root-path

          name="root"

          path="" />

    </paths>

    分享Uri

    Intent intent = new Intent();

    Uri fileUri;

    if (Build.VERSION.SDK_INT >= 24) {

        fileUri = FileProvider.getUriForFile(mContext, "com.xxx.xxx.fileprovider",file);

    } else {

        fileUri = Uri.fromFile(file);

    }

    intent.setData(fileUri);

    List<ResolveInfo> resInfoList = mContext.getPackageManager()

            .queryIntentActivities(intent, PackageManager.MATCH_DEFAULT_ONLY);

    for (ResolveInfo resolveInfo : resInfoList) {

        String packageName = resolveInfo.activityInfo.packageName;

        mContext.grantUriPermission(packageName, fileUri, Intent.FLAG_GRANT_READ_URI_PERMISSION

                | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);

    }

    mContext.setResult(Activity.RESULT_OK, intent);

    下面就是B客户端正确的适配方案:

    public static String getPath(final Context context, final Uri uri) {

            // DocumentProvider

            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT && DocumentsContract.isDocumentUri(context, uri)) {

                // ExternalStorageProvider

                if (isExternalStorageDocument(uri)) {

                    final String docId = DocumentsContract.getDocumentId(uri);

                    final String[] split = docId.split(":");

                    final String type = split[0];

                    if ("primary".equalsIgnoreCase(type)) {

                        return Environment.getExternalStorageDirectory() + "/" + split[1];

                    }

                    // TODO handle non-primary volumes

                }

                // DownloadsProvider

                else if (isDownloadsDocument(uri)) {

                    final String id = DocumentsContract.getDocumentId(uri);

                    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();

                if (isOtherStorageDocument(uri))

                    return uri.getPath().substring("/root/".length());

                return getDataColumn(context, uri, null, null);

            }

            // File

            else if ("file".equalsIgnoreCase(uri.getScheme())) {

                return uri.getPath();

            }

            return null;

        }

        /**

        * Get the value of the data column for this Uri. This is useful for

        * MediaStore Uris, and other file-based ContentProviders.

        *

        * @param context      The context.

        * @param uri          The Uri to query.

        * @param selection    (Optional) Filter used in the query.

        * @param selectionArgs (Optional) Selection arguments used in the query.

        * @return The value of the _data column, which is typically a file path.

        */

        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;

        }

        /**

        * @param uri The Uri to check.

        * @return Whether the Uri authority is FileManagerProvider.

        */

        public static boolean isOtherStorageDocument(Uri uri) {

            return "com.xxx.xxx.fileprovider".equals(uri.getAuthority());

        }

        /**

        * @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());

        }

        public static Uri formUri(Context mContext, File file) {

            Uri fileUri;

            if (Build.VERSION.SDK_INT >= 24) {

                fileUri = FileProvider.getUriForFile(mContext, "com.xxx.xxx.xxx.fileprovider",

                        file);

            } else {

                fileUri = Uri.fromFile(file);

            }

            return fileUri;

        }

    相关文章

      网友评论

        本文标题:Android7.0适配FileProvider分享Uri,获取

        本文链接:https://www.haomeiwen.com/subject/prlxlctx.html