文件描述符 如需使用文件描述符打开媒体文件,请使用类似于以下代码段所示的逻辑: // Open a specific media item using ParcelFileDescriptor. ContentResolver resolver = getApplicationContext() .getContentResolver();
// "rw" for read-and-write; // "rwt" for truncating or overwriting existing file contents. String readOnlyMode = "r"; try (ParcelFileDescriptor pfd = resolver.openFileDescriptor(content-uri, readOnlyMode)) { // Perform operations on "pfd". } catch (IOException e) { e.printStackTrace(); }
文件流 如需使用文件流打开媒体文件,请使用类似于以下代码段所示的逻辑: // Open a specific media item using InputStream. ContentResolver resolver = getApplicationContext() .getContentResolver(); try (InputStream stream = resolver.openInputStream(content-uri)) { // Perform operations on "stream". }
直接文件路径 如果您没有任何与存储空间相关的权限,您可以访问应用专属目录中的文件,并可使用 File API 访问归因于您的应用的媒体文件。 性能 当您使用直接文件路径依序读取媒体文件时,其性能与 MediaStore API 相当。 但是,当您使用直接文件路径随机读取和写入媒体文件时,进程的速度可能最多会慢一倍。在此类情况下,我们建议您改为使用 MediaStore API。
DATA 列 当您访问现有媒体文件时,您可以使用您的逻辑中 DATA 列的值。这是因为,此值包含有效的文件路径。但是,不要假设文件始终可用。请准备好处理可能发生的任何基于文件的 I/O 错误。 另一方面,如需创建或更新媒体文件,请勿使用 DATA 列的值。请改用 DISPLAY_NAME 和 RELATIVE_PATH 列的值。
添加项目 如需将媒体项添加到现有集合,请调用类似于以下内容的代码。此代码段可在搭载 Android 10 或更高版本的设备上访问 VOLUME_EXTERNAL_PRIMARY 卷。这是因为在这些设备上,您只能修改主要卷的内容,如存储卷部分所述。 // Add a specific media item. ContentResolver resolver = getApplicationContext() .getContentResolver();
// Find all audio files on the primary external storage device. Uri audioCollection; if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) { audioCollection = MediaStore.Audio.Media .getContentUri(MediaStore.VOLUME_EXTERNAL_PRIMARY); } else { audioCollection = MediaStore.Audio.Media.EXTERNAL_CONTENT_URI; }
// Publish a new song. ContentValues newSongDetails = new ContentValues(); newSongDetails.put(MediaStore.Audio.Media.DISPLAY_NAME, "My Song.mp3");
// Keeps a handle to the new song's URI in case we need to modify it // later. Uri myFavoriteSongUri = resolver .insert(audioCollection, newSongDetails);
// Add a media item that other apps shouldn't see until the item is // fully written to the media store. ContentResolver resolver = getApplicationContext() .getContentResolver();
// Find all audio files on the primary external storage device. Uri audioCollection; if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) { audioCollection = MediaStore.Audio.Media .getContentUri(MediaStore.VOLUME_EXTERNAL_PRIMARY); } else { audioCollection = MediaStore.Audio.Media.EXTERNAL_CONTENT_URI; }
ContentValues songDetails = new ContentValues(); songDetails.put(MediaStore.Audio.Media.DISPLAY_NAME, "My Workout Playlist.mp3"); songDetails.put(MediaStore.Audio.Media.IS_PENDING, 1);
Uri songContentUri = resolver .insert(audioCollection, songDetails);
try (ParcelableFileDescriptor pfd = resolver.openFileDescriptor(songContentUri, "w", null)) { // Write data into the pending audio file. }
// Now that we're finished, release the "pending" status, and allow other apps // to play the audio track. songDetails.clear(); songDetails.put(MediaStore.Audio.Media.IS_PENDING, 0); resolver.update(songContentUri, songDetails, null, null);
更新项目 如需更新应用拥有的媒体文件,请运行类似于以下内容的代码: // Updates an existing media item. long mediaId = // MediaStore.Audio.Media._ID of item to update. ContentResolver resolver = getApplicationContext() .getContentResolver();
// When performing a single item update, prefer using the ID String selection = MediaStore.Audio.Media._ID + " = ?";
// By using selection + args we protect against improper escaping of // values. Here, "song" is an in-memory object that caches the song's // information. String[] selectionArgs = new String[] { getId().toString() };
// Update an existing song. ContentValues updatedSongDetails = new ContentValues(); updatedSongDetails.put(MediaStore.Audio.Media.DISPLAY_NAME, "My Favorite Song.mp3");
// Use the individual song's URI to represent the collection that's // updated. int numSongsUpdated = resolver.update( myFavoriteSongUri, updatedSongDetails, selection, selectionArgs);
ContentResolver resolver = context.getContentResolver(); Uri uri = MediaStore.Images.Media.EXTERNAL_CONTENT_URI; Uri item = resolver.insert(uri, values);
try { ParcelFileDescriptor pfd = resolver.openFileDescriptor(item, "w", null); // write data into the pending image. } catch (IOException e) { LogUtil.log("write image fail"); }
// clear IS_PENDING flag after writing finished. values.clear(); values.put(MediaStore.Images.Media.IS_PENDING, 0);//释放,使其他应用可以访问 resolver.update(item, values, null, null);