Sdílet prostřednictvím


Externí úložiště

Externí úložiště odkazuje na úložiště souborů, které není v interním úložišti a není výhradně přístupné aplikaci, která je za soubor zodpovědná. Primárním účelem externího úložiště je poskytnout místo pro umístění souborů, které mají být sdíleny mezi aplikacemi nebo které jsou příliš velké, aby se vešly do interního úložiště.

V minulosti externí úložiště odkazovalo na diskový oddíl na vyměnitelném médiu, jako je karta SD (označuje se také jako přenosné úložiště). Tento rozdíl už není tak relevantní, protože se zařízení s Androidem vyvíjejí a řada zařízení s Androidem už nepodporuje vyměnitelné úložiště. Místo toho některá zařízení přidělují některé interní nevolatelné paměti Androidu, která může provádět stejnou funkci jako vyměnitelné médium. To se označuje jako emulované úložiště a stále se považuje za externí úložiště. Některé zařízení s Androidem můžou mít také několik oddílů externího úložiště. Tablet s Androidem (kromě interního úložiště) může mít emulované úložiště a jeden nebo více slotů pro kartu SD. Všechny tyto oddíly se považují za externí úložiště pro Android.

Na zařízeních s více uživateli bude mít každý uživatel vyhrazený adresář v primárním externím oddílu úložiště pro své externí úložiště. Aplikace spuštěné jako jeden uživatel nebudou mít přístup k souborům od jiného uživatele na zařízení. Soubory pro všechny uživatele jsou stále čitelné a zapisovatelné na světě; Android však bude sandboxovat každý profil uživatele od ostatních.

Čtení a zápis do souborů je v Xamarin.Androidu téměř stejné jako u jakékoli jiné aplikace .NET. Aplikace Xamarin.Android určuje cestu k souboru, který bude manipulován, a pak pro přístup k souborům používá standardní idiomy .NET. Vzhledem k tomu, že skutečné cesty k internímu a externímu úložišti se můžou lišit od zařízení po zařízení nebo verze Androidu na verzi Androidu, nedoporučuje se pevně kódovat cestu k souborům. Místo toho Xamarin.Android zveřejňuje nativní rozhraní API androidu, která vám pomůžou určit cestu k souborům v interním a externím úložišti.

Tato příručka popisuje koncepty a rozhraní API v Androidu, které jsou specifické pro externí úložiště.

Veřejné a soukromé soubory v externím úložišti

Existují dva různé typy souborů, které může aplikace udržovat v externím úložišti:

  • Soukromé soubory – Soukromé soubory jsou soubory, které jsou specifické pro vaši aplikaci (ale jsou stále čitelné a zapisovatelné na světě). Android očekává, že soukromé soubory jsou uložené v určitém adresáři v externím úložišti. I když se soubory nazývají "soukromé", jsou stále viditelné a přístupné jinými aplikacemi na zařízení, nejsou si dovolit žádnou zvláštní ochranu androidem.

  • Veřejné soubory – Jedná se o soubory, které nejsou považovány za specifické pro aplikaci a mají být volně sdíleny.

Rozdíly mezi těmito soubory jsou primárně koncepční. Soukromé soubory jsou soukromé v tom smyslu, že jsou považovány za součást aplikace, zatímco veřejné soubory jsou jakékoli jiné soubory, které existují v externím úložišti. Android poskytuje dvě různá rozhraní API pro překlad cest k soukromým a veřejným souborům, ale jinak se stejná rozhraní API .NET používají ke čtení a zápisu do těchto souborů. Jedná se o stejná rozhraní API, která jsou popsána v části věnované čtení a zápisu.

Soukromé externí soubory

Soukromé externí soubory jsou považovány za specifické pro aplikaci (podobně jako interní soubory), ale jsou udržovány v externím úložišti z libovolného počtu důvodů (například příliš velké pro interní úložiště). Podobně jako u interních souborů se tyto soubory odstraní při odinstalaci aplikace uživatelem.

Primární umístění privátních externích souborů je nalezeno voláním metody Android.Content.Context.GetExternalFilesDir(string type). Tato metoda vrátí Java.IO.File objekt, který představuje privátní externí adresář úložiště pro aplikaci. Předání null této metody vrátí cestu k adresáři úložiště uživatele pro aplikaci. Například pro aplikaci s názvem com.companyname.appbalíčku by byl "kořenový" adresář privátních externích souborů:

/storage/emulated/0/Android/data/com.companyname.app/files/

Tento dokument bude odkazovat na adresář úložiště pro soukromé soubory v externím úložišti jako PRIVATE_EXTERNAL_STORAGE.

Parametr je GetExternalFilesDir() řetězec, který určuje adresář aplikace. Jedná se o adresář určený k poskytnutí standardního umístění pro logickou organizaci souborů. Řetězcové hodnoty jsou k dispozici prostřednictvím konstant ve Android.OS.Environment třídě:

