डिवाइस के शेयर किए गए स्टोरेज से दस्तावेज़ और अन्य फ़ाइलें ऐक्सेस करना

Android 4.4 (एपीआई लेवल 19) और उसके बाद के वर्शन वाले डिवाइसों पर, आपका ऐप्लिकेशन इंटरैक्ट कर सकता है दस्तावेज़ों की सेवा देने वाली कंपनी के साथ मिलकर, जैसे, बाहरी स्टोरेज और क्लाउड-आधारित स्टोरेज. फ़्रेमवर्क को ऐक्सेस करें. इस फ़्रेमवर्क की मदद से उपयोगकर्ता, सिस्टम पिकर से इंटरैक्ट कर सकते हैं के लिए, Google Play पर बनाने, खोलने या उसमें बदलाव करने के लिए, अपने ऐप्लिकेशन को इस्तेमाल करें.

क्योंकि उपयोगकर्ता उन फ़ाइलों या डायरेक्ट्री को चुनता है जिन्हें आपका ऐप्लिकेशन इस्तेमाल करता है ऐक्सेस कर सकता है, इस मैकेनिज़्म के लिए किसी सिस्टम की आवश्यकता नहीं होती अनुमतियां, और उपयोगकर्ता के कंट्रोल और निजता ऐक्सेस करने की सुविधा मिलती है को बेहतर बनाया गया है. इसके अतिरिक्त, ये फ़ाइलें, जो एक किसी खास ऐप्लिकेशन के लिए बनी डायरेक्ट्री और मीडिया स्टोर के बाहर, डिवाइस में बनी रहती है आपका ऐप्लिकेशन अनइंस्टॉल हो जाएगा.

इस फ़्रेमवर्क का इस्तेमाल करने के लिए, ये चरण पूरे करें:

  1. कोई ऐप्लिकेशन ऐसे इंटेंट को शुरू करता है जिसमें स्टोरेज से जुड़ी कार्रवाई शामिल है. यह कार्रवाई इस्तेमाल के किसी खास उदाहरण के बारे में बताता है, जिसे फ़्रेमवर्क उपलब्ध हैं.
  2. उपयोगकर्ता को सिस्टम पिकर दिखता है, जिसकी मदद से वे दस्तावेज़ उपलब्ध कराने वाली सेवा को ब्राउज़ कर सकते हैं और वह जगह या दस्तावेज़ चुनें जहां स्टोरेज से जुड़ी कार्रवाई की गई है.
  3. ऐप्लिकेशन, ऐसे यूआरआई को पढ़ने और लिखने का ऐक्सेस देता है जो उपयोगकर्ता की चुनी गई जगह या दस्तावेज़. इस यूआरआई का इस्तेमाल करके, ऐप्लिकेशन इस पर काम कर सकता है: चुनी गई जगह पर क्लिक करें.

Android 9 (एपीआई लेवल 28) पर चलने वाले डिवाइसों पर मीडिया फ़ाइल का ऐक्सेस देने के लिए या कम है, तो READ_EXTERNAL_STORAGE अनुमति दें और maxSdkVersion को 28 पर सेट करें.

इस गाइड में, इस्तेमाल के उन अलग-अलग उदाहरणों के बारे में बताया गया है जिनके साथ यह फ़्रेमवर्क काम करता है फ़ाइलों और अन्य दस्तावेज़ों पर काम करता है. इसमें यह भी बताया गया है कि परफ़ॉर्मेंस मैक्स कैंपेन कार्रवाइयां करता है.

दस्तावेज़ और अन्य फ़ाइलें ऐक्सेस करने के लिए, इस्तेमाल के उदाहरण

स्टोरेज के ऐक्सेस का फ़्रेमवर्क फ़ाइलें और अन्य दस्तावेज़.

नई फ़ाइल बनाना
इस ACTION_CREATE_DOCUMENT इंटेंट कार्रवाई की मदद से, उपयोगकर्ता किसी खास जगह पर फ़ाइल सेव कर सकते हैं.
कोई दस्तावेज़ या फ़ाइल खोलना
इस ACTION_OPEN_DOCUMENT इंटेंट कार्रवाई की मदद से उपयोगकर्ता, खोलने के लिए कोई खास दस्तावेज़ या फ़ाइल चुन सकते हैं.
किसी डायरेक्ट्री के कॉन्टेंट का ऐक्सेस देना
इस ACTION_OPEN_DOCUMENT_TREE Android 5.0 (एपीआई लेवल 21) और उसके बाद के वर्शन पर उपलब्ध इंटेंट कार्रवाई से, उपयोगकर्ता कोई खास डायरेक्ट्री चुनने के लिए, अपने ऐप्लिकेशन को सभी फ़ाइलों का ऐक्सेस दें और सब-डायरेक्ट्री शामिल होंगी.

