অ্যান্ড্রয়েড Uri.getPath () দ্বারা আসল পথ পান


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
এটি স্পষ্টতই একটি দেরি করা মন্তব্য, তবে আমি কেবল এটি উল্লেখ করতে চেয়েছিলাম যে স্টার্টঅ্যাক্টিভিটি ফর রিসাল্টকোড পদ্ধতিটি একটি ফলাফল কোড নয়, একটি আর্গুমেন্ট হিসাবে একটি অনুরোধ কোড গ্রহণ করে।
তিয়ানসিয়াং জিয়াং

তোমাকে uri.getPath()কি সত্যিকারের পথ দেয়নি?
দর্পণ

# এটির চেষ্টা করে দেখুন, যদি আপনি আসল পথ পেতে সমস্যাটি পান তবে আপনি আমার উত্তরগুলি চেষ্টা করতে পারেন। উপরের উত্তরগুলি আমাকে সাহায্য করে না। ব্যাখ্যা : - এই পদ্ধতিটি ইউআরআই পায় এবং তারপরে আপনার অ্যান্ড্রয়েড ডিভাইসের এপিআই স্তরটি পরীক্ষা করে তারপরে এপিআই স্তর অনুযায়ী এটি বাস্তব পথ তৈরি করবে। আসল পাথ তৈরির কোডটি এপিআই স্তর অনুযায়ী আলাদা is এখানে আমার উত্তর
সুনীল

উত্তর:


56

শারীরিক পথ পাওয়াই কি আপনার পক্ষে সত্যিই প্রয়োজনীয়?
উদাহরণস্বরূপ, ImageView.setImageURI()এবং ContentResolver.openInputStream()কোনও ফাইলের আসল পথটি না জেনে আপনার সামগ্রীগুলি অ্যাক্সেস করার অনুমতি দিন।


এটি ঠিক আমি যা চেয়েছিলাম তা খুঁজে পেয়েছি, কিন্তু খুঁজে পেল না। ধন্যবাদ।
ডেভগুলি

6
দুঃখিত এবং আমি যদি এই চিত্রটি ফাইলটিতে রূপান্তর করতে চাই, তবে এটি কীভাবে করবেন?
চ্লেবটা

6
শারীরিক পথ ফাইল নাম এবং এক্সটেনশনে অ্যাক্সেস দেয়। ফাইল আপলোড ক্ষেত্রে।
ক্লোকার

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 এটি অন্য একটি বিকল্প, তবে উপরের চেয়ে ভাল হিসাবে প্রস্তাবিত। এটিও দেখুন
সন্দীপ

6
হাই @ m3n0R, মোটো জি-তে, মিডিয়াস্টোর I ছবিগুলি I চিত্রসমূহ umns চিত্রসমূহ D এই কলামটি ছাড়াই কীভাবে চিত্র পাবেন?
সীমা

16
ত্রুটিটি নিশ্চিত করুন যে কার্সার এটি থেকে ডেটা অ্যাক্সেস করার আগে সঠিকভাবে শুরু হয়েছে .. এপিআই 19-এ চেক করা হয়েছে
ময়ূর আর আমিপাড়া

1
@ রেনেজিউজ: দুর্দান্ত উত্স। অবশেষে আমি এই সমস্যার সমাধান করতে পেরেছি বলে ধন্যবাদ জানাই - অ্যান্ড্রয়েডের সূচনালগ্ন থেকে এত পরিবর্তন হয়েছে তা আমি বুঝতে পারি নি। আমি এপিআই 21 চালিয়ে যাচ্ছিলাম এবং যখন আপনি লিঙ্কিত সাইটে প্রদর্শিত API 19 প্রয়োগটি ব্যবহার করেছিলেন, শেষ পর্যন্ত এটি কার্যকর হয়েছিল worked
মিলোস ইভানোভিক

2
কার্সার উইন্ডো থেকে সারি 0, কর -1 পড়তে পারেনি। কার্সার থেকে ডেটা অ্যাক্সেস করার আগে সঠিকভাবে শুরু হয়েছে তা নিশ্চিত করুন।
মাভেň ツ

18

@ রেনে জুসে - উপরের মন্তব্যে ... এই লিঙ্কটির জন্য ধন্যবাদ!

। আসল পাথ পাওয়ার কোডটি একটি এসডিকে থেকে অন্যরকমের থেকে কিছুটা আলাদা তাই নীচে আমাদের কাছে তিনটি পদ্ধতি রয়েছে যা বিভিন্ন এসডিকে নিয়ে কাজ করে।

getRealPathFromURI_API19 (): API 19 19 (বা তারপরে কিন্তু পরীক্ষিত নয়) -এর আসল পাথ ফেরৎ পাওয়া

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/


আপডেট 2016 মার্চ

চিত্রগুলির পথ নিয়ে সমস্ত সমস্যা সমাধানের জন্য আমি ফেসবুক এবং অন্যান্য অ্যাপ্লিকেশন হিসাবে একটি কাস্টম গ্যালারী তৈরি করার চেষ্টা করি। এর কারণ আপনি কেবল স্থানীয় ফাইল (সত্যিকারের ফাইলগুলি, ভার্চুয়াল বা অস্থায়ী নয়) ব্যবহার করতে পারেন, আমি এই লাইব্রেরি দিয়ে সমস্ত সমস্যার সমাধান করি।

