Uri.getPath द्वारा Android को असली रास्ता मिलेगा ()


107

मैं गैलरी से छवि प्राप्त करने की कोशिश कर रहा हूं।

Intent intent = new Intent();
intent.setType("image/*");
intent.setAction(Intent.ACTION_GET_CONTENT);
startActivityForResult(Intent.createChooser(intent, "Select picture"), resultCode );

इस गतिविधि से लौटने के बाद मेरे पास एक डेटा है, जिसमें उरी शामिल है। ऐसा लग रहा है:

content://media/external/images/1

मैं इस पथ को वास्तविक (जैसे ' /sdcard/image.png') में कैसे बदल सकता हूं ?

धन्यवाद


1
यह स्पष्ट रूप से एक बहुत देर से टिप्पणी है, लेकिन मैं सिर्फ यह बताना चाहता था कि startActivityForResultCode विधि एक तर्क के रूप में एक अनुरोध कोड लेता है, परिणाम कोड नहीं।
तियानजिन Xiong

क्या uri.getPath()आपने आपको असली रास्ता नहीं दिया?
डारपन

# यह प्रयास करें, यदि आपको वास्तविक मार्ग प्राप्त करने के लिए समस्या हो रही है, तो आप मेरे उत्तरों की कोशिश कर सकते हैं। उपरोक्त उत्तरों से मुझे मदद नहीं मिली। स्पष्टीकरण : - इस विधि को यूआरआई मिलता है और फिर अपने एंड्रॉइड डिवाइस के एपीआई स्तर की जांच करें उसके बाद एपीआई स्तर के अनुसार यह रियल पथ उत्पन्न करेगा। API पथ के अनुसार वास्तविक पथ बनाने के लिए कोड अलग है। यहाँ मेरा जवाब है
सुनील

जवाबों:


56

क्या वास्तव में आपके लिए शारीरिक मार्ग प्राप्त करना आवश्यक है?
उदाहरण के लिए, ImageView.setImageURI()और ContentResolver.openInputStream()आपको इसके वास्तविक मार्ग को जाने बिना किसी फ़ाइल की सामग्री तक पहुँचने की अनुमति देता है।


इसका ठीक वही जो मैंने खोजा है, लेकिन नहीं मिला। धन्यवाद।
davs

6
क्षमा करें और यदि मैं इस छवि को फ़ाइल में परिवर्तित करना चाहता हूं, तो वास्तविक पथ प्राप्त किए बिना इसे कैसे करें?
चेल्बेटा

6
भौतिक पथ फ़ाइल नाम और एक्सटेंशन तक पहुँच देता है। फ़ाइल अपलोड के मामले में।
3

195

मैं यह करता हूं:

Uri selectedImageURI = data.getData();
imageFile = new File(getRealPathFromURI(selectedImageURI));

तथा:

private String getRealPathFromURI(Uri contentURI) {
    String result;
    Cursor cursor = getContentResolver().query(contentURI, null, null, null, null);
    if (cursor == null) { // Source is Dropbox or other similar local file path
        result = contentURI.getPath();
    } else { 
        cursor.moveToFirst(); 
        int idx = cursor.getColumnIndex(MediaStore.Images.ImageColumns.DATA); 
        result = cursor.getString(idx);
        cursor.close();
    }
    return result;
}

नोट: managedQuery()विधि पदावनत है, इसलिए मैं इसका उपयोग नहीं कर रहा हूं।

अंतिम संपादन: सुधार हमें कर्सर बंद करना चाहिए !!


1
stackoverflow.com/a/7265235/375093 यह एक और विकल्प है, लेकिन ऊपर से बेहतर बताया गया है। इसे भी देखें
Sundeep

6
Hi @ m3n0R, Moto G में, MediaStore.Images.ImageColumns.DATA कॉलम बिल्कुल मौजूद नहीं है। इस कॉलम के बिना छवि कैसे प्राप्त करें?
प्रात:

16
ERROR सुनिश्चित करें कि डेटा को एक्सेस करने से पहले कर्सर को प्रारंभिक रूप से ठीक किया गया है .. एपीआई 19 में जाँच
मयूर आर। अमिपारा

