Android depolama alanı kullanım alanları ve en iyi uygulamalar

Kullanıcılara dosyaları üzerinde daha fazla kontrol olanağı sunmak ve dosya karmaşasını sınırlamak için Android 10'da uygulamalar için kapsamlı depolama adlı yeni bir depolama paradigması kullanıma sunuldu. Kapsama alınmış depolama alanı, uygulamaların cihazın harici depolama alanında dosya depolama ve dosyalara erişme şeklini değiştirir. Uygulamanızı kapsamlı depolama alanını destekleyecek şekilde taşımanıza yardımcı olması için bu kılavuzda özetlenen yaygın depolama alanı kullanım alanlarıyla ilgili en iyi uygulamaları takip edin. Kullanım alanları iki kategoriye ayrılır: medya dosyalarını işleme ve medya dışı dosyaları işleme.

Çoğu durumda uygulamanız, diğer uygulamaların erişmesi gerekmeyen veya erişmemesi gereken dosyalar oluşturur. Sistem, bu tür dosyaları yönetmek için uygulamaya özel depolama konumları sağlar.

Android'de dosyaları depolama ve dosyalara erişme hakkında daha fazla bilgi edinmek için depolama alanı eğitim kılavuzlarına göz atın.

Medya dosyalarını işleme

Bu bölümde, medya dosyalarını (video, resim ve ses dosyaları) işlemeyle ilgili yaygın kullanım alanlarından bazıları açıklanmakta ve uygulamanızın kullanabileceği üst düzey yaklaşım anlatılmaktadır. Aşağıdaki tabloda bu kullanım alanlarının her biri özetlenmekte ve daha fazla ayrıntı içeren bölümlerin her birine bağlantı verilmektedir.

Kullanım alanı Özet
Tüm resim veya video dosyalarını gösterme Tüm Android sürümleri için aynı yaklaşımı kullanın.
Belirli bir klasördeki resimleri veya videoları gösterme Tüm Android sürümleri için aynı yaklaşımı kullanın.
Fotoğraflardaki konum bilgilerine erişme Uygulamanız kapsamlı depolama alanı kullanıyorsa bir yaklaşım kullanın. Uygulamanız kapsamlı depolama alanını devre dışı bırakıyorsa farklı bir yaklaşım kullanın.
Yeni indirmeler için depolama konumunu tanımlama Uygulamanız kapsamlı depolama alanı kullanıyorsa bir yaklaşım kullanın. Uygulamanız kapsamlı depolama alanını devre dışı bırakıyorsa farklı bir yaklaşım kullanın.
Kullanıcı medya dosyalarını bir cihaza aktarma Tüm Android sürümleri için aynı yaklaşımı kullanın.
Tek bir işlemde birden fazla medya dosyasını değiştirme veya silme Android 11 için bir yaklaşım kullanın. Android 10 için kapsamlı depolama alanını devre dışı bırakın ve Android 9 ve önceki sürümlerdeki yaklaşımı kullanın.
Mevcut bir resmi içe aktarma Tüm Android sürümleri için aynı yaklaşımı kullanın.
Tek bir resim çekme Tüm Android sürümleri için aynı yaklaşımı kullanın.
Medya dosyalarını diğer uygulamalarla paylaşma Tüm Android sürümleri için aynı yaklaşımı kullanın.
Medya dosyalarını belirli bir uygulamayla paylaşma Tüm Android sürümleri için aynı yaklaşımı kullanın.
Doğrudan dosya yollarını kullanan kod veya kitaplıklardan dosyalara erişme Android 11 için bir yaklaşım kullanın. Android 10 için kapsamlı depolama alanını devre dışı bırakın ve Android 9 ve önceki sürümlerdeki yaklaşımı kullanın.

Birden fazla klasördeki resim veya video dosyalarını gösterme

query() API'sini kullanarak bir medya koleksiyonunu sorgulama Medya dosyalarını filtrelemek veya sıralamak için projection, selection, selectionArgs ve sortOrder parametrelerini ayarlayın.

