Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/android/217.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Android 从文件URI获取内容URI?_Android - Fatal编程技术网

Android 从文件URI获取内容URI?

Android 从文件URI获取内容URI?,android,Android,我使用将图像下载到系统的多媒体资料中,然后在广播接收器中(下载成功后)使用意图将图像设置为壁纸 一切正常,但最近在4.4上,我开始在Photos/Google+应用程序中遇到一个异常,因为它需要一个内容URI而不是文件URI 所以我的问题是,是否有人知道如何将完整的文件路径/URI(file://)转换为内容样式的URI(content://) 很抱歉缺少源代码,我不在拥有源代码的计算机上,但我希望没有源代码的问题有意义,从完整路径获取内容样式uri 编辑: 图像被复制到系统的库或媒体库中,而不

我使用将图像下载到系统的多媒体资料中,然后在广播接收器中(下载成功后)使用意图将图像设置为壁纸

一切正常,但最近在4.4上,我开始在Photos/Google+应用程序中遇到一个异常,因为它需要一个内容URI而不是文件URI

所以我的问题是,是否有人知道如何将完整的文件路径/URI(file://)转换为内容样式的URI(content://)

很抱歉缺少源代码,我不在拥有源代码的计算机上,但我希望没有源代码的问题有意义,从完整路径获取内容样式uri

编辑:

图像被复制到系统的库或媒体库中,而不是保存在我的应用程序内部存储中

下面是我想要转换的示例:

file:///storage/emulated/0/Pictures/Rockstar/image.jpg

编辑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
所以我的问题是,是否有人知道如何将完整的文件路径/URI(file://)转换为内容样式的URI(content://)


实现一个
ContentProvider
。为提供本地文件提供了一个现成的解决方案。

我不确定您用于设置墙纸的技术,但最简单的方法可能是使用不需要任何URI的
WallperManager.setStream()

还请注意,如果文件可公开访问,则文件URI仅在应用程序之间工作,因此内容URI是一种更通用的解决方案

使用内容URI意味着
ContentProvider
将为文件提供服务。哪一个取决于文件所在的位置

如果您的应用程序具有对文件的直接读取访问权限,您可以通过使用支持库的
FileProvider
类等在应用程序中实现内容提供程序,但只有当文件位于应用程序的私有数据存储中时,才应真正使用该类


如果将映像添加到系统媒体库中,您可能应该使用MediaStore提供的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 flow post:

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;
    }
}

也许这会对将来的人有所帮助。

是的,文件会下载到系统的媒体库(使用下载管理器),但我可以通过DownloadManager.COLUMN\u LOCAL\u URI列在广播接收器中访问的所有内容都是该文件的完整路径。如何根据该完整路径从MediaStore获取URI?此外,我还使用了一个intent和一个URI,以便gallery或Photos应用程序可以裁剪图像。我还没有尝试过自己,但请查看该列并下载完成后,检查它是否包含内容URI。如果它看起来太复杂,您仍然可以实现自己的内容提供商,但我觉得这像是一个黑客。我正在下载图像(使用下载管理器)到系统的媒体库,而不是将文件存储在我的应用程序的内部存储器中。那么,在这种情况下,ContentProvider会是一种选择吗?我有(例如)file:///sdcard/media/images/myimage.png 我想转换成:content://media/internal/images/media/445what 这里是c吗?我的意思是这个光标的定义是什么。
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;
    }
}