Przypadki użycia i sprawdzone metody dotyczące miejsca na dane na Androidzie

Aby zapewnić użytkownikom większą kontrolę nad plikami i ograniczyć bałagan w plikach, w Androidzie 10 wprowadzono nowy model miejsca na dane w aplikacjach nazywany miejscem ograniczonym do danych. Pamięć podręczna zmienia sposób, w jaki aplikacje przechowują pliki w pamięci zewnętrznej urządzenia i mają do nich dostęp. Aby ułatwić migrację aplikacji do obsługi miejsca na dane o zakresie, skorzystaj ze sprawdzonych metod dotyczących typowych przypadków użycia miejsca na dane opisane w tym przewodniku. Przypadki użycia dzielą się na 2 kategorie: obsługa plików multimedialnych i obsługa plików niemultimedialnych.

Więcej informacji o przechowywaniu plików i uzyskiwaniu do nich dostępu na Androidzie znajdziesz w przewodnikach szkoleniowych dotyczących miejsca na dane.

Obsługa plików multimedialnych

W tej sekcji omawiamy typowe przypadki użycia plików multimedialnych (plików wideo, graficznych i audio) oraz omawiamy ogólne podejście, jakie może stosować Twoja aplikacja. Tabela poniżej zawiera podsumowanie każdego z tych przypadków użycia oraz linki do sekcji zawierających bardziej szczegółowe informacje.

Przypadek użycia Podsumowanie
Pokaż wszystkie pliki graficzne lub wideo Użyj tego samego podejścia w przypadku wszystkich wersji Androida.
Pokazywanie obrazów lub filmów z określonego folderu Użyj tego samego podejścia w przypadku wszystkich wersji Androida.
Uzyskiwanie dostępu do informacji o lokalizacji ze zdjęć Użyj jednej metody, jeśli aplikacja wykorzystuje ograniczone miejsce na dane. Jeśli Twoja aplikacja nie korzysta z ograniczonego miejsca na dane, użyj innego podejścia.
Określanie lokalizacji, w której mają być zapisywane nowo pobrane pliki Użyj jednej metody, jeśli aplikacja wykorzystuje ograniczone miejsce na dane. Jeśli Twoja aplikacja nie korzysta z ograniczonego miejsca na dane, użyj innego podejścia.
Eksportowanie plików multimedialnych użytkowników na urządzenie Użyj tego samego podejścia w przypadku wszystkich wersji Androida.
Modyfikowanie lub usuwanie wielu plików multimedialnych w ramach jednej operacji W przypadku Androida 11 używaj jednego podejścia. W przypadku Androida 10 zrezygnuj z miejsca na dane i zacznij korzystać z tej metody w przypadku Androida 9 i starszych wersji.
Importowanie pojedynczego obrazu, który już istnieje Użyj tego samego podejścia w przypadku wszystkich wersji Androida.
Robienie jednego zdjęcia Użyj tego samego podejścia w przypadku wszystkich wersji Androida.
Udostępnianie plików multimedialnych innym aplikacjom Użyj tego samego podejścia w przypadku wszystkich wersji Androida.
Udostępnianie plików multimedialnych za pomocą określonej aplikacji Użyj tego samego podejścia w przypadku wszystkich wersji Androida.
Dostęp do plików z kodu lub bibliotek, które korzystają z bezpośrednich ścieżek do plików W przypadku Androida 11 używaj jednego podejścia. W przypadku Androida 10 zrezygnuj z miejsca na dane i zacznij korzystać z tej metody w przypadku Androida 9 i starszych wersji.

Pokaż pliki graficzne i wideo z kilku folderów

Wyślij zapytanie do kolekcji multimediów za pomocą interfejsu API query(). Aby filtrować lub sortować pliki multimedialne, dostosuj parametry projection, selection, selectionArgs i sortOrder.

Wyświetlanie obrazów lub filmów z określonego folderu

