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

Aby zapewnić użytkownikom większą kontrolę nad plikami i ograniczyć porządek w plikach, Android 10 wprowadził nowy model miejsca na dane dla aplikacji, tzw. miejsce w zakresie. Zakres miejsca na dane zmienia sposób, w jaki aplikacje przechowują pliki w pamięci zewnętrznej i korzystają z nich. Aby ułatwić sobie migrację aplikacji, aby obsługiwała ograniczone miejsce na dane, postępuj zgodnie ze sprawdzonymi metodami dotyczącymi typowych przypadków użycia miejsca na dane opisanych w tym przewodniku. Przypadki użycia dzielą się na 2 kategorie: obsługa plików multimedialnych i obsługa plików innych niż multimedialne.

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 opisujemy typowe przypadki użycia plików multimedialnych (plików wideo, graficznych i audio) i przedstawiamy ogólne podejście, z jakiego może korzystać Twoja aplikacja. Tabela poniżej zawiera podsumowanie każdego z tych przypadków użycia wraz z linkami do poszczególnych sekcji zawierających dalsze informacje.

Przypadek użycia Podsumowanie
Pokaż wszystkie pliki graficzne lub wideo Zrób to samo w przypadku wszystkich wersji Androida.
Wyświetlanie obrazów lub filmów z określonego folderu Zrób to samo w przypadku wszystkich wersji Androida.
Uzyskiwanie dostępu do informacji o lokalizacji ze zdjęć Jeśli aplikacja korzysta z ograniczonego miejsca na dane, użyj jednej metody. Jeśli Twoja aplikacja rezygnuje z korzystania z ograniczonego miejsca na dane, użyj innego podejścia.
Określanie lokalizacji zapisu nowo pobranych plików Jeśli aplikacja korzysta z ograniczonego miejsca na dane, użyj jednej metody. Jeśli Twoja aplikacja rezygnuje z korzystania z ograniczonego miejsca na dane, użyj innego podejścia.
Eksportowanie plików multimedialnych użytkowników na urządzenie Zrób to samo w przypadku wszystkich wersji Androida.
Modyfikowanie lub usuwanie wielu plików multimedialnych w jednej operacji W Androidzie 11 stosuj jedną metodę. W przypadku Androida 10 zrezygnuj z ograniczonego miejsca na dane i użyj rozwiązania z Androida 9 i starszych wersji.
Zaimportuj jeden obraz, który już istnieje Zrób to samo w przypadku wszystkich wersji Androida.
Robienie jednego zdjęcia Zrób to samo w przypadku wszystkich wersji Androida.
Udostępnianie plików multimedialnych innym aplikacjom Zrób to samo w przypadku wszystkich wersji Androida.
Udostępnianie plików multimedialnych określonej aplikacji Zrób to samo w przypadku wszystkich wersji Androida.
Uzyskiwanie dostępu do plików z kodu lub bibliotek, które używają bezpośrednich ścieżek do plików W Androidzie 11 stosuj jedną metodę. W przypadku Androida 10 zrezygnuj z ograniczonego miejsca na dane i użyj rozwiązania z Androida 9 i starszych wersji.

Pokazuj pliki graficzne lub 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.

Pokaż obrazy lub filmy z określonego folderu

Użyj tej metody:

  1. Zgodnie ze sprawdzonymi metodami opisanymi w artykule Przesyłanie prośby o uprawnienia aplikacji poproś o uprawnienie READ_EXTERNAL_STORAGE.
  2. Odzyskaj pliki multimedialne na podstawie wartości parametru MediaColumns.DATA, który zawiera bezwzględną ścieżkę systemu plików do elementu multimedialnego na dysku.

Uwaga: uzyskując dostęp do istniejącego pliku multimedialnego, w logice możesz użyć wartości z kolumny DATA. Wynika to z faktu, że ta wartość ma prawidłową ścieżkę pliku. Nie zakładaj jednak, że plik jest zawsze dostępny. Przygotuj się na ewentualną obsługę wszelkich błędów wejścia-wyjścia opartych na plikach.

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 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.

.

Określ lokalizację zapisu nowo pobranych plików

Jeśli Twoja aplikacja korzysta z pamięci o ograniczonym zakresie, zwróć uwagę na lokalizację, w której przechowujesz pobrane pliki multimedialne.

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

