标签: mediastore

Scoped Storage:如何通过 MediaStore 删除多个音频文件?

我正在尝试从设备的外部存储中删除音频文件(例如在/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

android mediastore android-10.0 scoped-storage

8
推荐指数
1
解决办法
2775
查看次数

使用Android的MediaStore(ContentResolver/范围存储)创建图像文件后文件扩展名和文件名错误

我正在使用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

8
推荐指数
1
解决办法
1360
查看次数

将文件写入 Android Q 中可公开访问的文档文件夹 - 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 中的这些变化是为了让用户更多地“了解应用程序如何访问他们的数据”,但是一旦他们了解您的应用程序如何使用您的数据,就不会有问题。

android mediastore android-10.0 scoped-storage

8
推荐指数
1
解决办法
2466
查看次数

无法在 Android 10 上更新 MediaStore

我一直在通过 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,正确的解决方法是什么?

android mediastore android-10.0

8
推荐指数
1
解决办法
3633
查看次数

在 Android Q 中访问外部存储中的照片

我最近将应用程序的目标版本升级到 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)

java android mediastore android-10.0 scoped-storage

8
推荐指数
1
解决办法
3968
查看次数

MediaStore.Images.Media.insertImage在某些设备上抛出权限拒绝

我的代码行有问题:

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)

permissions android mediastore

7
推荐指数
1
解决办法
6581
查看次数

无论如何要使用 Mediastore 访问隐藏文件夹?(安卓)

我正在尝试制作照片查看器,但遇到了一些问题。

我想查看用 .nomedia 文件隐藏的文件夹,但 Mediastore 似乎没有扫描这些文件夹。无论如何要在查询中显示这些文件夹?

谢谢!

directory android image mediastore

7
推荐指数
0
解决办法
391
查看次数

如何使android Q中添加的RELATIVE_PATH向后兼容?

根据文档,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)

media storage android mediastore scoped-storage

7
推荐指数
1
解决办法
1921
查看次数

在 Android 10 设备中找不到 java.lang.IllegalArgumentException Volume external_primary

崩溃:找不到 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

7
推荐指数
2
解决办法
3273
查看次数

如何在Android 11中实现新的存储API?

设想

我有两个应用程序,一个是跟踪器应用程序,它记录传入和传出呼叫并压缩这些文件,并将文件路径发送到主应用程序,通过主应用程序将Inter-Process Communication这些文件上传到服务器。

现在我正在将这两个应用程序升级到 Android 11。在 Tracker 应用程序中,我用于MediaStore.Files API保存文件并尝试使用主应用程序中的文件路径读取这些文件。读取文件时File.canRead()返回false主应用程序。即使我尝试MediaStore API读取这些文件,它也会返回空Cursor

在这里我有几个问题。

  1. 我可以读取 Android 11 上的“其他”应用创建的文件吗?我在某处读到,您无法在 Android 11 中访问其他应用程序文件。
  2. 我的应用程序是否有资格MANAGE_EXTERNAL_STORAGE访问存储中的所有文件?
  3. 处理这种情况的最佳方法是什么?
  4. ``存储访问框架``可以帮助我处理这种情况吗?

我正在将文件保存在 public 目录中Documents/AppData/Audio。请给我有关此的工作链接。任何帮助将不胜感激。谢谢

android mediastore storage-access-framework scoped-storage android-11

7
推荐指数
1
解决办法
8678
查看次数