Udostępnij za pośrednictwem


Magazyn plików i dostęp za pomocą platformy Xamarin.Android

Typowym wymaganiem dla aplikacji systemu Android jest manipulowanie plikami — zapisywanie obrazów, pobieranie dokumentów lub eksportowanie danych w celu udostępnienia innym programom. System Android (oparty na systemie Linux) obsługuje tę funkcję, zapewniając miejsce na magazyn plików. System Android grupuje system plików na dwa różne typy magazynu:

  • Magazyn wewnętrzny — jest to część systemu plików, do którego można uzyskać dostęp tylko przez aplikację lub system operacyjny.
  • Magazyn zewnętrzny — jest to partycja do przechowywania plików, które są dostępne dla wszystkich aplikacji, użytkownika i ewentualnie innych urządzeń. Na niektórych urządzeniach magazyn zewnętrzny może być wymienny (na przykład karta SD).

Te grupowania są tylko koncepcyjne i niekoniecznie odwołują się do jednej partycji lub katalogu na urządzeniu. Urządzenie z systemem Android zawsze zapewnia partycję dla magazynu wewnętrznego i magazynu zewnętrznego. Istnieje możliwość, że niektóre urządzenia mogą mieć wiele partycji, które są uważane za magazyn zewnętrzny. Niezależnie od partycji interfejsy API do odczytywania, zapisywania lub tworzenia plików są takie same. Istnieją dwa zestawy interfejsów API, których aplikacja Xamarin.Android może używać do uzyskiwania dostępu do plików:

  1. Interfejsy API platformy .NET (dostarczane przez platformę Mono i opakowane przez platformę Xamarin.Android) — obejmują one pomocników systemu plików udostępnianych przez platformę Xamarin.Essentials. Interfejsy API platformy .NET zapewniają najlepszą zgodność międzyplatformową i w związku z tym skupimy się na tych interfejsach API.
  2. Natywne interfejsy API dostępu do plików Java (udostępniane przez język Java i opakowane przez platformę Xamarin.Android) — język Java udostępnia własne interfejsy API do odczytywania i zapisywania plików. Są to całkowicie akceptowalne alternatywy dla interfejsów API platformy .NET, ale są specyficzne dla systemu Android i nie są odpowiednie dla aplikacji, które mają być międzyplatformowe.

Odczytywanie i zapisywanie w plikach jest prawie identyczne w środowisku Xamarin.Android, podobnie jak w przypadku dowolnej innej aplikacji .NET. Aplikacja Xamarin.Android określa ścieżkę do pliku, który będzie manipulowany, a następnie używa standardowych idiomów platformy .NET na potrzeby dostępu do plików. Ponieważ rzeczywiste ścieżki do magazynu wewnętrznego i zewnętrznego mogą się różnić w zależności od urządzenia do urządzenia lub wersji systemu Android do wersji systemu Android, nie zaleca się kodowania ścieżki do plików. Zamiast tego użyj interfejsów API platformy Xamarin.Android, aby określić ścieżkę do plików. Dzięki temu interfejsy API platformy .NET do odczytywania i zapisywania plików uwidacznia natywne interfejsy API systemu Android, które pomogą określić ścieżkę do plików w magazynie wewnętrznym i zewnętrznym.

Przed omówieniem interfejsów API związanych z dostępem do plików należy zapoznać się z niektórymi szczegółami dotyczącymi magazynu wewnętrznego i zewnętrznego. Zostanie to omówione w następnej sekcji.

Magazyn wewnętrzny i zewnętrzny

Koncepcyjnie magazyn wewnętrzny i magazyn zewnętrzny są bardzo podobne — są to miejsca, w których aplikacja platformy Xamarin.Android może zapisywać pliki. To podobieństwo może być mylące dla deweloperów, którzy nie znają systemu Android, ponieważ nie jest jasne, kiedy aplikacja powinna używać magazynu wewnętrznego a magazynu zewnętrznego.