1
@ReneJuuse: उत्कृष्ट संसाधन। मैं अंत में इस मुद्दे को धन्यवाद करने के लिए हल करने में कामयाब रहा - मुझे एहसास नहीं हुआ कि एंड्रॉइड की स्थापना के बाद से बहुत सारे बदलाव हुए थे। मैं API 21 चला रहा था और जब मैंने आपके द्वारा लिंक की गई साइट पर दिखाई गई एपीआई 19 कार्यान्वयन का उपयोग किया, तो आखिरकार यह काम कर गया।
मिलोस इवानोविक

2
CursorWindow से पंक्ति 0, col -1 को नहीं पढ़ा जा सका। सुनिश्चित करें कि इससे डेटा एक्सेस करने से पहले कर्सर को आरंभीकृत किया गया है।
मव26

18

@Rene Juuse - ऊपर टिप्पणी में ... इस लिंक के लिए धन्यवाद!

। वास्तविक पथ पाने के लिए कोड एक एसडीके से दूसरे में थोड़ा अलग है इसलिए नीचे हमारे पास तीन विधियां हैं जो विभिन्न एसडीके से संबंधित हैं।

getRealPathFromURI_API19 (): API 19 के लिए वास्तविक पथ देता है (या ऊपर लेकिन परीक्षण नहीं किया गया) GetRealPathFromURI_API11to18 (): API 11 से API 18 के लिए वास्तविक पथ देता है ।RealPathFromURI_below11 (): API के लिए वास्तविक पथ 11 से नीचे का रिटर्न

