Uygulamaya özel dosyalara erişme

Birçok durumda, uygulamanız diğer uygulamaların erişmesi gerekmeyen dosyalar oluşturur veya erişimi olması gerekir. Sistem, bu tür verilerin depolanması için aşağıdaki konumları sağlar: uygulamaya özel dosyalar:

  • Dahili depolama dizinleri: Bu dizinler hem özel kalıcı dosyaları ve başka bir konumu depolamak için başka bir konum önbellek verileri. Sistem, diğer uygulamaların bu konumlara erişmesini engeller ve Android 10 (API düzeyi 29) ve sonraki sürümlerde bu konumlar şifrelenir. Bu özellikleri nedeniyle bu konumları, uygulamanızın kendisi erişebilir.

  • Harici depolama dizinleri: Bu dizinler hem özel bir depolama alanı hem de kalıcı dosyaları ve başka bir konumu depolamak için başka bir konum önbellek verileri. Başka bir uygulamanın bu dizinlere erişmesi mümkün olsa da Söz konusu uygulama uygun izinlere sahipse bu dizinlerde depolanan dosyalar yalnızca uygulamanız tarafından kullanılmalıdır. Özellikle dosya oluşturmayı planlıyorsanız diğer uygulamaların erişebilmesini istiyorsanız, uygulamanız bu dosyaları şurada depolamalıdır: Harici depolama alanının paylaşılan depolama bölümü .

Kullanıcı uygulamanızı kaldırdığında, uygulamaya özel depolama alanına kaydedilen dosyalar emin olun. Bu davranış nedeniyle, verileri kaydetmek için bu depolama alanını kullanmamalısınız. Kullanıcının uygulamanızdan bağımsız olarak kalıcı olmasını beklediği her şey. Örneğin, Örneğin, uygulamanız kullanıcılara fotoğraf çekme izni veriyorsa kullanıcı daha uygulamanızı kaldırdıktan sonra bile bu fotoğraflara erişebilirler. Bu nedenle Bunun yerine, bu tür dosyaları uygun depolama alanına kaydetmek için paylaşılan depolama medya koleksiyonudur.

Aşağıdaki bölümlerde, Google Etiket Yöneticisi'nde dosyaların nasıl depolanacağı dizinleri de kullanabilirsiniz.

Dahili depolama alanından erişim

Sistem, her uygulama için dahili depolama içinde dizinler sağlar. Burada uygulamasını kullanarak kendi dosyalarını düzenleyebilir. Uygulamanızın web siteleri için bir dizin kalıcı dosyalar, bir diğeri ise uygulamanızın önbelleğe alınmış dosyaları içermelidir. Uygulamanız için herhangi bir sistem gerekmiyor bu dizinlerdeki dosyaları okuma ve bunlara yazma izni verir.

Diğer uygulamalar, dahili depolama alanında depolanan dosyalara erişemez. Bu durum, diğer uygulamaların erişememesi gereken uygulama verileri için iyi bir yerdir.

Ancak bu dizinlerin genellikle küçük olduğunu unutmayın. Yazmadan önce dahili depolama alanına aktarma işlemi gerçekleştirdiğinizde, uygulamanızın ücretsiz boş bırakın.

Kalıcı dosyalara erişme

Uygulamanızın normal, kalıcı dosyaları indirebileceğiniz bir dizinde bulunur filesDir kullanarak erişin bir bağlam nesnesinin özelliğine sahiptir. Bu çerçevede size yardımcı olacak bu dizindeki dosyalara erişebilir ve dosya depolayabilir.

Dosyalara erişme ve dosyaları depolama

Dosyalara erişmek ve depolamak için File API'yi kullanabilirsiniz.

Uygulamanızın performansını korumaya yardımcı olmak için aynı uygulamayı açıp kapatmayın işlemi birden fazla kez yapacaksınız.

Aşağıdaki kod snippet'i, File API'nin nasıl kullanılacağını göstermektedir:

Kotlin

val file = File(context.filesDir, filename)

Java

File file = new File(context.getFilesDir(), filename);