Na Androidzie 11 i nowszych pliki w zewnętrznym katalogu aplikacji nie są dostępne dla innych aplikacji, nawet jeśli pobierasz je przy użyciu DownloadManager.

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

Zdefiniuj prawidłową lokalizację domyślną do przechowywania plików multimedialnych użytkowników:

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

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

Działa na Androidzie 11

Użyj tej metody:

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

    • Jeśli uprawnienia zostały przyznane, kontynuuj operację modyfikowania lub usuwania.
    • Jeśli uprawnienia nie zostały przyznane, wyjaśnij użytkownikowi, dlaczego dana funkcja aplikacji go wymaga.

Dowiedz się więcej o zarządzaniu grupami plików multimedialnych za pomocą metod dostępnych na Androidzie 11 i nowszych.

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.

działa na Androidzie 9 lub starszym,

Użyj tej metody:

  1. Zgodnie ze sprawdzonymi metodami opisanymi w artykule Przesyłanie prośby o uprawnienia aplikacji poproś o uprawnienie WRITE_EXTERNAL_STORAGE.
  2. Aby zmodyfikować lub usunąć pliki multimedialne, użyj interfejsu API MediaStore.

Zaimportuj jeden obraz, który już istnieje

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

Prezentowanie własnego interfejsu

Użyj tej metody:

  1. Zgodnie ze sprawdzonymi metodami opisanymi w artykule Przesyłanie prośby o uprawnienia aplikacji poproś o uprawnienie READ_EXTERNAL_STORAGE.
  2. Użyj interfejsu API query(), aby przesłać zapytanie do kolekcji multimediów.
  3. Wyświetlaj 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 odfiltrować typy obrazów, które selektor systemowy wyświetla użytkownikowi do wyboru, możesz użyć tagów setType() lub EXTRA_MIME_TYPES.

Robienie jednego zdjęcia

Jeśli chcesz zrobić 1 obraz do wykorzystania w aplikacji (np. jako zdjęcie na profilu użytkownika), użyj właściwości ACTION_IMAGE_CAPTURE, aby poprosić użytkownika o zrobienie zdjęcia aparatem urządzenia. System zapisze 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 Androidzie 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

Użyj tej metody:

  1. Zgodnie ze sprawdzonymi metodami opisanymi w artykule Przesyłanie prośby o uprawnienia aplikacji poproś o uprawnienie READ_EXTERNAL_STORAGE.
  2. 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.

działa na Androidzie 9 lub starszym,

Użyj tej metody:

  1. Zgodnie ze sprawdzonymi metodami opisanymi w artykule Przesyłanie prośby o uprawnienia aplikacji poproś o uprawnienie WRITE_EXTERNAL_STORAGE.
  2. Dostęp do plików za pomocą bezpośrednich ścieżek do plików.

Obsługa plików innych niż multimedialne

W tej sekcji opisujemy typowe przypadki użycia plików innych niż multimedialne i wyjaśniamy ogólne podejście, z jakiego aplikacja może korzystać. 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 Zrób to samo w przypadku wszystkich wersji Androida.
Zapisywanie w plikach na dodatkowych woluminach pamięci masowej W Androidzie 11 stosuj jedną metodę. W przypadku starszych wersji Androida użyj innego podejścia.
Migracja istniejących plików ze starszej lokalizacji przechowywania 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 Zrób to samo w przypadku wszystkich wersji Androida.
Pamięć podręczna na pliki inne niż multimedialne Zrób to samo w przypadku wszystkich wersji Androida.
Eksportowanie plików innych niż multimedialne na urządzenie Jeśli aplikacja korzysta z ograniczonego miejsca na dane, użyj jednej metody. 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 odfiltrować typy plików, które selektor systemowy wyświetli użytkownikowi do wyboru, użyj 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 w plikach na dodatkowych woluminach pamięci masowej

Woluminy pamięci dodatkowej obejmują karty SD. Informacje o podanym woluminie miejsca na dane można uzyskać za pomocą klasy StorageVolume.

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

Działa na Androidzie 11

Użyj tej metody:

  1. Użyj modelu ograniczonego miejsca na dane.
  2. Docelowa wersja Androida 10 (poziom interfejsu API 29) lub niższy.
  3. Zadeklaruj uprawnienie WRITE_EXTERNAL_STORAGE.
  4. Wykonaj jeden z tych rodzajów dostępu:
    • Dostęp do plików przez interfejs API MediaStore.
    • 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 ramki 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.