public class RealPathUtil {

@SuppressLint("NewApi")
public static String getRealPathFromURI_API19(Context context, Uri uri){
    String filePath = "";
    String wholeID = DocumentsContract.getDocumentId(uri);

     // Split at colon, use second item in the array
     String id = wholeID.split(":")[1];

     String[] column = { MediaStore.Images.Media.DATA };     

     // where id is equal to             
     String sel = MediaStore.Images.Media._ID + "=?";

     Cursor cursor = context.getContentResolver().query(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, 
                               column, sel, new String[]{ id }, null);

     int columnIndex = cursor.getColumnIndex(column[0]);

     if (cursor.moveToFirst()) {
         filePath = cursor.getString(columnIndex);
     }   
     cursor.close();
     return filePath;
}


@SuppressLint("NewApi")
public static String getRealPathFromURI_API11to18(Context context, Uri contentUri) {
      String[] proj = { MediaStore.Images.Media.DATA };
      String result = null;

      CursorLoader cursorLoader = new CursorLoader(
              context, 
        contentUri, proj, null, null, null);        
      Cursor cursor = cursorLoader.loadInBackground();

      if(cursor != null){
       int column_index = 
         cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
       cursor.moveToFirst();
       result = cursor.getString(column_index);
      }
      return result;  
}

public static String getRealPathFromURI_BelowAPI11(Context context, Uri contentUri){
           String[] proj = { MediaStore.Images.Media.DATA };
           Cursor cursor = context.getContentResolver().query(contentUri, proj, null, null, null);
           int column_index
      = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
           cursor.moveToFirst();
           return cursor.getString(column_index);
}

फ़ॉन्ट: http://hmkcode.com/android-display-selected-image-and-its-real-path/


UPDATE 2016 मार्च

छवियों के पथ के साथ सभी समस्याओं को ठीक करने के लिए मैं फेसबुक और अन्य ऐप के रूप में एक कस्टम गैलरी बनाने की कोशिश करता हूं। ऐसा इसलिए है क्योंकि आप केवल स्थानीय फ़ाइलों (वास्तविक फ़ाइलें, आभासी या अस्थायी नहीं) का उपयोग कर सकते हैं, मैं इस पुस्तकालय के साथ सभी समस्याओं को हल करता हूं।

https://github.com/nohana/Laevatein (इस लाइब्रेरी कैमरे से तस्वीर लेने के लिए या galery से चुनते हैं, अगर आप गैलरी से चुन वह एलबम के साथ एक दराज है और सिर्फ स्थानीय फ़ाइलों को दिखाने के लिए है)


@ सैमसंग एस 4 पर न तो
रिकार्डो

Im वास्तव में Android में सभी प्रकार के स्रोत चित्रों का प्रबंधन करने के लिए अपनी कड़ी मेहनत करता है। यदि आप अपलोड करते हैं, या गैलेरी से चयन करते हैं, तो सबसे अच्छा समाधान फेसबुक से गैलरियों के रूप में बनाया जाता है। यह एक कस्टम गैलरी है जिसमें डिवाइस में सिर्फ वास्तविक चित्र हैं, कोई आभासी या अस्थायी नहीं है। मैं इस लाइब्रेरी का उपयोग करके अपने ऐप की सभी समस्याओं को ठीक करता हूं। github.com/nohana/Laevatein इसकी बहुत अच्छी लाइब्रेरी है। अनुकूलित करना सरल नहीं है, लेकिन आप कोड खोल सकते हैं और अपने बदलाव कर सकते हैं। मैं आशा करता हूं यह आपकी मदद कर सकते हैं।
luizfelipetx

4.4.1 के साथ मेरे सैमसंग S2 पर टूट गया
ओलिवर डिक्सन

मुझे पीडीएफ या डॉक जैसी फाइलें प्राप्त करने की आवश्यकता है, मैं पथ प्राप्त करने में असमर्थ हूं। क्या आप मेरी मदद कर सकते हैं?
अनीश कुमार

1
बहुत बढ़िया! अंत में कुछ ऐसा है जो वास्तव में काम करता है। काफी समय से इसकी तलाश थी। धन्यवाद।
जेवर

14

नोट यह @ user3516549 उत्तर में एक सुधार है और मैंने इसे Moto G3 पर Android 6.0.1 के साथ जांचा है।
मेरे पास यह समस्या है इसलिए मैंने @ user3516549 का उत्तर देने की कोशिश की है लेकिन कुछ मामलों में यह ठीक से काम नहीं कर रहा था। मैंने पाया है कि एंड्रॉइड 6.0 (या उससे ऊपर) में जब हम गैलरी छवि को चुनना शुरू करते हैं तो एक स्क्रीन खुल जाएगी जो हाल की छवियां दिखाती है जब उपयोगकर्ता इस सूची से छवि का चयन करते हैं तो हमें उरई मिल जाएगी।

content://com.android.providers.media.documents/document/image%3A52530

जबकि अगर उपयोगकर्ता हाल के बजाय स्लाइडिंग दराज से गैलरी का चयन करता है तो हमें उरई मिलेगा

content://media/external/images/media/52530

इसलिए मैंने इसे संभाल लिया है getRealPathFromURI_API19()

public static String getRealPathFromURI_API19(Context context, Uri uri) {
        String filePath = "";
        if (uri.getHost().contains("com.android.providers.media")) {
            // Image pick from recent 
            String wholeID = DocumentsContract.getDocumentId(uri);

            // Split at colon, use second item in the array
            String id = wholeID.split(":")[1];

            String[] column = {MediaStore.Images.Media.DATA};

            // where id is equal to
            String sel = MediaStore.Images.Media._ID + "=?";

            Cursor cursor = context.getContentResolver().query(MediaStore.Images.Media.EXTERNAL_CONTENT_URI,
                    column, sel, new String[]{id}, null);

            int columnIndex = cursor.getColumnIndex(column[0]);

            if (cursor.moveToFirst()) {
                filePath = cursor.getString(columnIndex);
            }
            cursor.close();
            return filePath;
        } else {
            // image pick from gallery 
           return  getRealPathFromURI_BelowAPI11(context,uri)
        }

    }

संपादित करें: यदि आप उच्च संस्करण में बाहरी एसडीकार्ड में फ़ाइल की छवि पथ प्राप्त करने की कोशिश कर रहे हैं, तो मेरे प्रश्न की जांच करें


हाय दोस्त, हाँ यह सच है। लेकिन यह इसलिए हो रहा है क्योंकि अब Google के पास आपके फ़ोन से Google डॉक्स पर सभी फ़ोटो अपलोड करने के लिए एक डिफ़ॉल्ट प्रारूप है। और सिर्फ अपने फोन में थंबिनल को सेव करें। यदि आपको Google डॉक्स से यह uri मिलता है, तो आपको इसका उपयोग करने से पहले फोटो डाउनलोड करना होगा। यह सामान्य रूप से अच्छा नहीं है। इसलिए, यहां सभी समस्याओं को ठीक करने के लिए, अब इस लाइब्रेरी का उपयोग करके im करें। (यह लाइब्रेरी केवल स्थानीय फ़ाइलों का उपयोग करती है, और इस समाधान से आपकी समस्याएं हल हो जाएंगी), या आप लाइब्रेरी से कोड निकाल सकते हैं और अपनी समस्या में शामिल होने के लिए खुद को सुधार सकते हैं। github.com/nohana/Laevatein मुझे उम्मीद है कि यह आपकी मदद कर सकता है।
लुइज़फेलिपेट

1+, इसका काम मेरे लिए एकदम सही है। जैसा कि @ जयप्रकाशसोनी ने अपने जवाब में कहा कि मुझे मोटो जी 4 प्ले में अपना ऐप चलाने पर उसी समस्या का सामना करना पड़ा है, लेकिन जब मैं उपरोक्त कोड का उपयोग करता हूं तो यह मेरे लिए ठीक काम करता है। धन्यवाद। आप मेरा समय बचाते हैं
शैलेश

6

संपादित करें: यहाँ इस समाधान का उपयोग करें: https://stackoverflow.com/a/20559175/2033223 सही काम करता है!

सबसे पहले, आपके समाधान @luizfelipetx के लिए धन्यवाद

मैंने तुम्हारे हल को थोड़ा बदल दिया। यह मेरे लिए काम करता है:

public static String getRealPathFromDocumentUri(Context context, Uri uri){
    String filePath = "";

    Pattern p = Pattern.compile("(\\d+)$");
    Matcher m = p.matcher(uri.toString());
    if (!m.find()) {
        Log.e(ImageConverter.class.getSimpleName(), "ID for requested image not found: " + uri.toString());
        return filePath;
    }
    String imgId = m.group();

    String[] column = { MediaStore.Images.Media.DATA };
    String sel = MediaStore.Images.Media._ID + "=?";

    Cursor cursor = context.getContentResolver().query(MediaStore.Images.Media.EXTERNAL_CONTENT_URI,
            column, sel, new String[]{ imgId }, null);

    int columnIndex = cursor.getColumnIndex(column[0]);

    if (cursor.moveToFirst()) {
        filePath = cursor.getString(columnIndex);
    }
    cursor.close();

    return filePath;
}

नोट: तो हमें दस्तावेज़ और छवि मिली, यह निर्भर करता है, अगर छवि 'रीसेंट', 'गैलरी' या कभी भी आती है। इसलिए मैं इसे देखने से पहले सबसे पहले छवि आईडी निकालता हूं।


1

Hii यहाँ कैमरा या आंधी से छवि लेने के लिए मेरा पूरा कोड है

// मेरी परिवर्तनशील घोषणा

protected static final int CAMERA_REQUEST = 0;
    protected static final int GALLERY_REQUEST = 1;
    Bitmap bitmap;
    Uri uri;
    Intent picIntent = null;

//क्लिक पर

if (v.getId()==R.id.image_id){
            startDilog();
        }

// विधि शरीर

private void startDilog() {
    AlertDialog.Builder myAlertDilog = new AlertDialog.Builder(yourActivity.this);
    myAlertDilog.setTitle("Upload picture option..");
    myAlertDilog.setMessage("Where to upload picture????");
    myAlertDilog.setPositiveButton("Gallery", new DialogInterface.OnClickListener() {
        @Override
        public void onClick(DialogInterface dialog, int which) {
            picIntent = new Intent(Intent.ACTION_GET_CONTENT,null);
            picIntent.setType("image/*");
            picIntent.putExtra("return_data",true);
            startActivityForResult(picIntent,GALLERY_REQUEST);
        }
    });
    myAlertDilog.setNegativeButton("Camera", new DialogInterface.OnClickListener() {
        @Override
        public void onClick(DialogInterface dialog, int which) {
            picIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
            startActivityForResult(picIntent,CAMERA_REQUEST);
        }
    });
    myAlertDilog.show();
}

// और बाकी चीजें

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    super.onActivityResult(requestCode, resultCode, data);
    if (requestCode==GALLERY_REQUEST){
        if (resultCode==RESULT_OK){
            if (data!=null) {
                uri = data.getData();
                BitmapFactory.Options options = new BitmapFactory.Options();
                options.inJustDecodeBounds = true;
                try {
                    BitmapFactory.decodeStream(getContentResolver().openInputStream(uri), null, options);
                    options.inSampleSize = calculateInSampleSize(options, 100, 100);
                    options.inJustDecodeBounds = false;
                    Bitmap image = BitmapFactory.decodeStream(getContentResolver().openInputStream(uri), null, options);
                    imageofpic.setImageBitmap(image);
                } catch (FileNotFoundException e) {
                    e.printStackTrace();
                }
            }else {
                Toast.makeText(getApplicationContext(), "Cancelled",
                        Toast.LENGTH_SHORT).show();
            }
        }else if (resultCode == RESULT_CANCELED) {
            Toast.makeText(getApplicationContext(), "Cancelled",
                    Toast.LENGTH_SHORT).show();
        }
    }else if (requestCode == CAMERA_REQUEST) {
        if (resultCode == RESULT_OK) {
            if (data.hasExtra("data")) {
                bitmap = (Bitmap) data.getExtras().get("data");
                uri = getImageUri(YourActivity.this,bitmap);
                File finalFile = new File(getRealPathFromUri(uri));
                imageofpic.setImageBitmap(bitmap);
            } else if (data.getExtras() == null) {

                Toast.makeText(getApplicationContext(),
                        "No extras to retrieve!", Toast.LENGTH_SHORT)
                        .show();

                BitmapDrawable thumbnail = new BitmapDrawable(
                        getResources(), data.getData().getPath());
                pet_pic.setImageDrawable(thumbnail);

            }

        } else if (resultCode == RESULT_CANCELED) {
            Toast.makeText(getApplicationContext(), "Cancelled",
                    Toast.LENGTH_SHORT).show();
        }
    }
}