Akış kullanarak dosya depolama

File API'yi kullanmaya alternatif olarak, openFileOutput() yazan bir FileOutputStream almak için filesDir dizinindeki bir dosyaya yükleyebilirsiniz.

Aşağıdaki kod snippet'i bir dosyaya nasıl metin yazılacağını gösterir:

Kotlin

val filename = "myfile"
val fileContents = "Hello world!"
context.openFileOutput(filename, Context.MODE_PRIVATE).use {
        it.write(fileContents.toByteArray())
}

Java

String filename = "myfile";
String fileContents = "Hello world!";
try (FileOutputStream fos = context.openFileOutput(filename, Context.MODE_PRIVATE)) {
    fos.write(fileContents.toByteArray());
}

Diğer uygulamaların şurada depolanan dosyalara erişmesine izin vermek için: dahili depolama alanındaki bu dizini oluşturmak için FileProvider ve FLAG_GRANT_READ_URI_PERMISSION özelliğini gönderin.

Dosyaya akış üzerinden erişme

Bir dosyayı akış olarak okumak için şunu kullanın: openFileInput():

Kotlin

context.openFileInput(filename).bufferedReader().useLines { lines ->
    lines.fold("") { some, text ->
        "$some\n$text"
    }
}

Java

FileInputStream fis = context.openFileInput(filename);
InputStreamReader inputStreamReader =
        new InputStreamReader(fis, StandardCharsets.UTF_8);
StringBuilder stringBuilder = new StringBuilder();
try (BufferedReader reader = new BufferedReader(inputStreamReader)) {
    String line = reader.readLine();
    while (line != null) {
        stringBuilder.append(line).append('\n');
        line = reader.readLine();
    }
} catch (IOException e) {
    // Error occurred when opening raw file for reading.
} finally {
    String contents = stringBuilder.toString();
}

Dosya listesini göster

filesDir içindeki tüm dosyaların adlarını içeren bir dizi alabilirsiniz. telefon ederek dizin fileList(), gösterildiği gibi şu kod snippet'ini kullanabilirsiniz:

Kotlin

var files: Array<String> = context.fileList()

Java

Array<String> files = context.fileList();

İç içe dizinler oluşturma

Ayrıca, iç içe yerleştirilmiş dizinler oluşturabilir veya Kotlin tabanlı olarak getDir() File dizinine kök dizini ve yeni bir dizin adı aktararak oluşturucu:

Kotlin

context.getDir(dirName, Context.MODE_PRIVATE)

Java

File directory = context.getFilesDir();
File file = new File(directory, filename);

Önbellek dosyaları oluşturma

Hassas verileri yalnızca geçici olarak depolamanız gerekiyorsa uygulamanın dahili depolama içindeki atanmış önbellek dizinini oluşturur. Olduğu gibi tüm uygulamaya özel depolama alanları için, bu dizinde depolanan dosyalar kullanıcı uygulamanızı kaldırdığında kaldırılır. Ancak, bu dizindeki dosyalar daha erken kaldırılabilir.

Önbelleğe alınan bir dosya oluşturmak için şu çağrıyı yapın: File.createTempFile():

Kotlin

File.createTempFile(filename, null, context.cacheDir)

Java

File.createTempFile(filename, null, context.getCacheDir());

Uygulamanız bu dizindeki bir dosyaya şunları kullanarak erişir: cacheDir özelliği bağlam nesnesi ve File API'si:

Kotlin

val cacheFile = File(context.cacheDir, filename)

Java

File cacheFile = new File(context.getCacheDir(), filename);

Önbellek dosyalarını kaldır

Android bazen önbellek dosyalarını kendiliğinden silmiş olsa da bu dosyaları sizin için temizleyebilir. Her zaman uygulamanın dahili depolama alanındaki önbellek dosyaları.

