Xamarin.Android ile Dosya Depolama ve Erişim
Android uygulamaları için yaygın bir gereksinim, resimleri kaydetmek, belgeleri indirmek veya diğer programlarla paylaşmak üzere verileri dışarı aktarmak gibi dosyaları işlemektir. Android (Linux tabanlıdır) dosya depolama alanı sağlayarak bunu destekler. Android, dosya sistemini iki farklı depolama türüne göre gruplandırr:
- İç Depolama: Bu, dosya sisteminin yalnızca uygulama veya işletim sistemi tarafından erişilebilen bir bölümüdür.
- Dış Depolama: Bu, tüm uygulamalar, kullanıcı ve muhtemelen diğer cihazlar tarafından erişilebilen dosyaların depolanması için bir bölümdür. Bazı cihazlarda harici depolama çıkarılabilir (SD kart gibi) olabilir.
Bu gruplandırmalar yalnızca kavramsaldır ve cihazdaki tek bir bölüme veya dizine başvurmak zorunda değildir. Android cihazı her zaman iç depolama ve dış depolama için bölüm sağlar. Bazı cihazlarda dış depolama alanı olarak kabul edilen birden çok bölüm olabilir. Bölüm ne olursa olsun, dosyaları okumak, yazmak veya oluşturmak için API'ler aynıdır. Xamarin.Android uygulamasının dosya erişimi için kullanabileceği iki API kümesi vardır:
- .NET API'leri (Mono tarafından sağlanır ve Xamarin.Android tarafından sarmalanmıştır) – Bunlar Xamarin.Essentials tarafından sağlanan dosya sistemi yardımcılarını içerir. .NET API'leri en iyi platformlar arası uyumluluğu sağlar ve bu nedenle bu kılavuzun odağı bu API'lerde olacaktır.
- Yerel Java dosya erişim API'leri (Java tarafından sağlanan ve Xamarin.Android tarafından sarmalanmış) – Java, dosyaları okumak ve yazmak için kendi API'lerini sağlar. Bunlar .NET API'lerine tamamen kabul edilebilir bir alternatiftir, ancak Android'e özgü olup platformlar arası olması amaçlanan uygulamalar için uygun değildir.
Xamarin.Android'de okuma ve dosyalara yazma, diğer tüm .NET uygulamalarıyla olduğu gibi neredeyse aynıdır. Xamarin.Android uygulaması, işlenecek dosyanın yolunu belirler ve ardından dosya erişimi için standart .NET deyimlerini kullanır. İç ve dış depolamanın gerçek yolları cihazdan cihaza veya Android sürümünden Android sürümüne farklılık gösterebileceğinden, dosyaların yolunu sabit olarak kodlayabilirsiniz. Bunun yerine, dosyaların yolunu belirlemek için Xamarin.Android API'lerini kullanın. Bu şekilde, dosyaları okumak ve yazmak için .NET API'leri, iç ve dış depolamadaki dosyaların yolunu belirlemeye yardımcı olacak yerel Android API'lerini kullanıma sunar.
Dosya erişimiyle ilgili API'leri tartışmadan önce, iç ve dış depolamayı çevreleyen bazı ayrıntıları anlamak önemlidir. Bu, sonraki bölümde ele alınacaktır.
İç ve dış depolama karşılaştırması
Kavramsal olarak, iç depolama ve dış depolama çok benzerdir; her ikisi de Xamarin.Android uygulamasının dosyaları kaydedebileceği yerlerdir. Bu benzerlik, Android'i tanımayan geliştiriciler için kafa karıştırıcı olabilir, bir uygulamanın ne zaman dahili depolama ve dış depolama kullanması gerektiği açık değildir.
İç depolama, Android'in işletim sistemine, API'lere ve tek tek uygulamalar için ayırmış olduğu geçici olmayan belleği ifade eder. Bu alana işletim sistemi veya uygulamalar dışında erişilemez. Android, her uygulama için iç depolama bölümünde bir dizin ayırır. Uygulama kaldırıldığında, bu dizindeki iç depolama alanında tutulan tüm dosyalar da silinir. İç depolama, yalnızca uygulama tarafından erişilebilen ve diğer uygulamalarla paylaşılmayan veya uygulama kaldırıldıktan sonra çok az değere sahip olacak dosyalar için idealdir. Android 6.0 veya üzeri sürümlerde dahili depolamadaki dosyalar, Android 6.0'daki Otomatik Yedekleme özelliği kullanılarak Google tarafından otomatik olarak yedeklenebilir. İç depolamanın aşağıdaki dezavantajları vardır:
- Dosyalar paylaşılamaz.
- Uygulama kaldırıldığında dosyalar silinir.
- İç depolamada kullanılabilir alan sınırlı olabilir.
Dış depolama, iç depolama olmayan ve yalnızca bir uygulama için erişilmeyen dosya depolamayı ifade eder. Dış depolamanın birincil amacı, uygulamalar arasında paylaşılacak veya iç depolamaya sığamayacak kadar büyük dosyaları yerleştirebileceğiniz bir yer sağlamaktır. Dış depolamanın avantajı, normalde dosyalar için iç depolamadan çok daha fazla alana sahip olmasıdır. Ancak, dış depolamanın her zaman bir cihazda bulunması garanti edilmemektedir ve kullanıcıdan erişim için özel izin isteyebilir.
Not
Birden çok kullanıcıyı destekleyen cihazlar için Android, her kullanıcıya hem iç hem de dış depolamada kendi dizinini sağlar. Bu dizine cihazdaki diğer kullanıcılar erişemez. Bu ayrım, iç veya dış depolamadaki dosyalara yolları sabit kodlamadıkları sürece uygulamalar için görünmez.
Temel bir kural olarak, Xamarin.Android uygulamaları makul olduğunda dosyalarını dahili depolama alanına kaydetmeyi tercih etmeli ve dosyaların diğer uygulamalarla paylaşılması gerektiğinde, çok büyük olduğunda veya uygulama kaldırılsa bile saklanması gerektiğinde harici depolamaya güvenmelidir. Örneğin, bir yapılandırma dosyası, oluşturan uygulama dışında hiçbir önemi olmadığından iç depolama için en uygun dosyadır. Buna karşılık, fotoğraflar harici depolama için iyi bir adaydır. Bunlar çok büyük olabilir ve çoğu durumda uygulama kaldırılmış olsa bile kullanıcı bunları paylaşmak veya bunlara erişmek isteyebilir.
Bu kılavuz, iç depolamaya odaklanacaktır. Xamarin.Android uygulamasında dış depolama kullanma hakkında ayrıntılı bilgi için lütfen Dış depolama kılavuzuna bakın.
dahili depolama ile çalışma
Bir uygulamanın iç depolama dizini işletim sistemi tarafından belirlenir ve özelliği tarafından Android uygulamalarına Android.Content.Context.FilesDir
sunulur. Bu, Android'in uygulama için özel olarak ayırdığı dizini temsil eden bir Java.IO.File
nesne döndürür. Örneğin, iç depolama dizininin com.companyname paket adına sahip bir uygulama şu olabilir:
/data/user/0/com.companyname/files
Bu belge, iç depolama dizinine INTERNAL_STORAGE olarak başvurur.
Önemli
dahili depolama dizininin tam yolu cihazdan cihaza ve Android sürümleri arasında farklılık gösterebilir. Bu nedenle, uygulamaların dahili dosyalar depolama dizinine giden yolu sabit olarak kodlamaması ve bunun yerine gibi System.Environment.GetFolderPath()
Xamarin.Android API'lerini kullanmaları gerekir.
Kod paylaşımını en üst düzeye çıkarmak için Xamarin.Android uygulamaları (veya Xamarin.Android'i hedefleyen Xamarin.Forms uygulamaları) yöntemini kullanmalıdır System.Environment.GetFolderPath()
. Xamarin.Android'de, bu yöntem ile aynı konumdaki Android.Content.Context.FilesDir
bir dizin için bir dize döndürür. Bu yöntem, System.Environment.SpecialFolder
işletim sistemi tarafından kullanılan özel klasörlerin yollarını temsil eden bir dizi numaralandırılmış sabiti tanımlamak için kullanılan bir sabit listesi alır. Tüm System.Environment.SpecialFolder
değerler Xamarin.Android'de geçerli bir dizine eşlenmez. Aşağıdaki tabloda, belirli bir değeri System.Environment.SpecialFolder
için hangi yolun bekleyebileceğiniz açıklanmaktadır:
System.Environment.SpecialFolder | Yol |
---|---|
ApplicationData |
INTERNAL_STORAGE/.config |
Desktop |
INTERNAL_STORAGE/Masaüstü |
LocalApplicationData |
INTERNAL_STORAGE/.local/share |
MyDocuments |
INTERNAL_STORAGE |
MyMusic |
INTERNAL_STORAGE/Müzik |
MyPictures |
INTERNAL_STORAGE/Resimler |
MyVideos |
INTERNAL_STORAGE/Videolar |
Personal |
INTERNAL_STORAGE |
Fonts |
INTERNAL_STORAGE/.fonts |
Templates |
INTERNAL_STORAGE/Şablonlar |
CommonApplicationData |
/usr/share |
CommonApplicationData |
/usr/share |
dahili depolamadaki dosyaları okuma veya dosyalara yazma
Bir dosyaya yazmak için C# API'lerinden herhangi biri yeterlidir; tek gereken, uygulamaya ayrılan dizindeki dosyanın yolunu almaktır. Ana iş parçacığını engelleyen dosya erişimiyle ilişkilendirilebilen sorunları en aza indirmek için .NET API'lerinin zaman uyumsuz sürümlerinin kullanılması kesinlikle önerilir.
Bu kod parçacığı, bir uygulamanın iç depolama dizinine UTF-8 metin dosyasına tamsayı yazmanın bir örneğidir:
public async Task SaveCountAsync(int count)
{
var backingFile = Path.Combine(System.Environment.GetFolderPath(System.Environment.SpecialFolder.Personal), "count.txt");
using (var writer = File.CreateText(backingFile))
{
await writer.WriteLineAsync(count.ToString());
}
}
Sonraki kod parçacığı, metin dosyasında depolanan bir tamsayı değerini okumak için tek bir yol sağlar:
public async Task<int> ReadCountAsync()
{
var backingFile = Path.Combine(System.Environment.GetFolderPath(System.Environment.SpecialFolder.Personal), "count.txt");
if (backingFile == null || !File.Exists(backingFile))
{
return 0;
}
var count = 0;
using (var reader = new StreamReader(backingFile, true))
{
string line;
while ((line = await reader.ReadLineAsync()) != null)
{
if (int.TryParse(line, out var newcount))
{
count = newcount;
}
}
}
return count;
}
Xamarin.Essentials Kullanma – Dosya Sistemi Yardımcıları
Xamarin.Essentials, platformlar arası uyumlu kod yazmaya yönelik bir dizi API'dir. Dosya Sistemi Yardımcıları, uygulamanın önbelleğini ve veri dizinlerini bulma işlemini basitleştirmek için bir dizi yardımcı içeren bir sınıftır. Bu kod parçacığı, bir uygulamanın iç depolama dizinini ve önbellek dizinini bulma örneği sağlar:
// Get the path to a file on internal storage
var backingFile = Path.Combine(Xamarin.Essentials.FileSystem.AppDataDirectory, "count.txt");
// Get the path to a file in the cache directory
var cacheFile = Path.Combine(Xamarin.Essentials.FileSystem.CacheDirectory, "count.txt");
Dosyaları MediaStore
MediaStore
, bir Android cihazında medya dosyaları (videolar, müzik, görüntüler) hakkında meta veri toplayan bir Android bileşenidir. Amacı, bu dosyaların cihazdaki tüm Android uygulamaları arasında paylaşımını basitleştirmektir.
Özel dosyalar paylaşılabilir medya olarak gösterilmez. Örneğin, bir uygulama özel dış depolama alanına resim kaydederse, bu dosya medya tarayıcısı (MediaStore
) tarafından alınmaz.
Ortak dosyalar tarafından MediaStore
alınır. Sıfır bayt dosya adına sahip dizinler. NOMEDIA tarafından MediaStore
taranmayacak.