Belirli bir klasördeki resimleri veya videoları gösterme

Bu yaklaşımı kullanın:

  1. Uygulama İzinleri İsteme bölümünde belirtilen en iyi uygulamaları izleyerek READ_EXTERNAL_STORAGE iznini isteyin.
  2. Medya öğesinin diskteki mutlak dosya sistemi yolunu içeren MediaColumns.DATA değerine göre medya dosyalarını alma

Not: Mevcut bir medya dosyasına eriştiğinizde mantığınızda DATA sütununun değerini kullanabilirsiniz. Bunun nedeni, bu değerin geçerli bir dosya yoluna sahip olmasıdır. Ancak dosyanın her zaman kullanılabilir olduğunu varsaymayın. Oluşabilecek dosya tabanlı G/Ç hatalarını gidermeye hazır olun.

Medya dosyası oluşturmak veya güncellemek için ise DATA sütununu kullanmayın. Bunun yerine DISPLAY_NAME ve RELATIVE_PATH sütunlarını kullanın.

Fotoğraflardaki konum bilgilerine erişme

Uygulamanız kapsamlı depolama alanı kullanıyorsa medya depolama alanı kılavuzunun Fotoğraflardaki konum bilgileri bölümündeki adımları uygulayın.

Yeni indirmeler için depolama konumunu tanımlama

Uygulamanız kapsamlı depolama alanı kullanıyorsa indirdiğiniz medya dosyalarını depolamak için seçtiğiniz konuma dikkat edin.

Diğer uygulamaların dosyalara erişmesi gerekiyorsa indirme işlemleri veya belge koleksiyonları için iyi tanımlanmış medya koleksiyonlarını kullanabilirsiniz.

Android 11 ve sonraki sürümlerde, harici uygulamaya özel dizininizdeki dosyalara, bu dosyaları getirmek için DownloadManager kullansanız bile diğer uygulamalar erişemez.

Kullanıcı medya dosyalarını bir cihaza aktarma

Kullanıcı medya dosyalarını depolamak için uygun bir varsayılan konum tanımlayın:

Tek bir işlemle birden fazla medya dosyasını değiştirme veya silme

Uygulamanızın çalıştığı Android sürümlerine göre mantık ekleyin.

Android 11'de çalışır.

Bu yaklaşımı şu durumlarda kullanın:

  1. MediaStore.createWriteRequest() veya MediaStore.createTrashRequest() kullanarak uygulamanızın yazma veya silme isteği için beklemede olan intent oluşturun ve ardından bu intent'i çağırarak kullanıcıdan bir dizi dosyayı düzenleme izni isteyin.
  2. Kullanıcının yanıtını değerlendirin:

    • İzin verildiyse değiştirme veya silme işlemine devam edin.
    • İzin verilmediyse uygulamanızdaki özelliğin neden bu izne ihtiyaç duyduğunu kullanıcıya açıklayın.

Android 11 ve sonraki sürümlerde kullanılabilen bu yöntemleri kullanarak medya dosyası gruplarını yönetme hakkında daha fazla bilgi edinin.

Android 10'da çalışıyorsa

Uygulamanız Android 10'u (API düzeyi 29) hedefliyorsa kapsamlı depolama alanının kapsamı dışında kalmayı seçin ve bu işlemi gerçekleştirmek için Android 9 ve önceki sürümlere yönelik yaklaşımı kullanmaya devam edin.

Android 9 veya daha eski bir sürüm yüklü

Bu yaklaşımı şu durumlarda kullanın:

  1. Uygulama İzinleri İsteme bölümünde belirtilen en iyi uygulamaları izleyerek WRITE_EXTERNAL_STORAGE iznini isteyin.
  2. Medya dosyalarını değiştirmek veya silmek için MediaStore API'yi kullanın.

Mevcut bir resmi içe aktarma

