Aracılığıyla paylaş


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:

  1. .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.
  2. 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.FilesDirbir dizin için bir dize döndürür. Bu yöntem, System.Environment.SpecialFolderiş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.SpecialFolderiç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 MediaStorealınır. Sıfır bayt dosya adına sahip dizinler. NOMEDIA tarafından MediaStoretaranmayacak.