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:
- Uygulama İzinleri İsteme bölümünde belirtilen en iyi uygulamaları izleyerek
READ_EXTERNAL_STORAGEiznini isteyin. - Medya öğesinin diskteki mutlak dosya sistemi yolunu içeren
MediaColumns.DATAdeğ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:
- Uygulamaya özel depolama alanı veya paylaşılan depolama alanı kullanarak kullanıcıların, medya dosyalarının diğer uygulamalar tarafından okunabilir olup olmayacağını seçmesine izin verin.
- Kullanıcıların, uygulamaya özel dizinlerdeki dosyaları daha genel erişime açık bir konuma aktarmasına izin verin. Medya dosyalarını cihazın galerisine aktarmak için MediaStore'un resim, video ve ses koleksiyonlarını kullanı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:
MediaStore.createWriteRequest()veyaMediaStore.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.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:
- Uygulama İzinleri İsteme bölümünde belirtilen en iyi uygulamaları izleyerek
WRITE_EXTERNAL_STORAGEiznini isteyin. - Medya dosyalarını değiştirmek veya silmek için
MediaStoreAPI'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:
- Uygulama İzinleri İsteme bölümünde belirtilen en iyi uygulamaları izleyerek
READ_EXTERNAL_STORAGEiznini isteyin. - Bir medya koleksiyonunu sorgulamak için
query()API'sini kullanın. - 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:
- Uygulama İzinleri İsteme bölümünde belirtilen en iyi uygulamaları izleyerek
READ_EXTERNAL_STORAGEiznini isteyin. - 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:
- Uygulama İzinleri İsteme bölümünde belirtilen en iyi uygulamaları izleyerek
WRITE_EXTERNAL_STORAGEiznini isteyin. - 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:
- Kapsamlı depolama modelini kullanın.
- Android 10 (API düzeyi 29) veya daha eski bir sürümü hedeflemelidir.
WRITE_EXTERNAL_STORAGEiznini beyan edin.- Aşağıdaki erişim türlerinden birini uygulayın:
MediaStoreAPI'yi kullanarak dosya erişimi.Fileveyafopen()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
Uygulamanızın, Android 11'i hedefleyen yeni sürümüne yükseltme yapan kullanıcıların verilerini taşıyabilmesi için
preserveLegacyExternalStorageişaretinitrueolarak ayarlayarak eski depolama modelini koruyun.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:
- Android 10 veya daha eski bir sürümü hedeflemelidir.
- Uygulamanızın, taşımanız gereken dosyalara erişebilmesi için kapsamlı depolama alanını devre dışı bırakın.
-
Dosyaları
/sdcard/altındaki mevcut konumlarından kapsamlı depolama alanıyla erişilebilen bir konuma taşımak içinFileAPI'yi kullanan kodu dağıtın:- Gizli uygulama dosyalarını
getExternalFilesDir()yönteminin döndürdüğü dizine taşıyın. - Paylaşılan medya dışı dosyaları
Downloads/dizininin uygulamaya özel bir alt dizinine taşıyın.
- Gizli uygulama dosyalarını
- 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.
- Küçük dosyalar veya hassas bilgiler içeren dosyalar:
Context#getCacheDir()kullanın. - Büyük dosyalar veya hassas bilgi içermeyen dosyalar:
Context#getExternalCacheDir()kullanın.
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: