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  宁静致远,一览众山小  阅读(700)  评论(0编辑  收藏  举报

导航