Paylaşılan depolama alanındaki dokümanlara ve diğer dosyalara erişme

Android 4.4 (API düzeyi 19) ve sonraki sürümleri çalıştıran cihazlarda uygulamanız etkileşimde bulunabilir bir doküman sağlayıcı ile ve bulut tabanlı depolama da dahil olmak üzere depolama alanı Erişim Çerçevesi. Bu çerçeve, kullanıcıların sistem seçiciyle etkileşime girmesine olanak tanır seçmek için doküman sağlayıcı seçin ve ek dokümanlar ile diğer dosyaları seçin oluşturmak, açmak veya değiştirmek için uygulamanızı kullanabilirsiniz.

Çünkü kullanıcı, uygulamanızın indireceği dosyaları veya dizinleri bu mekanizmanın çalışması için herhangi bir sistem izinleri ve kullanıcı denetimi ve gizliliği geliştirilmiştir. Ayrıca, uygulamaya özgü bir dizin ve medya mağazasının dışındaki bir dizin takip etmeniz gerekir.

Çerçeveyi kullanmak için şu adımları izlemeniz gerekir:

  1. Uygulama, depolama alanıyla ilgili işlem içeren bir intent çağırıyor. Bu işlem belirli bir kullanım alanına karşılık gelir kullanılabilir.
  2. Kullanıcı, doküman sağlayıcısına göz atmasına olanak tanıyan bir sistem seçici görür. ve depolamayla ilgili işlemin gerçekleştirileceği konumu veya dokümanı seçin.
  3. Uygulama, kullanıcının kimliğini temsil eden bir URI'ye okuma ve yazma erişimi kazanır. seçilen konumu veya dokümanı gösterir. Uygulama, bu URI kullanılarak şurada işlemler gerçekleştirebilir: konum açılır.
ziyaret edin.

Android 9 (API düzeyi 28) yüklü cihazlarda medya dosyası erişimini desteklemek için veya düşük olduğunda READ_EXTERNAL_STORAGE izninin ardından maxSdkVersion öğesini 28 olarak ayarlayın.

Bu kılavuzda, çerçevenin dosyalar ve diğer dokümanlarla çalışmayı öğreneceğiz. Ayrıca projenin başarısını garantilemek için kullanıcı tarafından seçilen konumdaki işlemleri içerir.

Dokümanlara ve diğer dosyalara erişmek için kullanım alanları

Depolama Erişim Çerçevesi, veri erişimiyle ilgili aşağıdaki kullanım alanlarını destekler dosyalar ve diğer dokümanlar için de geçerlidir.

Yeni dosya oluşturma
ACTION_CREATE_DOCUMENT intent işlemi, kullanıcıların bir dosyayı belirli bir konuma kaydetmesine olanak tanır.
Doküman veya dosya açma
ACTION_OPEN_DOCUMENT intent işlemi, kullanıcıların açmak için belirli bir doküman veya dosya seçmesine olanak tanır.
Dizin içeriğine erişim izni verme
ACTION_OPEN_DOCUMENT_TREE Android 5.0 (API düzeyi 21) ve sonraki sürümlerde kullanılabilen intent işlemi belirli bir dizini seçebilir, böylece uygulamanızın tüm dosyalara ve alt dizinlerinin altında bulunabilir.

Aşağıdaki bölümlerde, her bir kullanım alanının nasıl yapılandırılacağına ilişkin yol gösterici bilgiler sağlanmaktadır.

Yeni dosya oluşturma

