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);
这段代码似乎是正确的。复杂的地方在于我使用的是模型和适配器,因此请执行几个步骤。
- 从我的 SD 卡中提取视频
- 将
Uri
更改为 Bitmap
用于 ThumbnailUtils
方法。
- 将该位图放入新的
VideoGridItem
对象中
- 将该对象添加到我的适配器。
- 在我的适配器 class 中调用
getVideo()
从我的模型对象中获取位图
- 在我的适配器中将该位图设置为我的
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文件真的很好看),里面也可能是狼
我想我的大部分代码都是正确的。我正在尝试从我的 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);
这段代码似乎是正确的。复杂的地方在于我使用的是模型和适配器,因此请执行几个步骤。
- 从我的 SD 卡中提取视频
- 将
Uri
更改为Bitmap
用于ThumbnailUtils
方法。 - 将该位图放入新的
VideoGridItem
对象中 - 将该对象添加到我的适配器。
- 在我的适配器 class 中调用
getVideo()
从我的模型对象中获取位图 - 在我的适配器中将该位图设置为我的
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文件真的很好看),里面也可能是狼