视频播放器(二)-获取视频信息

  • 第2节 获取视频信息
    • 1 ContentProvider
    • 2 系统级的ContentProvider
    • 3 使用Media Provider的缺点
    • 4 Media Provider查询视频文件

第2节 获取视频信息

要知道设备上有哪些可以被播放的视频文件,一般来讲有两个方法,

  1. 遍历设备磁盘上所有的目录,根据文件的后缀名,把这些目录中所有的视频文件都找出来;
  2. 向安卓系统提供的Media Provider提出查询请求,从而获取我们希望的视频文件信息;

从“减小开发难度,利用安卓系统自身功能,选择最简单的方案”的角度出发,我们采用Media Provider

2.1 ContentProvider

ContentProvider是安卓系统的四大组件之一,为别的组件(Activity、Service)“提供内容”。它就像是一个拥有某种数据的网站,安卓系统运行的其它组件可以通过“网址”访问这个网站,获取需要查询的数据。

  1. ContentProvider可以是私有的,只能为它所在的应用提供数据访问请求;
  2. ContentProvider也可以是公开的,为别的应用程序提供数据访问请求。
    当我们自己开发一个ContentProvider的时候,就要在应用的AndroidManifest.xml文件中声明它的存在,
<application  android:allowBackup="true" ....../>

        <activity android:name=".MyActivity" />

    <provider  android:name=".MyContentProvider" android:authorities="com.anddle.videoplayer" android:exported="false"/>  -->false为私有的,true为公开的

</application>

从这里也可以看出,它和Activity的地位是一样的,所以与Activity一样并称为安卓系统的四大组件之一。

2.2 系统级的ContentProvider

安卓系统上,有一个叫做Media ProviderContentProvider。它作为系统级别的应用程序在系统上运行,专门负责收集多媒体文件(音频、视频、文件)相关的信息。

Media Provider在开机启动后,会在后台“监听”磁盘上文件的变化,特定情况下,会自动更新多媒体文件的信息,例如磁盘上是否增加了媒体文件,是否被删除了媒体文件,有的媒体文件名称是否发生了修改等等。

所以当任何应用想获取这类文件相关的信息时,就可以向Media Provider发起查询的请求。Media Provider帮我们完成了视频文件信息的收集,因此,我们就不用自己去遍历磁盘上的文件进行视频文件的收集和整理了。

除了Media Provider,系统还提供了

  1. Contacts Provider:用来查询联系人信息;
  2. Calendar Provider:用来提供日历相关信息的查询;
  3. Bookmark Provider:用来提供书签信息的查询;


其它的就不再一一列出了。

2.3 使用Media Provider的缺点

使用Media Provider有一点需要注意,Media Provider对磁盘多媒体文件的“监控”,并不是实时的。当删除磁盘上一个已有的视频文件时,Media Provider并不会马上知道,而是要等到下一次的扫描之后,才会更新这个信息。因此,如果使用Media Provider做为我们提供视频信息的来源,就要考虑到“一个视频刚好被修改了,但是还没有来得及在Media Provider中更新信息”的情况。

