2014-04-21 179 views
5

我現在用的是DownloadManager使用意圖來設置圖像作爲壁紙的圖像下載到系統的畫廊,然後在廣播接收器(一旦下載成功)。從文件URI獲取內容URI?

一切都工作正常,但最近對4.4我開始在圖片/谷歌+應用一個例外,因爲它期待一個內容URI,而不是一個文件URI。

所以我的問題是,如果有人知道如何轉換一個完整的文件路徑/ URI(文件://)到內容風格的URI(內容://)?

對不起,我沒有源代碼,我是從具有源電腦了,但我希望這個問題是有道理的,沒有它,得到一個完整的路徑內容風格URI。

編輯:

的圖像被複制到系統的畫廊或媒體庫,而不是救了我的應用程序內部的StoreAge內。

這裏是什麼,我想轉換一個例子:

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 
+0

THX您( – NickUnuchek

回答

4

我能弄明白。這是在這裏找到的代碼的組合:Converting android image 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()); 

出於某種原因開始媒體掃描儀,newing文件,以及獲取絕對路徑是重要的,我不是完全可以肯定爲什麼,但我不能在這上面花更多的時間!

從文件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; 
    } 
} 

也許這將幫助別人的未來

+0

這是什麼?我的意思是這個遊標的定義是什麼。 – user4057066

1

所以我的問題是,如果有人知道如何轉換一個完整的文件路徑/ URI(file://)轉換爲內容樣式URI(content://)?

實現一個ContentProviderFileProvider提供了用於提供本地文件的開箱即用解決方案。

+0

)我正在下載圖片(使用下載管理器)到系統的媒體庫中,而不是將這些文件存儲在我的應用程序的內部存儲中,那麼ContentProvider是否會成爲這種情況下的方式? file:///sdcard/media/images/myimage.png我想轉換爲:content:// media/internal/images/media/445 – selsine

1

我不確定你使用的技術來設置壁紙,但最簡單的方法可能是使用WallpaperManager.setStream(),它不需要任何URI。

另請注意,如果文件可公開訪問,則文件URI僅適用於應用程序,因此內容URI是更通用的解決方案。

使用內容URI意味着一個ContentProvider將成爲該文件。哪一個取決於你的文件所在的位置。

如果您的應用程序具有對文件的直接讀取訪問權限,則可以使用支持庫的FileProvider類來實現應用程序中的內容提供者,但只有在文件位於您的應用的私人數據存儲。

如果圖像被添加到系統媒體庫,您應該使用MediaStore提供的URI。

+0

是的,文件已下載到系統的媒體庫(使用下載管理器),但是我可以通過DownloadManager.COLUMN_LOCAL_URI列在廣播接收器中訪問的所有內容都是該文件的完整路徑。我如何根據完整路徑從MediaStore獲取URI?此外,我正在使用意圖和URI,以便圖庫或照片應用可以裁剪圖像。 – selsine

+0

我還沒有嘗試過自己,但看看[DownloadManager.COLUMN_MEDIAPROVIDER_URI](http://developer.android.com/reference/android/app/DownloadManager.html#COLUMN_MEDIAPROVIDER_URI)列並檢查它是否包含內容下載完成後的URI。如果它看起來太複雜了,你仍然可以實現你自己的內容提供者,但這對我來說就像是一種黑客。 – BladeCoder

+0

我昨天試過了,並且可悲地返回NULL。 – selsine