Zastosuj tę metodę:

  1. Postępuj zgodnie ze sprawdzonymi metodami opisanymi w artykule Uzyskiwanie uprawnień aplikacji i poproś o uprawnienie READ_EXTERNAL_STORAGE.
  2. Pobieraj pliki multimedialne na podstawie wartości MediaColumns.DATA, która zawiera bezwzględną ścieżkę systemu plików do elementu multimedialnego na dysku.

Uwaga: gdy otwierasz istniejący plik multimedialny, możesz użyć wartości z kolumny DATA w logice. Dzieje się tak, ponieważ ta wartość ma prawidłową ścieżkę pliku. Nie zakładaj jednak, że plik jest zawsze dostępny. Przygotuj się na ewentualne błędy wejścia-wyjścia oparte na plikach.

Z kolei do tworzenia lub aktualizowania pliku multimedialnego nie używaj kolumny DATA. Zamiast tego używaj kolumn DISPLAY_NAME i RELATIVE_PATH.

Uzyskiwanie dostępu do informacji o lokalizacji ze zdjęć

Jeśli Twoja aplikacja używa takiego miejsca, wykonaj czynności opisane w przewodniku po miejscu na multimedia, w sekcji Informacje o lokalizacji na zdjęciach.

Określ lokalizację miejsca na dane dla nowych pobranych plików

Jeśli aplikacja wykorzystuje ograniczone miejsce na dane, zwracaj uwagę na lokalizację, w której mają być przechowywane pobrane pliki multimedialne.

Jeśli inne aplikacje wymagają dostępu do plików, możesz używać dobrze zdefiniowanych kolekcji multimediów do pobierania lub kolekcji dokumentów.

Na Androidzie 11 i nowszych pliki znajdujące się w zewnętrznym katalogu aplikacji nie są dostępne dla innych aplikacji, nawet jeśli do ich pobierania używasz DownloadManager.

Eksportowanie plików multimedialnych użytkowników na urządzenie

Określ prawidłową domyślną lokalizację przechowywania plików multimedialnych użytkownika:

Modyfikowanie lub usuwanie wielu plików multimedialnych w ramach jednej operacji

Stosuj logikę opartą na wersjach Androida, na których działa Twoja aplikacja.

Android 11

Zastosuj tę metodę:

  1. Utwórz oczekującą intencję dla żądania zapisu lub usunięcia Twojej aplikacji za pomocą MediaStore.createWriteRequest() lub MediaStore.createTrashRequest(), a następnie poproś użytkownika o pozwolenie na edytowanie zestawu plików przez wywołanie tej intencji.
  2. Oceń odpowiedź użytkownika:

    • Jeśli uprawnienia zostały przyznane, możesz je zmodyfikować lub usunąć.
    • Jeśli uprawnienia nie zostały przyznane, wyjaśnij użytkownikowi, dlaczego dana funkcja w aplikacji ich potrzebuje.

Dowiedz się więcej o tym, jak zarządzać grupami plików multimedialnych za pomocą tych metod, które są dostępne na Androidzie 11 i nowszych.

Android 10

Jeśli Twoja aplikacja jest kierowana na Androida 10 (poziom interfejsu API 29), zrezygnuj z ograniczonego miejsca na dane i nadal korzystaj z metod na Androidzie 9 i starszych, aby wykonywać tę operację.

działa na Androidzie 9 lub starszym,

Zastosuj tę metodę:

  1. Postępuj zgodnie ze sprawdzonymi metodami opisanymi w artykule Uzyskiwanie uprawnień aplikacji i poproś o uprawnienie WRITE_EXTERNAL_STORAGE.
  2. Aby zmodyfikować lub usunąć pliki multimedialne, użyj interfejsu API MediaStore.

Importowanie pojedynczego obrazu, który już istnieje

Jeśli chcesz zaimportować pojedynczy obraz, który już istnieje (aby np. użyć go jako zdjęcia w profilu użytkownika), aplikacja może użyć własnego interfejsu lub selektora systemowego.

Prezentowanie własnego interfejsu

Zastosuj tę metodę:

  1. Postępuj zgodnie ze sprawdzonymi metodami opisanymi w artykule Uzyskiwanie uprawnień aplikacji i poproś o uprawnienie READ_EXTERNAL_STORAGE.
  2. Użyj interfejsu API query(), aby zapytać kolekcję multimediów.
  3. Wyświetl wyniki w niestandardowym interfejsie aplikacji.

