在第三方应用中使用图库打开图片时,无法“将照片设置为”的问题

结论:

使用 content Uri 而不是 File Uri 去让图库打开图片即可。

 

分析过程:

首先看一下点击“将照片设置为”按钮需要经过哪些activity跳转,过滤“start u0”(我不确定这个log是不是公版代码就带了)

在图库中打开图片,并点击“将照片设置为”时:

09-11 03:18:21.051 429-3924/system_process I/ActivityManager: START u0 {act=android.intent.action.CHOOSER flg=0x1 cmp=android/com.android.internal.app.ChooserActivity clip={image/* U:content://media/external/images/media/52} (has extras)} from uid 10061
09-11 03:18:21.192 429-3713/system_process I/ActivityManager: START u0 {act=android.intent.action.ATTACH_DATA dat=content://media/external/images/media/52 typ=image/* flg=0x3000001 cmp=com.android.gallery3d/.app.Wallpaper (has extras)} from uid 10061
09-11 03:18:21.313 429-3713/system_process I/ActivityManager: START u0 {act=android.service.wallpaper.CROP_AND_SET_WALLPAPER dat=content://media/external/images/media/52 flg=0x1 pkg=com.android.wallpapercropper cmp=com.android.wallpapercropper/.WallpaperCropActivity} from uid 10061

在第三方应用中打开图片,并点击“将照片设置为”时:

09-11 03:20:24.024 429-19703/system_process I/ActivityManager: START u0 {act=android.intent.action.VIEW dat=file:///storage/emulated/0/wallpaper_04.jpg typ=image/jpeg flg=0x10000000 cmp=com.android.gallery3d/.app.GalleryActivity} from uid 10065
09-11 03:20:29.024 429-19703/system_process I/ActivityManager: START u0 {act=android.intent.action.CHOOSER flg=0x1 cmp=android/com.android.internal.app.ChooserActivity clip={image/* U:file:///storage/emulated/0/wallpaper_04.jpg} (has extras)} from uid 10061
09-11 03:20:29.121 429-19703/system_process I/ActivityManager: START u0 {act=android.intent.action.ATTACH_DATA dat=file:///storage/emulated/0/wallpaper_04.jpg typ=image/* flg=0x3000001 cmp=com.android.gallery3d/.app.Wallpaper (has extras)} from uid 10061

 

看到已经先经历了一个chooser后转跳转到com.android.gallery3d.app.Wallpaper这个activity中。在图库中还会跳转到com.android.wallpapercropper.WallpaperCropActivity,而第三方却没有,那么问题应该就是出现在com.android.gallery3d.app.Wallpaper这个activity中了。

到com.android.gallery3d.app.Wallpaper.java文件中看看(大概这份图库的代码是rk px3 android 7.1的)

在onResume()中:

            case STATE_PHOTO_PICKED: {
				Log.d(TAG, "onResume mState=STATE_PHOTO_PICKED");
                Intent cropAndSetWallpaperIntent;
                if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
                    WallpaperManager wpm = WallpaperManager.getInstance(getApplicationContext());
                    try {
                        cropAndSetWallpaperIntent = wpm.getCropAndSetWallpaperIntent(mPickedItem);
                        startActivity(cropAndSetWallpaperIntent);
                        finish();
                        return;
                    } catch (ActivityNotFoundException anfe) {
                        // ignored; fallthru to existing crop activity
                    } catch (IllegalArgumentException iae) {
                        // ignored; fallthru to existing crop activity
                    }
                }

这段代码会打开WallpaperCropActivity,但是有判断条件,有try/catch。

判断条件就先不考虑了,就是对版本限制。

try/catch中,catch到错误了就直接跳过,也没有打印。加上printStackTrace()后编译进机器试试。

                    } catch (ActivityNotFoundException anfe) {
                        anfe.printStackTrace();
                        // ignored; fallthru to existing crop activity
                    } catch (IllegalArgumentException iae) {
                        iae.printStackTrace();
                        // ignored; fallthru to existing crop activity
                    }

在第三方应用中打开图片,并点击“将照片设置为”。过滤"Wallpaper":

09-11 07:12:27.505 431-1103/system_process I/ActivityManager: START u0 {act=android.intent.action.ATTACH_DATA dat=file:///storage/emulated/0/wallpaper_04.jpg typ=image/* flg=0x3000001 cmp=com.android.gallery3d/.app.Wallpaper (has extras)} from uid 10061
09-11 07:12:27.584 11171-11171/com.android.gallery3d D/Wallpaper: onResume mState=STATE_INIT
    onResume mState=STATE_PHOTO_PICKED
09-11 07:12:27.587 11171-11171/com.android.gallery3d W/System.err: java.lang.IllegalArgumentException: Image URI must be of the content scheme type
        at android.app.WallpaperManager.getCropAndSetWallpaperIntent(WallpaperManager.java:886)
        at com.android.gallery3d.app.Wallpaper.onResume(Wallpaper.java:110)
cropAndSetWallpaperIntent = wpm.getCropAndSetWallpaperIntent(mPickedItem);

 这一行代码报了错误。

在网上寻找错误时,找到了一个网址https://stackoverflow.com/questions/23207604/get-a-content-uri-from-a-file-uri上面有解决方法。详细自己去看原文,大概的意思是要使用 content Uri 而不是 File Uri 去让图库打开图片即可。并且提供了一个将路径转换为Content Uri的方法。

public static Uri getImageContentUri(Context context, String absPath) {
    Log.v(TAG, "getImageContentUri: " + absPath);

    Cursor cursor = context.getContentResolver().query(
        MediaStore.Images.Media.EXTERNAL_CONTENT_URI
        , new String[] { MediaStore.Images.Media._ID }
        , MediaStore.Images.Media.DATA + "=? "
        , new String[] { absPath }, null);

    if (cursor != null && cursor.moveToFirst()) {
        int id = cursor.getInt(cursor.getColumnIndex(MediaStore.MediaColumns._ID));
        return Uri.withAppendedPath(MediaStore.Images.Media.EXTERNAL_CONTENT_URI , Integer.toString(id));

    } else if (!absPath.isEmpty()) {
         ContentValues values = new ContentValues();
         values.put(MediaStore.Images.Media.DATA, absPath);
         return context.getContentResolver().insert(
            MediaStore.Images.Media.EXTERNAL_CONTENT_URI, values);
    } else {
        return null;
    }
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值