10.1.2 完整的MediaStore视频示例
下面是一个完整的示例,其将从MediaStore检索所有可用的视频文件,并分别显示他们的缩略图和标题。此示例中使用MediaStore.Video.Thumbnails类,它在Android(API Level 5)及以上版本可用。
package com.nthm.androidtestActivity; import java.io.File; import java.util.ArrayList; import java.util.List; import com.nthm.androidtest.R; import android.app.Activity; import android.content.Context; import android.content.Intent; import android.database.Cursor; import android.net.Uri; import android.os.Bundle; import android.provider.MediaStore; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.AdapterView; import android.widget.BaseAdapter; import android.widget.ImageView; import android.widget.ListView; import android.widget.TextView; import android.widget.AdapterView.OnItemClickListener; public class VideoGallery extends Activity implements OnItemClickListener { private Cursor cursor; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.videogallery);
我们使用一个ListView来显示视频列表。
1 ListView listView=(ListView) findViewById(R.id.ListView);
接下来是想要从MediaStore.Video.Thumbnails查询中获得的列的列表。
1 String[]thumbColumn={MediaStore.Video.Thumbnails.DATA,MediaStore.Video.Thumbnails.VIDEO_ID};
然后是想要从MediaStore.Video.Media查询中获得的列的列表
1 String[]mediaColumns={MediaStore.Video.Media._ID,MediaStore.Video.Media.DATA,MediaStore.Video.Media.TITLE,MediaStore.Video.Media.MIME_TYPE};
在主查询中将选择所有在MediaStore中表示的视频。
1 cursor=managedQuery(MediaStore.Video.Media.EXTERNAL_CONTENT_URI, mediaColumns, null, null, null);
查询返回的每一行都将在下面的ArrayList中创建一条目录。每个目录都是在一个VideoViewInfo对象,它是在本示例中特别定义的类,以保存本活动中使用的视频信息。
1 ArrayList<VideoViewInfo> videoRows=new ArrayList<VideoViewInfo>();
接下来遍历在Cursor对象中包含的数据,为每行创建一个VideoViewInfo对象,并将它添加到ArrayList中。
1 if(cursor.moveToFirst()){
因为我们想要在遍历第一行数据之后才移动到下一行,所以采用一个do...while循环。do循环部分将在测试/执行while子句之前发生。在循环中,将为每个返回的数据行创建一个新的VideoViewInfo对象。
1 do{ 2 VideoViewInfo newVVI=new VideoViewInfo();
然后可以从Cursor兑现中提取所有相关的数据。正如刚才描述的那样,我们还将使用另一个查询为每个视频提取缩略图,而且这些数据块将存储在VideoViewInfo对象中。
1 int id=cursor.getInt(cursor.getColumnIndex(MediaStore.Video.Media._ID)); 2 Cursor thumbCursor=managedQuery(MediaStore.Video.Thumbnails.EXTERNAL_CONTENT_URI, thumbColumn, MediaStore.Video.Thumbnails.VIDEO_ID+"="+id, null, null); 3 if(thumbCursor.moveToFirst()){ 4 newVVI.thumbPath=thumbCursor.getString(thumbCursor.getColumnIndex(MediaStore.Video.Thumbnails.DATA)); 5 } 6 newVVI.filePath=cursor.getString(cursor.getColumnIndex(MediaStore.Video.Media.DATA)); 7 newVVI.title=cursor.getString(cursor.getColumnIndex(MediaStore.Video.Media.TITLE)); 8 newVVI.mimeType=cursor.getString(cursor.getColumnIndex(MediaStore.Video.Media.MIME_TYPE));
最后,将VideoViewInfo对象添加到ArrayList(videoRows)中。
1 videoRows.add(newVVI); 2 }while(cursor.moveToNext()); 3 }
一旦获得了所有视频,就可以继续操作。将ListView对象的适配器设置为VideoGalleryAdapter(下面将要定义的内部类)的一个新实例。同时,设置此活动为ListView的setOnItemClickListener。
1 listView.setAdapter(new VideoGalleryAdapter(this, videoRows)); 2 listView.setOnItemClickListener(this); 3 }
当单击ListView中的一个条目时,将调用onItemClick方法。这个方法将从Cursor对象中提取所需要的数据,同时将创建一个意图,以启动设备上默认的播放器应用程序来播放视频。可以创建自己的MediaPlayer,或者使用这里的VideoView类。
1 @Override 2 public void onItemClick(AdapterView<?> parent, View view, int position, 3 long id) { 4 if(cursor.moveToPosition(position)){ 5 int fileColumn=cursor.getColumnIndex(MediaStore.Video.Media.DATA); 6 int mimeCloumn=cursor.getColumnIndex(MediaStore.Video.Media.MIME_TYPE); 7 String videoFilePath=cursor.getString(fileColumn); 8 String mimeType=cursor.getString(mimeCloumn); 9 Intent intent=new Intent(android.content.Intent.ACTION_VIEW); 10 File newFile=new File(videoFilePath); 11 intent.setDataAndType(Uri.fromFile(newFile), mimeType); 12 startActivity(intent); 13 } 14 }
下面是一个非常基本的VideoViewInfo类,它用来保存每个返回的视频的信息。
1 class VideoViewInfo{ 2 String filePath; 3 String mimeType; 4 String thumbPath; 5 String title; 6 }
由于在活动中使用了ListView对象来显示每个从MediaStore查询返回的视频,因此将使用ListView来显示视频的标题和缩略图。为了将数据提交给ListView对象,需要构造一个设配器。接下来将创建一个设配器VideoGalleryAdapter,其扩展了BaseAdapter。
构造了这个类之后,将它传递给保存所有从mediaStore查询中返回的视频的ArrayList。
BaseAdapter是一个抽象类,所以为了扩展他,需要实现一个方法。大多数方法都很简单,仅仅是操作传入的ArrayList,如getCount和getItem方法,需要重点关注的是getView方法。
1 class VideoGalleryAdapter extends BaseAdapter{ 2 private Context context; 3 private List<VideoViewInfo> videoItems; 4 private LayoutInflater inflater; 5 public VideoGalleryAdapter(Context _context,ArrayList<VideoViewInfo> _items){ 6 context=_context; 7 videoItems=_items; 8 inflater=(LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE); 9 } 10 @Override 11 public int getCount() { 12 return videoItems.size(); 13 } 14 15 @Override 16 public Object getItem(int position) { 17 return videoItems.get(position); 18 } 19 20 @Override 21 public long getItemId(int position) { 22 return position; 23 }
getView方法用于返回在ListView中表示的每一行的视图,此处向其传入一个待返回的位置(连同一个表示当前视图的View对象和一个表示父ViewGroup的对象)。
1 @Override 2 public View getView(int position, View convertView, ViewGroup parent) {
为了构造将要返回的视图,需要扩展用于每一行的布局。在当前情况下,可以使用videogallery_list_item.xml中定义的布局。
1 View videoRow=inflater.inflate(R.layout.videogallery_list_item, null);
在扩展布局之后可以获得定义的各个视图,并使用VideoViewInfo对象的ArrayList中的数据来定义显示什么内容。下面演示了针对用于显示每个视频的缩略图的ImageView而如何实现该操作。
1 ImageView videoThumb=(ImageView) videoRow.findViewById(R.id.ImageView); 2 if(videoItems.get(position).thumbPath!=null){ 3 videoThumb.setImageURI(Uri.parse(videoItems.get(position).thumbPath)); 4 }
下面的代码获得显示视频标题的TextView,并根据VideoViewInfo对象的ArrayList中的数据来设置文本。
1 TextView videoTitle=(TextView) videoRow.findViewById(R.id.TextView); 2 videoTitle.setText(videoItems.get(position).title);
最后,返回新构造的View对象。
1 return videoRow; 2 } 3 } 4 }
下面是定义上述活动的布局的videogallery.xml文件。
1 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 2 android:layout_width="match_parent" 3 android:layout_height="match_parent" 4 android:orientation="vertical" 5 > 6 <ListView 7 android:layout_width="wrap_content" 8 android:layout_height="wrap_content" 9 android:id="@+id/ListView" 10 ></ListView> 11 </LinearLayout>
下面是用于定义ListView中每一行的布局的videogallery_list_item.xml。
1 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 2 android:layout_width="match_parent" 3 android:layout_height="match_parent" 4 android:orientation="horizontal" 5 > 6 <ImageView 7 android:id="@+id/ImageView" 8 android:layout_width="wrap_content" 9 android:layout_height="wrap_content" 10 /> 11 <TextView 12 android:id="@+id/TextView" 13 android:text="TextView" 14 android:layout_width="fill_parent" 15 android:layout_height="wrap_content" 16 android:textSize="35dip"></TextView> 17 </LinearLayout>
你会注意到显示的缩略图具有不同的大小。他们是由MediaScanner服务创建的,采用与视频本身相同的大小。为了显示大小相同的缩略图,可以调整在videogallery_list_item.xml列表中列出的ImageView条目的参数。
1 <ImageView 2 android:id="@+id/ImageView" 3 android:layout_width="50dip" 4 android:layout_height="50dip" 5 />
现在每个视频缩略图将显示50dipX50dip(术语dip表示“密度无关的像素”)。160dip等于显示器上的1英寸,无论该显示器上像素的分辨率或密度是多少。
posted on 2014-09-04 13:47 宁静致远,一览众山小 阅读(740) 评论(0) 编辑 收藏 举报