Użyj selektora systemowego

Użyj intencji ACTION_GET_CONTENT, która prosi użytkownika o wybranie obrazu do zaimportowania.

Jeśli chcesz przefiltrować typy obrazów wyświetlanych użytkownikowi przez selektor systemowy, możesz użyć setType() lub EXTRA_MIME_TYPES.

Zrób zdjęcie

Jeśli chcesz zapisać pojedynczy obraz do użycia w aplikacji (np. jako zdjęcie w profilu użytkownika), użyj intencji ACTION_IMAGE_CAPTURE, aby poprosić użytkownika o zrobienie zdjęcia aparatem urządzenia. System zapisze zrobione zdjęcie w tabeli MediaStore.Images.

Udostępniaj pliki multimedialne innym aplikacjom

Aby dodać rekordy bezpośrednio do MediaStore, użyj metody insert(). Więcej informacji znajdziesz w sekcji Dodawanie elementu w przewodniku po miejscu na multimedia.

Udostępnianie plików multimedialnych określonej aplikacji

Użyj komponentu FileProvider na Androidzie zgodnie z opisem w przewodniku Konfigurowanie udostępniania plików.

uzyskiwać dostęp do plików z kodu lub bibliotek, które korzystają z bezpośrednich ścieżek plików;

Stosuj logikę opartą na wersjach Androida, na których działa Twoja aplikacja.

Android 11

Zastosuj tę metodę:

  1. Postępuj zgodnie ze sprawdzonymi metodami opisanymi w artykule Uzyskiwanie uprawnień aplikacji i poproś o uprawnienie READ_EXTERNAL_STORAGE.
  2. Dostęp do plików możesz uzyskać za pomocą bezpośrednich ścieżek.

Więcej informacji znajdziesz w sekcji dotyczącej otwierania plików multimedialnych przy użyciu bezpośrednich ścieżek plików.

Android 10

Jeśli Twoja aplikacja jest kierowana na Androida 10 (poziom interfejsu API 29), zrezygnuj z ograniczonego miejsca na dane i nadal korzystaj z metod na Androidzie 9 i starszych, aby wykonywać tę operację.

działa na Androidzie 9 lub starszym,

Zastosuj tę metodę:

  1. Postępuj zgodnie ze sprawdzonymi metodami opisanymi w artykule Uzyskiwanie uprawnień aplikacji i poproś o uprawnienie WRITE_EXTERNAL_STORAGE.
  2. Dostęp do plików możesz uzyskać za pomocą bezpośrednich ścieżek.

Obsługa plików innych niż multimedialne

W tej sekcji omawiamy typowe przypadki użycia plików innych niż multimedialne oraz ogólnie znane podejście do korzystania z aplikacji. Tabela poniżej zawiera podsumowanie każdego z tych przypadków użycia i podaje linki do poszczególnych sekcji, które zawierają bardziej szczegółowe informacje.

Przypadek użycia Podsumowanie
Otwieranie pliku dokumentu Użyj tego samego podejścia w przypadku wszystkich wersji Androida.
Zapisz w plikach w woluminach pamięci dodatkowej W przypadku Androida 11 używaj jednego podejścia. Użyj innego podejścia w przypadku wcześniejszych wersji Androida.
Przenieś istniejące pliki ze starszej lokalizacji miejsca na dane Jeśli to możliwe, przenieś pliki do ograniczonego miejsca na dane. W razie potrzeby zrezygnuj z ograniczonego miejsca na dane w przypadku Androida 10.
Udostępnianie treści innym aplikacjom Użyj tego samego podejścia w przypadku wszystkich wersji Androida.
Buforowanie plików innych niż multimedialne Użyj tego samego podejścia w przypadku wszystkich wersji Androida.
Eksportowanie plików innych niż multimedialne na urządzenie Użyj jednej metody, jeśli aplikacja wykorzystuje ograniczone miejsce na dane. Jeśli Twoja aplikacja nie korzysta z ograniczonego miejsca na dane, użyj innego podejścia.