Android.OS.Environment Adresář
DirectoryAlarms PRIVATE_EXTERNAL_STORAGE/alarmy
DirectoryDcim PRIVATE_EXTERNAL_STORAGE/DCIM
DirectoryDownloads PRIVATE_EXTERNAL_STORAGE/Stáhnout
DirectoryDocuments PRIVATE_EXTERNAL_STORAGE/dokumenty
DirectoryMovies PRIVATE_EXTERNAL_STORAGE/Filmy
DirectoryMusic PRIVATE_EXTERNAL_STORAGE/Hudba
DirectoryNotifications PRIVATE_EXTERNAL_STORAGE/oznámení
DirectoryPodcasts PRIVATE_EXTERNAL_STORAGE/podcasty
DirectoryRingtones PRIVATE_EXTERNAL_STORAGE/vyzváněcí tóny
DirectoryPictures PRIVATE_EXTERNAL_STORAGE/obrázky

U zařízení s více oddíly externího úložiště budou mít každý oddíl adresář určený pro soukromé soubory. Metoda Android.Content.Context.GetExternalFilesDirs(string type) vrátí pole .Java.IO.Files Každý objekt bude představovat privátní adresář specifický pro aplikaci na všech sdílených/externích úložných zařízeních, kde může aplikace umístit soubory, které vlastní.

Důležité

Přesná cesta k privátnímu externímu adresáři úložiště se může lišit od zařízení po zařízení a mezi verzemi Androidu. Z tohoto důvodu nesmí aplikace pevně kódovat cestu k tomuto adresáři a místo toho používat rozhraní API Xamarin.Android, například Android.Content.Context.GetExternalFilesDir().

Veřejné externí soubory

Veřejné soubory jsou soubory, které existují v externím úložišti, které nejsou uložené v adresáři, který Android přiděluje privátním souborům. Veřejné soubory se při odinstalaci aplikace neodstraní. Aplikace pro Android musí mít udělená oprávnění, aby mohly číst nebo zapisovat jakékoli veřejné soubory. Veřejné soubory mohou existovat kdekoli v externím úložišti, ale podle konvence Android očekává, že veřejné soubory existují v adresáři identifikované vlastností Android.OS.Environment.ExternalStorageDirectory. Tato vlastnost vrátí Java.IO.File objekt, který představuje primární externí adresář úložiště. Například může Android.OS.Environment.ExternalStorageDirectory odkazovat na následující adresář:

/storage/emulated/0/

Tento dokument bude odkazovat na adresář úložiště pro veřejné soubory v externím úložišti jako PUBLIC_EXTERNAL_STORAGE.

Android také podporuje koncept adresářů aplikací na PUBLIC_EXTERNAL_STORAGE. Tyto adresáře jsou přesně stejné jako adresáře aplikací pro PRIVATE_EXTERNAL_STORAGE a jsou popsány v tabulce v předchozí části. Metoda Android.OS.Environment.GetExternalStoragePublicDirectory(string directoryType) vrátí objekt, který odpovídá adresáři Java.IO.File veřejné aplikace. Parametr directoryType je povinný parametr a nemůže být null.

Volání Environment.GetExternalStoragePublicDirectory(Environment.DirectoryDocuments).AbsolutePath například vrátí řetězec, který bude vypadat přibližně takto:

/storage/emulated/0/Documents

Důležité

Přesná cesta k veřejnému externímu adresáři úložiště se může lišit od zařízení po zařízení a mezi verzemi Androidu. Z tohoto důvodu nesmí aplikace pevně kódovat cestu k tomuto adresáři a místo toho používat rozhraní API Xamarin.Android, například Android.OS.Environment.ExternalStorageDirectory.

Práce s externím úložištěm

Jakmile aplikace Xamarin.Android získá úplnou cestu k souboru, měla by k vytváření, čtení, zápisu nebo odstraňování souborů využívat jakákoli standardní rozhraní API .NET. Tím se maximalizuje množství kódu kompatibilního s více platformami pro aplikaci. Než se ale pokusíte o přístup k souboru, musí aplikace Xamarin.Android zajistit, aby k němu bylo možné získat přístup.

  1. Ověřte externí úložiště – V závislosti na povaze externího úložiště je možné, že aplikace nemusí být připojená a použitelná. Všechny aplikace by měly před pokusem o jeho použití zkontrolovat stav externího úložiště.
  2. Proveďte kontrolu oprávnění za běhu – aplikace pro Android musí požádat uživatele o oprávnění, aby měl přístup k externímu úložišti. To znamená, že před jakýmkoli přístupem k souborům by se měla provést žádost o oprávnění za běhu. Průvodce Oprávněními v Xamarin.Android obsahuje další podrobnosti o oprávněních Androidu.

