You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Android获取MediaStore音乐流派列表失败,界面空白无报错求解决

解决MediaStore获取流派列表界面空白的问题

我帮你排查了代码里的几个关键问题,这应该就是界面空白的原因,咱们一步步来修复:

1. Cursor遍历跳过了首项数据

在getGenreList方法里,你先调用cursor.moveToFirst(),紧接着又调用cursor.moveToNext(),这会直接跳过第一个流派的数据——如果你的设备里只有一个流派,就会完全加载不到内容。

修改主Cursor的遍历逻辑,改成直接用while循环(会自动处理空Cursor的情况):

public void getGenreList() {
    String[] proj1 = new String[]{
            MediaStore.Audio.Genres.NAME,
            MediaStore.Audio.Genres._ID
    };
    ContentResolver cr = getContext().getContentResolver();
    cursor = cr.query(MediaStore.Audio.Genres.EXTERNAL_CONTENT_URI, proj1, null, null, null);
    
    // 修正后的遍历逻辑
    if (cursor != null) {
        while (cursor.moveToNext()) {
            int index = cursor.getColumnIndexOrThrow(MediaStore.Audio.Genres.NAME);
            String genre = cursor.getString(index);
            index = cursor.getColumnIndexOrThrow(MediaStore.Audio.Genres._ID);
            long genreId = Long.parseLong(cursor.getString(index));
            Uri uri = MediaStore.Audio.Genres.Members.getContentUri("external", genreId);
            Cursor tempCursor = cr.query(uri, null, null, null, null);
            
            // 子Cursor同样修正遍历逻辑
            if (tempCursor != null) {
                while (tempCursor.moveToNext()) {
                    index = tempCursor.getColumnIndexOrThrow(MediaStore.Audio.Media.TITLE);
                    String title = tempCursor.getString(index);
                    index = tempCursor.getColumnIndexOrThrow(MediaStore.Audio.Artists.ARTIST);
                    String artist = tempCursor.getString(index);
                    index = tempCursor.getColumnIndexOrThrow(MediaStore.Audio.Albums.ALBUM);
                    String album = tempCursor.getString(index);
                    genreInfo g = new genreInfo(artist, title, album, genre);
                    genreList.add(g);
                }
                tempCursor.close();
            }
        }
        cursor.close(); // 别忘了关闭Cursor,避免内存泄漏
        // 关键:通知Adapter数据更新
        genreAdapter1.notifyDataSetChanged();
    }
}

2. 未通知RecyclerView数据更新

你加载完所有数据后,没有调用genreAdapter1.notifyDataSetChanged(),RecyclerView不知道数据已经更新,所以即使数据加载成功,界面也不会刷新。上面的代码已经把这行加上了,放在Cursor关闭之后。

3. Fragment实例化方法错误

你的newInstance方法返回的是BlankFragment,但你的类名是BlankFragment3,这会导致实例化错误(如果这个方法被调用的话),赶紧修正:

public static BlankFragment3 newInstance(String param1, String param2) {
    BlankFragment3 fragment = new BlankFragment3();
    Bundle args = new Bundle();
    args.putString(ARG_PARAM1, param1);
    args.putString(ARG_PARAM2, param2);
    fragment.setArguments(args);
    return fragment;
}

4. 确认需求匹配:流派列表VS流派下的歌曲

注意:你当前的代码逻辑是把每个流派下的所有歌曲都添加到列表中,相当于显示所有歌曲并附带流派标签;但如果你的需求是显示流派列表(每个项是一个流派名称,比如“摇滚”“流行”),那你的逻辑就错了,应该改成每个流派只添加一次,示例如下:

// 修改后的getGenreList,用于获取流派列表(每个流派一条数据)
public void getGenreList() {
    String[] proj1 = new String[]{
            MediaStore.Audio.Genres.NAME,
            MediaStore.Audio.Genres._ID
    };
    ContentResolver cr = getContext().getContentResolver();
    cursor = cr.query(MediaStore.Audio.Genres.EXTERNAL_CONTENT_URI, proj1, null, null, null);
    
    if (cursor != null) {
        while (cursor.moveToNext()) {
            int index = cursor.getColumnIndexOrThrow(MediaStore.Audio.Genres.NAME);
            String genreName = cursor.getString(index);
            long genreId = cursor.getLong(cursor.getColumnIndexOrThrow(MediaStore.Audio.Genres._ID));
            
            // 获取该流派下的歌曲数量
            Uri membersUri = MediaStore.Audio.Genres.Members.getContentUri("external", genreId);
            Cursor countCursor = cr.query(membersUri, new String[]{"COUNT(*)"}, null, null, null);
            int songCount = 0;
            if (countCursor != null && countCursor.moveToFirst()) {
                songCount = countCursor.getInt(0);
                countCursor.close();
            }
            
            // 添加流派信息到列表(需要修改genreInfo的构造方法,支持传入流派名称和歌曲数量)
            genreList.add(new genreInfo(genreName, songCount));
        }
        cursor.close();
        genreAdapter1.notifyDataSetChanged();
    }
}

同时要对应修改genreAdapter的布局和绑定逻辑,显示流派名称和歌曲数量,而不是歌曲的标题、艺术家等信息。

5. 权限检查(补充)

虽然你说歌曲和专辑能正常获取,但还是确认一下:Android 6.0+需要动态请求READ_EXTERNAL_STORAGE权限,在Fragment的onViewCreated里添加权限检查:

@Override
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
    super.onViewCreated(view, savedInstanceState);
    // 检查存储权限
    if (ContextCompat.checkSelfPermission(requireContext(), Manifest.permission.READ_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {
        ActivityCompat.requestPermissions(requireActivity(), new String[]{Manifest.permission.READ_EXTERNAL_STORAGE}, 1001);
    } else {
        // 权限已授予,加载数据
        getGenreList();
    }
}

// 处理权限请求结果
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
    super.onRequestPermissionsResult(requestCode, permissions, grantResults);
    if (requestCode == 1001 && grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
        getGenreList();
    }
}

按照上面的步骤修改后,应该就能正常显示内容了,如果还有问题,可以告诉我你的具体需求(是显示流派列表还是流派下的歌曲)以及测试设备的Android版本,我再帮你进一步排查。

内容的提问来源于stack exchange,提问作者devesh kumawat

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.15 03:53:03