2.4 Media Provider查询视频文件

  1. 确定向Media Provider发出查询请求的地址-uri,它就像访问网站时,要输入的网址一样。系统提供了两个位置的uri,一个是指向内部存储的uri,一个是指向外部存储的uri。我们要查询的视频文件都是存放在外部存储地址上的;

    Uri uri = MediaStore.Video.Media.EXTERNAL_CONTENT_URI;
  2. 确定要请求的视频文件信息。在视频列表中,我们需要展示视频的标题、创建时间,还需要播放它时使用的文件所在地址。这些信息在Media Provider中都对应着查询它们使用的字段名称;

    String[] searchKey = new String[] {
    MediaStore.Video.Media.TITLE, -->对应文件的标题
    MediaStore.Images.Media.DATA, -->对应文件的存放位置
    MediaStore.Images.Media.DATE_ADDED -->对应文件的创建时间
    };
  3. 确定查询的条件。我们之前假设过只关心那些叫做Video的目录。因此我们要确定的只是查询到的文件路径中,包含有/Video这个字段。

    String where = MediaStore.Video.Media.DATA + " like \"%"+"/Video"+"%\"";

    这个条件参数的写法就和SQL数据库语言的语法一样。这里我们不打算讲SQL语法,只要知道在我们这个例子中这样使用就好了;

  4. 设定查询结果的排序方式,使用默认的排序方式就可以了,

    String sortOrder = MediaStore.Video.Media.DEFAULT_SORT_ORDER;
  5. 获取ContentResolver对象,让它使用前面的参数向Media Provider发起查询请求;查询的结果存放在Cursor--指标当中;

    ContentResolver resolver = getContentResolver();
    Cursor cursor = resolver.query(
                    uri,
                    searchKey, 
                    where, 
                    null, 
                    sortOrder);
  6. 遍历Cursor,得到它指向的每一条查询到的信息;当Cursor指向某条数据的时候,我们就获取它携带的每个字段的值;

    while(cursor.moveToNext())
    {
        String path = cursor.getString(cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA));
        String name = cursor.getString(cursor.getColumnIndex(MediaStore.Video.Media.TITLE));
        String createdTime = cursor.getString(cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATE_ADDED));
        ......  
    }
  7. 存放获取的视频文件信息,创建一个VideoItem类

    public class VideoItem {
    
        String name;
        String path;
        Bitmap thumb;
        String createdTime;
    
        VideoItem(String strPath, String strName, String createdTime) {
    
            this.path = strPath;
            this.name = strName;
            ......
       }
    }

    将视频文件创建的时间从Unix格式的时间戳,转换成“年月日分”这种可读的形势,

    VideoItem(String strPath, String strName, String createdTime) {
        ......
        SimpleDateFormat sf = new SimpleDateFormat("yy年MM月dd日HH时mm分");
        Date d = new Date(Long.valueOf(createdTime)*1000);
        this.createdTime = sf.format(d);
    }

    获取视频文件的缩略图,Android SDK提供了一个利用视频文件地址获取视频缩略图的工具,用起来非常简单的,通过它将得到缩略图的Bitmap;

    VideoItem(String strPath, String strName, String createdTime) {
        ......
        this.thumb = ThumbnailUtils.createVideoThumbnail(path, MediaStore.Images.Thumbnails.MINI_KIND);
    }

    图片生成的尺寸可以通过第二个参数设置,MINI_KIND
    表示小的缩略图;FULL_SCREEN_KIND表示大尺寸的缩略图;MICRO_KIND表示超小图的缩略图。这里我们采用的是MINI_KIND

  8. Cursor使用完了之后要把它关闭掉,

    cursor.close();

整理一下前面的各个步骤,获取外部存储上Video目录中所有视频文件的方式如下,

Uri uri = MediaStore.Video.Media.EXTERNAL_CONTENT_URI;

String[] searchKey = new String[] {
    MediaStore.Video.Media.TITLE,
    MediaStore.Images.Media.DATA,
    MediaStore.Images.Media.DATE_ADDED
};
String [] keywords = null;
String where = MediaStore.Video.Media.DATA + " like \"%"+"/Video"+"%\"";
String sortOrder = MediaStore.Video.Media.DEFAULT_SORT_ORDER;

ContentResolver resolver = getContentResolver();
Cursor cursor = resolver.query(
                    uri,
                    searchKey, 
                    where, 
                    keywords, 
                    sortOrder);

if(cursor != null)
{
    while(cursor.moveToNext())
    {
        String path = cursor.getString(cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA));
        String name = cursor.getString(cursor.getColumnIndex(MediaStore.Video.Media.TITLE));

        String createdTime = cursor.getString(cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATE_ADDED));

        VideoItem item = new VideoItem(path, name, createdTime);
        ......  
    }

    cursor.close();
}

最后一点千万不要忘记,要在应用的AndroidManifest.xml文件中,添加读取外部存储器的权限,

<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.anddle.anddleplayer">

    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
    ......

</manifest>

你可能感兴趣的:(视频,安卓开发,应用)