Bir dosyayı dahili depolama alanındaki önbellek dizininden kaldırmak için şu yöntemlerden birini kullanın: aşağıdaki yöntemleri kullanabilirsiniz:

  • Bir File nesnesinde delete() yöntemi şu dosyayı temsil eder:

    Kotlin

    cacheFile.delete()
    

    Java

    cacheFile.delete();
    
  • İlgili içeriği oluşturmak için kullanılan deleteFile() yöntemini çağırın:

    Kotlin

    context.deleteFile(cacheFileName)
    

    Java

    context.deleteFile(cacheFileName);
    

Harici depolama cihazından erişim

Dahili depolama alanı, uygulamaya özel dosyaları depolamak için yeterli alan sağlamıyorsa harici depolama kullanmayı düşünün. Sistem, uygulamanın kullanıcıya değer sağlayan dosyaları düzenleyebileceği harici depolama alanı inceleyebilirsiniz. Bir dizin, uygulamanızın kalıcı öğeleri için tasarlanmıştır dosyaları, diğeri ise uygulamanızın önbelleğe alınmış dosyaları ile senkronize edilir.

Android 4.4 (API düzeyi 19) veya sonraki sürümlerde uygulamanızın harici dizinlerdeki uygulamaya özel dizinlere erişmek için depolama alanıyla ilgili izinler depolama alanına sahip olursunuz. Bu dizinlerde depolanan dosyalar, uygulamanız için kaldırıldı.

Android 9 (API düzeyi 28) veya önceki sürümleri çalıştıran cihazlarda uygulamanız diğer uygulamalara ait olan uygulamaya özel dosyalar (uygulamanızın gerekli depolama alanı izinlerine sahip olur. Kullanıcılara dosyaları üzerinde daha fazla kontrol Android 10 (API düzeyi 29) ve sonraki sürümleri hedefleyen uygulamalar, dosya karmaşıklığını azaltmak için harici depolamaya kapsamlı erişim veya kapsamlı depolama alanı varsayılan olarak ayarlıdır. Kapsama alındığında Storage etkinleştirildiğinde, uygulamalar diğer uygulamalara gönderebilirsiniz.

Kullanılabilir depolama alanı olduğunu doğrulama

Harici depolama, kullanıcının olabileceği fiziksel bir birimde bulunduğu için olduğundan emin olun, okumaya çalışmadan önce cildin erişilebilir olduğunu doğrulayın veya harici depolamadan uygulamaya özel veriler yazma.

Şu numarayı arayarak ses seviyesini sorgulayabilirsiniz: Environment.getExternalStorageState(). Döndürülen durum MEDIA_MOUNTED, ardından harici depolama alanındaki uygulamaya özel dosyaları okuyabilir ve yazabilirsiniz. Eğer MEDIA_MOUNTED_READ_ONLY bu dosyaları yalnızca okuyabilirsiniz.

Örneğin, depolama alanının doldurulmasını belirlemek için aşağıdaki yöntemler yararlıdır uygunluk durumu:

Kotlin

// Checks if a volume containing external storage is available
// for read and write.
fun isExternalStorageWritable(): Boolean {
    return Environment.getExternalStorageState() == Environment.MEDIA_MOUNTED
}

// Checks if a volume containing external storage is available to at least read.
fun isExternalStorageReadable(): Boolean {
     return Environment.getExternalStorageState() in
        setOf(Environment.MEDIA_MOUNTED, Environment.MEDIA_MOUNTED_READ_ONLY)
}

Java

// Checks if a volume containing external storage is available
// for read and write.
private boolean isExternalStorageWritable() {
    return Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED);
}

// Checks if a volume containing external storage is available to at least read.
private boolean isExternalStorageReadable() {
     return Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED) ||
            Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED_READ_ONLY);
}

Çıkarılabilir harici depolama alanı olmayan cihazlarda aşağıdaki komutu kullanarak harici depolama kullanılabilirlik mantığınızı test etmek için sanal bir birim etkinleştirin:

adb shell sm set-virtual-disk true

Fiziksel bir depolama konumu seçin

Bazen dahili belleğinin bir bölümünü Harici depolama alanı, bir SD kart yuvası da sağlar. Bu, cihazda daha fazla depolama alanı içerebilecek birden fazla fiziksel birimin olması nedeniyle uygulamaya özel depolama alanınız için hangisinin kullanılacağını seçin.

