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

Aby zapewnić użytkownikom większą kontrolę nad plikami i ograniczyć ich bałagan, w Androidzie 10 wprowadziliśmy nową metodę przechowywania danych w aplikacjach, zwaną storage wydzielonym. Ograniczony dostęp do pamięci zmienia sposób, w jaki aplikacje przechowują pliki i do nich uzyskują dostęp na zewnętrznej pamięci urządzenia. Aby ułatwić sobie migrację aplikacji na obsługę ograniczonego miejsca na dane, stosuj sprawdzone metody dotyczące typowych przypadków użycia miejsca na dane opisane w tym przewodniku. Przypadki użycia są podzielone na 2 kategorie: obsługa plików multimedialnych i obsługa plików niemultimedialnych.

W wielu przypadkach Twoja aplikacja tworzy pliki, do których inne aplikacje nie powinny mieć dostępu. System udostępnia lokalizacje przechowywania dla poszczególnych aplikacji, które umożliwiają zarządzanie takimi plikami.

Więcej informacji o przechowywaniu plików i dostępie do nich na urządzeniach z Androidem znajdziesz w przewodnikach dotyczących miejsca na dane.

Obsługa plików multimedialnych

W tej sekcji opisano kilka typowych przypadków użycia dotyczących obsługi plików multimedialnych (plików wideo, obrazów i dźwięku) oraz ogólne podejście, którego może używać aplikacja. Tabela poniżej zawiera podsumowanie tych przypadków użycia oraz linki do sekcji, w których znajdziesz więcej informacji.

Przypadek użycia Podsumowanie
Pokaż wszystkie pliki z obrazami lub filmami Stosuj to samo podejście we wszystkich wersjach Androida.
Wyświetlanie obrazów lub filmów z określonego folderu Stosuj to samo podejście we wszystkich wersjach Androida.
Dostęp do informacji o lokalizacji ze zdjęć Jeśli Twoja aplikacja korzysta z ograniczonego dostępu do miejsca na dane, zastosuj jedno z tych podejść. Jeśli Twoja aplikacja nie korzysta z ograniczonego dostępu do miejsca na dane, zastosuj inne podejście.
Definiowanie lokalizacji przechowywania nowych pobranych plików Jeśli Twoja aplikacja korzysta z ograniczonego dostępu do miejsca na dane, zastosuj jedno z tych podejść. Jeśli Twoja aplikacja nie korzysta z ograniczonego dostępu do miejsca na dane, zastosuj inne podejście.
Eksportowanie plików multimediów użytkownika na urządzenie Stosuj to samo podejście we wszystkich wersjach Androida.
Modyfikowanie lub usuwanie wielu plików multimedialnych w jednej operacji Użyj jednego podejścia w przypadku Androida 11. W przypadku Androida 10 zrezygnuj ze skanowania ograniczonego zakresem i zamiast tego zastosuj podejście stosowane w przypadku Androida 9 i starszych wersji.
Zaimportuj jeden obraz, który już istnieje Stosuj to samo podejście we wszystkich wersjach Androida.
Robienie jednego zdjęcia Stosuj to samo podejście we wszystkich wersjach Androida.
Udostępnianie plików multimedialnych za pomocą innych aplikacji Stosuj to samo podejście we wszystkich wersjach Androida.
Udostępnianie plików multimedialnych określonej aplikacji Stosuj to samo podejście we wszystkich wersjach Androida.
Uzyskiwanie dostępu do plików z kodu lub bibliotek, które używają bezpośrednich ścieżek plików Użyj jednego podejścia w przypadku Androida 11. W przypadku Androida 10 zrezygnuj ze skanowania ograniczonego zakresem i zamiast tego zastosuj podejście stosowane w przypadku Androida 9 i starszych wersji.

Pokazuj pliki graficzne lub wideo z kilku folderów

Wysyłanie zapytania do kolekcji multimediów za pomocą interfejsu API query(). Aby filtrować lub sortować pliki multimedialne, dostosuj parametry projection, selection, selectionArgs i sortOrder.

wyświetlać obrazy lub filmy z określonego folderu.

Skorzystaj z tego podejścia:

  1. Zgodnie ze sprawdzonymi metodami opisanymi w artykule na temat żądania uprawnień aplikacji poproś o uprawnienie READ_EXTERNAL_STORAGE.
  2. Pobierz pliki multimedialne na podstawie wartości parametru MediaColumns.DATA, który zawiera bezwzględną ścieżkę do pliku multimedialnego na dysku.

Uwaga: gdy uzyskujesz dostęp do istniejącego pliku multimedialnego, możesz użyć wartości w kolumnie DATA w swojej logice. Wynika to z faktu, że ta wartość ma prawidłową ścieżkę pliku. Nie zakładaj jednak, że plik jest zawsze dostępny. Bądź przygotowany na ewentualne błędy we/wy związane z plikami.

