Android में फ़ाइल पथ से सामग्री uri प्राप्त करें


271

मैं एक छवि का पूर्ण पथ जानता हूं (उदाहरण के लिए, /sdcard/cats.jpg)। क्या इस फ़ाइल के लिए सामग्री uri प्राप्त करने का कोई तरीका है?

वास्तव में मेरे कोड में, मैं एक छवि डाउनलोड करता हूं और इसे किसी विशेष स्थान पर सहेजता हूं। ImageView उदाहरण में छवि को सेट करने के लिए, वर्तमान में मैं पथ का उपयोग करके फ़ाइल खोलता हूं, बाइट्स प्राप्त करता हूं और एक बिटमैप बनाता हूं और फिर ImageView उदाहरण में बिटमैप सेट करता हूं। यह एक बहुत ही धीमी प्रक्रिया है, इसके बजाय अगर मुझे कंटेंट यूरी मिल सकता है तो मैं बहुत आसानी से विधि का उपयोग कर सकता हूं imageView.setImageUri(uri)


23
उड़ी उरी = उरी.पारसे ("फाइल: ///sdcard/img.png");
आनंद तिवारी

13
+1 टिप्पणी करने के लिए, बस Uri.parse ("फ़ाइल: //" + filePath) को ट्रिक करना चाहिए
जर्मन

Uri.Parse का मूल्यह्रास किया गया है और "जोड़ा जाना" है
पोल्लरिस

@pollaris Uri.parse को एपीआई 1 में जोड़ा गया था और यह पदावनत के लिए चिह्नित नहीं है।
जेपी डे ला टोरे

Uri.parse ( "कुछ"); मुझ पर काम नहीं कर रहा है, मैं इसका कारण नहीं खोज सकता ...
बे

जवाबों:


480

इसके साथ प्रयास करें:

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 पर
मिशिन

28
उन तरीकों में से कोई भी सामग्री URI के लिए एक फ़ाइल पथ नहीं हल करता है। मैं समझता हूँ कि यह तत्काल समस्या हल हो गई है।
जेफरी ब्लाटमैन

38
हार्डकोड न करें "/ sdcard /"; पर्यावरण का उपयोग करें ।getExternalStorageDirectory ()। getPath () इसके बजाय
ekatz

8
उपरोक्त दोनों समाधान यही है: कुछ अलग है। मुझे सामग्री चाहिए: // स्वरूप URI।
जिनाल

5
हे Uri.fromFileएंड्रॉइड 26+ पर काम नहीं करेगा, आपको फ़ाइल प्रदाता
vuhung3990

85

अपडेट करें

यहां यह माना जाता है कि आपका मीडिया (छवि / वीडियो) पहले से ही सामग्री प्रदाता के साथ जोड़ा गया है। यदि नहीं, तो आप सामग्री URL को ठीक से प्राप्त नहीं कर पाएंगे जो आप चाहते हैं। इसके बजाय फाइल उड़ी होगी।

मेरी फ़ाइल एक्सप्लोरर गतिविधि के लिए मेरे पास एक ही सवाल था। आपको पता होना चाहिए कि फ़ाइल के लिए सामग्री केवल छवि, ऑडियो और वीडियो जैसे मीडियास्टोर डेटा का समर्थन करती है। मैं आपको sdcard से एक छवि का चयन करने से छवि सामग्री uri प्राप्त करने के लिए कोड दे रहा हूं। इस कोड की कोशिश करो, शायद यह आपके लिए काम करेगा ...

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

मैं सामग्री खोजने के लिए एक विधि की तलाश में था: // मेरी रिकॉर्ड की गई वीडियो फ़ाइल का यूआरआई और उपरोक्त कोड नेक्सस 4 (एंड्रॉइड 4.3) पर सटीक काम करता है। यह अच्छा होगा यदि आप कृपया कोड की व्याख्या कर सकते हैं।
अजित मेमन

मैंने निरपेक्ष पथ "/ sdcard / Image Depo / picture.png" के साथ एक फ़ाइल के लिए सामग्री उरई प्राप्त करने के लिए यह कोशिश की है। यह काम नहीं करता था, इसलिए मैंने कोड पथ को डीबग किया और पाया कि कर्सर खाली है, और जब कंटेंटप्रोविडर में प्रवेश किया जा रहा है, तो यह कंटेंट उरी के रूप में शून्य है। कृपया मदद कीजिए।
श्रीकृष्ण

1
मेरे पास फ़ाइल पथ है - फ़ाइल: ///storage/emulated/0/Android/data/com.packagename/files/out.mp4, लेकिन जब मैं सामग्री प्राप्त करने का प्रयास करता हूं तो अशक्त हो जाता है। मैं भी बदल रहा है की कोशिश की MediaStore.Images.Mediaकरने के लिए MediaStore.Video.Mediaकोई भाग्य, लेकिन अभी भी।
नरेंद्र सिंह