Mevcut bir resmi içe aktarmak istediğinizde (örneğin, bir kullanıcının profil fotoğrafı olarak kullanmak için) uygulamanız işlem için kendi kullanıcı arayüzünü veya sisteme ait seçim aracını kullanabilir.

Kendi kullanıcı arayüzünüzü sunma

Bu yaklaşımı şu durumlarda kullanın:

  1. Uygulama İzinleri İsteme bölümünde belirtilen en iyi uygulamaları izleyerek READ_EXTERNAL_STORAGE iznini isteyin.
  2. Bir medya koleksiyonunu sorgulamak için query() API'sini kullanın.
  3. Sonuçları uygulamanızın özel kullanıcı arayüzünde gösterin.

Sisteme ait seçim aracını kullanma

Kullanıcıdan içe aktarılacak bir resim seçmesini isteyen ACTION_GET_CONTENT intent'ini kullanın.

Sisteme ait seçim aracının kullanıcıya sunduğu resim türlerini filtrelemek istiyorsanız setType() veya EXTRA_MIME_TYPES kullanabilirsiniz.

Tek bir görüntü yakalama

Uygulamanızda kullanmak üzere tek bir resim çekmek istediğinizde (ör. kullanıcının profil fotoğrafı olarak kullanmak için) ACTION_IMAGE_CAPTURE intent'ini kullanarak kullanıcıdan cihazın kamerasını kullanarak fotoğraf çekmesini isteyin. Sistem, çekilen fotoğrafı MediaStore.Images tablosunda saklar.

Medya dosyalarını diğer uygulamalarla paylaşma

Kayıtları doğrudan MediaStore'a eklemek için insert() yöntemini kullanın. Daha fazla bilgi için medya depolama kılavuzunun Öğe ekleme bölümüne bakın.

Medya dosyalarını belirli bir uygulamayla paylaşma

Dosya paylaşımını ayarlama kılavuzunda açıklandığı şekilde Android FileProvider bileşenini kullanın.

Doğrudan dosya yollarını kullanan kod veya kitaplıklardan dosyalara erişme

Uygulamanızın çalıştığı Android sürümlerine göre mantık ekleyin.

Android 11'de çalışır.

Bu yaklaşımı şu durumlarda kullanın:

  1. Uygulama İzinleri İsteme bölümünde belirtilen en iyi uygulamaları izleyerek READ_EXTERNAL_STORAGE iznini isteyin.
  2. Doğrudan dosya yollarını kullanarak dosyalara erişme

Daha fazla bilgi için doğrudan dosya yollarını kullanarak medya dosyalarını açma ile ilgili bölüme bakın.

Android 10'da çalışıyorsa

Uygulamanız Android 10'u (API düzeyi 29) hedefliyorsa kapsamlı depolama alanının kapsamı dışında kalmayı seçin ve bu işlemi gerçekleştirmek için Android 9 ve önceki sürümlere yönelik yaklaşımı kullanmaya devam edin.

Android 9 veya daha eski bir sürüm yüklü

Bu yaklaşımı şu durumlarda kullanın:

  1. Uygulama İzinleri İsteme bölümünde belirtilen en iyi uygulamaları izleyerek WRITE_EXTERNAL_STORAGE iznini isteyin.
  2. Doğrudan dosya yollarını kullanarak dosyalara erişme

Medya dışı dosyaları işleme

Bu bölümde, medya dışı dosyaları işlemeyle ilgili yaygın kullanım alanlarından bazıları açıklanmakta ve uygulamanızın kullanabileceği üst düzey yaklaşım anlatılmaktadır. Aşağıdaki tabloda bu kullanım alanlarının her biri özetlenmekte ve daha fazla ayrıntı içeren bölümlerin her birine bağlantı verilmektedir.