Aby utworzyć lub zaktualizować plik multimedialny, 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 korzysta z pamięci w zakresie ograniczonym, wykonaj czynności opisane w przewodniku po pamięci masowej w sekcji Informacje o lokalizacji na zdjęciach.

Definiowanie lokalizacji zapisu nowych plików pobranych

Jeśli Twoja aplikacja korzysta z ograniczonego miejsca na dane, pamiętaj o tym, gdzie zapisujesz pobrane pliki multimedialne.

Jeśli inne aplikacje wymagają dostępu do plików, rozważ użycie dobrze zdefiniowanych kolekcji multimediów na potrzeby pobierania lub kolekcji dokumentów.

W Androidzie 11 i nowszych pliki w zewnętrznym katalogu aplikacji są niedostępne dla innych aplikacji, nawet jeśli używasz do ich pobierania polecenia DownloadManager.

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

Określ odpowiednią domyślną lokalizację do przechowywania plików multimedialnych użytkownika:

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

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

Działa na Androidzie 11

Skorzystaj z tego podejścia:

  1. Utwórz oczekujący zamiar dla żądania zapisu lub usunięcia w aplikacji za pomocą MediaStore.createWriteRequest() lub MediaStore.createTrashRequest(), a następnie poproś użytkownika o zezwolenie na edytowanie zbioru plików, wywołując ten zamiar.
  2. Oceń odpowiedź użytkownika:

    • Jeśli uprawnienia zostały przyznane, kontynuuj operację modyfikowania lub usuwania.
    • Jeśli użytkownik nie przyznał uprawnień, wyjaśnij mu, dlaczego funkcja w aplikacji ich potrzebuje.

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

działa w Androidzie 10,

Jeśli Twoja aplikacja jest kierowana na Androida 10 (poziom interfejsu API 29), zrezygnuj z ograniczonego miejsca na dane i nadal używaj tej samej metody co w Androidzie 9 lub starszym.

działa na Androidzie 9 lub starszym,

Skorzystaj z tego podejścia:

  1. Zgodnie ze sprawdzonymi metodami opisanymi w artykule na temat żądania uprawnień aplikacji 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ć istniejący już obraz (np. do użycia jako zdjęcie profilowe użytkownika), aplikacja może użyć do tego celu własnego interfejsu użytkownika lub selektora systemowego.

Prezentowanie własnego interfejsu

Skorzystaj z tego podejścia:

  1. Zgodnie ze sprawdzonymi metodami opisanymi w artykule na temat żądania uprawnień aplikacji poproś o uprawnienie READ_EXTERNAL_STORAGE.
  2. Użyj interfejsu API query(), aby wysłać zapytanie do kolekcji multimediów.
  3. Wyświetlanie wyników 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 odfiltrować typy obrazów, które system udostępnia użytkownikowi, możesz użyć setType() lub EXTRA_MIME_TYPES.

Robienie jednego zdjęcia

Jeśli chcesz wykonać pojedyncze zdjęcie, aby użyć go w aplikacji (np. jako zdjęcia do profilu użytkownika), użyj intencji ACTION_IMAGE_CAPTURE, aby poprosić użytkownika o zrobienie zdjęcia za pomocą aparatu urządzenia. System przechowuje zrobione zdjęcie w tabeli MediaStore.Images.

Udostępnianie plików multimedialnych innym aplikacjom

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

Udostępnianie plików multimedialnych określonej aplikacji

Użyj komponentu FileProvider na urządzeniu z Androidem zgodnie z opisem w przewodniku Konfigurowanie udostępniania plików.

Dostęp do plików z kodu lub bibliotek, które używają bezpośrednich ścieżek do plików

Stosuj logikę na podstawie wersji Androida, na których działa Twoja aplikacja.

Działa na Androidzie 11

Skorzystaj z tego podejścia:

  1. Zgodnie ze sprawdzonymi metodami opisanymi w artykule na temat żądania uprawnień aplikacji poproś o uprawnienie READ_EXTERNAL_STORAGE.
  2. Uzyskiwać dostęp do plików za pomocą bezpośrednich ścieżek do plików.

Więcej informacji znajdziesz w sekcji o otwieraniu plików multimedialnych za pomocą bezpośrednich ścieżek do plików.

Działa na Androidzie 10

Jeśli Twoja aplikacja jest kierowana na Androida 10 (poziom interfejsu API 29), zrezygnuj z ograniczonego miejsca na dane i nadal korzystaj z tej metody w Androidzie 9 lub starszym.

Android 9 lub starszy

Skorzystaj z tego podejścia:

  1. Zgodnie ze sprawdzonymi metodami opisanymi w artykule na temat żądania uprawnień aplikacji poproś o uprawnienie WRITE_EXTERNAL_STORAGE.
  2. Uzyskiwać dostęp do plików za pomocą bezpośrednich ścieżek do plików.

Obsługa plików niemultimediów

W tej sekcji opisaliśmy kilka typowych przypadków użycia dotyczących obsługi plików niebędących plikami multimedialnymi oraz ogólne podejście, którego może używać aplikacja. Tabela poniżej zawiera podsumowanie każdego z tych przypadków użycia oraz linki do poszczególnych sekcji, które zawierają dalsze szczegółowe informacje.

Przypadek użycia Podsumowanie
Otwieranie pliku dokumentu Stosuj to samo podejście we wszystkich wersjach Androida.
Zapisywanie danych w plikach na woluminach pamięci pomocniczej Użyj jednego podejścia w przypadku Androida 11. W przypadku starszych wersji Androida należy zastosować inne podejście.
Przenoszenie istniejących plików ze starego miejsca na dane W miarę możliwości przenieś pliki do ograniczonego zakresu pamięci. W razie potrzeby zrezygnuj z ograniczonego miejsca na dane w Androidzie 10.
Udostępnianie treści innym aplikacjom Stosuj to samo podejście we wszystkich wersjach Androida.
Pamięć podręczna na pliki inne niż multimedialne Stosuj to samo podejście we wszystkich wersjach Androida.
Eksportowanie plików niemultimediów na urządzenie Jeśli Twoja aplikacja korzysta z ograniczonego dostępu do miejsca na dane, zastosuj jedno z tych podejść. Jeśli Twoja aplikacja rezygnuje z korzystania 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 filtrować typy plików, które selektor systemowy ma wyświetlać użytkownikowi, możesz użyć setType() lub EXTRA_MIME_TYPES.

Możesz na przykład znaleźć wszystkie pliki PDF, ODT i TXT, używając 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);

zapisywanie danych do plików na woluminach pamięci dodatkowej,

Do pamięci dodatkowej należą karty SD. Informacje o danym woluminie pamięci masowej można uzyskać, korzystając z klasy StorageVolume.

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

Uruchomienie na Androidzie 11

Użyj tej metody:

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

Działa na starszych wersjach

Użyj struktury dostępu do miejsca na dane, która umożliwia użytkownikom wybór lokalizacji w woluminie dodatkowym, w której aplikacja może zapisać plik.

Migracja istniejących plików z uprzednio używanego miejsca na dane

Katalog jest uważany za starszą lokalizację pamięci masowej, jeśli nie jest katalogiem specyficznym dla aplikacji ani publicznym katalogiem współdzielonym. Jeśli Twoja aplikacja tworzy lub zużywa pliki w starszej lokalizacji pamięci, zalecamy przeniesienie plików aplikacji do lokalizacji dostępnych za pomocą ograniczonej pamięci i wprowadzenie niezbędnych zmian w aplikacji, aby mogła pracować z plikami w ograniczonej pamięci.

Zachowywanie dostępu do starszej lokalizacji pamięci na potrzeby migracji danych

Aplikacja musi zachować dostęp do starszego miejsca na dane, aby przenieść pliki aplikacji do lokalizacji dostępnych za pomocą ograniczonego miejsca na dane. Sposób, w jaki należy to zrobić, zależy od docelowego poziomu interfejsu API aplikacji.

Jeśli Twoja aplikacja jest kierowana na Androida 11
  1. Ustaw flagę preserveLegacyExternalStorage na true, aby zachować starszy model pamięci i umożliwić migrację danych użytkownika po przejściu na nową wersję aplikacji kierowanej na Androida 11.

  2. Kontynuuj wycofywanie ograniczonego dostępu do pamięci, aby Twoja aplikacja mogła nadal uzyskiwać dostęp do plików w starszej lokalizacji pamięci na urządzeniach z Androidem 10.

Jeśli Twoja aplikacja jest kierowana na Androida 10

Zrezygnuj z ograniczonego miejsca na dane, aby ułatwić sobie zarządzanie działaniem aplikacji w różnych wersjach Androida.

Migracja danych aplikacji

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

  1. kierować aplikację na Androida 10 lub starszego;
  2. Wyłącz ograniczoną pamięć, aby aplikacja miała dostęp do plików, które są potrzebne do przeniesienia.
  3. Wdróż kod, który za pomocą interfejsu API File przenosi pliki z bieżącej lokalizacji w regionie /sdcard/ do lokalizacji, która jest dostępna w ramach miejsca na dane o zakresie:

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

