FinalTeam / RxGalleryFinal

图片选择库,单选/多选、拍照、裁剪、压缩,自定义。包括视频选择和录制。
https://github.com/FinalTeam/RxGalleryFinal
2.83k stars 513 forks source link

targetSdkVersion >= 30 Bug修复 #314

Closed xiaozhi003 closed 3 years ago

xiaozhi003 commented 3 years ago

项目用到相册的功能,找了好久只有这个库还比较新,不过还是遇到了很多坑;比如Android10和11的适配问题,在此我将targetSdkVersion >= 30的问题做了一个修复,当然我只用到单张图片和相机拍照的功能,只对我用到的功能做了修复;之后有时间我会fork一份做一个完整的更新;

1.相机不可用问题

// 该判断为空
if (captureIntent.resolveActivity(context.getPackageManager()) == null) 

Android 11 需要在清单文件中添加查询声明

<manifest package="com.example.game">
    <queries>
        <!-- 打开相机意图-->
        <intent>
            <action android:name="android.media.action.IMAGE_CAPTURE" />
        </intent>
    </queries>
    ...
</manifest>

2.遍历图像报错

MediaUtils.getMediaWithImageList查询数据库中的图片不支持LIMIT,Android11需要用Bundle参数传递

    /**
     * 从数据库中读取图片
     */
    public static List<MediaBean> getMediaWithImageList(Context context, String bucketId, int page, int limit) {
        ...
        Cursor cursor = null;
        // 适配Android 11
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
            Bundle bundle = createSqlQueryBundle(selection, selectionArgs, MediaStore.Images.Media.DATE_ADDED + " DESC", limit, offset);
            cursor = contentResolver.query(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, projection.toArray(new String[projection.size()]), bundle, null);
        } else {
            cursor = contentResolver.query(
                    MediaStore.Images.Media.EXTERNAL_CONTENT_URI, projection.toArray(new String[projection.size()]), selection,
                    selectionArgs, MediaStore.Images.Media.DATE_ADDED + " DESC LIMIT " + limit + " OFFSET " + offset);
        ...
        }

    private static Bundle createSqlQueryBundle(String selection, String[] selectionArgs, String sortOrder, int limit, int page) {
        if (selection == null && selectionArgs == null && sortOrder == null) {
            return null;
        }
        Bundle queryArgs = new Bundle();
        if (selection != null) {
            queryArgs.putString(ContentResolver.QUERY_ARG_SQL_SELECTION, selection);
        }
        if (selectionArgs != null) {
            queryArgs.putStringArray(ContentResolver.QUERY_ARG_SQL_SELECTION_ARGS, selectionArgs);
        }
        if (sortOrder != null) {
            queryArgs.putString(ContentResolver.QUERY_ARG_SQL_SORT_ORDER, sortOrder);
        }
        queryArgs.putString(ContentResolver.QUERY_ARG_SQL_LIMIT, limit + " offset " + page);
        return queryArgs;
    }

3.相机拍照后图像没有生成

MediaUtils.getMediaBeanWithImage该方法无法查找拍照返回的图像信息,实际是图像未生成导致

需要在MediaGridFragment中修改openCamera方法

    public void openCamera(Context context) {
        ...
        if (Build.VERSION.SDK_INT < Build.VERSION_CODES.N) {
            captureIntent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(fileImagePath));
        } else {
            Uri photoUri = FileProvider.getUriForFile(context, "cn.xz.gallery.fileprovider", new File(mImagePath));
            ContentValues contentValues = new ContentValues(1);
            contentValues.put(MediaStore.Images.Media.DATA, mImagePath);
            Uri uri = getContext().getContentResolver().insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, contentValues);
            captureIntent.putExtra(MediaStore.EXTRA_OUTPUT, photoUri);
        }
        ...
    }

AndroidManifes.xml中添加

    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/Theme.AndroidGallery"> 
        ...
        <provider
            android:name="androidx.core.content.FileProvider"
            android:authorities="cn.xz.gallery.fileprovider"
            android:exported="false"
            android:grantUriPermissions="true"
            tools:replace="android:authorities">
            <meta-data
                android:name="android.support.FILE_PROVIDER_PATHS"
                android:resource="@xml/gallery_file_paths_public"
                tools:replace="android:resource" />
        </provider>
        ...

    </application>

添加res/xml/gallery_file_paths_public.xml

<external-path name="external_files" path="." />
zjperson commented 3 years ago

android:requestLegacyExternalStorage="true" 需要加在application节点

xiaozhi003 commented 3 years ago

建议使用 https://github.com/HuanTanSheng/EasyPhotos.git 或者 https://github.com/LuckSiege/PictureSelector.git