Magazyn wewnętrzny odnosi się do nietrwałej pamięci przydzielanej przez system Android do systemu operacyjnego, zestawów API i poszczególnych aplikacji. Ta przestrzeń nie jest dostępna z wyjątkiem systemu operacyjnego lub aplikacji. System Android przydzieli katalog w wewnętrznej partycji magazynu dla każdej aplikacji. Po odinstalowaniu aplikacji wszystkie pliki przechowywane w magazynie wewnętrznym w tym katalogu również zostaną usunięte. Magazyn wewnętrzny najlepiej nadaje się do plików, które są dostępne tylko dla aplikacji i które nie będą udostępniane innym aplikacjom lub będą miały bardzo małą wartość po odinstalowaniu aplikacji. W systemie Android 6.0 lub nowszym pliki w magazynie wewnętrznym mogą być automatycznie tworzone przez firmę Google przy użyciu funkcji automatycznej kopii zapasowej w systemie Android 6.0. Magazyn wewnętrzny ma następujące wady:

  • Nie można udostępniać plików.
  • Pliki zostaną usunięte po odinstalowaniu aplikacji.
  • Miejsce dostępne w magazynie wewnętrznym może być ograniczone.

Magazyn zewnętrzny odnosi się do magazynu plików, który nie jest magazynem wewnętrznym i nie jest dostępny wyłącznie dla aplikacji. Głównym celem magazynu zewnętrznego jest zapewnienie miejsca do umieszczania plików, które mają być udostępniane między aplikacjami lub które są zbyt duże, aby zmieścić się w magazynie wewnętrznym. Zaletą magazynu zewnętrznego jest to, że zwykle ma znacznie więcej miejsca dla plików niż magazyn wewnętrzny. Jednak magazyn zewnętrzny nie zawsze musi być obecny na urządzeniu i może wymagać specjalnego uprawnienia od użytkownika w celu uzyskania do niego dostępu.

Uwaga

W przypadku urządzeń obsługujących wielu użytkowników system Android udostępni każdemu użytkownikowi własny katalog zarówno w magazynie wewnętrznym, jak i zewnętrznym. Ten katalog jest niedostępny dla innych użytkowników na urządzeniu. Ta separacja jest niewidoczna dla aplikacji, o ile nie są one zakodowane na stałe ścieżek do plików w magazynie wewnętrznym lub zewnętrznym.

W zasadzie aplikacje platformy Xamarin.Android powinny preferować zapisywanie plików w magazynie wewnętrznym, gdy jest to uzasadnione, i polegać na magazynie zewnętrznym, gdy pliki muszą być udostępniane innym aplikacjom, są bardzo duże lub powinny być zachowywane nawet wtedy, gdy aplikacja zostanie odinstalowana. Na przykład plik konfiguracji najlepiej nadaje się do magazynu wewnętrznego, ponieważ nie ma znaczenia, z wyjątkiem aplikacji, która ją tworzy. Natomiast zdjęcia są dobrym kandydatem do magazynowania zewnętrznego. Mogą być bardzo duże i w wielu przypadkach użytkownik może chcieć je udostępnić lub uzyskać do nich dostęp, nawet jeśli aplikacja zostanie odinstalowana.

Ten przewodnik koncentruje się na magazynie wewnętrznym. Aby uzyskać szczegółowe informacje na temat korzystania z magazynu zewnętrznego w aplikacji platformy Xamarin.Android, zobacz przewodnik Zewnętrzny magazyn .

Praca z magazynem wewnętrznym

Wewnętrzny katalog magazynu aplikacji jest określany przez system operacyjny i jest udostępniany aplikacjom systemu Android przez Android.Content.Context.FilesDir właściwość . Spowoduje to zwrócenie Java.IO.File obiektu reprezentującego katalog przeznaczony wyłącznie dla aplikacji przez system Android. Na przykład aplikacja o nazwie pakietu com.companyname wewnętrznym katalogiem magazynu może być:

/data/user/0/com.companyname/files

Ten dokument będzie odwoływać się do wewnętrznego katalogu magazynu jako INTERNAL_STORAGE.

Ważne

