Dapatkan konten uri dari jalur file di android


271

Saya tahu jalur absolut dari suatu gambar (katakan misalnya, /sdcard/cats.jpg). Apakah ada cara untuk mendapatkan konten uri untuk file ini?

Sebenarnya dalam kode saya, saya mengunduh gambar dan menyimpannya di lokasi tertentu. Untuk mengatur gambar dalam instance ImageView, saat ini saya membuka file menggunakan path, mendapatkan byte dan membuat bitmap dan kemudian mengatur bitmap dalam instance ImageView. Ini adalah proses yang sangat lambat, alih-alih jika saya bisa mendapatkan konten uri maka saya bisa dengan mudah menggunakan metode ini imageView.setImageUri(uri)


23
Uri uri = Uri.parse ("file: ///sdcard/img.png");
Anand Tiwari

13
Memberi +1 pada komentar, hanya Uri.parse ("file: //" + filePath) yang dapat melakukan trik
German Latorre

Uri.Parse disusutkan dan "ditambahkan"
pollaris

@pollaris Uri.parse ditambahkan di API 1 dan tidak ditandai untuk penghentian.
JP de la Torre

Uri.parse ("sesuatu"); tidak bekerja pada saya, saya tidak dapat menemukan alasan mengapa ...
Bay

Jawaban:


480

Coba dengan:

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

Atau dengan:

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

3
Terima kasih! Metode kedua berfungsi dengan baik pada 1.6, 2.1 dan 2.2 tetapi yang pertama hanya pada 2.2
mishkin

28
tak satu pun dari metode tersebut yang menyelesaikan jalur file ke URI konten. Saya mengerti itu memecahkan masalah langsung sekalipun.
Jeffrey Blattman

38
Jangan hardcode "/ sdcard /"; gunakan Environment.getExternalStorageDirectory (). getPath () sebagai gantinya
ekatz

8
Inilah yang dikembalikan kedua solusi di atas: 1. file: ///storage/emulated/0/DCIM/Camera/VID_20140312_171146.mp4 2. /storage/emulated/0/DCIM/Camera/VID_20140312_171146.mp4 Tapi yang saya cari karena adalah sesuatu yang berbeda. Saya butuh konten: // memformat URI. Jawaban dari Jinal tampaknya bekerja dengan sempurna
Ajith Memana

5
hei Uri.fromFiletidak akan bekerja di android 26+, Anda harus menggunakan penyedia file
vuhung3990

85

MEMPERBARUI

Di sini diasumsikan bahwa media Anda (Gambar / Video) sudah ditambahkan ke penyedia media konten. Jika tidak, Anda tidak akan bisa mendapatkan URL konten seperti yang Anda inginkan. Sebaliknya akan ada file Uri.

Saya memiliki pertanyaan yang sama untuk aktivitas file explorer saya. Anda harus tahu bahwa contenturi untuk file hanya mendukung data mediastore seperti gambar, audio dan video. Saya memberi Anda kode untuk mendapatkan konten gambar uri dari memilih gambar dari sdcard. Coba kode ini, mungkin itu akan berhasil untuk Anda ...

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

Saya sedang mencari metode untuk menemukan konten: // URI dari file video saya yang direkam dan kode di atas tampaknya berfungsi sempurna pada Nexus 4 (Android 4.3). Alangkah baiknya jika Anda bisa menjelaskan kodenya.
Ajith Memana

Saya telah mencoba ini untuk mendapatkan Uri Konten untuk File dengan jalur Absolute "/ sdcard / Image Depo / picture.png". Itu tidak berhasil, jadi saya men-debug jalur kode dan menemukan bahwa kursor kosong, dan ketika entri ditambahkan ke ContentProvider, memberikan nol sebagai Uri Konten. Tolong bantu.
Sri Krishna

1
Saya memiliki path file - file: ///storage/emulated/0/Android/data/com.packagename/files/out.mp4, tetapi mendapatkan null ketika saya mencoba mendapatkan contentUri. Saya juga mencoba mengubah MediaStore.Images.Mediake MediaStore.Video.Media, tapi tetap tidak berhasil.
Narendra Singh

1
Ini tidak berfungsi pada android Pie api 28. Kursor kembali null
Ibrahim Gharyali

1
Bisakah Anda memperbarui metode ini untuk Android 10 karena kolom DATA tidak dapat diakses di Android 10?
Khushbu Shah

