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ę:
- Postępuj zgodnie ze sprawdzonymi metodami opisanymi w artykule Uzyskiwanie uprawnień aplikacji i poproś o uprawnienie
READ_EXTERNAL_STORAGE
. - 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:
- Zezwalaj użytkownikom na decydowanie, czy ich pliki multimedialne mają być dostępne do odczytu dla innych aplikacji, w zależności od ustawienia pamięci dla aplikacji lub pamięci współdzielonej.
- Zezwalaj użytkownikom na eksportowanie plików z katalogów aplikacji do bardziej ogólnie dostępnej lokalizacji. Użyj kolekcji obrazów, filmów i dźwięków MediaStore, aby wyeksportować pliki multimedialne do galerii na urządzeniu.
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ę:
- Utwórz oczekującą intencję dla żądania zapisu lub usunięcia Twojej aplikacji za pomocą
MediaStore.createWriteRequest()
lubMediaStore.createTrashRequest()
, a następnie poproś użytkownika o pozwolenie na edytowanie zestawu plików przez wywołanie tej intencji. 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ę:
- Postępuj zgodnie ze sprawdzonymi metodami opisanymi w artykule Uzyskiwanie uprawnień aplikacji i poproś o uprawnienie
WRITE_EXTERNAL_STORAGE
. - 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ę:
- Postępuj zgodnie ze sprawdzonymi metodami opisanymi w artykule Uzyskiwanie uprawnień aplikacji i poproś o uprawnienie
READ_EXTERNAL_STORAGE
. - Użyj interfejsu API
query()
, aby zapytać kolekcję multimediów. - 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ę:
- Postępuj zgodnie ze sprawdzonymi metodami opisanymi w artykule Uzyskiwanie uprawnień aplikacji i poproś o uprawnienie
READ_EXTERNAL_STORAGE
. - 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ę:
- Postępuj zgodnie ze sprawdzonymi metodami opisanymi w artykule Uzyskiwanie uprawnień aplikacji i poproś o uprawnienie
WRITE_EXTERNAL_STORAGE
. - 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ę:
- Użyj modelu ograniczonego miejsca na dane.
- Kierowanie na Androida 10 (poziom interfejsu API 29) lub niższego.
- Zadeklaruj uprawnienie
WRITE_EXTERNAL_STORAGE
. - 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
czyfopen()
.
- Dostęp do plików za pomocą interfejsu API
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
Ustaw flagę
preserveLegacyExternalStorage
natrue
, 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.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:
- Kieruj na Androida 10 lub starszego.
- Zrezygnuj z ograniczonego miejsca na dane, by aplikacja miała dostęp do plików, które chcesz przenieść.
-
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:- Przenieś wszystkie prywatne pliki aplikacji do katalogu zwracanego przez metodę
getExternalFilesDir()
. - Przenieś wszystkie udostępnione pliki niemultimedialne do podkatalogu przeznaczonego dla aplikacji w katalogu
Downloads/
.
- Przenieś wszystkie prywatne pliki aplikacji do katalogu zwracanego przez metodę
- 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.
- Małe pliki lub pliki zawierające informacje poufne: użyj usługi
Context#getCacheDir()
. - Duże pliki lub pliki, które nie zawierają informacji poufnych: użyj
Context#getExternalCacheDir()
.
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: