我正在尝试从设备的外部存储中删除音频文件(例如在/storage/emulated/0/Music文件夹中)。在分析了MediaStore示例之后,我最终得到了 API 28 及更早版本的以下解决方案:
fun deleteTracks(trackIds: LongArray): Int {
val whereClause = buildWildcardInClause(trackIds.size) // _id IN (?, ?, ?, ...)
return resolver.delete(MediaStore.Audio.Media.EXTERNAL_CONTENT_URI, whereClause, Array(trackIds.size) { trackIds[it].toString() })
}
Run Code Online (Sandbox Code Playgroud)
我注意到上面的代码只从 MediaStore 数据库中删除曲目,而不是从设备中删除(重新启动后文件会重新添加到 MediaStore)。因此,我修改了该代码以查询该Media.DATA列,然后使用该信息删除关联的文件。这按预期工作。
但是现在 Android Q 引入了 Scoped Storage,Media.DATA(和Albums.ALBUM_ART)现在已被弃用,因为应用程序可能无法访问这些文件。ContentResolver.openFileDescriptor只能用于读取文件,不能用于删除文件。
那么从 Android Q 开始,推荐的删除曲目的方法是什么?该样品不表明如何从删除多个文件MediaStore,并MediaStore.Audio.Media似乎的工作方式不同MediaStore.Images.Media。
我正在使用MediaStore 和 ContentResolver API 来保存图像文件 (jpg/png/gif) MediaStore.Images。它可以工作,但问题是所有文件都以 .jpg 扩展名保存,并且文件名始终为“millis.jpg 中的当前时间”。
以下是我在 ContentValues 中放入的内容的示例:
date_added=1575480356 _display_name=2067623.gif date_modified=1575480356 mime_type=image/gif
Run Code Online (Sandbox Code Playgroud)
但将其插入 ContentResolver 并写入文件后,显示名称更改为2067623.jpg,文件名更改为1575480356.jpg.
如何让它保留文件名和扩展名?
代码:
ContentResolver resolver = activity.getContentResolver();
Uri mediaCollection;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
mediaCollection = MediaStore.Images.Media.getContentUri(MediaStore.VOLUME_EXTERNAL_PRIMARY);
} else {
mediaCollection = MediaStore.Images.Media.EXTERNAL_CONTENT_URI;
}
ContentValues mediaDetails = new ContentValues();
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
final String relativeLocation = Environment.DIRECTORY_PICTURES + File.separator + "my_folder";
mediaDetails.put(MediaStore.Images.Media.DATE_TAKEN, System.currentTimeMillis());
mediaDetails.put(MediaStore.Images.Media.IS_PENDING, 1);
mediaDetails.put(MediaStore.MediaColumns.RELATIVE_PATH, relativeLocation);
}
String mimeType …Run Code Online (Sandbox Code Playgroud) java android mediastore android-contentresolver scoped-storage
迁移到 Android 后 QI 无法再找到合适的方式来获得对文档文件夹的写入权限 ( /storage/emulated/0/Documents)
在任何人提到有关范围存储的许多其他问题之前,我已经阅读了其中的许多问题,并且根据我目前所见,所有解决方案都使用特定于应用程序的目录或仅访问媒体目录(而不是文档文件夹访问权限)。
根据我在 Android QI 中的理解,可以选择:
ACTION_OPEN_DOCUMENT_TREE我开发的应用程序用于对主题进行测试,来自测试的数据会自动存储在可公开访问的 Documents 文件夹中,有点像: /storage/emulated/0/Documents/myAppName/subjectName/testData-todaysDate.pdf
当用户想要访问测试数据时,他们将智能手机插入计算机并导航到文档文件夹,其余的就很明显了。出于这个原因,我必须使用可公开访问的存储。还想象他们想通过另一个应用程序打开手机上的测试数据,同样的交易!
所以我正在寻找的解决方案需要能够做到以下几点:
/storage/emulated/0/Documents/ACTION_OPEN_DOCUMENT_TREE我知道 Android Q 中的这些变化是为了让用户更多地“了解应用程序如何访问他们的数据”,但是一旦他们了解您的应用程序如何使用您的数据,就不会有问题。
我一直在通过 ContentResolver 更新 MediaStore 中的元数据,但这不再适用于 Android Q (API 29)。下面的代码给了我一个警告,并且描述没有更新:
ContentValues values = new ContentValues();
values.put(MediaStore.Images.Media.DESCRIPTION, "Some text");
int res = getContext().getContentResolver().update(
MediaStore.Images.Media.EXTERNAL_CONTENT_URI,
values,
MediaStore.Images.Media._ID + "= ?", new String[]{sImageId});
Run Code Online (Sandbox Code Playgroud)
android.process.media W/MediaProvider:忽略来自 com.example.android.someapp.app 的描述突变
这篇 Medium 文章描述了 Google 如何更改用于访问和更新文件的 API,但是仅更新元数据呢?该警告似乎告诉我 Google 不再希望允许第三方应用使用 MediaStore,而且我还找到了警告的来源:https : //android.googlesource.com/platform/packages/providers/MediaProvider/+/ master/src/com/android/providers/media/MediaProvider.java#2960
有谁知道为什么此更新不适用于 Android 10,正确的解决方法是什么?
我最近将应用程序的目标版本升级到 API 29。由于 Android 10 中的范围存储,我使用 MediaStore API 来存储和检索应用程序外部存储中的图像。之前,我曾经getExternalStoragePublicDirectory存储通过相机拍摄的图像,现在我使用MediaStore.Images.Media.EXTERNAL_CONTENT_URI将文件写入外部存储位置。
我现在面临的问题是,当我打开我的应用程序并拍照时,它存储在我给“myapp”的文件夹名称下,我可以通过 Mediastore 光标检索我的图像并将它们显示在自定义图库中。当我卸载我的应用程序“myapp”文件夹时仍然存在。当我再次安装我的应用程序并尝试从图库中读取图像时,光标没有返回任何图像。但是如果我再次拍照,那么我可以将它们加载到我的自定义图库中。自定义图库视图只是屏幕底部的一行图像,因此用户无需浏览照片文件夹即可将图像加载到应用程序。
这就是我在 MediaStore 中存储图像的方式
内容价值:
String RELATIVE_PATH = Environment.DIRECTORY_PICTURES + File.separator + "myApp";
final ContentValues contentValues = new ContentValues();
contentValues.put(MediaStore.MediaColumns.DISPLAY_NAME, generateImageName(new Date()));
contentValues.put(MediaStore.MediaColumns.MIME_TYPE, "image/jpg");
contentValues.put(MediaStore.MediaColumns.RELATIVE_PATH, RELATIVE_PATH);
Run Code Online (Sandbox Code Playgroud)
生成名称方法:
int sameSecondCount;
protected String generateName(Date now)
{
String result = formatter.format(now);
long nowMillis = now.getTime();
if (nowMillis / 1000 == lastMillis / 1000)
{
sameSecondCount++;
result += "_" + sameSecondCount;
}
else
sameSecondCount = 0;
lastMillis = nowMillis; …Run Code Online (Sandbox Code Playgroud) 我的代码行有问题:
String path = MediaStore.Images.Media.insertImage(activity.getContentResolver(), bitmap, "feedback", null);
Run Code Online (Sandbox Code Playgroud)
Activity不为null,位图不为null.
我收到错误:
0-22 11:23:59.644 29514-29527/? E/DatabaseUtils: Writing exception to parcel
10-22 11:23:59.644 29514-29527/? E/DatabaseUtils: java.lang.SecurityException: Permission Denial: writing com.android.providers.media.MediaProvider uri content://media/external/images/media from pid=1380, uid=10136 requires android.permission.WRITE_EXTERNAL_STORAGE, or grantUriPermission()
10-22 11:23:59.644 29514-29527/? E/DatabaseUtils: at android.content.ContentProvider.enforceWritePermissionInner(ContentProvider.java:679)
10-22 11:23:59.644 29514-29527/? E/DatabaseUtils: at android.content.ContentProvider$Transport.enforceWritePermission(ContentProvider.java:494)
10-22 11:23:59.644 29514-29527/? E/DatabaseUtils: at android.content.ContentProvider$Transport.insert(ContentProvider.java:258)
10-22 11:23:59.644 29514-29527/? E/DatabaseUtils: at android.content.ContentProviderNative.onTransact(ContentProviderNative.java:163)
10-22 11:23:59.644 29514-29527/? E/DatabaseUtils: at android.os.Binder.execTransact(Binder.java:453)
10-22 11:23:59.645 1380-1467/? E/MediaStore: Failed to insert image
10-22 11:23:59.645 1380-1467/? E/MediaStore: java.lang.SecurityException: Permission …Run Code Online (Sandbox Code Playgroud) 我正在尝试制作照片查看器,但遇到了一些问题。
我想查看用 .nomedia 文件隐藏的文件夹,但 Mediastore 似乎没有扫描这些文件夹。无论如何要在查询中显示这些文件夹?
谢谢!
根据文档,RELATIVE_PATH 在 API 级别 29 中添加 public static final String RELATIVE_PATH 该媒体项在其持久存储的存储设备中的相对路径。例如,存储在 /storage/0000-0000/DCIM/Vacation/IMG1024.JPG 的项目的路径为 DCIM/Vacation/。
在 Android Q 之前,如何组织在 Android 上插入 MediaStore 的媒体文件 Afaik:根据已删除的文档,它PRIMARY_DIRECTORY不起作用
put(MediaStore.MediaColumns.PRIMARY_DIRECTORY, relativePath)
/**
* The primary directory name this media exists under. The value may be
* {@code NULL} if the media doesn't have a primary directory name.
*
* @removed
* @deprecated Replaced by {@link #RELATIVE_PATH}.
*/
@Column(Cursor.FIELD_TYPE_STRING)
@Deprecated
public static final String PRIMARY_DIRECTORY = "primary_directory";
Run Code Online (Sandbox Code Playgroud) 崩溃:找不到 java.lang.IllegalArgumentException 卷 external_primary
从媒体商店查询曲目时,我在某些 Android 10 设备(其中大部分来自小米米 A2 Lite、摩托罗拉、HMD Global Nokia)中遇到此崩溃。
Cursor cursor = getContentResolver().query(MediaStore.Audio.Media.EXTERNAL_CONTENT_URI, null, null, null, null);
我应该为 Android 10 设备传递不同的 URI 吗?(但是它在大多数设备中都可以正常工作)
堆栈跟踪 :
Caused by java.lang.IllegalArgumentException: Volume external_primary not found
at android.database.DatabaseUtils.readExceptionFromParcel(DatabaseUtils.java:170)
at android.database.DatabaseUtils.readExceptionFromParcel(DatabaseUtils.java:140)
at android.content.ContentProviderProxy.query(ContentProviderProxy.java:423)
at android.content.ContentResolver.query(ContentResolver.java:946)
at android.content.ContentResolver.query(ContentResolver.java:881)
at android.content.ContentResolver.query(ContentResolver.java:837)
at com.example.musicplayer.CursorFactory.getAllSongsCursor(CursorFactory.java:164)
Run Code Online (Sandbox Code Playgroud)
编辑:根据报告的这个问题,怀疑这可能是那些使用 Android 10 操作系统的设备中的 sdcard 问题。
android mediastore android-contentresolver android-sdcard android-10.0
设想
我有两个应用程序,一个是跟踪器应用程序,它记录传入和传出呼叫并压缩这些文件,并将文件路径发送到主应用程序,通过主应用程序将Inter-Process Communication这些文件上传到服务器。
现在我正在将这两个应用程序升级到 Android 11。在 Tracker 应用程序中,我用于MediaStore.Files API保存文件并尝试使用主应用程序中的文件路径读取这些文件。读取文件时File.canRead()返回false主应用程序。即使我尝试MediaStore API读取这些文件,它也会返回空Cursor。
在这里我有几个问题。
MANAGE_EXTERNAL_STORAGE访问存储中的所有文件?我正在将文件保存在 public 目录中Documents/AppData/Audio。请给我有关此的工作链接。任何帮助将不胜感激。谢谢
android mediastore storage-access-framework scoped-storage android-11
android ×10
mediastore ×10
android-10.0 ×5
java ×2
android-11 ×1
directory ×1
image ×1
media ×1
permissions ×1
storage ×1