https://github.com/nohana/Laevatein (এই গ্রন্থাগারটি ক্যামেরা থেকে ছবি তোলা বা গ্যালারি থেকে চয়ন করতে হবে, যদি আপনি গ্যালারী থেকে চয়ন করেন তবে তার অ্যালবামের সাথে একটি ড্রয়ার রয়েছে এবং কেবল স্থানীয় ফাইলগুলি দেখানো হবে)


স্যামসুং এস 4-তে ক্লকার নেই
রিকার্ডো

অ্যান্ড্রয়েডে সমস্ত ধরণের উত্স চিত্র পরিচালনা করা সত্যিই আমার পক্ষে শক্ত। যদি আপনি আপলোড করেন বা গ্যালারি থেকে চয়ন করেন তবে সেরা সমাধানটি ফেসবুক থেকে গ্যালারী হিসাবে তৈরি করা। এটি ডিভাইসে কেবল আসল চিত্র সহ একটি কাস্টম গ্যালারী, কোনও ভার্চুয়াল বা অস্থায়ী নয়। আমি এই অ্যাপ্লিকেশনটিতে এই গ্রন্থাগারটি ব্যবহার করে সমস্ত সমস্যার সমাধান করেছি। github.com/nohana/Laevatein এটি সত্যই ভাল লাইব্রেরি। কাস্টমাইজ করা সহজ নয়, তবে আপনি কোডটি খুলতে এবং আপনার পরিবর্তনগুলি করতে পারেন। আমি আশা করি এটা তোমাকে সাহায্য করবে।
luizfelipetx 25'16


আমার পিডিএফ বা ডকের মতো ফাইলগুলি পাওয়া দরকার, আমি পথটি পেতে অক্ষম। তুমি কি আমাকে সাহায্য করবে?
আনিস কুমার

1
অসাধারণ! অবশেষে এমন কিছু যা সত্যই কাজ করে। দীর্ঘদিন ধরে এই সন্ধান করছিল। ধন্যবাদ।
জাভাটার

14

দ্রষ্টব্য এটি @ ব্যবহারকারী 3516549 উত্তরের উন্নতি এবং আমি এটিকে অ্যান্ড্রয়েড 6.0.1 এর সাথে মোটো জি 3 এ পরীক্ষা করে
দেখেছি আমার এই সমস্যাটি রয়েছে তাই আমি @ ব্যবহারকারী 3516549 এর উত্তর চেষ্টা করেছি তবে কিছু ক্ষেত্রে এটি সঠিকভাবে কাজ করছে না। আমি খুঁজে পেয়েছি যে অ্যান্ড্রয়েড .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)
        }

    }

সম্পাদনা করুন: আপনি যদি উচ্চতর সংস্করণে বাহ্যিক এসডিকার্ডে ফাইলের চিত্রের সন্ধানের চেষ্টা করছেন তবে আমার প্রশ্নটি পরীক্ষা করুন


হাই বন্ধু, হ্যাঁ সত্য। তবে এটি ঘটছে কারণ এখন আপনার ফোন থেকে সমস্ত ফটোগুলি গুগল ডক্সে আপলোড করার জন্য গুগলের একটি ডিফল্ট ফর্ম্যাট রয়েছে। এবং কেবল আপনার ফোনে থাম্বনাল সংরক্ষণ করুন। আপনি যদি গুগল ডক্স থেকে এই ইউরি পান তবে আপনার এটি ব্যবহারের আগে ছবিটি ডাউনলোড করতে হবে। এটি সাধারণভাবে ভাল নয়। সুতরাং, এখানে সমস্ত সমস্যা সমাধানের জন্য, এখন এই লাইব্রেরিটি ব্যবহার করছি। (এই লাইব্রেরিটি কেবল স্থানীয় ফাইলগুলি ব্যবহার করে এবং এই সমাধানের সাহায্যে আপনার সমস্যার সমাধান হবে), বা আপনি লাইব্রেরি থেকে কোডটি বের করতে পারেন এবং নিজের সমস্যায় অংশ নিতে নিজেকে উন্নত করতে পারেন। github.com/nohana/Laevatein আশা করি এটা আপনাকে সাহায্য করতে পারেন।
luizfelipetx

1+, এটি আমার জন্য উপযুক্ত। যেমন @ জয়প্রকাশসনি তার উত্তরে বলেছিল যে আমি মটো জি 4 খেলায় আমার অ্যাপটি চালানোর সময় আমারও একই সমস্যার মুখোমুখি হয়েছিল কিন্তু যখন আমি উপরের কোডটি ব্যবহার করি তবে এটি আমার পক্ষে ভাল কাজ করে। তোমাকে ধন্যবাদ. আপনি আমার সময় বাঁচান
শৈলেশ

6

সম্পাদনা: এই সমাধানটি এখানে ব্যবহার করুন: https://stackoverflow.com/a/20559175/2033223 নিখুঁত কাজ করে!

প্রথমত, আপনার সমাধান @ লুইজফেলিপেটেক্সের জন্য ধন্যবাদ

আমি আপনার সমাধানটি কিছুটা পরিবর্তন করেছি। এটি আমার পক্ষে কাজ করে:

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

হাই, ক্যামেরা বা গ্যালারী থেকে চিত্র নেওয়ার জন্য আমার সম্পূর্ণ কোড এটি

// আমার পরিবর্তনশীল ঘোষণা

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

// onclick

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);
জন জো

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.