Penyimpanan dan Akses File dengan Xamarin.Android
Persyaratan umum untuk aplikasi Android adalah memanipulasi file - menyimpan gambar, mengunduh dokumen, atau mengekspor data untuk dibagikan dengan program lain. Android (yang didasarkan pada Linux) mendukung ini dengan menyediakan ruang untuk penyimpanan file. Android mengelompokkan sistem file ke dalam dua jenis penyimpanan yang berbeda:
- Penyimpanan Internal - ini adalah bagian dari sistem file yang hanya dapat diakses oleh aplikasi atau sistem operasi.
- Penyimpanan Eksternal – ini adalah partisi untuk penyimpanan file yang dapat diakses oleh semua aplikasi, pengguna, dan mungkin perangkat lain. Pada beberapa perangkat, penyimpanan eksternal mungkin dapat dilepas (seperti kartu SD).
Pengelompokan ini hanya konseptual, dan tidak selalu merujuk ke satu partisi atau direktori pada perangkat. Perangkat Android akan selalu menyediakan partisi untuk penyimpanan internal dan penyimpanan eksternal. Ada kemungkinan bahwa perangkat tertentu mungkin memiliki beberapa partisi yang dianggap sebagai penyimpanan eksternal. Terlepas dari partisi API untuk membaca, menulis, atau membuat file sama. Ada dua set API yang dapat digunakan aplikasi Xamarin.Android untuk akses file:
- API .NET (disediakan oleh Mono dan dibungkus oleh Xamarin.Android) - Ini termasuk pembantu sistem file yang disediakan oleh Xamarin.Essentials. API .NET memberikan kompatibilitas lintas platform terbaik dan dengan demikian fokus panduan ini akan ada pada API ini.
- API akses file Java asli (disediakan oleh Java dan dibungkus oleh Xamarin.Android) - Java menyediakan API sendiri untuk membaca dan menulis file. Ini adalah alternatif yang dapat diterima sepenuhnya untuk API .NET, tetapi khusus untuk Android dan tidak cocok untuk aplikasi yang dimaksudkan untuk menjadi lintas platform.
Membaca dan menulis ke file hampir identik di Xamarin.Android seperti halnya aplikasi .NET lainnya. Aplikasi Xamarin.Android menentukan jalur ke file yang akan dimanipulasi, lalu menggunakan idiom .NET standar untuk akses file. Karena jalur aktual ke penyimpanan internal dan eksternal dapat bervariasi dari perangkat ke perangkat atau dari versi Android ke versi Android, tidak disarankan untuk memberi kode keras jalur ke file. Sebagai gantinya, gunakan API Xamarin.Android untuk menentukan jalur ke file. Dengan begitu, API .NET untuk membaca dan menulis file mengekspos API Android asli yang akan membantu menentukan jalur ke file di penyimpanan internal dan eksternal.
Sebelum membahas API yang terlibat dengan akses file, penting untuk memahami beberapa detail seputar penyimpanan internal dan eksternal. Ini akan dibahas di bagian berikutnya.
Secara konseptual, penyimpanan internal dan penyimpanan eksternal sangat mirip - keduanya adalah tempat di mana aplikasi Xamarin.Android dapat menyimpan file. Kesamaan ini mungkin membingungkan bagi pengembang yang tidak terbiasa dengan Android karena tidak jelas kapan aplikasi harus menggunakan penyimpanan internal vs penyimpanan eksternal.
Penyimpanan internal mengacu pada memori non-volatil yang dialokasikan Android ke sistem operasi, APK, dan untuk aplikasi individual. Ruang ini tidak dapat diakses kecuali oleh sistem operasi atau aplikasi. Android akan mengalokasikan direktori di partisi penyimpanan internal untuk setiap aplikasi. Saat aplikasi dihapus, semua file yang disimpan di penyimpanan internal di direktori tersebut juga akan dihapus. Penyimpanan internal paling cocok untuk file yang hanya dapat diakses oleh aplikasi dan yang tidak akan dibagikan dengan aplikasi lain atau akan memiliki nilai yang sangat sedikit setelah aplikasi dihapus instalannya. Di Android 6.0 atau yang lebih tinggi, file di penyimpanan internal dapat dicadangkan secara otomatis oleh Google menggunakan fitur Auto Backup di Android 6.0. Penyimpanan internal memiliki kerugian berikut:
- File tidak dapat dibagikan.
- File akan dihapus saat aplikasi dihapus instalasinya.
- Ruang yang tersedia pada penyimpanan internal mungkin terbatas.
Penyimpanan eksternal mengacu pada penyimpanan file yang bukan penyimpanan internal dan tidak dapat diakses secara eksklusif oleh aplikasi. Tujuan utama penyimpanan eksternal adalah untuk menyediakan tempat untuk menempatkan file yang dimaksudkan untuk dibagikan antara aplikasi atau yang terlalu besar agar sesuai dengan penyimpanan internal. Keuntungan dari penyimpanan eksternal adalah biasanya memiliki lebih banyak ruang untuk file daripada penyimpanan internal. Namun, penyimpanan eksternal tidak selalu dijamin ada di perangkat dan mungkin memerlukan izin khusus dari pengguna untuk mengaksesnya.
Catatan
Untuk perangkat yang mendukung beberapa pengguna, Android akan menyediakan direktori mereka sendiri kepada setiap pengguna di penyimpanan internal dan eksternal. Direktori ini tidak dapat diakses oleh pengguna lain pada perangkat. Pemisahan ini tidak terlihat oleh aplikasi selama tidak melakukan jalur hardcode ke file di penyimpanan internal atau eksternal.
Sebagai aturan praktis, aplikasi Xamarin.Android harus lebih memilih menyimpan file mereka di penyimpanan internal ketika wajar, dan mengandalkan penyimpanan eksternal ketika file perlu dibagikan dengan aplikasi lain, sangat besar, atau harus dipertahankan bahkan jika aplikasi dihapus instalasinya. Misalnya, file konfigurasi paling cocok untuk penyimpanan internal karena tidak penting kecuali aplikasi yang membuatnya. Sebaliknya, foto adalah kandidat yang baik untuk penyimpanan eksternal. Mereka bisa sangat besar dan dalam banyak kasus pengguna mungkin ingin membagikannya atau mengaksesnya bahkan jika aplikasi dihapus instalasinya.
Panduan ini akan berfokus pada penyimpanan internal. Silakan lihat panduan Penyimpanan eksternal untuk detail tentang penggunaan penyimpanan eksternal di aplikasi Xamarin.Android.
Direktori penyimpanan internal untuk aplikasi ditentukan oleh sistem operasi, dan diekspos ke aplikasi Android oleh Android.Content.Context.FilesDir
properti . Ini akan mengembalikan objek yang Java.IO.File
mewakili direktori yang didedikasikan Android secara eksklusif untuk aplikasi. Misalnya, aplikasi dengan nama paket com.companyname direktori penyimpanan internal mungkin:
/data/user/0/com.companyname/files
Dokumen ini akan merujuk ke direktori penyimpanan internal sebagai INTERNAL_STORAGE.
Penting
Jalur yang tepat ke direktori penyimpanan internal dapat bervariasi dari perangkat ke perangkat dan antar versi Android. Karena itu, aplikasi tidak boleh mengkodekan jalur ke direktori penyimpanan file internal, dan sebaliknya menggunakan API Xamarin.Android, seperti System.Environment.GetFolderPath()
.
Untuk memaksimalkan berbagi kode, aplikasi Xamarin.Android (atau aplikasi Xamarin.Forms yang menargetkan Xamarin.Android) harus menggunakan metode .System.Environment.GetFolderPath()
Di Xamarin.Android, metode ini akan mengembalikan string untuk direktori yang merupakan lokasi yang sama dengan Android.Content.Context.FilesDir
. Metode ini mengambil enum, System.Environment.SpecialFolder
, yang digunakan untuk mengidentifikasi sekumpulan konstanta enumerasi yang mewakili jalur folder khusus yang digunakan oleh sistem operasi. Tidak semua System.Environment.SpecialFolder
nilai akan memetakan ke direktori yang valid di Xamarin.Android. Tabel berikut menjelaskan jalur apa yang dapat diharapkan untuk nilai tertentu dari System.Environment.SpecialFolder
:
System.Environment.SpecialFolder | Jalur |
---|---|
ApplicationData |
INTERNAL_STORAGE/.config |
Desktop |
INTERNAL_STORAGE/Desktop |
LocalApplicationData |
INTERNAL_STORAGE/.local/share |
MyDocuments |
INTERNAL_STORAGE |
MyMusic |
INTERNAL_STORAGE/Musik |
MyPictures |
INTERNAL_STORAGE/Gambar |
MyVideos |
INTERNAL_STORAGE/Video |
Personal |
INTERNAL_STORAGE |
Fonts |
INTERNAL_STORAGE/.fonts |
Templates |
INTERNAL_STORAGE/Templat |
CommonApplicationData |
/usr/share |
CommonApplicationData |
/usr/share |
Salah satu API C# untuk menulis ke file sudah cukup; semua yang diperlukan adalah mendapatkan jalur ke file yang ada di direktori yang dialokasikan untuk aplikasi. Sangat disarankan agar versi asinkron API .NET digunakan untuk meminimalkan masalah apa pun yang mungkin terkait dengan akses file yang memblokir utas utama.
Cuplikan kode ini adalah salah satu contoh penulisan bilangan bulat ke file teks UTF-8 ke direktori penyimpanan internal aplikasi:
public async Task SaveCountAsync(int count)
{
var backingFile = Path.Combine(System.Environment.GetFolderPath(System.Environment.SpecialFolder.Personal), "count.txt");
using (var writer = File.CreateText(backingFile))
{
await writer.WriteLineAsync(count.ToString());
}
}
Cuplikan kode berikutnya menyediakan salah satu cara untuk membaca nilai bilangan bulat yang disimpan dalam file teks:
public async Task<int> ReadCountAsync()
{
var backingFile = Path.Combine(System.Environment.GetFolderPath(System.Environment.SpecialFolder.Personal), "count.txt");
if (backingFile == null || !File.Exists(backingFile))
{
return 0;
}
var count = 0;
using (var reader = new StreamReader(backingFile, true))
{
string line;
while ((line = await reader.ReadLineAsync()) != null)
{
if (int.TryParse(line, out var newcount))
{
count = newcount;
}
}
}
return count;
}
Xamarin.Essentials adalah sekumpulan API untuk menulis kode yang kompatibel lintas platform. Pembantu Sistem File adalah kelas yang berisi serangkaian pembantu untuk menyederhanakan lokasi cache dan direktori data aplikasi. Cuplikan kode ini memberikan contoh cara menemukan direktori penyimpanan internal dan direktori cache untuk aplikasi:
// Get the path to a file on internal storage
var backingFile = Path.Combine(Xamarin.Essentials.FileSystem.AppDataDirectory, "count.txt");
// Get the path to a file in the cache directory
var cacheFile = Path.Combine(Xamarin.Essentials.FileSystem.CacheDirectory, "count.txt");
adalah MediaStore
komponen Android yang mengumpulkan data meta tentang file media (video, musik, gambar) di perangkat Android. Tujuannya adalah menyederhanakan berbagi file-file ini di semua aplikasi Android di perangkat.
File privat tidak akan muncul sebagai media yang dapat dibagikan. Misalnya, jika aplikasi menyimpan gambar ke penyimpanan eksternal privatnya, file tersebut tidak akan diambil oleh pemindai media (MediaStore
).
File publik akan diambil oleh MediaStore
. Direktori yang memiliki nama file byte nol . NOMEDIA tidak akan dipindai oleh MediaStore
.