नीचे दिए गए सेक्शन में, इस्तेमाल के हर उदाहरण को कॉन्फ़िगर करने के तरीके के बारे में बताया गया है.

एक नई फ़ाइल बनाएं

इसका इस्तेमाल करें ACTION_CREATE_DOCUMENT इंटेंट कार्रवाई: सिस्टम फ़ाइल पिकर लोड करें और उपयोगकर्ता को फ़ाइल की सामग्री लिखने की जगह. यह प्रोसेस, इसे "इस रूप में सेव करें" में इस्तेमाल किया गया हो ऐसे डायलॉग जिनका इस्तेमाल दूसरे ऑपरेटिंग सिस्टम करते हैं.

ध्यान दें: ACTION_CREATE_DOCUMENT किसी मौजूदा फ़ाइल है. अगर आपका ऐप्लिकेशन उसी नाम से किसी फ़ाइल को सेव करने की कोशिश करता है, तो सिस्टम फ़ाइल के नाम के आखिर में ब्रैकेट में एक संख्या जोड़ता है.

उदाहरण के लिए, अगर आपका ऐप्लिकेशन confirmation.pdf उस डायरेक्ट्री में है जिसमें उस फ़ाइल के साथ पहले से ही एक फ़ाइल मौजूद है नाम है, तो सिस्टम नई फ़ाइल को confirmation(1).pdf.

इंटेंट कॉन्फ़िगर करते समय, फ़ाइल का नाम और MIME टाइप तय करें. उस फ़ाइल या डायरेक्ट्री का यूआरआई बताएं जिसे फ़ाइल पिकर को डिफ़ॉल्ट रूप से लोड होने वाले पैरामीटर का उपयोग करके 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)
}

Java

// 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 टाइप तय करें. साथ ही, आपके पास यह विकल्प भी है उस फ़ाइल का यूआरआई बताएं जिसे फ़ाइल पिकर को पहली बार दिखाने पर लोड करने के लिए EXTRA_INITIAL_URI एक से ज़्यादा इंटेंट पर क्लिक करें.

नीचे दिया गया कोड स्निपेट, वेबसाइट खोलने के लिए इंटेंट बनाने और शुरू करने का तरीका बताता है PDF दस्तावेज़:

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

Java

// 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 (एपीआई लेवल 30) और उसके बाद के वर्शन पर, उपयोगकर्ता से किसी व्यक्ति को चुनने का अनुरोध करने के लिए ACTION_OPEN_DOCUMENT इंटेंट कार्रवाई निम्नलिखित डायरेक्ट्री से फ़ाइलें शामिल करें:

  • Android/data/ डायरेक्ट्री और सभी सबडायरेक्ट्री.
  • Android/obb/ डायरेक्ट्री और सभी सबडायरेक्ट्री.

किसी डायरेक्ट्री के कॉन्टेंट का ऐक्सेस दें

फ़ाइल मैनेजमेंट और मीडिया बनाने वाले ऐप्लिकेशन, आम तौर पर डायरेक्ट्री हैरारकी. अपने ऐप्लिकेशन में यह सुविधा उपलब्ध कराने के लिए, इनका इस्तेमाल करें: ACTION_OPEN_DOCUMENT_TREE इंटेंट कार्रवाई, जो उपयोगकर्ता को पूरी डायरेक्ट्री का ऐक्सेस देने की अनुमति देती है ट्री, जिसमें कुछ अपवाद Android 11 (एपीआई लेवल 30) से शुरू होते हैं. आपका ऐप्लिकेशन ये काम कर सकता है फिर चुनी गई डायरेक्ट्री और उसकी किसी भी सब-डायरेक्ट्री में मौजूद कोई भी फ़ाइल ऐक्सेस करें.

ACTION_OPEN_DOCUMENT_TREE का इस्तेमाल करने पर, आपका ऐप्लिकेशन सिर्फ़ उन डायरेक्ट्री में मौजूद फ़ाइलें शामिल होती हैं जिन्हें उपयोगकर्ता चुनता है. आपके पास अन्य सेवाओं का ऐक्सेस नहीं है ऐप्लिकेशन ऐसी फ़ाइलें जो उपयोगकर्ता की चुनी गई डायरेक्ट्री के बाहर मौजूद हैं. यह उपयोगकर्ता के हिसाब से ऐक्सेस किए जाने वाले ऐक्सेस की मदद से, उपयोगकर्ता यह चुन सकते हैं कि उन्हें किस तरह का कॉन्टेंट दिखाना है आपके ऐप्लिकेशन के साथ आसानी से शेयर किया जा सकता है.

इसके अलावा, आपके पास उस डायरेक्ट्री का यूआरआई तय करने का भी विकल्प है जिसे फ़ाइल पिकर को डिफ़ॉल्ट रूप से लोड होने वाले पैरामीटर का उपयोग करके 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)
}

Java

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 (एपीआई लेवल 30) और उसके बाद के वर्शन पर, इनके ऐक्सेस का अनुरोध करने के लिए ACTION_OPEN_DOCUMENT_TREE इंटेंट कार्रवाई डायरेक्ट्री:

  • डिवाइस के स्टोरेज की संख्या की रूट डायरेक्ट्री.
  • हर उस एसडी कार्ड वॉल्यूम की रूट डायरेक्ट्री जिसे डिवाइस मैन्युफ़ैक्चरर ने बनाया है उसे भरोसेमंद माना जाता है, भले ही कार्ड एम्युलेट किया गया हो या हटाए जा सकते हैं. भरोसेमंद वॉल्यूम उसे कहते हैं जिसे कोई ऐप्लिकेशन ज़्यादातर ऐक्सेस कर सकता है समय.
  • Download डायरेक्ट्री.

इसके अलावा, Android 11 (एपीआई लेवल 30) और उसके बाद के वर्शन पर, उपयोगकर्ता के चुने गए अनुरोध के लिए ACTION_OPEN_DOCUMENT_TREE इंटेंट कार्रवाई नीचे दी गई डायरेक्ट्री से अलग-अलग फ़ाइलें:

  • Android/data/ डायरेक्ट्री और सभी सबडायरेक्ट्री.
  • Android/obb/ डायरेक्ट्री और सभी सबडायरेक्ट्री.

चुनी गई जगह पर कार्रवाइयां करें

जब उपयोगकर्ता सिस्टम के फ़ाइल पिकर का इस्तेमाल करके कोई फ़ाइल या डायरेक्ट्री चुन लेता है, तो आप onActivityResult():

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

Java

@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.
        }
    }
}

चुने गए आइटम के यूआरआई का रेफ़रंस मिलने पर, आपका ऐप्लिकेशन कई कार्रवाइयां कर सकता है कार्रवाइयों के लिए इस्तेमाल किया जा सकता है. उदाहरण के लिए, आप आइटम के मेटाडेटा को ऐक्सेस कर सकते हैं, बदलाव कर सकते हैं और आइटम को हटा दें.

नीचे दिए सेक्शन में, उन फ़ाइलों पर कार्रवाइयां करने का तरीका बताया गया है जिन्हें उपयोगकर्ता ने चुनता है.

उन कार्रवाइयों का पता लगाना जो सेवा देने वाली कंपनी के साथ काम करती हैं

अलग-अलग कॉन्टेंट देने वाले लोग अलग-अलग कार्रवाइयां करने की अनुमति देते हैं दस्तावेज़—जैसे कि दस्तावेज़ को कॉपी करना या किसी दस्तावेज़ का थंबनेल देखना. यहां की यात्रा पर हूं पता करें कि कोई सेवा देने वाली कंपनी किन कार्रवाइयों को सपोर्ट करती है. Document.COLUMN_FLAGS. इसके बाद, आपके ऐप्लिकेशन का यूज़र इंटरफ़ेस (यूआई) सिर्फ़ वे विकल्प दिखा सकता है जो सेवा देने वाली कंपनी के साथ काम करते हैं.

अनुमतियां लागू रखें

जब आपका ऐप्लिकेशन पढ़ने या लिखने के लिए कोई फ़ाइल खोलता है, तो सिस्टम उस फ़ाइल के लिए यूआरआई की अनुमति की अनुमति, जो उपयोगकर्ता के डिवाइस तक लागू रहती है रीस्टार्ट हो जाता है. हालांकि, मान लें कि आपका ऐप्लिकेशन एक इमेज-एडिटिंग ऐप्लिकेशन है और आपको उपयोगकर्ता उन पांच इमेज को सीधे ऐक्सेस कर सकते हैं जिनमें उन्होंने हाल ही में बदलाव किया है आपके ऐप्लिकेशन से. अगर उपयोगकर्ता का डिवाइस रीस्टार्ट हो गया है, तो आपको उपयोगकर्ता को फ़ाइलें ढूंढने के लिए, सिस्टम पिकर पर वापस जाएं.

सभी डिवाइस पर फ़ाइल का ऐक्सेस बनाए रखने के लिए, रीस्टार्ट करें और बेहतर उपयोगकर्ता बनाएं अनुभव है, तो आपका ऐप "ले" सकता है स्थायी यूआरआई की अनुमति से यह तय होता है कि सिस्टम ऑफ़र, जैसा कि नीचे दिए गए कोड स्निपेट में दिखाया गया है:

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)