Dokładna ścieżka do wewnętrznego katalogu magazynu może się różnić w zależności od urządzenia do urządzenia i między wersjami systemu Android. W związku z tym aplikacje nie mogą trwale kodować ścieżki do wewnętrznego katalogu magazynu plików, a zamiast tego używają interfejsów API platformy Xamarin.Android, takich jak System.Environment.GetFolderPath().

Aby zmaksymalizować udostępnianie kodu, aplikacje platformy Xamarin.Android (lub aplikacje platformy Xamarin.Forms przeznaczone dla platformy Xamarin.Android) powinny używać System.Environment.GetFolderPath() metody . W środowisku Xamarin.Android ta metoda zwróci ciąg katalogu, który jest tą samą lokalizacją co Android.Content.Context.FilesDir. Ta metoda przyjmuje wyliczenie , System.Environment.SpecialFolderktóre służy do identyfikowania zestawu wyliczonych stałych reprezentujących ścieżki folderów specjalnych używanych przez system operacyjny. Nie wszystkie System.Environment.SpecialFolder wartości będą mapować na prawidłowy katalog na platformie Xamarin.Android. W poniższej tabeli opisano, jakiej ścieżki można oczekiwać dla danej wartości System.Environment.SpecialFolder:

System.Environment.SpecialFolder Ścieżka
ApplicationData INTERNAL_STORAGE/.config
Desktop INTERNAL_STORAGE/desktop
LocalApplicationData INTERNAL_STORAGE/.local/share
MyDocuments INTERNAL_STORAGE
MyMusic INTERNAL_STORAGE/Muzyka
MyPictures INTERNAL_STORAGE/zdjęcia
MyVideos INTERNAL_STORAGE/wideo
Personal INTERNAL_STORAGE
Fonts INTERNAL_STORAGE/.fonts
Templates INTERNAL_STORAGE/szablony
CommonApplicationData /usr/share
CommonApplicationData /usr/share

Odczytywanie lub zapisywanie w plikach w magazynie wewnętrznym

Wszystkie interfejsy API języka C# do zapisywania w pliku są wystarczające. Wystarczy uzyskać ścieżkę do pliku, który znajduje się w katalogu przydzielonym do aplikacji. Zdecydowanie zaleca się użycie asynchronicznych wersji interfejsów API platformy .NET w celu zminimalizowania wszelkich problemów, które mogą być skojarzone z dostępem do plików blokującym główny wątek.

Ten fragment kodu jest jednym z przykładów pisania liczby całkowitej w pliku tekstowym UTF-8 w wewnętrznym katalogu magazynu aplikacji:

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());
    }
}

Następny fragment kodu umożliwia odczytanie wartości całkowitej przechowywanej w pliku tekstowym:

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;
}

Korzystanie z platformy Xamarin.Essentials — pomocnicy systemu plików

Xamarin.Essentials to zestaw interfejsów API do pisania kodu zgodnego z wielu platformami. Pomocnicy systemu plików to klasa zawierająca szereg pomocników ułatwiających lokalizowanie pamięci podręcznej i katalogów danych aplikacji. Ten fragment kodu zawiera przykład znajdowania wewnętrznego katalogu magazynu i katalogu pamięci podręcznej dla aplikacji:

// 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");

Ukrywanie plików z MediaStore

Jest MediaStore to składnik systemu Android, który zbiera metadane dotyczące plików multimedialnych (wideo, muzyki, obrazów) na urządzeniu z systemem Android. Jego celem jest uproszczenie udostępniania tych plików we wszystkich aplikacjach systemu Android na urządzeniu.

Pliki prywatne nie będą wyświetlane jako nośniki udostępnione. Jeśli na przykład aplikacja zapisze obraz w prywatnym magazynie zewnętrznym, ten plik nie zostanie odebrany przez skaner multimediów (MediaStore).

Pliki publiczne zostaną odebrane przez program MediaStore. Katalogi, które mają zero bajtowej nazwy pliku . PROGRAM NOMEDIA nie zostanie przeskanowany przez MediaStoreprogram .