Rinomina il file del Mediastore creato dall'app in Android 10. Funziona su Android API 30 ma mostra un errore nell'API 29
Qui, questa funzione renameFile (..) funziona nell'API 30 di Android. Ma non funziona nell'API 29 di Android e mostra l'errore come:
java.lang.IllegalArgumentException: Spostamento del contenuto: // media / external / file / 116 che non fa parte di una raccolta ben definita non consentito
Nota di aggiornamento:
--- Inizia ---
Per poter lavorare con sdk-29 dobbiamo usare Uri come extUri = MediaStore.Downloads.getContentUri (MediaStore.VOLUME_EXTERNAL) come:
private static Uri extUri = MediaStore.Downloads.getContentUri(MediaStore.VOLUME_EXTERNAL);
al posto del codice sottostante. E aggiorna anche MediaStore.Files.FileColumns a MediaStore.Downloads
--- Finisce ---
Uri extUri = MediaStore.Files.getContentUri(MediaStore.VOLUME_EXTERNAL);
String relativeLocation = Environment.DIRECTORY_DOWNLOADS + File.separator + "AppFolder";
funzione renameFile (...)
boolean renameFile(Context context, String newName, String displayName) {
try {
Long id = getIdFromDisplayName(displayName);
ContentResolver contentResolver = context.getContentResolver();
Uri mUri = ContentUris.withAppendedId(extUri, id);
ContentValues contentValues = new ContentValues();
contentValues.put(MediaStore.Files.FileColumns.IS_PENDING, 1);
contentResolver.update(mUri, contentValues, null, null);
contentValues.clear();
contentValues.put(MediaStore.Files.FileColumns.DISPLAY_NAME, newName);
// contentValues.put(MediaStore.Files.FileColumns.MIME_TYPE, "files/pdf");
// contentValues.put(MediaStore.Files.FileColumns.RELATIVE_PATH, relativeLocation);
// contentValues.put(MediaStore.Files.FileColumns.TITLE, "SomeName");
// contentValues.put(MediaStore.Files.FileColumns.DATE_ADDED, System.currentTimeMillis() / 1000);
// contentValues.put(MediaStore.Files.FileColumns.DATE_TAKEN, System.currentTimeMillis());
contentValues.put(MediaStore.Files.FileColumns.IS_PENDING, 0);
contentResolver.update(mUri, contentValues, null, null);
return true;
} catch (Exception ex) {
ex.printStackTrace();
}
return false;
}
funzione getIdFromDisplayName (...)
@RequiresApi(api = Build.VERSION_CODES.Q)
Long getIdFromDisplayName(String displayName) {
String[] projection;
projection = new String[]{MediaStore.Files.FileColumns._ID};
// TODO This will break if we have no matching item in the MediaStore.
Cursor cursor = getContentResolver().query(extUri, projection,
MediaStore.Files.FileColumns.DISPLAY_NAME + " LIKE ?", new String[]{displayName}, null);
assert cursor != null;
cursor.moveToFirst();
if (cursor.getCount() > 0) {
int columnIndex = cursor.getColumnIndex(projection[0]);
long fileId = cursor.getLong(columnIndex);
cursor.close();
return fileId;
}
return null;
}
Risposte
java.lang.IllegalArgumentException: Spostamento del contenuto: // media / external / file / 116 che non fa parte di una raccolta ben definita non consentito
Quindi è per Android Q non consentito se si utilizza la raccolta;
Uri extUri = MediaStore.Files.getContentUri(MediaStore.VOLUME_EXTERNAL);
Ma è consentita una "raccolta ben definita" come:
Uri extUri = MediaStore.Images.Media.getContentUri(MediaStore.VOLUME_EXTERNAL);
// Use "Pictures/MyFolder" for RELATIVE_PATH
Lascio a voi la ricerca di altre collezioni ben definite.
Perché questo è solo per Android Q non lo so.
Puoi vedere il messaggio nel file java: https://android.googlesource.com/platform/packages/providers/MediaProvider/+/refs/heads/master/src/com/android/providers/media/MediaProvider.java
Citazione:
// We only support movement under well-defined collections
switch (match) {
case AUDIO_MEDIA_ID:
case VIDEO_MEDIA_ID:
case IMAGES_MEDIA_ID:
case DOWNLOADS_ID:
break;
default:
throw new IllegalArgumentException("Movement of " + uri
+ " which isn't part of well-defined collection not allowed");
}
Se la ridenominazione non riesce, utilizzare SAF (come menzionato prima). Come rinominare un file in Android conoscendo solo il suo contenuto multimediale Uri