Java

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

दस्तावेज़ के मेटाडेटा की जांच करना

जब आपके पास किसी दस्तावेज़ का यूआरआई होता है, तो आपको इसके मेटाडेटा का ऐक्सेस मिलता है. यह स्निपेट, यूआरआई के ज़रिए तय किए गए दस्तावेज़ के लिए मेटाडेटा इकट्ठा करके उसे लॉग करता है:

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")
        }
    }
}

Java

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

दस्तावेज़ खोलना

किसी दस्तावेज़ के यूआरआई का रेफ़रंस देकर, आप आगे के लिए दस्तावेज़ खोल सकते हैं प्रोसेस चल रही है. यह सेक्शन बिटमैप और इनपुट खोलने के उदाहरण दिखाता है स्ट्रीम.

बिट मैप

नीचे दिया गया कोड स्निपेट 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
}

Java

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.

इनपुट स्ट्रीम

नीचे दिया गया कोड स्निपेट यह दिखाता है कि किसी 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()
}

Java

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

दस्तावेज़ में बदलाव करना

टेक्स्ट दस्तावेज़ में बदलाव करने के लिए, स्टोरेज ऐक्सेस फ़्रेमवर्क का इस्तेमाल किया जा सकता है.

नीचे दिया गया कोड स्निपेट, बताए गए दस्तावेज़ के कॉन्टेंट को ओवरराइट कर देता है दिए गए यूआरआई से:

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()
    }
}

Java

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

दस्तावेज़ मिटाना

अगर आपके पास किसी दस्तावेज़ का यूआरआई है और Document.COLUMN_FLAGS यह होनी चाहिए SUPPORTS_DELETE, तो उस दस्तावेज़ को मिटाया जा सकता है. उदाहरण के लिए:

Kotlin

DocumentsContract.deleteDocument(applicationContext.contentResolver, uri)

Java

DocumentsContract.deleteDocument(applicationContext.contentResolver, uri);

मिलता-जुलता मीडिया यूआरआई वापस पाएं

कॉन्टेंट बनाने getMediaUri() तरीका, मीडिया स्टोर यूआरआई देता है, जो दिए गए दस्तावेज़ों के बराबर होता है प्रोवाइडर यूआरआई. दो यूआरआई, एक ही मौजूदा आइटम को दिखाते हैं. मीडिया का इस्तेमाल करना स्टोर यूआरआई, शेयर किए गए फ़ोल्डर से मीडिया फ़ाइलें ऐक्सेस करना डिवाइस की मेमोरी पर टैप करें.

getMediaUri() तरीके में, ExternalStorageProvider यूआरआई का इस्तेमाल किया जा सकता है. चालू है यह तरीका Android 12 (एपीआई लेवल 31) और उसके बाद वाले वर्शन के लिए उपलब्ध है. MediaDocumentsProvider यूआरआई.

वर्चुअल फ़ाइल खोलें

Android 7.0 (एपीआई लेवल 25) और इसके बाद के वर्शन पर, आपका ऐप्लिकेशन वर्चुअल फ़ाइलों का इस्तेमाल कर सकता है जिसे स्टोरेज ऐक्सेस फ़्रेमवर्क उपलब्ध कराता है. वर्चुअल फ़ाइलें होने के बावजूद इसमें बाइनरी रिप्रज़ेंटेशन नहीं है, इसलिए आपका ऐप्लिकेशन किसी दूसरे फ़ाइल टाइप में या उन फ़ाइलों को ACTION_VIEW इंटेंट कार्रवाई.

वर्चुअल फ़ाइलें खोलने के लिए, आपके क्लाइंट ऐप्लिकेशन को खास लॉजिक शामिल करना होगा, ताकि उन्हें. अगर आपको फ़ाइल की झलक देखने के लिए, फ़ाइल को बाइट के रूप में दिखाना है, उदाहरण के लिए—आपको दस्तावेज़ों से किसी दूसरे MIME टाइप का अनुरोध करना होगा कंपनी.

जब उपयोगकर्ता कोई विकल्प चुन लेता है, तो तय करने के लिए नतीजों के डेटा में यूआरआई का इस्तेमाल करें क्या फ़ाइल वर्चुअल है, जैसा कि इस कोड स्निपेट में दिखाया गया है:

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
}

Java

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()
    }
}

Java

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

अन्य संसाधन

दस्तावेज़ों और अन्य फ़ाइलों को सेव और ऐक्सेस करने के बारे में ज़्यादा जानने के लिए, यहां दिए गए संसाधनों की मदद लें.

सैंपल

वीडियो