Farklı konumlara erişmek için şu numarayı arayın: ContextCompat.getExternalFilesDirs(). Kod snippet'inde gösterildiği gibi, döndürülen dizideki ilk öğe birincil harici depolama birimi olarak kabul edilir. Dolu değilse bu sesi kullan veya mevcut değil.

Kotlin

val externalStorageVolumes: Array<out File> =
        ContextCompat.getExternalFilesDirs(applicationContext, null)
val primaryExternalStorage = externalStorageVolumes[0]

Java

File[] externalStorageVolumes =
        ContextCompat.getExternalFilesDirs(getApplicationContext(), null);
File primaryExternalStorage = externalStorageVolumes[0];

Kalıcı dosyalara erişme

Harici depolama alanındaki uygulamaya özel dosyalara erişmek için şu numarayı arayın: getExternalFilesDir().

Uygulamanızın performansını korumaya yardımcı olmak için aynı uygulamayı açıp kapatmayın işlemi birden fazla kez yapacaksınız.

Aşağıdaki kod snippet'i, getExternalFilesDir() yönteminin nasıl çağrılacağını gösterir:

Kotlin

val appSpecificExternalDir = File(context.getExternalFilesDir(null), filename)

Java

File appSpecificExternalDir = new File(context.getExternalFilesDir(null), filename);

Önbellek dosyaları oluşturma

Harici depolama alanındaki uygulamaya özel bir dosyayı önbelleğe eklemek için için externalCacheDir:

Kotlin

val externalCacheFile = File(context.externalCacheDir, filename)

Java

File externalCacheFile = new File(context.getExternalCacheDir(), filename);

Önbellek dosyalarını kaldır

Bir dosyayı harici önbellek dizininden kaldırmak için delete() yöntemini kullanan File nesnesi dosyayı temsil eder:

Kotlin

externalCacheFile.delete()

Java

externalCacheFile.delete();

Medya içeriği