private String getRealPathFromUri(Uri tempUri) {
    Cursor cursor = null;
    try {
        String[] proj = { MediaStore.Images.Media.DATA };
        cursor = this.getContentResolver().query(tempUri,  proj, null, null, null);
        int column_index = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
        cursor.moveToFirst();
        return cursor.getString(column_index);
    } finally {
        if (cursor != null) {
            cursor.close();
        }
    }
}
public static int calculateInSampleSize(
        BitmapFactory.Options options, int reqWidth, int reqHeight) {
    // Raw height and width of image
    final int height = options.outHeight;
    final int width = options.outWidth;
    int inSampleSize = 1;

    if (height > reqHeight || width > reqWidth) {

        final int halfHeight = height / 2;
        final int halfWidth = width / 2;

        // Calculate the largest inSampleSize value that is a power of 2 and keeps both
        // height and width larger than the requested height and width.
        while ((halfHeight / inSampleSize) > reqHeight
                && (halfWidth / inSampleSize) > reqWidth) {
            inSampleSize *= 2;
        }
    }
    return inSampleSize;
}

private Uri getImageUri(YourActivity youractivity, Bitmap bitmap) {
    ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
    bitmap.compress(Bitmap.CompressFormat.JPEG, 100, byteArrayOutputStream);
    String path = MediaStore.Images.Media.insertImage(youractivity.getContentResolver(), bitmap, "Title", null);
    return Uri.parse(path);
}

आप कैसे जानते हैं कि इस पंक्ति में 100 है options.inSampleSize = calculateInSampleSize(options, 100, 100);
जॉन जो

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