java之android.database.sqlite.SQLiteException : no such column: bucket_display_name

daizhj 阅读:40 2025-02-15 21:57:57 评论:0

我试图使用 MediaStore 获取包含音频文件的存储桶。这在 Android 10 API 29 上运行良好,但不适用于以前的 Android 版本。我附上了 Android 10 API 29 上的工作示例的屏幕截图。

Caused by: android.database.sqlite.SQLiteException: no such column: bucket_display_name (code 1 SQLITE_ERROR): , while compiling: SELECT bucket_display_name, bucket_id FROM audio ORDER BY date_added ASC

日志猫。

Caused by: android.database.sqlite.SQLiteException: no such column: bucket_display_name (code 1 SQLITE_ERROR): , while compiling: SELECT bucket_display_name, bucket_id FROM audio ORDER BY date_added ASC 
        at android.database.DatabaseUtils.readExceptionFromParcel(DatabaseUtils.java:179) 
        at android.database.DatabaseUtils.readExceptionFromParcel(DatabaseUtils.java:135) 
        at android.content.ContentProviderProxy.query(ContentProviderNative.java:418) 
        at android.content.ContentResolver.query(ContentResolver.java:802) 
        at android.content.ContentResolver.query(ContentResolver.java:752) 
        at android.content.ContentResolver.query(ContentResolver.java:710) 
        at com.aisar.mediaplayer.fragments.AudioFolderFragment$AsyncVideoFolderLoader.doInBackground(AudioFolderFragment.java:148) 
        at com.aisar.mediaplayer.fragments.AudioFolderFragment$AsyncVideoFolderLoader.doInBackground(AudioFolderFragment.java:130) 
        at android.os.AsyncTask$2.call(AsyncTask.java:333) 
        at java.util.concurrent.FutureTask.run(FutureTask.java:266) 
        at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:245)  
        at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1167)  
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:641)  
        at java.lang.Thread.run(Thread.java:764)  

代码:

class AsyncVideoFolderLoader extends AsyncTask<String, String, List<ModelAudioFolder>> { 
 
    private String sortBy; 
 
    public AsyncVideoFolderLoader(String sortBy) { 
        this.sortBy = sortBy; 
    } 
 
    @Override 
    protected List<ModelAudioFolder> doInBackground(String... strings) { 
        List<ModelAudioFolder> videoItems = new ArrayList<>(); 
        videoItems.clear(); 
 
        final HashMap<String, ModelAudioFolder> output = new HashMap<>(); 
        final Uri contentUri = MediaStore.Audio.Media.EXTERNAL_CONTENT_URI; 
 
        final String[] projection = {MediaStore.Audio.Media.BUCKET_DISPLAY_NAME, MediaStore.Audio.Media.BUCKET_ID}; 
 
        try (final Cursor cursor = getActivity().getContentResolver().query( 
                contentUri, 
                projection, 
                null, 
                null, 
                "" + sortBy)) { 
            if ((cursor != null) && (cursor.moveToFirst())) { 
                final int columnBucketName = cursor.getColumnIndex(MediaStore.Audio.Media.BUCKET_DISPLAY_NAME); 
                final int columnBucketId = cursor.getColumnIndex(MediaStore.Audio.Media.BUCKET_ID); 
 
 
                do { 
                    final String bucketName = cursor.getString(columnBucketName); 
                    final String bucketId = cursor.getString(columnBucketId); 
 
                    if (!output.containsKey(bucketId)) { 
                        final int count = getCount(contentUri, bucketId); 
 
                        final ModelAudioFolder item = new ModelAudioFolder( 
                                "" + bucketId, 
                                "" + bucketName, 
                                "", 
                                "" + getPath(bucketId), 
                                "" + count 
                        ); 
 
                        output.put(bucketId, item); 
                        videoItems.add(item); 
 
                    } 
 
                } while (cursor.moveToNext()); 
            } 
        } 
        return videoItems; 
    } 
 
    private int getCount(@NonNull final Uri contentUri, @NonNull final String bucketId) { 
        try (final Cursor cursor = getActivity().getContentResolver().query(contentUri, 
                null, MediaStore.Audio.Media.BUCKET_ID + "=?", new String[]{bucketId}, null)) { 
            return ((cursor == null) || (cursor.moveToFirst() == false)) ? 0 : cursor.getCount(); 
        } 
    } 
 
    private String getPath(String BUCKET_ID) { 
        String path = ""; 
        String selection = null; 
        String[] projection = { 
                MediaStore.Audio.Media.DATA, 
                MediaStore.Audio.Media.BUCKET_ID 
        }; 
        Cursor cursor = getActivity().getContentResolver().query( 
                MediaStore.Audio.Media.EXTERNAL_CONTENT_URI, 
                projection, 
                selection, 
                null, 
                null); 
        while (cursor.moveToNext()) { 
            if (BUCKET_ID.equals(cursor.getString(1))) { 
                //add only those videos that are in selected/chosen folder 
                path = cursor.getString(0); 
            } 
        } 
        return path; 
    } 
 
    @Override 
    protected void onPostExecute(List<ModelAudioFolder> audioFolderList) { 
        super.onPostExecute(audioFolderList); 
 
        if (audioFolderList.size() <= 0) { 
            noFoldersRl.setVisibility(View.VISIBLE); 
            foldersRl.setVisibility(View.GONE); 
        } else { 
            noFoldersRl.setVisibility(View.GONE); 
            foldersRl.setVisibility(View.VISIBLE); 
        } 
 
        Log.d("FoldersSize", "onPostExecute: " + audioFolderList.size()); 
 
        adapterAudioFolder = new AdapterAudioFolder(getActivity(), audioFolderList, dashboardActivity); 
        foldersRv.setAdapter(adapterAudioFolder); 
    } 
} 

...

请您参考如下方法:

异常原因是BUCKET_DISPLAY_NAME。它已添加到 API 29 中。在此之前,我们对 API 28 及以下版本使用 DISPLAY_NAME。请参阅文档 BUCKET_DISPLAY_NAME .

对于解决方案,您可以根据当前的 API 级别编写条件。为了获取文件夹名称,您可以使用RELATIVE_PATH


标签:java
声明

1.本站遵循行业规范,任何转载的稿件都会明确标注作者和来源;2.本站的原创文章,请转载时务必注明文章作者和来源,不尊重原创的行为我们将追究责任;3.作者投稿可能会经我们编辑修改或补充。

关注我们

一个IT知识分享的公众号