Kullanım alanı Özet
Doküman dosyası açma Tüm Android sürümleri için aynı yaklaşımı kullanın.
İkincil depolama birimlerindeki dosyalara yazma Android 11 için bir yaklaşım kullanın. Android'in önceki sürümleri için farklı bir yaklaşım kullanın.
Mevcut dosyaları eski bir depolama konumundan taşıma Mümkün olduğunda dosyalarınızı kapsamlı depolama alanına taşıyın. Gerektiğinde Android 10 için kapsamlı depolama alanını devre dışı bırakın.
Diğer uygulamalarla içerik paylaşma Tüm Android sürümleri için aynı yaklaşımı kullanın.
Medya dışı dosyaları önbelleğe alma Tüm Android sürümleri için aynı yaklaşımı kullanın.
Medya dışı dosyaları bir cihaza aktarma Uygulamanız kapsamlı depolama alanı kullanıyorsa bir yaklaşım kullanın. Uygulamanız kapsamlı depolama alanını devre dışı bırakıyorsa farklı bir yaklaşım kullanın.

Doküman dosyası açma

Kullanıcıdan sisteme ait seçim aracını kullanarak açılacak bir dosya seçmesini istemek için ACTION_OPEN_DOCUMENT intent'ini kullanın. Sisteme ait seçim aracının kullanıcıya sunacağı dosya türlerini filtrelemek istiyorsanız setType() veya EXTRA_MIME_TYPES kullanabilirsiniz.

Örneğin, aşağıdaki kodu kullanarak tüm PDF, ODT ve TXT dosyalarını bulabilirsiniz:

Kotlin

startActivityForResult(
        Intent(Intent.ACTION_OPEN_DOCUMENT).apply {
            addCategory(Intent.CATEGORY_OPENABLE)
            type = "*/*"
            putExtra(Intent.EXTRA_MIME_TYPES, arrayOf(
                    "application/pdf", // .pdf
                    "application/vnd.oasis.opendocument.text", // .odt
                    "text/plain" // .txt
            ))
        },
        REQUEST_CODE
      )

Java

Intent intent = new Intent(Intent.ACTION_OPEN_DOCUMENT);
        intent.addCategory(Intent.CATEGORY_OPENABLE);
        intent.setType("*/*");
        intent.putExtra(Intent.EXTRA_MIME_TYPES, new String[] {
                "application/pdf", // .pdf
                "application/vnd.oasis.opendocument.text", // .odt
                "text/plain" // .txt
        });
        startActivityForResult(intent, REQUEST_CODE);

İkincil depolama birimlerindeki dosyalara yazma

İkincil depolama birimleri arasında SD kartlar bulunur. StorageVolume sınıfını kullanarak belirli bir depolama birimiyle ilgili bilgilere erişebilirsiniz.

Uygulamanızın çalıştığı Android sürümüne göre mantık ekleyin.

Android 11'de çalışır

Bu yaklaşımı şu durumlarda kullanın:

  1. Kapsamlı depolama modelini kullanın.
  2. Android 10 (API düzeyi 29) veya daha eski bir sürümü hedeflemelidir.
  3. WRITE_EXTERNAL_STORAGE iznini beyan edin.
  4. Aşağıdaki erişim türlerinden birini uygulayın:
    • MediaStore API'yi kullanarak dosya erişimi.
    • File veya fopen() gibi API'leri kullanarak doğrudan dosya yolu erişimi.

Eski sürümlerde çalışıyor

Kullanıcıların, uygulamanızın dosyayı yazabileceği ikincil depolama birimindeki konumu seçmesine olanak tanıyan Depolama Alanı Erişim Çerçevesi'ni kullanın.

Mevcut dosyaları eski bir depolama konumundan taşıma

Uygulamaya özel bir dizin veya herkese açık paylaşılan bir dizin olmayan dizinler eski depolama konumu olarak kabul edilir. Uygulamanız eski bir depolama konumunda dosya oluşturuyor veya kullanıyorsa uygulamanızın dosyalarını kapsamlı depolama alanıyla erişilebilen konumlara taşımanızı ve kapsamlı depolama alanındaki dosyalarla çalışmak için gerekli uygulama değişikliklerini yapmanızı öneririz.

Veri taşıma için eski depolama konumuna erişimi sürdürme