Şunu kullanın: ACTION_CREATE_DOCUMENT intent işlemi (ör. sistem dosya seçiciyi yüklemek ve kullanıcının dosya içeriğinin yazılacağı konumdur. Bu süreç, "farklı kaydet" seçeneğinde kullanılan iletişim kutuları oluşturur.

Not: ACTION_CREATE_DOCUMENT, olabilir. Uygulamanız aynı adla dosya kaydetmeye çalışırsa sistem dosya adının sonuna parantez içinde bir sayı ekler.

Örneğin, uygulamanız confirmation.pdf dosyasını içeren bu dosya zaten mevcut olan bir dizinde adını kullandığınızda, sistem yeni dosyayı confirmation(1).pdf.

Amacı yapılandırırken dosyanın adını ve MIME türünü belirtin ve isteğe bağlı olarak, dosya seçicinin eklemesi gereken dosyanın veya dizinin URI'sını belirtin ilk yüklendiğinde EXTRA_INITIAL_URI düşünmelisiniz.

Aşağıdaki kod snippet'i, dosya oluşturma:

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

Dosya aç

Uygulamanız, kullanıcıların veri girdiği depolama birimi olarak dokümanları kullanabilir paylaşmak veya başka dokümanlara aktarmak isteyebilirler. Birkaç Buna örnek olarak bir kullanıcının bir verimlilik dokümanı veya EPUB dosyası olarak kaydedilir.

Bu gibi durumlarda, kullanıcının ACTION_OPEN_DOCUMENT sistemin dosya seçici uygulamasını açar. Yalnızca bir MIME türü belirtin. Ayrıca isteğe bağlı olarak dosya seçicinin, ilk açtığınızda görüntülemesi gereken dosyanın URI'sini belirtin şunu kullanarak yüklenir: EXTRA_INITIAL_URI düşünmelisiniz.

Aşağıdaki kod snippet'i, PDF dokümanı:

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

Erişim kısıtlamaları

Android 11 (API düzeyi 30) ve sonraki sürümlerde Kullanıcının bireysel seçmesini istemek için ACTION_OPEN_DOCUMENT intent işlemi şu dizinlerden istediğiniz dosyaları seçin:

  • Android/data/ dizini ve tüm alt dizinler.
  • Android/obb/ dizini ve tüm alt dizinler.

Dizin içeriğine erişim izni verme

Dosya yönetimi ve medya oluşturma uygulamaları genellikle dizin hiyerarşisini inceleyin. Uygulamanızda bu özelliği sağlamak için ACTION_OPEN_DOCUMENT_TREE kullanıcının bir dizinin tamamına erişim izni vermesini sağlayan intent işlemi ağacında, Android 11'den (API düzeyi 30) itibaren bazı istisnalar yaşar. Uygulamanız şunları yapabilir: ardından seçilen dizindeki ve bu dizinlerin herhangi bir alt dizinindeki herhangi bir dosyaya erişin.

ACTION_OPEN_DOCUMENT_TREE kullanılırken, uygulamanız yalnızca kullanıcının seçtiği dizindeki dosyalar. Diğer uygulamaların bu kullanıcı tarafından seçilen dizinin dışında bulunan dosyalar. Bu Kullanıcı tarafından kontrol edilen erişim, kullanıcıların tam olarak ne tür içerikleri seçeceklerini seçmelerine olanak tanır. rahat bir şekilde paylaşabilmenizi sağlar.

İsteğe bağlı olarak, dosya seçicinin dizine eklemesi gereken dizinin URI'sını belirtebilirsiniz. ilk yüklendiğinde EXTRA_INITIAL_URI düşünmelisiniz.

Aşağıdaki kod snippet'i, dizin:

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

Erişim kısıtlamaları

Android 11 (API düzeyi 30) ve sonraki sürümlerde Aşağıdakilere erişim istemek için ACTION_OPEN_DOCUMENT_TREE intent işlemi dizinler:

  • Dahili depolama biriminin kök dizini.
  • Cihaz üreticisinin belirlediği her SD kart biriminin kök dizini Kartın emülasyonu veya kullanımı olup olmadığına bakılmaksızın güvenilir kabul edilir. çıkarılabilir. Bir uygulamanın çoğuna başarıyla erişebileceği hacim, güvenilir birimdir. pek karşılaşılan bir durum değil.
  • Download dizini.

Ayrıca, Android 11 (API düzeyi 30) ve sonraki sürümlerde Kullanıcının seçmesini istemek için ACTION_OPEN_DOCUMENT_TREE intent işlemi aşağıdaki dizinlerden ayrı ayrı dosyalar oluşturabilirsiniz:

  • Android/data/ dizini ve tüm alt dizinler.
  • Android/obb/ dizini ve tüm alt dizinler.

Seçilen konumda işlemler gerçekleştirin

Kullanıcı, sistemin dosya seçiciyi kullanarak bir dosya veya dizin seçtikten sonra, aşağıdaki kodu kullanarak seçilen öğenin URI'sini alabilirsiniz: 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.
        }
    }
}

Uygulamanız, seçilen öğenin URI'sına başvurarak birkaç işlem yapabilir işlemleri gerçekleştirmelerini sağlar. Örneğin, öğenin meta verilerine erişebilir, ardından öğeyi silebilirsiniz.

Aşağıdaki bölümlerde kullanıcının seçiyor.

Bir sağlayıcının desteklediği işlemleri belirleme

Farklı içerik sağlayıcılar, farklı işlemlerin doküman kopyalama veya dokümanın küçük resmini görüntüleme gibi yöntemlerle ilgili dokümanları oynayabilirsiniz. Alıcı: belirli bir sağlayıcının hangi işlemleri desteklediğini belirlemek için, Document.COLUMN_FLAGS. Bu işlemin ardından uygulamanızın kullanıcı arayüzü yalnızca sağlayıcının desteklediği seçenekleri gösterebilir.