Každý z těchto dvou úkolů bude popsán níže.

Ověření dostupnosti externího úložiště

Prvním krokem před zápisem do externího úložiště je zkontrolovat, jestli je čitelný nebo zapisovatelný. Vlastnost Android.OS.Environment.ExternalStorageState obsahuje řetězec, který identifikuje stav externího úložiště. Tato vlastnost vrátí řetězec, který představuje stav. Tato tabulka je seznamem ExternalStorageState hodnot, které mohou být vráceny Environment.ExternalStorageState:

ExternalStorageState Popis
MediaBadRemoval Média byla náhle odstraněna, aniž by byla řádně odpojena.
Kontrola médií Médium se nachází, ale prochází kontrolou disku.
MediaEjecting Média se právě odpojí a vysunou.
MediaMounted Média se připojují a dají se číst nebo zapisovat do.
MediaMountedReadOnly Média se připojují, ale dají se číst jenom z.
MediaNofs Médium je k dispozici, ale neobsahuje systém souborů vhodný pro Android.
MediaRemoved Neexistují žádná média.
MediaShared Média jsou k dispozici, ale nejsou připojena. Sdílí se přes USB s jiným zařízením.
MediaUnknown Stav média není v Androidu nerozpoznaný.
MediaUnmountable Médium je k dispozici, ale není možné ho připojit androidem.
MediaUnmounted Médium je přítomno, ale není připojeno.

Většina aplikací pro Android bude muset zkontrolovat, jestli je připojené externí úložiště. Následující fragment kódu ukazuje, jak ověřit, že je externí úložiště připojené pro přístup jen pro čtení nebo přístup pro čtení i zápis:

bool isReadonly = Environment.MediaMountedReadOnly.Equals(Environment.ExternalStorageState);
bool isWriteable = Environment.MediaMounted.Equals(Environment.ExternalStorageState);

Oprávnění externího úložiště

Android považuje přístup k externímu úložišti za nebezpečné oprávnění, což obvykle vyžaduje, aby uživatel udělil oprávnění pro přístup k prostředku. Uživatel může toto oprávnění kdykoli odvolat. To znamená, že před jakýmkoli přístupem k souborům by se měla provést žádost o oprávnění za běhu. Aplikace mají automaticky udělená oprávnění ke čtení a zápisu vlastních soukromých souborů. Aplikace můžou po udělení oprávnění uživateli číst a zapisovat soukromé soubory, které patří do jiných aplikací.

Všechny aplikace pro Android musí deklarovat jedno ze dvou oprávnění pro externí úložiště v AndroidManifest.xml . K identifikaci oprávnění musí být do AndroidManifest.xml přidán jeden z následujících dvou uses-permission prvků:

<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />

Poznámka:

Pokud uživatel udělí WRITE_EXTERNAL_STORAGE, pak READ_EXTERNAL_STORAGE je také implicitně udělen. V AndroidManifest.xml není nutné požadovat obě oprávnění.

Oprávnění se můžou přidat také pomocí karty Manifest androidu vlastností řešení:

Průzkumník řešení – Požadovaná oprávnění pro Visual Studio

Obecně řečeno, všechna nebezpečná oprávnění musí být schválena uživatelem. Oprávnění pro externí úložiště jsou anomálie v tom, že existují výjimky tohoto pravidla v závislosti na verzi Androidu, na které je aplikace spuštěná:

Vývojový diagram kontrol oprávnění externího úložiště

Další informace o provádění žádostí o oprávnění modulu runtime najdete v příručce Oprávnění v Xamarin.Android. Monodroid-sample LocalFiles také ukazuje jeden způsob provádění kontrol oprávnění modulu runtime.

Udělení a odvolání oprávnění pomocí ADB

V průběhu vývoje aplikace pro Android může být nutné udělit a odvolat oprávnění k otestování různých pracovních toků souvisejících s kontrolami oprávnění modulu runtime. To je možné provést na příkazovém řádku pomocí ADB. Následující fragmenty kódu příkazového řádku ukazují, jak udělit nebo odvolat oprávnění pomocí ADB pro aplikaci pro Android, jejíž název balíčku je com.companyname.app:

$ adb shell pm grant com.companyname.app android.permission.WRITE_EXTERNAL_STORAGE

$ adb shell pm revoke com.companyname.app android.permission.WRITE_EXTERNAL_STORAGE

Odstraňování souborů

K odstranění souboru z externího úložiště, jako System.IO.File.Deleteje například . Rozhraní JAVA API je také možné používat na úkor přenositelnosti kódu. Příklad:

System.IO.File.Delete("/storage/emulated/0/Android/data/com.companyname.app/files/count.txt");