Uygulama dosyalarını kapsamlı depolama alanıyla erişilebilen konumlara taşımak için uygulamanızın eski depolama alanı konumuna erişimi sürdürmesi gerekir. Kullanmanız gereken yaklaşım, uygulamanızın hedef API düzeyine bağlıdır.

Uygulamanız Android 11'i hedefliyorsa
  1. Uygulamanızın, Android 11'i hedefleyen yeni sürümüne yükseltme yapan kullanıcıların verilerini taşıyabilmesi için preserveLegacyExternalStorage işaretini true olarak ayarlayarak eski depolama modelini koruyun.

  2. Uygulamanızın Android 10 cihazlardaki eski depolama konumunda bulunan dosyalarınıza erişmeye devam edebilmesi için kapsamlı depolama alanını devre dışı bırakmaya devam edin.

Uygulamanız Android 10'u hedefliyorsa

Uygulamanızın davranışını Android sürümleri arasında korumayı kolaylaştırmak için kapsamlı depolama alanını devre dışı bırakın.

Uygulama verilerini taşıma

Uygulamanız taşınmaya hazır olduğunda aşağıdaki yaklaşımı kullanın:

  1. Android 10 veya daha eski bir sürümü hedeflemelidir.
  2. Uygulamanızın, taşımanız gereken dosyalara erişebilmesi için kapsamlı depolama alanını devre dışı bırakın.
  3. Dosyaları /sdcard/ altındaki mevcut konumlarından kapsamlı depolama alanıyla erişilebilen bir konuma taşımak için File API'yi kullanan kodu dağıtın:

    1. Gizli uygulama dosyalarını getExternalFilesDir() yönteminin döndürdüğü dizine taşıyın.
    2. Paylaşılan medya dışı dosyaları Downloads/ dizininin uygulamaya özel bir alt dizinine taşıyın.
  4. Uygulamanızın eski depolama dizinlerini /sdcard/ dizininden kaldırın.

Kullanıcılar, uygulamanızın yeni sürümünü yükledikten sonra cihazlarında veri taşıma işlemini tamamlar. Bir Analytics etkinliği oluşturarak kullanıcı tabanınız genelinde taşıma sürecini izleyebilirsiniz.

Kullanıcılar verilerini taşıdıktan sonra uygulamanız için Android 11'i hedefleyen başka bir güncelleme yayınlayın.

İçerikleri diğer uygulamalarla paylaşma

Uygulamanızın dosyalarını başka bir uygulamayla paylaşmak için FileProvider kullanın. Birbirleri arasında dosya paylaşması gereken tüm uygulamalar için her uygulamada bir içerik sağlayıcı kullanmanızı ve ardından uygulamalar koleksiyona eklendikçe verileri senkronize etmenizi öneririz.

Medya dışı dosyaları önbelleğe alma

Kullanmanız gereken yaklaşım, önbelleğe almanız gereken dosyaların türüne bağlıdır.

Medya dışı dosyaları bir cihaza aktarma

Medya dışı dosyaları depolamak için uygun bir varsayılan konum tanımlayın. Kullanıcıların, uygulamaya özel dizinlerdeki dosyaları daha genel erişime açık bir konuma aktarmasına izin verin. Medya dışı dosyaları cihaza aktarmak için MediaStore'un indirme veya doküman koleksiyonlarını kullanın.

Uygulamaya Özel Dosyaları İşleme

Uygulamanız, diğer uygulamaların erişmesi gerekmeyen veya erişmemesi gereken dosyalar oluşturuyorsa bu dosyaları uygulamaya özel depolama konumlarında saklayabilirsiniz.

Dahili depolama dizinleri

Sistem, diğer uygulamaların bu konumlara erişmesini engeller. Android 10 (API düzeyi 29) ve sonraki sürümlerde bu konumlar şifrelenir. Bu konumlar, yalnızca uygulamanızın erişebileceği hassas verileri depolamak için iyi bir yerdir.

