ImageView 中不显示视频(来自 SD 卡)缩略图 - Android

Video (from SD card) thumbnail does not show in ImageView - Android

我想我的大部分代码都是正确的。我正在尝试从我的 SD 卡中获取视频 (Uri),将它们更改为位图并将其放入 ThumbnailUtils(如 Stack 上的建议),如下所示:

Uri uri = Uri.fromFile(singleFile);
// create thumbnail: MINI_KIND: 512 x 384 thumbnail
bitmapThumb = ThumbnailUtils.createVideoThumbnail(uri.getPath(),MediaStore.Video.Thumbnails.MINI_KIND);

这段代码似乎是正确的。复杂的地方在于我使用的是模型和适配器,因此请执行几个步骤。

  1. 从我的 SD 卡中提取视频
  2. Uri 更改为 Bitmap 用于 ThumbnailUtils 方法。
  3. 将该位图放入新的 VideoGridItem 对象中
  4. 将该对象添加到我的适配器。
  5. 在我的适配器 class 中调用 getVideo() 从我的模型对象中获取位图
  6. 在我的适配器中将该位图设置为我的 ImageView

这些步骤中我可能遗漏了什么。我对此进行了记录:Bitmap bm = videoGridItem.getVideo(); 奇怪的是,bm returns 为空。这是有道理的,因为我在我的视频应该出现的地方什么也看不到。

下面的屏幕截图显示代码确实从我的 SD 卡中提取了我的 1 个视频(所以我的文件 I/O 可能没问题)并用占位符图像填充了网格的其余部分,但我不知道为什么不显示视频缩略图。没有崩溃或任何东西,只是没有缩略图。感谢您的帮助。

VideoTab.java

package org.azurespot.cutecollection.videotab;

import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.media.ThumbnailUtils;
import android.net.Uri;
import android.os.Bundle;
import android.os.Environment;
import android.provider.MediaStore;
import android.support.v4.app.Fragment;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.GridView;

import org.azurespot.R;

import java.io.File;
import java.util.ArrayList;

/**
 * Created by mizu on 2/8/15.
 */
public class VideoTab extends Fragment {


    ArrayList<VideoGridItem> videoList = new ArrayList<>();
    ArrayAdapter<VideoGridItem> adapter;
    private String[] numberSDCardFiles = null;
    File[] files;
    Bitmap bitmapThumb;
    VideoGridItem videoGridItem;
    VideoGridItem drawableObject;


    public VideoTab() {
        super();
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        // Inflate the layout for this fragment
        View v = inflater.inflate(R.layout.video_tab, container, false);

        // Create the Custom Adapter Object
        adapter = new GridViewVideoAdapter(getActivity(), videoList);
        // with fragments, make sure you include the rootView when finding id
        GridView gridView = (GridView) v.findViewById(R.id.video_grid);
        gridView.setAdapter(adapter);

        if(adapter.getCount() == 0) {
            // load contents of SD card
            loadVideos();

            // turn drawable into an object of type Bitmap
            drawableObject = new VideoGridItem(BitmapFactory.decodeResource(getResources(),
                    R.drawable.ic_video_placeholder));

            // add the default icons remaining, to GridView, if less than 14 files on SD card
            for (int i = 0; i < (14 - numberSDCardFiles.length); i++) {
                adapter.add(drawableObject);
                adapter.notifyDataSetChanged();
            }

        }


        return v;
    }

    public void loadVideos() {

        try {

            // gets directory Cute Videos from sd card
            File cuteVideosDir = new File(Environment.getExternalStoragePublicDirectory
                    (Environment.DIRECTORY_MOVIES), "Cute Videos");

            files = cuteVideosDir.listFiles();

            for (File singleFile : files) {

                Uri uri = Uri.fromFile(singleFile);

                // create thumbnail: MINI_KIND: 512 x 384 thumbnail
                bitmapThumb = ThumbnailUtils.createVideoThumbnail(uri.getPath(),
                        MediaStore.Video.Thumbnails.MINI_KIND);

                videoGridItem = new VideoGridItem(bitmapThumb);

                Log.d("TAG", "Value of videoGridItem: " + videoGridItem);

                adapter.add(videoGridItem);
                adapter.notifyDataSetChanged();

            }
        } catch (Exception e) {
            e.printStackTrace();
        }

        // get number of files in Cute Videos directory
        numberSDCardFiles =  new String[files.length];
    }
}

GridViewVideoAdapter.java

package org.azurespot.cutecollection.videotab;

import android.content.Context;
import android.graphics.Bitmap;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.ImageView;
import android.widget.LinearLayout;

import org.azurespot.R;

import java.util.ArrayList;

/**
 * Created by mizu on 2/8/15.
 */
public class GridViewVideoAdapter extends ArrayAdapter<VideoGridItem> {

    ViewHolder holder = null;
    int position;


    public GridViewVideoAdapter(Context context, ArrayList<VideoGridItem> videos) {
        super(context, 0, videos);

    }

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {

        View v = convertView;
        this.position = position;

        if (v == null) {

            v = LayoutInflater.from(getContext())
                    .inflate(R.layout.video_grid_item, parent, false);

            holder = new ViewHolder();
            holder.imageView = (ImageView) v.findViewById(R.id.video_grid_view);
            // stores holder with view
            v.setTag(holder);

        } else {

            holder = (ViewHolder)v.getTag();
        }

        // gets position of whichever photo you click on in the GridView
        final VideoGridItem videoGridItem = getItem(position);

        if (videoGridItem != null) {

            Bitmap bm = videoGridItem.getVideo();
            Log.d("TAG", "Value of bm: " + bm);

            holder.imageView.setImageBitmap(bm);

            // positioning the image in the GridView slot
            holder.imageView.setLayoutParams(new LinearLayout.LayoutParams(512, 384));
        }

        return v;

    }

    public class ViewHolder{
        ImageView imageView;
    }
}

VideoGridItem.java

package org.azurespot.cutecollection.videotab;

import android.graphics.Bitmap;

/**
 * Created by mizu on 3/28/15.
 */
public class VideoGridItem {

    private Bitmap video;


    public VideoGridItem(Bitmap video) {
        super();
        this.video = video;

    }

    public Bitmap getVideo() {

        return video;
    }


    public void setVideo(Bitmap video) {
        this.video = video;
    }
}

原来我的视频保存代码(在另一个 activity 中)毕竟不正确。我认为它没有任何错误,因为视频可以很好地保存到我的 SD 卡中。但我没有意识到的是,它们无法播放。仔细一看,我看到只保存了指定的文件名,而不是视频的实际 Uri

所以其他帖子关于 ThumbnailUtils.createVideoThumbnail() 的说法确实是正确的:唯一会 return null 的情况是视频文件已损坏或无法操作。所以一旦我解决了这个问题,一切都像一个魅力。所以上面的代码实际上是工作代码。

经验教训:不要假设您的 SD 卡目录中有工作视频!就算是披着羊皮(mp4文件真的很好看),里面也可能是狼