অ্যানড্রয়েডে ফাইলের পথ থেকে সামগ্রী ইউরি পান


271

আমি একটি চিত্রের পরম পাথ জানি (উদাহরণস্বরূপ, /sdcard/cats.jpg বলুন)। এই ফাইলটির জন্য সামগ্রীটি ইউরি করার কোনও উপায় আছে কি?

আসলে আমার কোডে, আমি একটি চিত্র ডাউনলোড করি এবং এটি একটি নির্দিষ্ট জায়গায় সংরক্ষণ করি। ইমেজভিউ দৃষ্টান্তে চিত্রটি সেট করার জন্য, বর্তমানে আমি পাথটি ব্যবহার করে ফাইলটি খুলি, বাইটগুলি পাই এবং একটি বিটম্যাপ তৈরি করি এবং তারপরে চিত্র-ভিউ দৃষ্টান্তে বিটম্যাপটি সেট করি। এটি খুব ধীর প্রক্রিয়া, পরিবর্তে যদি আমি সামগ্রীটি ইউরি পেতে পারি তবে আমি খুব সহজেই পদ্ধতিটি ব্যবহার করতে পারি imageView.setImageUri(uri)


23
উরি ইউরি = উরি.পারস ("ফাইল: ///sdcard/img.png");
আনন্দ তিওয়ারি

13
মন্তব্যে +1 করুন, কেবল উরি.পারস ("ফাইল: //" + ফাইলপথ) এর কৌশলটি করা উচিত
জার্মান লেটারে

উরি.পারসিকে অবহেলা করা হয়েছে এবং "যুক্ত করা হবে"
পোলারিস

@ পোলারিস উরি.পারসকে এপিআই 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 এ সূক্ষ্মভাবে কাজ করে তবে প্রথমটি কেবল ২.২-এ করা হয়েছে
মিশকিন

28
এই পদ্ধতির কোনওটিই একটি সামগ্রী ইউআরআইয়ের ফাইলের সমাধানের সমাধান করে না। আমি বুঝতে পারি যদিও এটি তাত্ক্ষণিক সমস্যার সমাধান করেছে।
জেফ্রি ব্লাটম্যান

38
"/ এসডিকার্ড /" হার্ডকোড করবেন না; পরিবর্তে এনভায়রনমেন্ট.জেট এক্সটার্নালস্টোরেজ ডিরেক্টরী ()। getPath () ব্যবহার করুন
একাটজ

8
উপরের সমাধানগুলি উভয়ই এটিই প্রত্যাবর্তন করে: ১. ফাইল: ///storage/emised/0/DCIM/Camera/VID_20140312_171146.mp4 ২ / স্টোরেজ / মিমুলেটেড / ডেমিআইএম / ক্যামেরা / ভিআইডি_20140312_171146.mp4 তবে আমি কী দেখছিলাম কারণ কিছু আলাদা। আমার সামগ্রীটি প্রয়োজন: // ফর্ম্যাট ইউআরআই।
জিনালের উত্তরটি

5
আরে Uri.fromFileঅ্যান্ড্রয়েড 26+ এ কাজ করবে না, আপনার ফাইল সরবরাহকারী ব্যবহার করা উচিত
vuhung3990

85

হালনাগাদ

এখানে ধারণা করা হয় যে আপনার মিডিয়া (চিত্র / ভিডিও) ইতিমধ্যে সামগ্রী সামগ্রী সরবরাহকারীতে যুক্ত হয়েছে। যদি তা না হয় তবে আপনি কী চান তা সঠিক হিসাবে আপনি সামগ্রী URL পেতে সক্ষম হবেন না able পরিবর্তে সেখানে উরি ফাইল থাকবে।

আমার ফাইল এক্সপ্লোরার ক্রিয়াকলাপের জন্য আমার একই প্রশ্ন ছিল। আপনার জানা উচিত যে ফাইলের সামগ্রীগুলি কেবল চিত্র, অডিও এবং ভিডিওর মতো মধ্যস্বত্বভোগী ডেটা সমর্থন করে। আমি আপনাকে এসডিকার্ড থেকে কোনও চিত্র নির্বাচন করতে ইমেজ সামগ্রী ইউরি পাওয়ার কোড দিচ্ছি। এই কোডটি ব্যবহার করে দেখুন, সম্ভবত এটি আপনার পক্ষে কাজ করবে ...

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 / ইমেজ ডিপো / পিকচার.পিএনজি" এর সাথে নিখুঁত পাথের সাথে একটি ফাইলের জন্য সামগ্রীর উরি পাওয়ার চেষ্টা করেছি। এটি কাজ করে না, তাই আমি কোডের পাথটি ডিবাগ করলাম এবং সন্ধান করলাম যে কার্সারটি খালি রয়েছে এবং কন্টেন্টপ্রাইডারে এন্ট্রি যুক্ত করা হচ্ছে, এটি বিষয়বস্তু উরি হিসাবে বাতিল হবে। সাহায্য করুন.
শ্রী কৃষ্ণ