Otwieranie pliku dokumentu

Użyj intencji ACTION_OPEN_DOCUMENT, aby poprosić użytkownika o wybranie pliku do otwarcia za pomocą selektora systemowego. Jeśli chcesz przefiltrować typy plików, które selektor systemowy będzie wybierać użytkownikowi, możesz użyć setType() lub EXTRA_MIME_TYPES.

Możesz na przykład wyszukać wszystkie pliki PDF, ODT i TXT, korzystając z tego kodu:

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

Zapisz w plikach w woluminach pamięci dodatkowej

Woluminy pamięci dodatkowej obejmują karty SD. Aby uzyskać dostęp do informacji o danym woluminie miejsca na dane, użyj klasy StorageVolume.

Stosuj logikę opartą na wersji Androida, na której działa Twoja aplikacja.

Android 11

Zastosuj tę metodę:

  1. Użyj modelu ograniczonego miejsca na dane.
  2. Kierowanie na Androida 10 (poziom interfejsu API 29) lub niższego.
  3. Zadeklaruj uprawnienie WRITE_EXTERNAL_STORAGE.
  4. Wykonaj jeden z tych warunków dostępu:
    • Dostęp do plików za pomocą interfejsu API MediaStore.
    • Bezpośredni dostęp do ścieżki pliku przy użyciu interfejsów API takich jak File czy fopen().

Działa w starszych wersjach

Użyj struktury dostępu do pamięci, która pozwala użytkownikom wybrać lokalizację na dodatkowym woluminie pamięci masowej, w którym aplikacja może zapisać plik.

Przenoszenie istniejących plików ze starszej lokalizacji przechowywania

Katalog jest uważany za starszą lokalizację przechowywania, jeśli nie jest katalogiem specyficznym dla aplikacji ani publicznym katalogiem udostępnionym. Jeśli aplikacja tworzy lub wykorzystuje pliki w starszym miejscu na dane, zalecamy przeniesienie plików aplikacji do lokalizacji dostępnych w ramach ograniczonego miejsca na dane i wprowadzenie zmian w aplikacji, aby można było pracować z plikami zapisanymi w zakresie.

Zachowaj dostęp do starszej lokalizacji miejsca na dane na potrzeby migracji danych

Aby można było przenieść pliki aplikacji do lokalizacji dostępnych w ograniczonym zakresie miejsca na dane, aplikacja musi utrzymać dostęp do starszej lokalizacji pamięci masowej. Podejście, z którego należy skorzystać, zależy od docelowego poziomu interfejsu API aplikacji.

Jeśli aplikacja jest kierowana na Androida 11
  1. Ustaw flagę preserveLegacyExternalStorage na true, aby zachować starszy model pamięci masowej, aby Twoja aplikacja mogła przenosić dane użytkownika po przejściu na nową wersję aplikacji kierowanej na Androida 11.

  2. Nadal rezygnuj z ograniczonego miejsca na dane, aby aplikacja nadal miała dostęp do plików na urządzeniach z Androidem 10 w starszej lokalizacji.

Jeśli aplikacja jest kierowana na Androida 10

Zrezygnuj z ograniczonego miejsca na dane, aby ułatwić sobie zachowanie działania aplikacji w różnych wersjach Androida.

Migracja danych aplikacji

Gdy aplikacja będzie gotowa do migracji, wykonaj te czynności:

  1. Kieruj na Androida 10 lub starszego.
  2. Zrezygnuj z ograniczonego miejsca na dane, by aplikacja miała dostęp do plików, które chcesz przenieść.
  3. Wdróż kod, który wykorzystuje interfejs API File do przenoszenia plików z ich bieżącej lokalizacji w lokalizacji /sdcard/ do lokalizacji dostępnej z miejscem na dane o ograniczonym zakresie:

    1. Przenieś wszystkie prywatne pliki aplikacji do katalogu zwracanego przez metodę getExternalFilesDir().
    2. Przenieś wszystkie udostępnione pliki niemultimedialne do podkatalogu przeznaczonego dla aplikacji w katalogu Downloads/.
  4. Usuń starsze katalogi pamięci aplikacji z katalogu /sdcard/.

