获取 MediaScanner 自动生成的视频缩略图

Obtaining the MediaScanner auto-generated Video thumbnails

如您所知,android 上的内置媒体扫描器会定期扫描整个文件系统并生成媒体(照片+视频)预览缩略图。这些是图库应用程序正在显示的缩略图。

在我的应用程序中,我有一个旋转木马,我想在其中显示 自动生成的 视频 的缩略图。出于速度的原因,并且因为它们已经存在。不幸的是,文档非常缺乏关于如何实际获取它们的信息。

public class MainActivity extends Activity {

    private Cursor cursor;
    private int columnIndex;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.content_main);

        // Set up an array of the Thumbnail Image ID column we want
        String[] projection = {MediaStore.Video.Thumbnails.VIDEO_ID};
        // Create the cursor pointing to the SDCard
        cursor = managedQuery( MediaStore.Video.Thumbnails.EXTERNAL_CONTENT_URI,
                projection, // Which columns to return
                null,       // Return all rows
                null,
                null);

        System.err.println("qqq video cnt=" + cursor.getCount());

        // Get the column index of the Thumbnails Image ID
        columnIndex = cursor.getColumnIndexOrThrow(projection[0]);

        GridView sdcardImages = (GridView) findViewById(R.id.sdcard);
        sdcardImages.setAdapter(new ImageAdapter(this));

        // Set up a click listener
        sdcardImages.setOnItemClickListener(new OnItemClickListener() {
            public void onItemClick(AdapterView parent, View v, int position, long id) {
                // Get the data location of the image
                String[] projection = {MediaStore.Video.Media.DATA};
                cursor = managedQuery( MediaStore.Video.Media.EXTERNAL_CONTENT_URI,
                        projection, // Which columns to return
                        null,       // Return all rows
                        null,
                        null);
                columnIndex = cursor.getColumnIndexOrThrow(projection[0]);
                cursor.moveToPosition(position);
                // Get image filename
                String imagePath = cursor.getString(columnIndex);
                // Use this path to do further processing, i.e. full screen display
                System.err.println("qqq path=" + imagePath);
            }
        });
    }

    private class ImageAdapter extends BaseAdapter {

        private Context context;

        public ImageAdapter(Context localContext) {
            context = localContext;
        }

        public int getCount() {
            System.err.println("qqq count " + cursor.getCount());
            return cursor.getCount();
        }
        public Object getItem(int position) {
            return position;
        }
        public long getItemId(int position) {
            return position;
        }
        public View getView(int position, View convertView, ViewGroup parent) {
            ImageView picturesView;
            if (convertView == null) {
                picturesView = new ImageView(context);


                // Move cursor to current position
                cursor.moveToPosition(position);
                // Get the current value for the requested column
                int imageID = cursor.getInt(columnIndex);

                Uri uri = Uri.withAppendedPath(
                        MediaStore.Video.Thumbnails.EXTERNAL_CONTENT_URI, "" + imageID);
                System.err.println("qqq getview uri="+uri.toString());

                // Set the content of the image based on the provided URI
                picturesView.setImageURI(uri);
                picturesView.setScaleType(ImageView.ScaleType.FIT_CENTER);
                picturesView.setPadding(8, 8, 8, 8);
                picturesView.setLayoutParams(new GridView.LayoutParams(100, 100));


                //picturesView.setImageBitmap(BitmapFactory.decodeResource(getResources(), android.R.drawable.ic_btn_speak_now));
            }
            else {
                picturesView = (ImageView)convertView;
            }
            return picturesView;
        }
    }
}

我得到的日志如下。它确实显示了正确数量的视频 (2),但即使缩略图媒体 URL "looks ok",返回的位图对象也为零。有什么想法吗?

W/System.err: qqq video cnt=2
W/System.err: qqq count 2
W/System.err: qqq count 2
W/System.err: qqq count 2
W/System.err: qqq getview uri=content://media/external/video/thumbnails/2484
W/System.err: qqq getview uri=content://media/external/video/thumbnails/2483
W/System.err: qqq count 2
W/System.err: qqq getview uri=content://media/external/video/thumbnails/2484
W/System.err: qqq count 2

这是如何完成的。注意缩略图路径可以是null,如果视频损坏或者是用编解码器编码android无法解析。

public class MainActivity extends Activity {

    private Cursor cursor;
    private int columnIndex;

    ArrayList thumbs = new ArrayList();

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.content_main);

        final String[] columns = {
                BaseColumns._ID, MediaStore.MediaColumns.DATA
        };

        ContentResolver cr = this.getContentResolver();
        Cursor cursor = cr.query(MediaStore.Video.Media.EXTERNAL_CONTENT_URI, columns, null, null, null);

        boolean cancel = false;
        if(null != cursor){
            while(cursor.moveToNext() && !cancel){
                String fileName = cursor.getString(cursor.getColumnIndex(MediaStore.MediaColumns.DATA));
                int imageId = cursor.getInt(cursor.getColumnIndex(BaseColumns._ID));

                thumbs.add(new Integer(imageId));
                System.err.println("qqq " + fileName + " " + imageId);
            }
        }

        GridView sdcardImages = (GridView) findViewById(R.id.sdcard);
        sdcardImages.setAdapter(new ImageAdapter(this));
    }

    private class ImageAdapter extends BaseAdapter {

        private Context context;

        public ImageAdapter(Context localContext) {
            context = localContext;
        }

        public int getCount() {
            System.err.println("qqq count " + thumbs.size());//cursor.getCount());
            //return cursor.getCount();
            return thumbs.size();
        }
        public Object getItem(int position) {
            return position;
        }
        public long getItemId(int position) {
            return position;
        }
        public View getView(int position, View convertView, ViewGroup parent) {
            ImageView picturesView;
            if (convertView == null) {
                picturesView = new ImageView(context);
                picturesView.setScaleType(ImageView.ScaleType.FIT_CENTER);
                picturesView.setPadding(8, 8, 8, 8);
                picturesView.setLayoutParams(new GridView.LayoutParams(250, 250));

               Bitmap myBitmap = BitmapFactory.decodeResource(getResources(), android.R.drawable.ic_menu_camera);
                Integer t = (Integer)thumbs.get(position);
                String path= getThumbPath(getContentResolver(), t.intValue());
                if (path != null) {
                    System.err.println("qqq getting " + path);
                    File f = new File(path);
                    if (!f.exists()) {
                        System.err.println("qqq invalid file! " + path);
                    }

                    myBitmap = BitmapFactory.decodeFile(path);//imgFile.getAbsolutePath());
                }
                picturesView.setImageBitmap(myBitmap);

            }
            else {
                picturesView = (ImageView)convertView;
            }
            return picturesView;
        }
    }


    public String getThumbPath(ContentResolver contentResolver, long photoId) {
        String path=null;
        Cursor thumbnails = contentResolver.query(android.provider.MediaStore.Video.Thumbnails.EXTERNAL_CONTENT_URI,
                null, android.provider.MediaStore.Video.Thumbnails.VIDEO_ID + "=?", new String[]{String.valueOf(photoId)}, null);

        for (thumbnails.moveToFirst(); !thumbnails.isAfterLast(); thumbnails.moveToNext()) {

            long thumbnailId = thumbnails.getLong(thumbnails.getColumnIndex(android.provider.MediaStore.Video.Thumbnails._ID));
            path = thumbnails.getString(thumbnails.getColumnIndex(android.provider.MediaStore.Video.Thumbnails.DATA));
            break;
        }

        thumbnails.close();
        return path;
    }
}