Uygulamanız, kullanıcıya yalnızca bu verileri harici dizinde uygulamaya özel dizinlerde veya depolama alanını (aşağıdaki kod snippet'inde gösterildiği gibi) seçin:

Kotlin

fun getAppSpecificAlbumStorageDir(context: Context, albumName: String): File? {
    // Get the pictures directory that's inside the app-specific directory on
    // external storage.
    val file = File(context.getExternalFilesDir(
            Environment.DIRECTORY_PICTURES), albumName)
    if (!file?.mkdirs()) {
        Log.e(LOG_TAG, "Directory not created")
    }
    return file
}

Java

@Nullable
File getAppSpecificAlbumStorageDir(Context context, String albumName) {
    // Get the pictures directory that's inside the app-specific directory on
    // external storage.
    File file = new File(context.getExternalFilesDir(
            Environment.DIRECTORY_PICTURES), albumName);
    if (file == null || !file.mkdirs()) {
        Log.e(LOG_TAG, "Directory not created");
    }
    return file;
}

Aşağıdaki gibi API sabit değerleri tarafından sağlanan dizin adlarını kullanmanız önemlidir: DIRECTORY_PICTURES. Bu dizin adları, dosyaların sistem tarafından düzgün bir şekilde işlenmesini sağlar. Önceden tanımlanmış alt dizinlerden hiçbiri isimlerin dosyalarınıza uymasını bunun yerine null öğesini getExternalFilesDir() öğesine iletin. Bu, kök döndürür harici depolama alanındaki uygulamaya özgü dizin.

Boş alan sorgusu

Birçok kullanıcının cihazında yeterli depolama alanı olmadığından uygulamanız tükettiğini düşünelim.

Ne kadar veri depoladığınızı önceden biliyorsanız verileri nasıl depoladığınızı ya da bir telefon araması yaparak cihazın, uygulamanıza katabileceği kadar yer getAllocatableBytes(). getAllocatableBytes() işlevinin döndürülen değeri mevcut değerden daha büyük olabilir bir alan sağlar. Bunun nedeni, sistemin, kaldırabileceği dosyalar emin olun.

Uygulamanızın verilerini kaydetmek için yeterli alan varsa allocateBytes(). Aksi takdirde, uygulamanız kullanıcıdan bazılarını kaldırmasını isteyebilir dosyaları kaldırın veya tüm önbelleği kaldırın dosyaları cihazınızdan kaldırabilirsiniz.

Aşağıdaki kod snippet'i, uygulamanızın boş alanı nasıl sorgulayabileceğiyle ilgili bir örnek göstermektedir cihazda:

Kotlin

// App needs 10 MB within internal storage.
const val NUM_BYTES_NEEDED_FOR_MY_APP = 1024 * 1024 * 10L;

val storageManager = applicationContext.getSystemService<StorageManager>()!!
val appSpecificInternalDirUuid: UUID = storageManager.getUuidForPath(filesDir)
val availableBytes: Long =
        storageManager.getAllocatableBytes(appSpecificInternalDirUuid)
if (availableBytes >= NUM_BYTES_NEEDED_FOR_MY_APP) {
    storageManager.allocateBytes(
        appSpecificInternalDirUuid, NUM_BYTES_NEEDED_FOR_MY_APP)
} else {
    val storageIntent = Intent().apply {
        // To request that the user remove all app cache files instead, set
        // "action" to ACTION_CLEAR_APP_CACHE.
        action = ACTION_MANAGE_STORAGE
    }
}

Java

// App needs 10 MB within internal storage.
private static final long NUM_BYTES_NEEDED_FOR_MY_APP = 1024 * 1024 * 10L;

StorageManager storageManager =
        getApplicationContext().getSystemService(StorageManager.class);
UUID appSpecificInternalDirUuid = storageManager.getUuidForPath(getFilesDir());
long availableBytes =
        storageManager.getAllocatableBytes(appSpecificInternalDirUuid);
if (availableBytes >= NUM_BYTES_NEEDED_FOR_MY_APP) {
    storageManager.allocateBytes(
            appSpecificInternalDirUuid, NUM_BYTES_NEEDED_FOR_MY_APP);
} else {
    // To request that the user remove all app cache files instead, set
    // "action" to ACTION_CLEAR_APP_CACHE.
    Intent storageIntent = new Intent();
    storageIntent.setAction(ACTION_MANAGE_STORAGE);
}

Depolama alanı yönetimi etkinliği oluşturma

Uygulamanız, kullanıma sunulduğunda izin verilen özel etkinlikler beyan edip oluşturabilir depoladığı verileri yönetmesine olanak tanır. Siz bu özel "alanı yönet" işlevini bildir etkinliği android:manageSpaceActivity özelliğini gönderin. Dosya yöneticisi uygulamaları bunu etkinlik Uygulamanız etkinliği dışa aktarmasa bile diğer bir deyişle, etkinlikleriniz android:exported - false.

Kullanıcıdan bazı cihaz dosyalarını kaldırmasını isteyin

Kullanıcının cihazdaki kaldırılacak dosyaları seçmesini istemek için bir intent çağırın dahil olmak üzere ACTION_MANAGE_STORAGE eyleme dökülebilir. Bu niyet, kullanıcıya bir istem gösterir. İstenirse bu istem cihazda kullanılabilir alan miktarını gösterin. Bunu göstermek için kullanıcı dostu bilgiler kullanıyorsanız aşağıdaki hesaplamanın sonucunu kullanın:

StorageStatsManager.getFreeBytes() / StorageStatsManager.getTotalBytes()

Kullanıcıdan tüm önbellek dosyalarını kaldırmasını iste

Alternatif olarak, kullanıcıdan önbellek dosyalarını tüm yerlerden temizlemesini isteyebilirsiniz. ekleyebilirsiniz. Bunu yapmak için ACTION_CLEAR_APP_CACHE intent işlemidir.

Ek kaynaklar

Dosyaları cihazın depolama alanına kaydetmeyle ilgili daha fazla bilgi için şuraya bakın: inceleyebilirsiniz.

Videolar