简体   繁体   English

Android 媒体商店问题:插入新播放列表返回空 URI

[英]Android Media store issue: Inserting new playlist returns null URI

I implemented a method for creating playlist in the Media Store using the method below:我使用以下方法实现了一种在媒体商店中创建播放列表的方法:

public static long createPlaylist(ContentResolver resolver, String name) {
    ContentValues values = new ContentValues(1);
    values.put(MediaStore.Audio.Playlists.NAME, name);
    Uri uri = resolver.insert(MediaStore.Audio.Playlists.EXTERNAL_CONTENT_URI, values);
    if (uri == null) {
        throw new Exception(
            "Failed to insert playlist: " + values);
    }

    String idString = uri.getLastPathSegment();
    if (idString == null) {
         throw new Exception(
              "Failed to parse uri last segment: " + uri);
    }

    return Long.parseLong(idString);
}

The method returns an id of newly created playlist.该方法返回新创建的播放列表的 id。 It works perfect on all devices except Nokia 3.1 Android 9. It fails by returning null URI when inserting values in Content resolver.它适用于除诺基亚 3.1 Android 9 以外的所有设备。在内容解析器中插入值时,它会返回空 URI 失败。

I also tried to insert values like in the code below:我还尝试插入如下代码中的值:

ContentValues values = new ContentValues(3);
values.put(MediaStore.Audio.Playlists.NAME, name);
values.put(MediaStore.Audio.Playlists.DATE_ADDED, now);
values.put(MediaStore.Audio.Playlists.DATE_MODIFIED, now);

What could be the reason for that?那可能是什么原因? I thought it should be working same way on all devices cause of the common implementation of Media Store in the framework.我认为它应该在所有设备上以相同的方式工作,原因是框架中媒体存储的通用实现。

Thanks for any help in advance.提前感谢您的任何帮助。

Have a look at logcat logs.查看 logcat 日志。 The method insert logs why it returned null.方法insert记录它返回空值的原因。 For instance, I had the same issue and it allowed me to find the cause :例如,我遇到了同样的问题,它让我找到了原因:

SQLiteDatabase(26594): android.database.sqlite.SQLiteConstraintException: UNIQUE constraint failed: files._data (code 2067 SQLITE_CONSTRAINT_UNIQUE)

So in my case, I was trying to save a file with a name that was already existing.所以在我的例子中,我试图用一个已经存在的名字来保存一个文件。


EDIT:编辑:

More precisions on my issue:关于我的问题的更精确:

I was creating a file name "hello.png" with resolver.insert(...) just like you.我和你一样用resolver.insert(...)创建了一个文件名“hello.png”。 Normally, if a file with that very name already exists in the file system, the new file is automatically renamed "hello (x).png"通常,如果文件系统中已经存在具有该名称的文件,则新文件会自动重命名为“hello (x).png”

Then for test purpose, I had to delete this file with adb, using adb shell rm -rf <myFolder> .然后为了测试目的,我不得不使用adb shell rm -rf <myFolder>删除这个文件,使用adb shell rm -rf <myFolder> But that was my mistake.但那是我的错误。

Since Android 10, you must use ContentResolver and Media Store, which is a database keeping track of the files saved by the app.从 Android 10 开始,您必须使用 ContentResolver 和 Media Store,这是一个跟踪应用程序保存的文件的数据库。 rm -rf does not update this database, so for the file system, no file named hello.png was existing (then the file is not renamed to hello (1).png ). rm -rf不会更新此数据库,因此对于文件系统,不存在名为hello.png的文件(然后该文件不会重命名为hello (1).png )。 But the database had a record saying that a such a file was existing, hence the exception SQLiteConstraintException .但是数据库有记录说存在这样的文件,因此异常SQLiteConstraintException

On Android 10+, to delete a file created by an application , you have to use在 Android 10+ 上,要删除应用程序创建的文件,您必须使用

adb shell content delete <args>

adb shell content allow you to make SQL like queries to the ContentResolver data base. adb shell content允许您对 ContentResolver 数据库进行类似 SQL 的查询。 For instance :例如 :

adb shell content query --uri content://media/external/images/media

produces a list of all external images.生成所有外部图像的列表。 You can then build the correct query to delete the right file(s).然后,您可以构建正确的查询以删除正确的文件。

In my case it was:就我而言,它是:

adb shell content delete --uri content://media/external/images/media --where bucket_display_name="\'HelloCollection\'"

This command will both remove the entry in the database and delete the file in the file system.此命令将删除数据库中的条目并删除文件系统中的文件。

Not sure why you would want a value for uri.不知道为什么你想要 uri 的值。 My method to insert works without fail, even on android 10. It is basically the same as your example though (although inserting into playlists brings up a file io permission error in Android 10)我的插入方法没有失败,即使在 android 10 上也是如此。尽管它与您的示例基本相同(尽管插入播放列表会在 Android 10 中引发文件 io 权限错误)

    public void createnewPlaylist(Context context, String newplaylist) {
    if (newplaylist != null && context != null) {

        ContentResolver resolver = context.getContentResolver();
        ContentValues values = new ContentValues(1);
        values.put(MediaStore.Audio.Playlists.NAME, newplaylist);
        try {
            resolver.insert(MediaStore.Audio.Playlists.EXTERNAL_CONTENT_URI, values);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 Android 9 (Pie) ContentResolver 查询 MediaStore.Images.Media.EXTERNAL_CONTENT_URI 在 api 28 上返回 null - Android 9 (Pie) ContentResolver query MediaStore.Images.Media.EXTERNAL_CONTENT_URI returns null on api 28 Android Store内容URI或媒体文件系统路径 - Android Store Content URI or Filesystem Path for Media Android 使用媒体存储 URI 删除目录 - Android delete directory using Media Store URI Android相机捕获活动返回null Uri - Android camera capture activity returns null Uri Android Camera Video Intent返回空URI - Android Camera Video intent returns null URI managedQuery(Media.EXTERNAL_CONTENT_URI,projection,null,null,null); 在设备上运行时返回null - managedQuery(Media.EXTERNAL_CONTENT_URI, projection,null,null, null); returns null when running on device Android媒体播放器播放列表和重置 - Android media player playlist and reset 插入与Android的联系人并查询结果uri不返回任何条目 - Inserting contact with android and querying the result uri returns no entries Android如何获取Media Store Image的唯一URI? - Android how to get the only uri of Media Store Image? 将歌曲插入播放列表返回null - insert song to playlist returns null
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM