1

我需要使用 Picasso 库在列表视图中显示每个视频的缩略图以更快地运行,因此我需要获取缩略图路径以供使用。

这是我获取缩略图路径的代码(我在 Google 上找到了它,我更改了一些内容以适应我的应用程序):

String getThumbnailPathForLocalFile(Uri uri)
     {
         Cursor thumbCursor = null;
         try
         {
             thumbCursor = c.getContentResolver().
                     query(uri
                     , null
                     , null , null, null);

             if(thumbCursor.moveToFirst())
             {
                 // the path is stored in the DATA column
                 int dataIndex = thumbCursor.getColumnIndexOrThrow( MediaStore.MediaColumns.DATA );
                 String thumbnailPath = thumbCursor.getString(dataIndex);
                 return thumbnailPath;
             }
         }
         finally
         {
             if(thumbCursor != null)
             {
                 thumbCursor.close();
             }
         }

         return null;
     }

我的 getView 功能:

@Override
    public View getView(int position, View convertView, ViewGroup parent) {
        View v = convertView;
        if (v == null) {
            LayoutInflater vi = (LayoutInflater) c
                    .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
            v = vi.inflate(R.layout.listview_item, null);
        }

        /* create a new view of my layout and inflate it in the row */
        // convertView = ( RelativeLayout ) inflater.inflate( resource, null );

        final Item item = items.get(position);
        if (item != null) {
            TextView t1 = (TextView) v.findViewById(R.id.txt_fileName);
            imageCity = (ImageView) v.findViewById(R.id.img_icon);

            switch (item.getType()) {
            case "video":
                String uri2 = item.getPath();
                Uri videoUri = MediaStore.Video.Thumbnails
                        .getContentUri(uri2);
                String VideoThumbnailPath =getThumbnailPathForLocalFile(videoUri);
                Picasso.with(c).load(new File(VideoThumbnailPath))
                        .resize(64, 64).into(imageCity);
                break;
            case "image":
                String uri4 = item.getPath();
                Picasso.with(c).load(new File(uri4)).resize(64, 64).into(imageCity);
                break;
            default:
                break;
            }


            if (t1 != null)
                t1.setText(item.getName());

        }
        return v;
    }

我检查了 logcat 和调试,所以我发现 thumbCursor 为空:

12-10 17:52:38.400: E/AndroidRuntime(8659): java.lang.NullPointerException: Attempt to invoke interface method 'boolean android.database.Cursor.moveToFirst()' on a null object reference
12-10 17:52:38.400: E/AndroidRuntime(8659):     at com.example.knock.FileArrayAdapter.getThumbnailPathForLocalFile(FileArrayAdapter.java:105)
12-10 17:52:38.400: E/AndroidRuntime(8659):     at com.example.knock.FileArrayAdapter.getView(FileArrayAdapter.java:73)

任何人都可以帮助我吗?非常感谢你

4

2 回答 2

2

您的 Uri 不正确。getContentUri(String volumeName)期望魔术词"external"而不是路径。而且您可能还没有缩略图。

您可以使用这段代码加载缩略图

private static final String SELECTION = MediaColumns.DATA + "=?";
private static final String[] PROJECTION = { BaseColumns._ID };
public static Bitmap loadVideoThumbnail(String videoFilePath, ContentResolver cr) {
    Bitmap result = null;
    Uri uri = MediaStore.Video.Media.EXTERNAL_CONTENT_URI;
    String[] selectionArgs = { videoFilePath };
    Cursor cursor = cr.query(uri, PROJECTION, SELECTION, selectionArgs, null);
    if (cursor.moveToFirst()) {
        // it's the only & first thing in projection, so it is 0
        long videoId = cursor.getLong(0);
        result = MediaStore.Video.Thumbnails.getThumbnail(cr, videoId,
                Thumbnails.MICRO_KIND, null);
    }
    cursor.close();
    return result;
}

它的作用是:

  1. 通过查询查找文件的视频IDVideo.Media
  2. 将该 videoId 传递给getThumbnail哪个块(在您的情况下是 ui 线程..),直到缩略图被制作和解码。

最大的缺点是你不能在这里使用毕加索的路径。(自定义加载工作,https://github.com/square/picasso/blob/master/picasso/src/main/java/com/squareup/picasso/MediaStoreRequestHandler.java似乎是一个实现,这里有一些描述:http://blog.jpardogo.com/requesthandler-api-for-picasso-library/ )

您可以获得缩略图路径,但如果您查看缩略图表的内容,例如通过这段代码

    StringBuilder sb = new StringBuilder();
    Cursor query = getContentResolver().query(
            Video.Thumbnails.EXTERNAL_CONTENT_URI, null, null, null, null);
    DatabaseUtils.dumpCursor(query, sb);
    query.close();
    Log.d("XXX", sb.toString());

您会看到并非每个视频都有缩略图。

但是那些可以通过

public static String loadVideoThumbnailPath(String videoFilePath,
        ContentResolver cr) {
    String result = null;
    Uri uri = MediaStore.Video.Media.EXTERNAL_CONTENT_URI;
    String[] selectionArgs = { videoFilePath };
    Cursor cursor = cr.query(uri, PROJECTION, SELECTION, selectionArgs,
            null);
    long videoId = -1;
    if (cursor.moveToFirst()) {
        videoId = cursor.getLong(0);
    }
    cursor.close();
    if (videoId > 0) {
        Uri uri2 = MediaStore.Video.Thumbnails.EXTERNAL_CONTENT_URI;
        String[] projection2 = { MediaStore.Video.Thumbnails.DATA };
        String selection2 = MediaStore.Video.Thumbnails.VIDEO_ID + "=?";
        String[] selectionArgs2 = { String.valueOf(videoId) };
        Cursor cursor2 = cr.query(uri2, projection2, selection2, selectionArgs2, null);
        if (cursor2.moveToFirst()) {
            result = cursor2.getString(0);
        }
        cursor2.close();
    }
    return result;
}

(仍然与PROJECTION上面相同的SELECTION常量)

于 2014-12-11T11:54:25.027 回答
1

获取视频文件缩略图的方法之一是使用MediaMetadataRetriever. 但是这个类获取视频文件的帧。因此,缩略图的大小可能比通常的缩略图大。然后您可以缩放该位图。

MediaMetadataRetriever mmr = new MediaMetadataRetriever();
Uri url = Uri.parse("android.resource://" + getPackageName() + "/" + R.raw.test); //Your file uri
mmr.setDataSource(getContext(), url);
Bitmap bitmap = mmr.getFrameAtTime();
ImageView imageview = findViewById(R.id.yourimageviewid);
imageview.setImageBitmap(bitmap);

另一种获取缩略图的方法:

Bitmap bitmap = ThumbnailUtils.createVideoThumbnail(filePath,
MediaStore.Images.Thumbnails.MINI_KIND);
于 2019-11-23T10:40:46.563 回答