Доступ к файлам SD-карты по
диалог Используйте DOCUMENT_TREE
, чтобы получить SD-карты Uri
.
Сообщите пользователю о том, как выбрать sd-card
в диалоговом окне. (С картинками или GIF-анимации)
// call for document tree dialog
Intent intent = new Intent(Intent.ACTION_OPEN_DOCUMENT_TREE);
startActivityForResult(intent, REQUEST_CODE_OPEN_DOCUMENT_TREE);
На onActivityResult
вы будете иметь выбранный каталог Uri
. (SdCardUri)
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
switch (requestCode) {
case REQUEST_CODE_OPEN_DOCUMENT_TREE:
if (resultCode == Activity.RESULT_OK) {
sdCardUri = data.getData();
}
beak;
}
}
Теперь нужно проверить, если пользователь,
а. выбрал SD-карту
b. выбрал SD-карту, в которой находится наш файл (некоторые устройства могут иметь несколько SD-карт).
Мы проверяем как a, так и b путем поиска файла через иерархию, от sd root до нашего файла. Если файл найден, будут получены оба условия a и b.
//First we get `DocumentFile` from the `TreeUri` which in our case is `sdCardUri`.
DocumentFile documentFile = DocumentFile.fromTreeUri(this, sdCardUri);
//Then we split file path into array of strings.
//ex: parts:{"", "storage", "extSdCard", "MyFolder", "MyFolder", "myImage.jpg"}
// There is a reason for having two similar names "MyFolder" in
//my exmple file path to show you similarity in names in a path will not
//distract our hiarchy search that is provided below.
String[] parts = (file.getPath()).split("\\/");
// findFile method will search documentFile for the first file
// with the expected `DisplayName`
// We skip first three items because we are already on it.(sdCardUri = /storage/extSdCard)
for (int i = 3; i < parts.length; i++) {
if (documentFile != null) {
documentFile = documentFile.findFile(parts[i]);
}
}
if (documentFile == null) {
// File not found on tree search
// User selected a wrong directory as the sd-card
// Here must inform user about how to get the correct sd-card
// and invoke file chooser dialog again.
} else {
// File found on sd-card and it is a correct sd-card directory
// save this path as a root for sd-card on your database(SQLite, XML, txt,...)
// Now do whatever you like to do with documentFile.
// Here I do deletion to provide an example.
if (documentFile.delete()) {// if delete file succeed
// Remove information related to your media from ContentResolver,
// which documentFile.delete() didn't do the trick for me.
// Must do it otherwise you will end up with showing an empty
// ImageView if you are getting your URLs from MediaStore.
//
Uri mediaContentUri = ContentUris.withAppendedId(
MediaStore.Images.Media.EXTERNAL_CONTENT_URI,
longMediaId);
getContentResolver().delete(mediaContentUri , null, null);
}
}
Примечание:
Вы должны предоставить разрешение на доступ к внешней памяти в манифесте и зева> = Зефир внутри приложения. https://stackoverflow.com/a/32175771/2123400
Редактировать Sd-Карте Файлы
Для редактирования существующего изображения на вашей SD-карты вам не нужны какие-либо из вышеперечисленных шагов, если вы хотите, чтобы вызвать другое приложение, чтобы сделать это для вы.
Здесь мы вызываем все действия (из всех установленных приложений) с возможностью редактирования изображений. (Программисты отмечают свои приложения в манифесте своими возможностями для обеспечения доступности из других приложений (видов деятельности)).
на вашем мероприятии editButton Клик:
String mimeType = getMimeTypeFromMediaContentUri(mediaContentUri);
startActivityForResult(Intent.createChooser(new Intent(Intent.ACTION_EDIT).setDataAndType(mediaContentUri, mimeType).putExtra(Intent.EXTRA_STREAM, mediaContentUri).addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION), "Edit"), REQUEST_CODE_SHARE_EDIT_SET_AS_INTENT);
и это, как получить MIMETYPE:
public String getMimeTypeFromMediaContentUri(Uri uri) {
String mimeType;
if (uri.getScheme().equals(ContentResolver.SCHEME_CONTENT)) {
ContentResolver cr = getContentResolver();
mimeType = cr.getType(uri);
} else {
String fileExtension = MimeTypeMap.getFileExtensionFromUrl(uri
.toString());
mimeType = MimeTypeMap.getSingleton().getMimeTypeFromExtension(
fileExtension.toLowerCase());
}
return mimeType;
}
Примечание:
На Android KitKat (4.4) не спрашивайте пользователю выбрать sd-карту, поскольку в этой версии Android DocumentProvider
не применимо, поэтому у нас нет шансов получить доступ к th e sd-card с таким подходом. Посмотрите на уровень API для DocumentProvider
https://developer.android.com/reference/android/provider/DocumentsProvider.html
Я ничего не нашел, что работает на Android KitKat (4.4). Если вы нашли что-нибудь полезное с KitKat, пожалуйста, поделитесь с нами.
В версиях ниже доступ к SD-карте KitKat уже предоставляется ОС.
Я не хочу удалять файл –
Скопировать с внешнего на sd? Копировать из Sd в внешний? – Eftekhari
Я думаю, что код, который вы предоставили, я удаляю всю директорию Sd Card. –