Przenoszenie istniejących plików ze starszej lokalizacji w pamięci masowej

Katalog jest uznawany za starszą lokalizację miejsca na dane, jeśli nie jest katalogiem dotyczącym konkretnej aplikacji ani publicznym katalogiem udostępnionym. Jeśli Twoja aplikacja tworzy lub wykorzystuje pliki w starszej lokalizacji pamięci masowej, zalecamy przeniesienie plików aplikacji do lokalizacji, które są dostępne w ograniczonym zakresie, oraz wprowadzenie niezbędnych zmian w aplikacjach, aby działały z plikami w ograniczonym zakresie.

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

Aby można było przenosić pliki aplikacji do lokalizacji dostępnych w ramach zakresu pamięci, aplikacja musi zachowywać dostęp do starszej lokalizacji pamięci masowej. Wybór 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 rezygnację z ograniczonego miejsca na dane, aby aplikacja nadal miała 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 migracji, użyj tej metody:

  1. Kieruj reklamy na Androida w wersji 10 lub starszej.
  2. Zrezygnuj z ograniczonego miejsca na dane, aby aplikacja miała dostęp do plików, które chcesz przenieść.
  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 aplikacji prywatnych do katalogu zwracanego przez metodę getExternalFilesDir().
    2. Przenieś wszystkie udostępnione pliki inne niż multimedialne do podkatalogu Downloads/ przeznaczonego dla aplikacji.
  4. Usuń starsze katalogi pamięci aplikacji z katalogu /sdcard/.

Po zainstalowaniu nowej wersji aplikacji użytkownicy muszą ukończyć proces migracji danych na swoich urządzeniach. Możesz monitorować proces migracji 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ć sobie pliki, zalecamy korzystanie z usług dostawcy treści w przypadku każdej z nich, a następnie synchronizowanie danych w miarę dodawania aplikacji do kolekcji.

Buforuj pliki inne niż multimedialne

Wybór zależy od typu plików, które chcesz przechowywać w pamięci podręcznej.

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

Określ prawidłową lokalizację domyślną do przechowywania plików innych niż multimedialne. Zezwalaj użytkownikom na eksportowanie plików z katalogów aplikacji do bardziej ogólnej lokalizacji. Pliki inne niż multimedialne możesz wyeksportować na urządzenie za pomocą pobranych plików lub kolekcji dokumentów MediaStore.

Tymczasowo zrezygnuj z miejsca na dane w zakresie

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.

Zrezygnuj z testów

Na urządzeniach z Androidem 10 (poziom interfejsu API 29) i nowszym testy aplikacji są domyślnie przeprowadzane w piaskownicy na dane. Ta piaskownica uniemożliwia aplikacji dostęp do plików spoza katalogu aplikacji i publicznie udostępnianych katalogów.

Jeśli test wyprowadza pliki dla hosta, takie jak zrzuty ekranu, dane debugowania, dane o pokryciu lub wskaźniki wydajności, możesz zapisać je w katalogach globalnych. Aby to zrobić, dodaj tę flagę do odpowiedniej jarzma, która wywołuje funkcję 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 tej flagi, nie możesz sprawdzić zgodności aplikacji z pamięcią w zakresie. Jeśli chcesz przetestować dane wyjściowe, lepiej zapisać dane w pamięci w zakresie aplikacji, która jest czytelna dla powłoki. Możesz pobrać ten katalog ograniczony do aplikacji. Aby określić katalog, z którego ma zostać pobrany plik, wywołaj getExternalMediaDirs().

Rezygnacja w wersji produkcyjnej aplikacji

Jeśli Twoja aplikacja jest kierowana na Androida 10 (poziom interfejsu API 29) lub starszego, możesz tymczasowo zrezygnować z udostępniania ograniczonego miejsca na dane w aplikacji produkcyjnej. Jeśli jednak kierujesz aplikację 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ć działanie aplikacji kierowanej na Androida 10 lub starszego w przypadku korzystania z ograniczonego zakresu pamięci, możesz włączyć to działanie, ustawiając wartość requestLegacyExternalStorage na false. Jeśli testujesz urządzenie z Androidem 11, możesz też użyć flag zgodności aplikacji, aby przetestować działanie aplikacji z zasięgiem pamięci masowej lub bez niego.

Dodatkowe materiały

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

Posty na blogu