1
আমার কাছে ফাইলের পথ রয়েছে - ফাইল: ///storage/emulated/0/Android/data/com.packagename/files/out.mp4, কিন্তু আমি বিষয়বস্তু ইউরির চেষ্টা করার সময় নালু হয়ে যাচ্ছি। আমিও পরিবর্তন চেষ্টা MediaStore.Images.Mediaকরার MediaStore.Video.Mediaকোন ভাগ্য, কিন্তু এখনও।
নরেন্দ্র সিং

1
এটি অ্যান্ড্রয়েড পাই এপিআই 28 এ কাজ করছে না
C

1
ডেটা কলাম অ্যান্ড্রয়েড 10 এ অ্যাক্সেসযোগ্য না হওয়ায় আপনি Android 10 এর জন্য এই পদ্ধতিটি আপডেট করতে পারেন?
খুশবু শাহ

16

// এই কোডটি ২.২ এ চিত্রগুলির জন্য কাজ করে, অন্য কোনও মিডিয়া প্রকারের কিনা তা নিশ্চিত নয়

   //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+ এ ভাগ করে নেওয়ার ক্ষেত্রে আমাকে সহায়তা করেছে, কারণ এই অ্যাপ্লিকেশনটির জন্য একটি সামগ্রীর উরির সাথে মিডিয়া স্ট্রিম প্রয়োজন - নিখুঁত পাথ কাজ করে না।
রিডকুলি

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

দ্বিতীয়টি (যা আমি ভিডিওগুলির জন্য করি তবে মিডিয়াস্টোর.ভিডিওর জন্য অডিও বা ফাইল বা মিডিয়াস্টোর.অডিও (ইত্যাদি) প্রতিস্থাপনের মাধ্যমে অন্যান্য ধরণের সঞ্চিত সামগ্রীর জন্যও ব্যবহার করা যেতে পারে):

/**
 * 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ক্ষেত্রটি নয়। আপনার কাছে ডেটা ক্ষেত্র নেই যেখানে সাধারণত সামগ্রীতে সরাসরি পথ থাকে, আপনাকে প্রথমে সামগ্রীটি পড়তে হবে এবং একটি ফাইলে বা মেমোরিতে লিখতে হবে এবং তারপরে আপনার নিজের পথ রয়েছে have
পিয়েরে

7

আপনি ব্যবহারের ভিত্তিতে এই দুটি উপায় ব্যবহার করতে পারেন

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

অথবা

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

আমি উভয় উপায় এবং উভয় কাজ চেষ্টা করেছি।


5

content://কোনও ফাইল থেকে সামগ্রী উরি তৈরির সহজ এবং শক্তিশালী উপায় হ'ল ফাইলপ্রোভাইডার ব্যবহার করা । ফাইলপ্রভাইডার দ্বারা সরবরাহ করা উরি অন্যান্য অ্যাপ্লিকেশনগুলির সাথে ফাইলগুলি ভাগ করে নেওয়ার জন্যও ইউরি সরবরাহ করতে ব্যবহার করা যেতে পারে। আপনার নিখুঁত পাথ থেকে ফাইল উরি পেতে Fileআপনি ডকুমেন্টফিল.ফ্র্যামফিল (নতুন ফাইল (পথ, নাম)) ব্যবহার করতে পারেন, এটি এপি 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

এটি দেরীতে হলেও ভবিষ্যতে কাউকে সাহায্য করতে পারে।

কোনও ফাইলের জন্য সামগ্রী ইউআরআই পেতে, আপনি নিম্নলিখিত পদ্ধতিটি ব্যবহার করতে পারেন:

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

এটি সামগ্রীটি ইউআরআই প্রদান করে।

কীভাবে সেটআপ করবেন তা শিখতে এটি পরীক্ষা করে দেখুন FileProvider


2

কোনও কোড না লিখে ফাইল আইডি প্রাপ্ত করা, কেবলমাত্র অ্যাডবি শেল সি এল আই কমান্ড সহ:

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

গুগল "সামগ্রী ইউরি থেকে বাস্তব পথ পাবে" এবং অনুসন্ধান ফলাফলের সারাংশে আপনার 0-ভোট উত্তরের সামগ্রী সহ এই প্রশ্নটি শীর্ষ 1 1 সুতরাং আমাকে প্রথম ভোট দিন। ধন্যবাদ ভাই!
উইকএন্ড

এটি দুর্দান্ত। তবে মনে হচ্ছে আপনি পাবেন: Permission Denial: Do not have permission in call getContentProviderExternal() from pid=15660, uid=10113 requires android.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLYযদি না আপনি বদ্ধমূল হন।
not2qubit

সুতরাং এই ফোনের রুট অ্যাক্সেস প্রয়োজন?
সম্মিতা কাব্যেশ

1

পূর্ববর্তী অ্যান্ড্রয়েড এন এর সংস্করণগুলিকে সমর্থন করার জন্য একটি বৈধতা ব্যবহার করা আরও ভাল, উদাহরণস্বরূপ:

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


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