16

// Kode ini berfungsi untuk gambar pada 2.2, tidak yakin apakah ada jenis media lain

   //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
Hebat, membantu saya berbagi ke Google+, karena aplikasi itu membutuhkan aliran media dengan konten Uri - jalur absolut tidak berfungsi.
Ridcully

1
Luar biasa! Saya dapat mengkonfirmasi ini bekerja dengan jenis media Audio juga.
Matt M

16

Solusi yang diterima mungkin adalah taruhan terbaik untuk tujuan Anda, tetapi untuk benar-benar menjawab pertanyaan di baris subjek:

Dalam aplikasi saya, saya harus mendapatkan jalur dari URI dan mendapatkan URI dari jalur. Mantan:

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

Yang terakhir (yang saya lakukan untuk video, tetapi juga dapat digunakan untuk Audio atau File atau jenis konten tersimpan lainnya dengan mengganti MediaStore.Audio (dll) untuk MediaStore.Video):

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

Pada dasarnya, DATAkolom MediaStore(atau sub-bagian mana pun yang Anda tanyakan) menyimpan path file, jadi Anda menggunakan info itu untuk mencarinya.


Tidak selalu demikian, ada dua kolom semi-terjamin yang dikembalikan, dan itu adalah OpenableColumns.DISPLAY_NAME & OpenableColumns.SIZEjika aplikasi pengirim bahkan mengikuti "aturan". Saya menemukan bahwa beberapa aplikasi utama hanya mengembalikan kedua bidang ini dan tidak selalu _databidang. Dalam kasus di mana Anda tidak memiliki bidang data yang biasanya berisi jalur langsung ke konten, Anda harus terlebih dahulu membaca konten dan menulisnya ke file atau ke dalam memori dan kemudian Anda memiliki jalur Anda sendiri.
Pierre

7

Anda dapat menggunakan dua cara ini berdasarkan penggunaan

Uri uri = Uri.parse("String file location");

atau

Uri uri = Uri.fromFile(new File("string file location"));

Saya telah mencoba keduanya dan keduanya berhasil.


5

Cara termudah dan kuat untuk membuat Konten Uri content://dari File adalah dengan menggunakan FileProvider . Uri yang disediakan oleh FileProvider dapat digunakan juga menyediakan Uri untuk berbagi file dengan aplikasi lain juga. Untuk mendapatkan File Uri dari jalur absolut FileAnda dapat menggunakan DocumentFile.fromFile (File baru (jalur, nama)), itu ditambahkan dalam Api 22, dan mengembalikan null untuk versi di bawah ini.

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


2

Memperoleh ID File tanpa menulis kode apa pun, hanya dengan perintah CLI adb shell:

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

Google "adb dapatkan jalur nyata dari konten uri" dan pertanyaan ini adalah 1 teratas, dengan konten jawaban 0 suara Anda dalam ringkasan hasil pencarian. Jadi izinkan saya menjadi yang pertama memberikan suara. Terima kasih kawan!
Akhir Pekan

Ini keren. Tapi sepertinya Anda akan mendapatkan Permission Denial: Do not have permission in call getContentProviderExternal() from pid=15660, uid=10113 requires android.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY:, kecuali Anda root.
not2qubit

jadi ini perlu akses root ponsel?
Samintha Kaveesh

1

Lebih baik menggunakan validasi untuk mendukung versi pra Android N, contoh:

  if (Build.VERSION.SDK_INT >=  Build.VERSION_CODES.N) {
     imageUri = Uri.parse(filepath);
  } else{
     imageUri = Uri.fromFile(new File(filepath));
  }

  if (Build.VERSION.SDK_INT >=  Build.VERSION_CODES.N) {
     ImageView.setImageURI(Uri.parse(new File("/sdcard/cats.jpg").toString()));         
  } else{
     ImageView.setImageURI(Uri.fromFile(new File("/sdcard/cats.jpg")));
  }

https://es.stackoverflow.com/questions/71443/reporte-crash-android-os-fileuriexposedexception-en-android-n


0

Anda dapat mencoba cuplikan kode di bawah ini

    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);
    }
    if(ca != null) {
        ca.close();
    }
    return null;
}

1
Apa itu VOLUME_NAME?
Evgenii Vorobei

Ini adalah "eksternal" atau "internal"
caopeng
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.