Android 4.4 (API লেভেল ১৯) এবং তার পরবর্তী ভার্সনে রান করা ডিভাইসে, আপনার অ্যাপ স্টোরেজ অ্যাক্সেস ফ্রেমওয়ার্ক ব্যবহার করে এক্সটার্নাল স্টোরেজ ভলিউম এবং ক্লাউড-ভিত্তিক স্টোরেজ সহ ডকুমেন্ট প্রোভাইডারের সাথে ইন্টার্যাক্ট করতে পারে। এই ফ্রেমওয়ার্ক ব্যবহারকারীদের সিস্টেম পিকারের সাথে ইন্টার্যাক্ট করার অনুমতি দেয় যাতে তারা ডকুমেন্ট প্রদানকারী বেছে নিতে পারেন এবং আপনার অ্যাপের জন্য নির্দিষ্ট ডকুমেন্ট ও অন্যান্য ফাইল বেছে নিতে পারেন যাতে সেগুলি তৈরি, খোলা বা পরিবর্তন করা যায়।
আপনার অ্যাপ অ্যাক্সেস করতে পারে এমন ফাইল বা ডিরেক্টরি বেছে নেওয়ার সাথে ব্যবহারকারী যুক্ত থাকেন বলে, এই মেকানিজমের জন্য কোনও সিস্টেম অনুমতির প্রয়োজন হয় না এবং ব্যবহারকারীর নিয়ন্ত্রণ ও গোপনীয়তা আরও উন্নত হয়। এছাড়াও, এইসব ফাইল, যা অ্যাপ-নির্দিষ্ট ডিরেক্টরির বাইরে এবং মিডিয়া স্টোরের বাইরে স্টোর করা থাকে, আপনার অ্যাপ আনইনস্টল করার পরেও ডিভাইসে থেকে যায়।
ফ্রেমওয়ার্ক ব্যবহার করার মধ্যে নিম্নলিখিত ধাপগুলি পড়ে:
- কোনও অ্যাপ এমন একটি ইনটেন্টকে কল করে যাতে স্টোরেজ-সম্পর্কিত অ্যাকশন থাকে। এই অ্যাকশনটি ফ্রেমওয়ার্কের মাধ্যমে উপলভ্য করা নির্দিষ্ট ব্যবহারের ক্ষেত্রে প্রযোজ্য।
- ব্যবহারকারী সিস্টেম পিকার দেখতে পান, যা তাকে ডকুমেন্ট প্রদানকারী ব্রাউজ করতে এবং স্টোরেজ-সম্পর্কিত অ্যাকশন যেখানে হয় সেই লোকেশন বা ডকুমেন্ট বেছে নিতে দেয়।
- অ্যাপটি ব্যবহারকারীর বেছে নেওয়া লোকেশন বা ডকুমেন্টকে উপস্থাপন করে এমন একটি URI-তে রিড ও রাইট অ্যাক্সেস পায়। এই URI ব্যবহার করে, অ্যাপটি বেছে নেওয়া লোকেশনে অপারেশন করতে পারবে।
Android 9 (API লেভেল ২৮) বা তার নিচের ভার্সনে চলে এমন ডিভাইসে মিডিয়া ফাইল অ্যাক্সেস করার সুবিধা দিতে, READ_EXTERNAL_STORAGE
অনুমতি ঘোষণা করুন এবং maxSdkVersion-কে 28-এ সেট করুন।
এই নির্দেশিকা থেকে আপনি ফাইল ও অন্যান্য ডকুমেন্ট নিয়ে কাজ করার জন্য ফ্রেমওয়ার্কের মাধ্যমে সমর্থিত বিভিন্ন ব্যবহারের ক্ষেত্র সম্পর্কে জানতে পারবেন। ব্যবহারকারীর বেছে নেওয়া লোকেশনে কীভাবে অপারেশন সম্পন্ন করতে হয় তাও এটি ব্যাখ্যা করে।
ডকুমেন্ট ও অন্যান্য ফাইল অ্যাক্সেস করার জন্য ব্যবহারিক ক্ষেত্র
ফাইল ও অন্যান্য ডকুমেন্ট অ্যাক্সেস করার জন্য স্টোরেজ অ্যাক্সেস ফ্রেমওয়ার্ক নিম্নলিখিত ব্যবহারের ক্ষেত্রে সহায়তা করে।
- নতুন ফাইল তৈরি করুন
-
ACTION_CREATE_DOCUMENTইনটেন্ট অ্যাকশন ব্যবহারকারীদের নির্দিষ্ট লোকেশনে ফাইল সেভ করার অনুমতি দেয়। - কোনও ডকুমেন্ট বা ফাইল খোলা
-
ACTION_OPEN_DOCUMENTইনটেন্ট অ্যাকশন ব্যবহারকারীদের খোলার জন্য একটি নির্দিষ্ট ডকুমেন্ট বা ফাইল বেছে নিতে দেয়। - কোনও ডিরেক্টরির কন্টেন্টে অ্যাক্সেস মঞ্জুর করা
- Android 5.0 (API লেভেল 21) এবং তার পরবর্তী যেকোনও ভার্সনে উপলভ্য
ACTION_OPEN_DOCUMENT_TREEইনটেন্ট অ্যাকশন, ব্যবহারকারীদের নির্দিষ্ট ডিরেক্টরি বেছে নেওয়ার অনুমতি দেয়, যার ফলে আপনার অ্যাপ সেই ডিরেক্টরির মধ্যে থাকা সব ফাইল ও সাব-ডিরেক্টরি অ্যাক্সেস করতে পারে।
প্রতিটি ব্যবহারের ক্ষেত্রে কীভাবে কনফিগার করতে হবে সেই সম্পর্কে নির্দেশ নিচে দেওয়া রয়েছে।
নতুন ফাইল তৈরি করুন
সিস্টেম ফাইল পিকার লোড করতে এবং ব্যবহারকারীকে কোনও ফাইলের কন্টেন্ট লেখার জন্য লোকেশন বেছে নেওয়ার অনুমতি দিতে
ACTION_CREATE_DOCUMENT
ইনটেন্ট অ্যাকশন ব্যবহার করুন। এই প্রসেসটি অন্যান্য অপারেটিং সিস্টেমের "এই নামে সেভ করুন" ডায়ালগের মতোই।
মনে রাখবেন: ACTION_CREATE_DOCUMENT আগে থেকে থাকা কোনও ফাইল
ওভাররাইট করতে পারে না। আপনার অ্যাপ একই নামে কোনও ফাইল সেভ করার চেষ্টা করলে, সিস্টেম
ফাইল নামের শেষে বন্ধনীতে একটি নম্বর যোগ করে।
যেমন, আপনার অ্যাপ যদি এমন কোনও ডিরেক্টরিতে
confirmation.pdf নামের ফাইল সেভ করার চেষ্টা করে যেখানে আগে থেকেই এই নামের ফাইল আছে, তাহলে সিস্টেম নতুন ফাইলটি
confirmation(1).pdf নামে সেভ করে।
ইনটেন্ট কনফিগার করার সময়, ফাইলের নাম ও MIME-এর প্রকার উল্লেখ করুন এবং
বিকল্প হিসেবে, ফাইল বা ডিরেক্টরির URI উল্লেখ করুন যা ফাইল পিকার প্রথমবার লোড হওয়ার সময়
EXTRA_INITIAL_URI
ইনটেন্ট এক্সট্রা ব্যবহার করে
দেখানো উচিত।
নিম্নলিখিত কোড স্নিপেট থেকে জানা যায় যে ফাইল তৈরি করার জন্য কীভাবে ইনটেন্ট তৈরি ও ইনভোক করতে হয়:
Kotlin
// Request code for creating a PDF document. const val CREATE_FILE = 1 private fun createFile(pickerInitialUri: Uri) { val intent = Intent(Intent.ACTION_CREATE_DOCUMENT).apply { addCategory(Intent.CATEGORY_OPENABLE) type = "application/pdf" putExtra(Intent.EXTRA_TITLE, "invoice.pdf") // Optionally, specify a URI for the directory that should be opened in // the system file picker before your app creates the document. putExtra(DocumentsContract.EXTRA_INITIAL_URI, pickerInitialUri) } startActivityForResult(intent, CREATE_FILE) }
জাভা
// Request code for creating a PDF document. private static final int CREATE_FILE = 1; private void createFile(Uri pickerInitialUri) { Intent intent = new Intent(Intent.ACTION_CREATE_DOCUMENT); intent.addCategory(Intent.CATEGORY_OPENABLE); intent.setType("application/pdf"); intent.putExtra(Intent.EXTRA_TITLE, "invoice.pdf"); // Optionally, specify a URI for the directory that should be opened in // the system file picker when your app creates the document. intent.putExtra(DocumentsContract.EXTRA_INITIAL_URI, pickerInitialUri); startActivityForResult(intent, CREATE_FILE); }
একটি ফাইল খুলুন
আপনার অ্যাপ ডকুমেন্টকে স্টোরেজের ইউনিট হিসেবে ব্যবহার করতে পারে যেখানে ব্যবহারকারীরা ডেটা লেখেন যা তারা সহকর্মীদের সাথে শেয়ার করতে বা অন্য ডকুমেন্টে ইমপোর্ট করতে চাইতে পারেন। কয়েকটি উদাহরণ হল, ব্যবহারকারী কোনও প্রোডাক্টিভিটি ডকুমেন্ট বা EPUB ফাইল হিসেবে সেভ করা কোনও বই খুলছেন।
এইসব ক্ষেত্রে, ACTION_OPEN_DOCUMENT
ইনটেন্ট কল করে ব্যবহারকারীকে ফাইল বেছে নেওয়ার অনুমতি দিন, যা সিস্টেমের ফাইল পিকার অ্যাপ খোলে। আপনার অ্যাপে কাজ করে শুধু সেই ধরনের ফাইল দেখাতে, MIME-এর প্রকার উল্লেখ করুন। এছাড়াও, আপনি বিকল্প হিসেবে
ফাইলের URI উল্লেখ করতে পারেন যা ফাইল চয়নকারি প্রথমবার লোড হওয়ার সময়
দেখাবে। এর জন্য
EXTRA_INITIAL_URI
ইনটেন্ট এক্সট্রা ব্যবহার করতে হবে।
নিচে দেওয়া কোড স্নিপেট থেকে জানা যাবে যে কীভাবে পিডিএফ ডকুমেন্ট খোলার জন্য ইনটেন্ট তৈরি ও ইনভোক করতে হয়:
Kotlin
// Request code for selecting a PDF document. const val PICK_PDF_FILE = 2 fun openFile(pickerInitialUri: Uri) { val intent = Intent(Intent.ACTION_OPEN_DOCUMENT).apply { addCategory(Intent.CATEGORY_OPENABLE) type = "application/pdf" // Optionally, specify a URI for the file that should appear in the // system file picker when it loads. putExtra(DocumentsContract.EXTRA_INITIAL_URI, pickerInitialUri) } startActivityForResult(intent, PICK_PDF_FILE) }
জাভা
// Request code for selecting a PDF document. private static final int PICK_PDF_FILE = 2; private void openFile(Uri pickerInitialUri) { Intent intent = new Intent(Intent.ACTION_OPEN_DOCUMENT); intent.addCategory(Intent.CATEGORY_OPENABLE); intent.setType("application/pdf"); // Optionally, specify a URI for the file that should appear in the // system file picker when it loads. intent.putExtra(DocumentsContract.EXTRA_INITIAL_URI, pickerInitialUri); startActivityForResult(intent, PICK_PDF_FILE); }
অ্যাক্সেস সংক্রান্ত বিধিনিষেধ
Android 11 (API লেভেল ৩০) এবং তার পরবর্তী ভার্সনে, আপনি
ACTION_OPEN_DOCUMENT ইনটেন্ট অ্যাকশন ব্যবহার করে ব্যবহারকারীকে নিম্নলিখিত ডিরেক্টরি থেকে আলাদা আলাদা ফাইল
বেছে নেওয়ার অনুরোধ করতে পারবেন না:
Android/data/ডিরেক্টরি এবং সব সাবডিরেক্টরি।Android/obb/ডিরেক্টরি এবং সব সাবডিরেক্টরি।
কোনও ডিরেক্টরির কন্টেন্টে অ্যাক্সেস দিন
ফাইল ম্যানেজমেন্ট এবং মিডিয়া-ক্রিয়েশন অ্যাপ সাধারণত ডিরেক্টরি হায়ারার্কিতে ফাইলের গ্রুপ ম্যানেজ করে। আপনার অ্যাপে এই সুবিধা প্রদান করতে, ACTION_OPEN_DOCUMENT_TREE
ইনটেন্ট অ্যাকশন ব্যবহার করুন, যা ব্যবহারকারীকে সম্পূর্ণ ডিরেক্টরি
ট্রি-তে অ্যাক্সেস প্রদান করার অনুমতি দেয়, Android 11 (API লেভেল ৩০) থেকে শুরু করে কিছু ব্যতিক্রম সহ। আপনার অ্যাপ তখন
বেছে নেওয়া ডিরেক্টরি এবং এর যেকোনও সাব-ডিরেক্টরির যেকোনও ফাইল অ্যাক্সেস করতে পারবে।
ACTION_OPEN_DOCUMENT_TREE ব্যবহার করার সময়, আপনার অ্যাপ শুধুমাত্র ব্যবহারকারীর বেছে নেওয়া ডিরেক্টরির ফাইল অ্যাক্সেস করতে পারে। ব্যবহারকারীর বেছে নেওয়া এই ডিরেক্টরির বাইরে থাকা অন্যান্য
অ্যাপের ফাইলে আপনার অ্যাক্সেস নেই। এই
ব্যবহারকারী-নিয়ন্ত্রিত অ্যাক্সেস ব্যবহারকারীদের ঠিক কোন কন্টেন্ট আপনার অ্যাপের সাথে শেয়ার করতে
স্বাচ্ছন্দ্য বোধ করেন তা বেছে নিতে দেয়।
বিকল্প হিসেবে, আপনি ডিরেক্টরির URI নির্দিষ্ট করতে পারেন যা ফাইল পিকারের
প্রথমবার লোড হওয়ার সময় দেখানো উচিত। এর জন্য
EXTRA_INITIAL_URI
ইনটেন্ট এক্সট্রা ব্যবহার করুন।
নিম্নলিখিত কোড স্নিপেট থেকে জানা যায় যে কীভাবে ডিরেক্টরি খোলার জন্য ইনটেন্ট তৈরি ও ইনভোক করতে হয়:
Kotlin
fun openDirectory(pickerInitialUri: Uri) { // Choose a directory using the system's file picker. val intent = Intent(Intent.ACTION_OPEN_DOCUMENT_TREE).apply { // Optionally, specify a URI for the directory that should be opened in // the system file picker when it loads. putExtra(DocumentsContract.EXTRA_INITIAL_URI, pickerInitialUri) } startActivityForResult(intent, your-request-code) }
জাভা
public void openDirectory(Uri uriToLoad) { // Choose a directory using the system's file picker. Intent intent = new Intent(Intent.ACTION_OPEN_DOCUMENT_TREE); // Optionally, specify a URI for the directory that should be opened in // the system file picker when it loads. intent.putExtra(DocumentsContract.EXTRA_INITIAL_URI, uriToLoad); startActivityForResult(intent, your-request-code); }
অ্যাক্সেস সংক্রান্ত বিধিনিষেধ
Android 11 (API লেভেল ৩০) এবং তার পরবর্তী ভার্সনে, আপনি নিম্নলিখিত ডিরেক্টরি অ্যাক্সেস করার অনুরোধ করতে
ACTION_OPEN_DOCUMENT_TREE ইনটেন্ট অ্যাকশন ব্যবহার করতে পারবেন না:
- ইন্টার্নাল স্টোরেজ ভলিউমের রুট ডিরেক্টরি।
- প্রতিটি এসডি কার্ড ভলিউমের রুট ডিরেক্টরি যা ডিভাইস প্রস্তুতকারক নির্ভরযোগ্য বলে মনে করে, কার্ডটি এমুলেট করা বা অপসারণযোগ্য কিনা তা নির্বিশেষে। একটি নির্ভরযোগ্য ভলিউম হল এমন একটি ভলিউম যা কোনও অ্যাপ বেশিরভাগ সময় সফলভাবে অ্যাক্সেস করতে পারে।
Downloadডিরেক্টরি।
এছাড়াও, Android 11 (API লেভেল ৩০) এবং তার পরবর্তী ভার্সনে, আপনি
ACTION_OPEN_DOCUMENT_TREE ইনটেন্ট অ্যাকশন ব্যবহার করে ব্যবহারকারীকে নিম্নলিখিত ডিরেক্টরি থেকে
আলাদা আলাদা ফাইল বেছে নেওয়ার অনুরোধ করতে পারবেন না:
Android/data/ডিরেক্টরি এবং সব সাবডিরেক্টরি।Android/obb/ডিরেক্টরি এবং সব সাবডিরেক্টরি।
বেছে নেওয়া লোকেশনে অপারেশন পারফর্ম করুন
ব্যবহারকারী সিস্টেমের ফাইল পিকার ব্যবহার করে কোনও ফাইল বা ডিরেক্টরি বেছে নেওয়ার পরে,
আপনি onActivityResult()-এ নিম্নলিখিত কোড ব্যবহার করে বেছে নেওয়া আইটেমের URI
উদ্ধার করতে পারবেন:
Kotlin
override fun onActivityResult( requestCode: Int, resultCode: Int, resultData: Intent?) { if (requestCode == your-request-code && resultCode == Activity.RESULT_OK) { // The result data contains a URI for the document or directory that // the user selected. resultData?.data?.also { uri -> // Perform operations on the document using its URI. } } }
জাভা
@Override public void onActivityResult(int requestCode, int resultCode, Intent resultData) { if (requestCode == your-request-code && resultCode == Activity.RESULT_OK) { // The result data contains a URI for the document or directory that // the user selected. Uri uri = null; if (resultData != null) { uri = resultData.getData(); // Perform operations on the document using its URI. } } }
বেছে নেওয়া আইটেমের URI-এর রেফারেন্স পাওয়ার মাধ্যমে, আপনার অ্যাপ আইটেমের উপর একাধিক অপারেশন পারফর্ম করতে পারে। যেমন, আপনি আইটেমের মেটাডেটা অ্যাক্সেস করতে, আইটেমটি সেখানেই এডিট করতে এবং আইটেমটি মুছে ফেলতে পারবেন।
ব্যবহারকারীর বেছে নেওয়া ফাইলের উপর কীভাবে অ্যাকশন সম্পূর্ণ করতে হয় তা নিম্নলিখিত বিভাগে দেখানো হয়েছে।
পরিষেবা প্রদানকারী কোন কোন অপারেশন সাপোর্ট করে তা নির্ধারণ করুন
বিভিন্ন কন্টেন্ট প্রোভাইডার ডকুমেন্টের উপর বিভিন্ন অপারেশন করার অনুমতি দেয়—যেমন ডকুমেন্ট কপি করা বা ডকুমেন্টের থাম্বনেল দেখা। কোনও নির্দিষ্ট পরিষেবা প্রদানকারী কোন কোন অপারেশন সাপোর্ট করে তা নির্ধারণ করতে, Document.COLUMN_FLAGS-এর ভ্যালু চেক করুন।
আপনার অ্যাপের UI তখন শুধুমাত্র পরিষেবা প্রদানকারীর দ্বারা সমর্থিত বিকল্পগুলি দেখাতে পারে।
অনুমতি বজায় রাখুন
আপনার অ্যাপ কোনও ফাইল পড়া বা লেখার জন্য খুললে, সিস্টেম আপনার অ্যাপকে সেই ফাইলের জন্য URI অনুমতি দেয়, যা ব্যবহারকারীর ডিভাইস রিস্টার্ট না করা পর্যন্ত থাকে। তবে, ধরুন আপনার অ্যাপটি একটি ছবি এডিট করার অ্যাপ এবং আপনি চান ব্যবহারকারীরা যাতে সরাসরি আপনার অ্যাপ থেকে তাদের সবচেয়ে সম্প্রতি এডিট করা ৫টি ছবি অ্যাক্সেস করতে পারেন। ব্যবহারকারীর ডিভাইস রিস্টার্ট হলে, ফাইলগুলি খুঁজে পেতে আপনাকে ব্যবহারকারীকে সিস্টেম পিকারে ফেরত পাঠাতে হবে।
ডিভাইস রিস্টার্ট করার পরেও ফাইল অ্যাক্সেস করার সুবিধা বজায় রাখতে এবং আরও ভালো ব্যবহারকারীর অভিজ্ঞতা তৈরি করতে, আপনার অ্যাপ সিস্টেমের অফার করা পারসিস্টেবল URI অনুমতি "নিতে" পারে, যেমনটি নিম্নলিখিত কোড স্নিপেটে দেখানো হয়েছে:
Kotlin
val contentResolver = applicationContext.contentResolver val takeFlags: Int = Intent.FLAG_GRANT_READ_URI_PERMISSION or Intent.FLAG_GRANT_WRITE_URI_PERMISSION // Check for the freshest data. contentResolver.takePersistableUriPermission(uri, takeFlags)
জাভা
final int takeFlags = intent.getFlags() & (Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); // Check for the freshest data. getContentResolver().takePersistableUriPermission(uri, takeFlags);
ডকুমেন্ট মেটাডেটা পরীক্ষা করা
কোনও ডকুমেন্টের URI আপনার কাছে থাকলে, আপনি সেটির মেটাডেটা অ্যাক্সেস করতে পারবেন। এই স্নিপেট URI দ্বারা নির্দিষ্ট করা ডকুমেন্টের মেটাডেটা সংগ্রহ করে এবং এটি লগ করে:
Kotlin
val contentResolver = applicationContext.contentResolver fun dumpImageMetaData(uri: Uri) { // The query, because it only applies to a single document, returns only // one row. There's no need to filter, sort, or select fields, // because we want all fields for one document. val cursor: Cursor? = contentResolver.query( uri, null, null, null, null, null) cursor?.use { // moveToFirst() returns false if the cursor has 0 rows. Very handy for // "if there's anything to look at, look at it" conditionals. if (it.moveToFirst()) { // Note it's called "Display Name". This is // provider-specific, and might not necessarily be the file name. val displayName: String = it.getString(it.getColumnIndex(OpenableColumns.DISPLAY_NAME)) Log.i(TAG, "Display Name: $displayName") val sizeIndex: Int = it.getColumnIndex(OpenableColumns.SIZE) // If the size is unknown, the value stored is null. But because an // int can't be null, the behavior is implementation-specific, // and unpredictable. So as // a rule, check if it's null before assigning to an int. This will // happen often: The storage API allows for remote files, whose // size might not be locally known. val size: String = if (!it.isNull(sizeIndex)) { // Technically the column stores an int, but cursor.getString() // will do the conversion automatically. it.getString(sizeIndex) } else { "Unknown" } Log.i(TAG, "Size: $size") } } }
জাভা
public void dumpImageMetaData(Uri uri) { // The query, because it only applies to a single document, returns only // one row. There's no need to filter, sort, or select fields, // because we want all fields for one document. Cursor cursor = getActivity().getContentResolver() .query(uri, null, null, null, null, null); try { // moveToFirst() returns false if the cursor has 0 rows. Very handy for // "if there's anything to look at, look at it" conditionals. if (cursor != null && cursor.moveToFirst()) { // Note it's called "Display Name". This is // provider-specific, and might not necessarily be the file name. String displayName = cursor.getString( cursor.getColumnIndex(OpenableColumns.DISPLAY_NAME)); Log.i(TAG, "Display Name: " + displayName); int sizeIndex = cursor.getColumnIndex(OpenableColumns.SIZE); // If the size is unknown, the value stored is null. But because an // int can't be null, the behavior is implementation-specific, // and unpredictable. So as // a rule, check if it's null before assigning to an int. This will // happen often: The storage API allows for remote files, whose // size might not be locally known. String size = null; if (!cursor.isNull(sizeIndex)) { // Technically the column stores an int, but cursor.getString() // will do the conversion automatically. size = cursor.getString(sizeIndex); } else { size = "Unknown"; } Log.i(TAG, "Size: " + size); } } finally { cursor.close(); } }
ডকুমেন্ট খুলুন
ডকুমেন্টের URI-এর রেফারেন্স থাকলে, আপনি আরও প্রসেস করার জন্য ডকুমেন্ট খুলতে পারবেন। এই বিভাগে বিটম্যাপ ও ইনপুট স্ট্রিম খোলার উদাহরণ দেখানো হয়েছে।
Bitmap
নিম্নলিখিত কোড স্নিপেট থেকে বোঝা যায় যে URI দেওয়া থাকলে কীভাবে
Bitmap ফাইল খুলতে হয়:
Kotlin
val contentResolver = applicationContext.contentResolver @Throws(IOException::class) private fun getBitmapFromUri(uri: Uri): Bitmap { val parcelFileDescriptor: ParcelFileDescriptor = contentResolver.openFileDescriptor(uri, "r") val fileDescriptor: FileDescriptor = parcelFileDescriptor.fileDescriptor val image: Bitmap = BitmapFactory.decodeFileDescriptor(fileDescriptor) parcelFileDescriptor.close() return image }
জাভা
private Bitmap getBitmapFromUri(Uri uri) throws IOException { ParcelFileDescriptor parcelFileDescriptor = getContentResolver().openFileDescriptor(uri, "r"); FileDescriptor fileDescriptor = parcelFileDescriptor.getFileDescriptor(); Bitmap image = BitmapFactory.decodeFileDescriptor(fileDescriptor); parcelFileDescriptor.close(); return image; }
বিটম্যাপ খোলার পরে, আপনি এটি একটি
ImageView-এ দেখাতে পারবেন।
ইনপুট স্ট্রিম
নিম্নলিখিত কোড স্নিপেট থেকে জানা যায় যে URI দেওয়া থাকলে কীভাবে InputStream অবজেক্ট খুলতে হয়। এই স্নিপেটে, ফাইলের লাইনগুলি একটি স্ট্রিংয়ে পড়া হচ্ছে:
Kotlin
val contentResolver = applicationContext.contentResolver @Throws(IOException::class) private fun readTextFromUri(uri: Uri): String { val stringBuilder = StringBuilder() contentResolver.openInputStream(uri)?.use { inputStream -> BufferedReader(InputStreamReader(inputStream)).use { reader -> var line: String? = reader.readLine() while (line != null) { stringBuilder.append(line) line = reader.readLine() } } } return stringBuilder.toString() }
জাভা
private String readTextFromUri(Uri uri) throws IOException { StringBuilder stringBuilder = new StringBuilder(); try (InputStream inputStream = getContentResolver().openInputStream(uri); BufferedReader reader = new BufferedReader( new InputStreamReader(Objects.requireNonNull(inputStream)))) { String line; while ((line = reader.readLine()) != null) { stringBuilder.append(line); } } return stringBuilder.toString(); }
ডকুমেন্ট এডিট করুন
আপনি স্টোরেজ অ্যাক্সেস ফ্রেমওয়ার্ক ব্যবহার করে কোনও টেক্সট ডকুমেন্ট এডিট করতে পারবেন।
নিম্নলিখিত কোড স্নিপেট প্রদত্ত URI দ্বারা উপস্থাপিত ডকুমেন্টের কন্টেন্ট ওভাররাইট করে:
Kotlin
val contentResolver = applicationContext.contentResolver private fun alterDocument(uri: Uri) { try { contentResolver.openFileDescriptor(uri, "w")?.use { FileOutputStream(it.fileDescriptor).use { it.write( ("Overwritten at ${System.currentTimeMillis()}\n") .toByteArray() ) } } } catch (e: FileNotFoundException) { e.printStackTrace() } catch (e: IOException) { e.printStackTrace() } }
জাভা
private void alterDocument(Uri uri) { try { ParcelFileDescriptor pfd = getActivity().getContentResolver(). openFileDescriptor(uri, "w"); FileOutputStream fileOutputStream = new FileOutputStream(pfd.getFileDescriptor()); fileOutputStream.write(("Overwritten at " + System.currentTimeMillis() + "\n").getBytes()); // Let the document provider know you're done by closing the stream. fileOutputStream.close(); pfd.close(); } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } }
ডকুমেন্ট মুছে দাও
আপনার কাছে কোনও ডকুমেন্টের URI থাকলে এবং ডকুমেন্টের
Document.COLUMN_FLAGS
-এ
SUPPORTS_DELETE
থাকলে,
আপনি ডকুমেন্টটি মুছে ফেলতে পারবেন। যেমন:
Kotlin
DocumentsContract.deleteDocument(applicationContext.contentResolver, uri)
জাভা
DocumentsContract.deleteDocument(applicationContext.contentResolver, uri);
একই ধরনের মিডিয়া URI ফিরিয়ে আনা
getMediaUri()
পদ্ধতিটি একটি মিডিয়া স্টোর URI প্রদান করে যা প্রদত্ত ডকুমেন্টের সমতুল্য
প্রদানকারী URI. ২টি URI একই আইটেমকে রেফার করে। মিডিয়া স্টোর URI ব্যবহার করে, আপনি আরও সহজে শেয়ার করা স্টোরেজ থেকে মিডিয়া ফাইল অ্যাক্সেস করতে পারবেন।
getMediaUri() পদ্ধতিতে ExternalStorageProvider URI কাজ করে। Android ১২ (API লেভেল ৩১) এবং তার পরবর্তী ভার্সনে, এই পদ্ধতি
MediaDocumentsProvider URI-কেও সাপোর্ট করে।
ভার্চুয়াল ফাইল খোলা
Android 7.0 (API লেভেল ২৫) এবং তার পরবর্তী যেকোনও ভার্সনে, আপনার অ্যাপ ভার্চুয়াল ফাইল ব্যবহার করতে পারে
যা Storage Access Framework উপলভ্য করে। ভার্চুয়াল ফাইলের বাইনারি রিপ্রেজেন্টেশন না থাকলেও, আপনার অ্যাপ অন্য ফাইলের ধরন হিসেবে সেগুলিকে জোর করে বা ACTION_VIEW ইনটেন্ট অ্যাকশন ব্যবহার করে সেইসব ফাইল দেখার মাধ্যমে সেগুলির কন্টেন্ট খুলতে পারে।
ভার্চুয়াল ফাইল খুলতে, আপনার ক্লায়েন্ট অ্যাপে সেগুলি ম্যানেজ করার জন্য বিশেষ লজিক অন্তর্ভুক্ত করতে হবে। আপনি যদি ফাইলের বাইট রিপ্রেজেন্টেশন পেতে চান—উদাহরণস্বরূপ, ফাইলের প্রিভিউ দেখতে—তাহলে আপনাকে ডকুমেন্ট প্রদানকারীর কাছ থেকে একটি বিকল্প MIME-এর প্রকারের জন্য অনুরোধ করতে হবে।
ব্যবহারকারী বেছে নেওয়ার পরে, ফাইলটি ভার্চুয়াল কিনা তা নির্ধারণ করতে ফলাফল ডেটাতে URI ব্যবহার করুন, যেমনটি নিম্নলিখিত কোড স্নিপেটে দেখানো হয়েছে:
Kotlin
private fun isVirtualFile(uri: Uri): Boolean { if (!DocumentsContract.isDocumentUri(this, uri)) { return false } val cursor: Cursor? = contentResolver.query( uri, arrayOf(DocumentsContract.Document.COLUMN_FLAGS), null, null, null ) val flags: Int = cursor?.use { if (cursor.moveToFirst()) { cursor.getInt(0) } else { 0 } } ?: 0 return flags and DocumentsContract.Document.FLAG_VIRTUAL_DOCUMENT != 0 }
জাভা
private boolean isVirtualFile(Uri uri) { if (!DocumentsContract.isDocumentUri(this, uri)) { return false; } Cursor cursor = getContentResolver().query( uri, new String[] { DocumentsContract.Document.COLUMN_FLAGS }, null, null, null); int flags = 0; if (cursor.moveToFirst()) { flags = cursor.getInt(0); } cursor.close(); return (flags & DocumentsContract.Document.FLAG_VIRTUAL_DOCUMENT) != 0; }
ডকুমেন্টটি ভার্চুয়াল ফাইল কিনা তা যাচাই করার পরে, আপনি ফাইলটিকে বিকল্প MIME টাইপে
পরিবর্তন করতে পারবেন, যেমন "image/png"। নিম্নলিখিত কোড
স্নিপেট দেখায় যে কীভাবে চেক করতে হয় যে ভার্চুয়াল ফাইলকে ছবি হিসেবে
দেখানো যাবে কিনা এবং যদি যায়, তাহলে ভার্চুয়াল ফাইল থেকে ইনপুট স্ট্রিম পায়:
Kotlin
@Throws(IOException::class) private fun getInputStreamForVirtualFile( uri: Uri, mimeTypeFilter: String): InputStream { val openableMimeTypes: Array<String>? = contentResolver.getStreamTypes(uri, mimeTypeFilter) return if (openableMimeTypes?.isNotEmpty() == true) { contentResolver .openTypedAssetFileDescriptor(uri, openableMimeTypes[0], null) .createInputStream() } else { throw FileNotFoundException() } }
জাভা
private InputStream getInputStreamForVirtualFile(Uri uri, String mimeTypeFilter) throws IOException { ContentResolver resolver = getContentResolver(); String[] openableMimeTypes = resolver.getStreamTypes(uri, mimeTypeFilter); if (openableMimeTypes == null || openableMimeTypes.length < 1) { throw new FileNotFoundException(); } return resolver .openTypedAssetFileDescriptor(uri, openableMimeTypes[0], null) .createInputStream(); }
অতিরিক্ত রিসোর্স
ডকুমেন্ট ও অন্যান্য ফাইল কীভাবে স্টোর ও অ্যাক্সেস করবেন সেই সম্পর্কে আরও জানতে, নিম্নলিখিত রিসোর্স দেখুন।
নমুনা
- ActionOpenDocument, GitHub-এ উপলভ্য।
- ActionOpenDocumentTree, GitHub-এ উপলভ্য।