Po zainstalowaniu nowej wersji aplikacji użytkownicy kończą proces migracji danych na swoich urządzeniach. Możesz monitorować proces migracji wśród całej grupy użytkowników, tworząc zdarzenie Analytics.

Po przeniesieniu danych przez użytkowników opublikuj kolejną aktualizację aplikacji, która będzie kierowana na Androida 11.

Udostępnianie treści innym aplikacjom

Aby udostępnić pliki aplikacji innej aplikacji, użyj FileProvider. W przypadku aplikacji, które muszą udostępniać pliki między sobą, zalecamy użycie dostawcy treści dla każdej aplikacji, a następnie zsynchronizowanie danych po dodaniu aplikacji do kolekcji.

Pamięć podręczna plików niemultimediów

Sposób, którego należy użyć, zależy od typu plików, które chcesz zapisać w pamięci podręcznej.

Eksportowanie plików niemultimediów na urządzenie

Określ odpowiednią domyślną lokalizację do przechowywania plików niemultimedialnych. Zezwalanie użytkownikom na eksportowanie plików z katalogów aplikacji do bardziej ogólnie dostępnej lokalizacji. Aby wyeksportować na urządzenie pliki inne niż multimedialne, użyj pobieranych plików lub kolekcji dokumentów w MediaStore.

Obsługa plików związanych z aplikacją

Jeśli Twoja aplikacja tworzy pliki, do których inne aplikacje nie potrzebują dostępu lub do których nie powinny mieć dostępu, możesz je przechowywać w miejscach przechowywania danych dla aplikacji.

Katalogi pamięci wewnętrznej

System uniemożliwia innym aplikacjom dostęp do tych lokalizacji, a w Androidzie 10 (poziom interfejsu API 29) i nowszych są one szyfrowane. Te lokalizacje to dobre miejsce na przechowywanie danych poufnych, do których dostęp ma tylko Twoja aplikacja.

Katalogi pamięci zewnętrznej

Jeśli w pamięci wewnętrznej nie ma wystarczająco dużo miejsca na pliki aplikacji, rozważ użycie pamięci zewnętrznej. Inna aplikacja może dostępować do tych katalogów, jeśli ma odpowiednie uprawnienia, ale pliki przechowywane w tych katalogach są przeznaczone tylko do użytku Twojej aplikacji.

W Androidzie 4.4 (poziom API 19) lub nowszym aplikacja nie musi prosić o żadne uprawnienia związane z pamięcią, aby uzyskać dostęp do katalogów aplikacji w pamięci zewnętrznej.

Gdy użytkownik odinstaluje aplikację, pliki zapisane w pamięci konkretnej aplikacji zostaną usunięte. Nie należy więc używać tej pamięci do zapisywania czegokolwiek, co użytkownik chce zachować niezależnie od aplikacji.

Tymczasowe wyłączenie ograniczonego miejsca na dane

Zanim Twoja aplikacja będzie w pełni zgodna z pamięcią w zakresie, możesz tymczasowo zrezygnować z tej funkcji zarówno w testach, jak i w aplikacji produkcyjnej.

Wycofanie zgody na udział w testach

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

Jeśli test wygeneruje pliki dla hosta, takie jak zrzuty ekranu, dane debugowania, dane dotyczące zasięgu lub dane o wydajności, możesz zapisać te pliki w katalogach globalnych. Aby to zrobić, dodaj ten parametr do odpowiedniego gniazda, które wywołuje am instrument:

-e no-isolated-storage 1

Ta flaga wpływa na wszystkie zachowanie instrumentowanego przypadku testowego i dotyczy wszystkich wywołanych kodów testowych. Dlatego, gdy używasz tego parametru, nie możesz sprawdzić zgodności aplikacji z ograniczonym miejscem na dane. Jeśli chcesz przetestować dane wyjściowe, lepiej zapisać dane w pamięci w zakresie aplikacji, która jest czytelna dla powłoki. Następnie możesz pobrać ten katalog ograniczony do aplikacji. Aby określić katalog, z którego ma zostać pobrany plik, wywołaj getExternalMediaDirs().

Rezygnacja z usługi w wersji produkcyjnej aplikacji

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

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

Aby przetestować, jak aplikacja kierowana na Androida 10 lub niższą wersję działa z użyciem ograniczonego miejsca na dane, możesz włączyć to zachowanie, ustawiając wartość requestLegacyExternalStorage na false. Jeśli testujesz aplikację na urządzeniu z Androidem 11, możesz też użyć flag zgodności aplikacji, aby przetestować jej działanie z dostępem do ograniczonego miejsca na dane lub bez niego.

Dodatkowe materiały

Więcej informacji o miejscu na dane w Androidzie znajdziesz w tych materiałach:

Posty na blogu