İzinleri sürdür

Uygulamanız okumak veya yazmak üzere bir dosya açtığında sistem, Söz konusu dosya için URI izni verme (kullanıcının cihazı gelene kadar geçerlidir) yeniden başlatılır. Ancak, uygulamanızın bir resim düzenleme uygulaması olduğunu ve kullanıcıların en son düzenledikleri 5 resme doğrudan erişmesini sağlayarak nasıl sağlayabileceğini de öğreneceksiniz. Kullanıcının cihazı yeniden başlatıldıysa kullanıcıya sistem seçiciye dönüp dosyaları bulun.

Cihaz yeniden başlatıldığında dosyalara erişimi korumak ve daha iyi bir kullanıcı oluşturmak için uygulamanız gereken kalıcı URI izni sağlar. aşağıdaki kod snippet'inde gösterildiği gibi sistem tekliflerini etkinleştirecektir:

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

Belge meta verilerini inceleme

Bir dokümanın URI'sına sahip olduğunuzda, dokümanın meta verilerine erişim sağlarsınız. Bu snippet, URI tarafından belirtilen bir dokümana ait meta verileri alır ve bunu günlüğe kaydeder:

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

Doküman açma

Bir dokümanın URI'sına başvurarak daha ayrıntılı bilgi edinmek için bahsedeceğim. Bu bölümde bit eşlem ve giriş açma örnekleri gösterilmektedir akış şeklinde gösterilir.

Bit eşlem

Aşağıdaki kod snippet'i, Bitmap dosyasına verilen URI:

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

Bit eşlemi açtıktan sonra, bir ImageView.

Akış girişi

Aşağıdaki kod snippet'i, URI. Bu snippet'te, dosya satırları bir dizeye okunmaktadır:

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

Doküman düzenleme

Yerinde metin dokümanını düzenlemek için Depolama Erişim Çerçevesi'ni kullanabilirsiniz.

Aşağıdaki kod snippet'i, gösterilen doküman içeriğinin üzerine yazar belirtilen URI ile:

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

Doküman silme

Bir dokümanın URI'sına sahipseniz ve dokümanın Document.COLUMN_FLAGS içerir SUPPORTS_DELETE, dokümanı silebilirsiniz. Örnek:

Kotlin

DocumentsContract.deleteDocument(applicationContext.contentResolver, uri)

Java

DocumentsContract.deleteDocument(applicationContext.contentResolver, uri);

Eşdeğer bir medya URI'si al

İlgili içeriği oluşturmak için kullanılan getMediaUri() yöntemi, belirtilen belgelere eşdeğer bir medya mağazası URI'si sağlar sağlayıcı URI'si. 2 URI, aynı temel öğeye işaret eder. Medyayı kullanma Böylece, paylaşılan medya dosyalarına daha kolay bir şekilde depolama alanı.

getMediaUri() yöntemi ExternalStorageProvider URI'ları destekler. Şu tarihte: Android 12 (API düzeyi 31) ve sonraki sürümlere sahip yöntem, aşağıdaki sürümleri de destekler: MediaDocumentsProvider URI.

Sanal dosya açın

Uygulamanız, Android 7.0 (API düzeyi 25) ve sonraki sürümlerde sanal dosyaları kullanabilir depolama alanı erişim çerçevesinin kullanılabilir hale getirdiğini doğrulayın. Sanal dosyalar olsa bile uygulamanız ikili gösterimi yoksa bu tür öğelerin içeriğini farklı bir dosya türü oluşturabilir veya bu dosyaları ACTION_VIEW amacı eyleme dökülebilir.

Sanal dosyaları açmak için istemci uygulamanızın, işlenecek özel bir mantık içermesi gerekir. gerekir. Dosyanın bayt cinsinden gösterimini elde etmek için dosyayı önizlemek üzere örneğin, dokümanlardan alternatif bir MIME türü istemeniz gerekiyorsa sağlar.

Kullanıcı bir seçim yaptıktan sonra, aşağıdaki kod snippet'inde gösterildiği gibi dosyanın sanal olup olmadığını belirtin:

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

Dokümanın sanal bir dosya olduğunu doğruladıktan sonra dosyasını "image/png" gibi alternatif bir MIME türüne dönüştürür. Aşağıdaki kod snippet, sanal bir dosyanın dosya olarak temsil edilip edilmeyeceğinin nasıl görüntüsü vardır, varsa sanal dosyadan giriş akışı alır:

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

Ek kaynaklar

Dokümanları ve diğer dosyaları depolama ve bunlara erişme hakkında daha fazla bilgi için aşağıdaki kaynaklara bakın.

Örnekler

Videolar