Gdy użytkownicy zainstalują nową wersję Twojej aplikacji, zakończą proces migracji danych na swoich urządzeniach. Możesz utworzyć zdarzenie Analytics, aby monitorować proces migracji użytkowników.

Gdy użytkownicy przeniosą swoje dane, opublikuj kolejną aktualizację aplikacji, którą kierujesz na Androida 11.

Udostępnianie treści innym aplikacjom

Aby udostępnić pliki aplikacji jednej innej aplikacji, użyj FileProvider. W przypadku aplikacji, które muszą udostępniać sobie pliki, zalecamy korzystanie z usług dostawcy treści w przypadku każdej aplikacji, a potem synchronizowanie danych w miarę dodawania aplikacji do kolekcji.

Buforuj pliki inne niż multimedialne

Podejście, które należy zastosować, zależy od typu plików, które chcesz zapisywać w pamięci podręcznej.

Eksportowanie plików innych niż multimedialne na urządzenie

Określ prawidłową domyślną lokalizację przechowywania plików innych niż multimedialne. Zezwalaj użytkownikom na eksportowanie plików z katalogów aplikacji do bardziej ogólnie dostępnej lokalizacji. Użyj plików do pobrania lub kolekcji dokumentów z MediaStore, aby wyeksportować na urządzenie pliki inne niż multimedialne.

Tymczasowe zrezygnowanie z miejsca na dane

Zanim Twoja aplikacja będzie w pełni zgodna z ograniczonym miejscem na dane, możesz tymczasowo z niej zrezygnować, zarówno w testach, jak i w aplikacji produkcyjnej.

Rezygnacja z testów

Na Androidzie 10 (poziom interfejsu API 29) i nowszych testy aplikacji są domyślnie przeprowadzane w piaskownicy pamięci masowej. Ta piaskownica uniemożliwia aplikacji dostęp do plików spoza katalogu aplikacji i katalogów udostępnionych publicznie.

Jeśli test generuje pliki dla hosta – na przykład zrzuty ekranu, dane debugowania, dane o pokryciu lub dane o wydajności – możesz je zapisać w katalogach globalnych. Aby to zrobić, dodaj to oznaczenie do odpowiedniej uprzęży, która wywołuje am instrument:

-e no-isolated-storage 1

Ta flaga wpływa na wszystkie zachowanie instrumentowanego przypadku testowego i ma wpływ na cały wywołany kod testowy. Dlatego użycie tej flagi nie pozwala sprawdzić zgodności aplikacji z ograniczonym miejscem na dane. W przypadku danych wyjściowych lepiej zapisać dane w pamięci o zakresie na poziomie aplikacji czytelnej dla powłoki. Następnie można pobrać katalog ograniczony do aplikacji. Aby określić, z którego katalogu pobrać plik, wywołaj metodę getExternalMediaDirs().

Rezygnacja w produkcyjnej wersji aplikacji

Jeśli Twoja aplikacja jest kierowana na Androida 10 (poziom interfejsu API 29) lub niższy, możesz tymczasowo zrezygnować z ograniczonego miejsca na dane w aplikacji produkcyjnej. Jeśli jednak kierujesz aplikację na Androida 10, musisz ustawić wartość requestLegacyExternalStorage na true w pliku manifestu aplikacji:

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

Aby przetestować zachowanie aplikacji kierowanej na Androida 10 lub starszego, gdy korzysta ona z pamięci o określonym zakresie, możesz włączyć to działanie, ustawiając wartość requestLegacyExternalStorage na false. Jeśli przeprowadzasz testy na urządzeniu z Androidem 11, możesz też użyć flag zgodności aplikacji, aby przetestować działanie aplikacji z ograniczonym miejscem na dane lub bez niego.

Dodatkowe materiały

Więcej informacji o pamięci Androida znajdziesz w tych materiałach:

Posty na blogu