Po Androidzie 4.4 Kitkat, a od 2017 roku udział Androida 4.4 i mniej wynosi około 20% i maleje, nie można zapisywać na karcie SD za pomocą File
klasy i getExternalStorageDirectory()
metody. Ta metoda zwraca pamięć wewnętrzną urządzenia i zapisywane obrazy widoczne dla każdej aplikacji. Możesz także zapisywać obrazy tylko prywatne w swojej aplikacji i zostać usunięte, gdy użytkownik usunie Twoją aplikację za pomocąopenFileOutput()
metodą.
Począwszy od systemu Android 6.0, możesz sformatować kartę SD jako pamięć wewnętrzną, ale tylko prywatną dla swojego urządzenia. (Jeśli sformatujesz samochód SD jako pamięć wewnętrzną, tylko twoje urządzenie będzie miało dostęp lub zobaczy jego zawartość) Możesz zapisać na tej karcie SD za pomocą inne odpowiedzi, ale jeśli chcesz użyć wymiennej karty SD, przeczytaj moją odpowiedź poniżej.
Powinieneś użyć Storage Access Framework, aby uzyskać onActivityResult
metodę działania uri do folderu , aby uzyskać folder wybrany przez użytkownika, i dodać trwałe, trwałe uprawnienia, aby móc uzyskać dostęp do folderu po ponownym uruchomieniu urządzenia.
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (resultCode == RESULT_OK) {
// selectDirectory() invoked
if (requestCode == REQUEST_FOLDER_ACCESS) {
if (data.getData() != null) {
Uri treeUri = data.getData();
tvSAF.setText("Dir: " + data.getData().toString());
currentFolder = treeUri.toString();
saveCurrentFolderToPrefs();
// grantUriPermission(getPackageName(), treeUri,
// Intent.FLAG_GRANT_READ_URI_PERMISSION |
// Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
final int takeFlags = data.getFlags()
& (Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
// Check for the freshest data.
getContentResolver().takePersistableUriPermission(treeUri, takeFlags);
}
}
}
}
Teraz zapisz folder zapisu we wspólnych preferencjach, aby nie prosić użytkownika o wybranie folderu za każdym razem, gdy chcesz zapisać obraz.
Powinieneś użyć DocumentFile
klasy, aby zapisać obraz, a nie, File
lub ParcelFileDescriptor
, aby uzyskać więcej informacji, możesz sprawdzić ten wątek, aby zapisać obraz na karcie SD za pomocą compress(CompressFormat.JPEG, 100, out);
metody i DocumentFile
klas.
mImage.setImageBitmap(_result.getBitmap());
mojegoonTaskComplete()
wywołania zwrotnego. Teraz muszę zezwolić użytkownikom na zapisywanie pliku lokalnie, jeśli chcą, za pomocą menu kontekstowego długie naciśnięcie. Powinienem móc skorzystać z poniższego rozwiązania. Co chcę wiedzieć, czy odkryłeś lepsze podejście do tego?