1
यह एंड्रॉइड पाई एपी 28 पर काम नहीं कर रहा है। कर्सर वापस अशक्त हो जाता है
इब्राहिम घारियाली

1
क्या आप Android 10 के लिए इस विधि को अपडेट कर सकते हैं क्योंकि DATA स्तंभ Android 10 में उपलब्ध नहीं है?
खुशबु शाह

16

// यह कोड 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 - निरपेक्ष पथ काम नहीं करता हो।
20

1
अति उत्कृष्ट! मैं ऑडियो मीडिया प्रकारों के साथ भी इस काम की पुष्टि कर सकता हूं।
मैट एम

16

स्वीकृत समाधान संभवतः आपके उद्देश्यों के लिए सबसे अच्छा दांव है, लेकिन वास्तव में विषय पंक्ति में प्रश्न का उत्तर देने के लिए:

मेरे ऐप में, मुझे यूआरआई से रास्ता निकालना है और यूआरआई से पथ प्राप्त करना है। भूतपूर्व:

/**
 * 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.Audio (आदि) 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;
}

मूल रूप से, DATAके स्तंभ MediaStoreभंडार फ़ाइल पथ (यह आप कर रहे हैं क्वेरी की या जो भी उप-धारा) है, तो आप उस जानकारी का उपयोग उसे ढूंढने की।


हमेशा ऐसा नहीं होता है, दो अर्द्ध-गारंटीकृत कॉलम लौटाए जाते हैं, और OpenableColumns.DISPLAY_NAME & OpenableColumns.SIZEयदि भेजने वाला ऐप "नियमों" का पालन भी करता है। मैंने पाया कि कुछ प्रमुख ऐप केवल इन दो फ़ील्ड्स को लौटाते हैं और हमेशा फ़ील्ड को नहीं _data। उस स्थिति में जहां आपके पास डेटा फ़ील्ड नहीं है, जिसमें आम तौर पर सामग्री के लिए एक सीधा रास्ता होता है, आपको पहले सामग्री को पढ़ना होगा और इसे फ़ाइल या मेमोरी में लिखना होगा और फिर आपके पास अपना रास्ता होगा।
पियरे

7

उपयोग के आधार पर आप इन दो तरीकों का उपयोग कर सकते हैं

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

या

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

मैंने दोनों तरह से कोशिश की है और दोनों काम करते हैं।


5

सबसे आसान और content://एक फ़ाइल से सामग्री उरी बनाने के लिए मजबूत तरीका FileProvider का उपयोग करने के लिए है । FileProvider द्वारा प्रदान की गई Uri का उपयोग Uri को अन्य एप्लिकेशन के साथ फाइल साझा करने के लिए भी प्रदान किया जा सकता है। फ़ाइल Uri को किसी पूर्ण पथ से प्राप्त करने के लिए Fileआप DocumentFile.fromFile (नई फ़ाइल (पथ, नाम)) का उपयोग कर सकते हैं, यह Api 22 में जोड़ा गया है, और नीचे दिए गए संस्करणों के लिए रिक्त है।

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

4

यह देर से, लेकिन भविष्य में किसी की मदद कर सकता है।

किसी फ़ाइल के लिए सामग्री URI प्राप्त करने के लिए, आप निम्न विधि का उपयोग कर सकते हैं:

FileProvider.getUriForFile(Context context, String authority, File file)

यह सामग्री को यूआरआई लौटाता है।

सेटअप करने का तरीका जानने के लिए इसे देखें FileProvider


2

किसी भी कोड को लिखे बिना फ़ाइल आईडी प्राप्त करना, बस adb शेल CLI कमांड के साथ:

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

Google "adb को सामग्री uri से वास्तविक मार्ग मिलता है" और यह प्रश्न शीर्ष 1 है, जिसमें आपके 0-वोट उत्तर की सामग्री खोज परिणाम सारांश में है। इसलिए मुझे सबसे पहले मतदान करने दीजिए। धन्यवाद भाई!
सप्ताहांत

यह अच्छा है। : लेकिन यह आप मिल जाएगा लगता है Permission Denial: Do not have permission in call getContentProviderExternal() from pid=15660, uid=10113 requires android.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY, जब तक आप जड़ें रहे हैं।
not2qubit

तो यह फोन की जड़ का उपयोग की आवश्यकता है?
समिथा केवेश

1

Android N के पूर्व संस्करणों का समर्थन करने के लिए सत्यापन का उपयोग करना बेहतर है, उदाहरण:

  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

यू नीचे कोड स्निपेट की कोशिश कर सकता है

    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
VOLUME_NAME क्या है?
इवगेनी वोरोबि

यह "बाहरी" या "आंतरिक" है
caopeng
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.