2010-06-09 82 views
185

我知道圖像的絕對路徑(比如,/sdcard/cats.jpg)。有沒有什麼辦法可以爲這個文件提供內容uri?從android中的文件路徑獲取內容uri

實際上,在我的代碼中,我下載了一張圖片並保存在一個特定的位置。爲了在ImageView中設置圖像,我使用路徑打開文件,獲取字節並創建一個位圖,然後在ImageView中設置位圖。這是一個非常緩慢的過程,而不是如果我能得到的內容URI那麼我可以很容易使用的方法ImageView.setImageUri(uri)

+19

Uri uri = Uri.parse(「file:///sdcard/img.png」); – 2011-09-29 06:39:16

+9

+1的評論,只是Uri.parse(「file://」+ filePath)應該做的竅門 – 2014-03-20 12:03:01

+0

Uri.Parse是折舊和「將被添加」 – pollaris 2017-11-29 16:54:04

回答

370

嘗試用:

ImageView.setImageURI(Uri.fromFile(new File("/sdcard/cats.jpg"))); 

或用:

ImageView.setImageURI(Uri.parse(new File("/sdcard/cats.jpg").toString())); 
+3

謝謝!第二種方法在1.6,2.1和2.2上正常工作,但僅在2.2中第一種方法 – mishkin 2010-11-30 02:45:14

+19

這兩種方法都不能解析到內容URI的文件路徑。我明白它解決了眼前的問題。 – 2011-04-26 20:46:52

+0

如果有SD卡路徑,但要內容uri @JO O主意完美工作:http://stackoverflow.com/a/11603841/336990 – CoDe 2012-09-09 08:29:09

13

//此代碼適用於2.2上的圖像,不確定是否有任何其他媒體類型

//Your file path - Example here is "/sdcard/cats.jpg" 
    final String filePathThis = imagePaths.get(position).toString(); 

    MediaScannerConnectionClient mediaScannerClient = new 
    MediaScannerConnectionClient() { 
    private MediaScannerConnection msc = null; 
    { 
     msc = new MediaScannerConnection(getApplicationContext(), this); 
     msc.connect(); 
    } 

    public void onMediaScannerConnected(){ 
     msc.scanFile(filePathThis, null); 
    } 


    public void onScanCompleted(String path, Uri uri) { 
     //This is where you get your content uri 
      Log.d(TAG, uri.toString()); 
     msc.disconnect(); 
    } 
    }; 
+1

很好,幫助我分享到Google+,因爲該應用需要帶有內容的媒體流Uri - 絕對路徑不起作用。 – Ridcully 2012-06-18 20:02:18

+0

非常好!我可以確認這也適用於音頻媒體類型。 – 2012-08-28 20:00:57

12

接受的s解決方案可能是您的目的最好的選擇,但要真正回答主題行中的問題:

在我的應用程序中,我必須從URI獲取路徑並從路徑中獲取URI。前者:

/** 
* Gets the corresponding path to a file from the given content:// URI 
* @param selectedVideoUri The content:// URI to find the file path from 
* @param contentResolver The content resolver to use to perform the query. 
* @return the file path as a string 
*/ 
private String getFilePathFromContentUri(Uri selectedVideoUri, 
     ContentResolver contentResolver) { 
    String filePath; 
    String[] filePathColumn = {MediaColumns.DATA}; 

    Cursor cursor = contentResolver.query(selectedVideoUri, filePathColumn, null, null, null); 
    cursor.moveToFirst(); 

    int columnIndex = cursor.getColumnIndex(filePathColumn[0]); 
    filePath = cursor.getString(columnIndex); 
    cursor.close(); 
    return filePath; 
} 

後者(這是我對影片做的,但也可以通過對MediaStore.Video代MediaStore.Audio(ETC),用於音頻或文件或其他類型的存儲內容):

/** 
* Gets the MediaStore video ID of a given file on external storage 
* @param filePath The path (on external storage) of the file to resolve the ID of 
* @param contentResolver The content resolver to use to perform the query. 
* @return the video ID as a long 
*/ 
private long getVideoIdFromFilePath(String filePath, 
     ContentResolver contentResolver) { 


    long videoId; 
    Log.d(TAG,"Loading file " + filePath); 

      // This returns us content://media/external/videos/media (or something like that) 
      // I pass in "external" because that's the MediaStore's name for the external 
      // storage on my device (the other possibility is "internal") 
    Uri videosUri = MediaStore.Video.Media.getContentUri("external"); 

    Log.d(TAG,"videosUri = " + videosUri.toString()); 

    String[] projection = {MediaStore.Video.VideoColumns._ID}; 

    // TODO This will break if we have no matching item in the MediaStore. 
    Cursor cursor = contentResolver.query(videosUri, projection, MediaStore.Video.VideoColumns.DATA + " LIKE ?", new String[] { filePath }, null); 
    cursor.moveToFirst(); 

    int columnIndex = cursor.getColumnIndex(projection[0]); 
    videoId = cursor.getLong(columnIndex); 

    Log.d(TAG,"Video ID is " + videoId); 
    cursor.close(); 
    return videoId; 
} 

基本上,MediaStoreDATA列(或任何它要查詢的子部分)存儲的文件路徑,讓你用這些信息來關注一下吧。

69

UPDATE

這裏假設你的媒體(圖片/視頻)已經加入到內容媒體提供商。如果沒有,那麼您將無法獲得您想要的 內容網址。相反會有文件Uri。

我對我的文件瀏覽器活動有同樣的問題。您應該知道文件的contenturi僅支持圖像,音頻和視頻等媒體存儲數據。我給你的代碼獲取圖像內容uri從sdcard中選擇圖像。試試這個代碼,也許它會爲你工作...

public static Uri getImageContentUri(Context context, File imageFile) { 
    String filePath = imageFile.getAbsolutePath(); 
    Cursor cursor = context.getContentResolver().query(
     MediaStore.Images.Media.EXTERNAL_CONTENT_URI, 
     new String[] { MediaStore.Images.Media._ID }, 
     MediaStore.Images.Media.DATA + "=? ", 
     new String[] { filePath }, null); 
    if (cursor != null && cursor.moveToFirst()) { 
    int id = cursor.getInt(cursor.getColumnIndex(MediaStore.MediaColumns._ID)); 
    cursor.close(); 
    return Uri.withAppendedPath(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, "" + id); 
    } else { 
    if (imageFile.exists()) { 
     ContentValues values = new ContentValues(); 
     values.put(MediaStore.Images.Media.DATA, filePath); 
     return context.getContentResolver().insert(
      MediaStore.Images.Media.EXTERNAL_CONTENT_URI, values); 
    } else { 
     return null; 
    } 
    } 
} 
+0

我正在尋找一種方法來查找我錄製的視頻文件的內容:// URI,上面的代碼似乎在Nexus 4(Android 4.3)上工作得很完美。如果您可以請解釋代碼,這將是很好的。 – 2014-03-12 12:35:56

+0

我已經嘗試過用絕對路徑「/ sdcard/Image Depo/picture.png」獲取文件的內容Uri。它沒有工作,所以我放棄了代碼路徑,發現Cursor是空的,並且當條目被添加到ContentProvider時,它將給出null作爲內容Uri。請幫忙。 – 2015-04-02 08:56:45

+0

這應該是公認的答案!此外,這是當Android試圖使用文件:ACTION_IMAGE_CAPTURE拍攝照片時出現Android預覽版N(即將推出的API級別24)時應用程序崩潰的修復程序:EXTRA_OUTPUT的Uri值導致FileUriExposedException。只需用'putExtra(MediaStore.EXTRA_OUTPUT,getImageContentUri(con​​text,imageFile))'替換'putExtra(MediaStore.EXTRA_OUTPUT,Uri.fromFile(imageFile))'。 – 2016-04-08 13:53:58

0

獲取文件ID,而無需編寫任何代碼,只需與亞行殼CLI命令:

adb shell content query --uri "content://media/external/video/media" | grep FILE_NAME | grep -Eo " _id=([0-9]+)," | grep -Eo "[0-9]+" 
0

U可以試試下面的代碼片段

public Uri getUri(ContentResolver cr, String path){ 
    Uri mediaUri = MediaStore.Files.getContentUri(VOLUME_NAME); 
    Cursor ca = cr.query(mediaUri, new String[] { MediaStore.MediaColumns._ID }, MediaStore.MediaColumns.DATA + "=?", new String[] {path}, null); 
    if (ca != null && ca.moveToFirst()) { 
     int id = ca.getInt(ca.getColumnIndex(MediaStore.MediaColumns._ID)); 
     ca.close(); 
     return MediaStore.Files.getContentUri(VOLUME_NAME,id); 
    } 
    ca.close(); 
    return null; 
} 
0

最簡單,從文件創建內容烏里content://穩健的方法是使用FileProvider。 Uri提供的FileProvider也可以用來提供Uri與其他應用程序共享文件。要從File的絕對路徑獲取文件Uri,可以使用DocumentFile。fromFile(新文件(路徑,名稱)),它在Api 22中添加,並在以下版本中返回null。

File imagePath = new File(Context.getFilesDir(), "images"); 
File newFile = new File(imagePath, "default_image.jpg"); 
Uri contentUri = getUriForFile(getContext(), "com.mydomain.fileprovider", newFile);