[英]Get a Content URI from a File URI?
我使用DownloadManager将图像下载到系统的图库,然后在广播接收器中(下载成功后)使用Intent将图像设置为壁纸。
一切都工作正常,但最近在4.4我开始在Photos / Google +应用程序中得到一个例外,因为它期望内容URI而不是文件URI。
所以我的问题是,如果有人知道如何将完整的文件路径/ URI(文件://)转换为内容样式URI(内容://)?
很抱歉缺少源代码,我远离拥有源代码的计算机,但我希望没有它的问题是有道理的,从完整的路径获取内容样式uri。
编辑:
图像将复制到系统的图库或媒体库中,而不会保存在我的应用内部存储中。
以下是我想要转换的示例:
file:///storage/emulated/0/Pictures/Rockstar/image.jpg
至
content://media/internal/images/media/445
编辑2:
以下是我从Google+应用中收到的错误:
04-21 10:50:35.090: E/AndroidRuntime(7220): FATAL EXCEPTION: main
04-21 10:50:35.090: E/AndroidRuntime(7220): Process: com.google.android.apps.plus, PID: 7220
04-21 10:50:35.090: E/AndroidRuntime(7220): java.lang.RuntimeException: Unable to resume activity
{com.google.android.apps.plus/com.google.android.apps.photos.phone.SetWallpaperActivity}:
java.lang.IllegalArgumentException: Image URI must be of the content scheme type
这是我用来让用户设置壁纸的代码:
String uriString = c.getString(c.getColumnIndex(DownloadManager.COLUMN_LOCAL_URI));
Uri u = Uri.parse(uriString);
Intent wall_intent = new Intent(Intent.ACTION_ATTACH_DATA);
wall_intent.setDataAndType(u, "image/*");
wall_intent.putExtra("mimeType", "image/*");
Intent chooserIntent = Intent.createChooser(wall_intent,
"Set As");
chooserIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
try {
context.startActivity(chooserIntent);
}
uriString
是:
file:///storage/emulated/0/Pictures/Rockstar/image.jpg
我弄清楚了。 它是这里找到的代码的组合: 转换android图像URI并在下载后扫描媒体文件。
所以在文件完成下载后,我得到了路径并执行以下操作:
String uriString = c.getString(c.getColumnIndex(DownloadManager.COLUMN_LOCAL_URI));
//Update the System
Uri u = Uri.parse(uriString);
context.sendBroadcast(new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE, u));
//Get the abs path using a file, this is important
File wallpaper_file = new File(u.getPath());
Uri contentURI = getImageContentUri(context, wallpaper_file.getAbsolutePath());
出于某种原因启动媒体扫描仪,新建文件,获取绝对路径很重要,我不确定为什么,但我不能再花这么多时间了!
从文件URI转换为内容URI的方法如下(取自链接的StackOver流程帖子:
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;
}
}
也许这将有助于未来的人。
所以我的问题是,如果有人知道如何将完整的文件路径/ URI(文件://)转换为内容样式URI(内容://)?
实现ContentProvider
。 FileProvider
提供了一个开箱即用的解决方案,用于提供本地文件。
我不确定你用来设置壁纸的技术,但最简单的方法可能是使用不需要任何URI的WallpaperManager.setStream()
。
另请注意,如果文件可公开访问,则文件URI仅在应用程序之间起作用,因此内容URI是更通用的解决方案。
使用内容URI意味着ContentProvider
将为该文件提供服务。 哪一个取决于您的文件所在的位置。
如果您的应用程序具有对文件的直接读取权限,则可以使用支持库的FileProvider
类在应用程序中实现内容提供程序,但实际上只有在文件位于专用数据存储中时才能使用你的应用程序。
如果将图像添加到系统媒体库,则应该使用MediaStore提供的URI。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.