Harici depolama dizinleri

Dahili depolama alanı, uygulamaya özel dosyaları depolamak için yeterli alan sağlamıyorsa bunun yerine harici depolama alanını kullanabilirsiniz. Başka bir uygulamanın uygun izinlere sahip olması durumunda bu dizinlere erişmesi mümkün olsa da bu dizinlerde depolanan dosyalar yalnızca uygulamanız tarafından kullanılmak üzere tasarlanmıştır.

Android 4.4 (API düzeyi 19) veya sonraki sürümlerde uygulamanızın, harici depolama alanındaki uygulamaya özel dizinlere erişmek için depolama alanıyla ilgili izinler istemesi gerekmez.

Kullanıcı uygulamanızı kaldırdığında uygulamaya özel depolama alanına kaydedilen dosyalar kaldırılır. Bu nedenle, kullanıcının uygulamanızdan bağımsız olarak kalıcı olmasını beklediği hiçbir şeyi kaydetmek için bu depolama alanını kullanmamanız gerekir.

Kapsamlı depolama alanını geçici olarak devre dışı bırakma

Uygulamanız kapsamlı depolama alanıyla tam uyumlu hale gelmeden önce hem testlerinizde hem de üretim uygulamanızda geçici olarak kapsamlı depolama alanını devre dışı bırakabilirsiniz.

Testlerinizde kapsam dışında bırakma

Android 10 (API düzeyi 29) ve sonraki sürümlerde uygulamanızın testleri varsayılan olarak bir depolama alanı korumalı alanında çalışır. Bu korumalı alan, uygulamanızın uygulamaya özel dizin ve herkese açık olarak paylaşılan dizinler dışındaki dosyalara erişmesini engeller.

Bir test, ana makine için ekran görüntüleri, hata ayıklama verileri, kapsam verileri veya performans metrikleri gibi dosyalar oluşturuyorsa bu dosyaları genel dizinlere yazabilirsiniz. Bunun için am instrument aracını çağıran ilgili donanıma aşağıdaki işareti ekleyin:

-e no-isolated-storage 1

Bu işaret, enstrümantasyon testi durumunun tüm davranışlarını ve çağrılan tüm test kodlarını etkiler. Bu nedenle, bu işareti kullandığınızda uygulamanızın kapsamlı depolama alanıyla uyumluluğunu doğrulayamazsınız. Test çıkışı için kabuk tarafından okunabilen uygulama kapsamlı depolama alanına yazmak daha iyidir. Ardından, uygulama kapsamlı bu dizini çekebilirsiniz. Hangi dizinden veri çekileceğini belirlemek için getExternalMediaDirs() yöntemini çağırın.

Üretim uygulamanızda devre dışı bırakma

Uygulamanız Android 10 (API düzeyi 29) veya daha eski bir sürümü hedefliyorsa üretim uygulamanızda kapsamlı depolama alanını geçici olarak devre dışı bırakabilirsiniz. Ancak Android 10'u hedefliyorsanız uygulamanızın manifest dosyasında requestLegacyExternalStorage değerini true olarak ayarlamanız gerekir:

<manifest ... >
  <!-- This attribute is "false" by default on apps targeting
       Android 10. -->
  <application android:requestLegacyExternalStorage="true" ... >
    ...
  </application>
</manifest>

Android 10 veya daha eski sürümleri hedefleyen bir uygulamanın kapsamlı depolama alanını kullanırken nasıl davrandığını test etmek için requestLegacyExternalStorage değerini false olarak ayarlayarak bu davranışı etkinleştirebilirsiniz. Android 11 çalıştıran bir cihazda test yapıyorsanız uygulamanızın kapsamlı depolama alanıyla veya kapsamlı depolama alanı olmadan davranışını test etmek için uygulama uyumluluk işaretlerini de kullanabilirsiniz.

Ek kaynaklar

Android depolama alanı hakkında daha fazla bilgi için aşağıdaki materyalleri inceleyin:

Blog yayınları