ContentProvider数据库共享之——MIME类型与getType()

前言:这篇没有前言……

 

相关文章:
1、《ContentProvider数据库共享之——概述》
2、《ContentProvider数据库共享之——实例讲解》
3、《ContentProvider数据库共享之——MIME类型与getType()》
4、《ContentProvider数据库共享之——读写权限与数据监听》

 

一、概述

在上篇中,我们讲了通过共享数据库的增、删、改、查问题,但在生成PeopleContentProvider类时,由于其派生自ContentProvider,所以我们我们重写了数据库操作的insert()、query()、update()、delete()函数,但对于getType()直接返回了null;我们这篇主要就讲讲这个getType()函数有什么用。

先看下getType()的官方说明:

 

public abstract String getType (Uri uri)

Implement this to handle requests for the MIME type of the data at the given URI. The returned MIME type should start with vnd.android.cursor.item for a single record, or vnd.android.cursor.dir/ for multiple items. This method can be called from multiple threads, as described in Processes and Threads.

Parameters
uri	the URI to query.
Returns
a MIME type string, or null if there is no type.

总体来说,就是传进去一个URI,返回一个表示MIME类型的字符串;里面还说,如果是单条记录应该返回以vnd.android.cursor.item/ 为首的字符串,如果是多条记录,应该返回vnd.android.cursor.dir/ 为首的字符串;
下面先来看看MIME类型是什么?

二、MIME类型

 

1、什么是MIME类型

根据百度百科的解释:MIME:全称Multipurpose Internet Mail Extensions,多功能Internet邮件扩充服务。它是一种多用途网际邮件扩充协议,在1992年最早应用于电子邮件系统,但后来也应用到浏览器。MIME类型就是设定某种扩展名的文件用一种应用程序来打开的方式类型,当该扩展名文件被访问的时候,浏览器会自动使用指定应用程序来打开。多用于指定一些客户端自定义的文件名,以及一些媒体文件打开方式。
看完之后,只有一个感觉……依然不懂!简单来讲,MIME类型就是用来标识当前的Activity所能打开的文件类型!

下面简单列出来系统中自带的几种文件类型和对应的MIME类型:

(前面是文件名,后面是对应的MIME类型字符串)

{".bmp", "image/bmp"}
{".c", "text/plain"}
{".class", "application/octet-stream"}
{".conf", "text/plain"}
{".cpp", "text/plain"}
{".doc", "application/msword"}

2、MIME类型有什么用

那现在看看在android中,MIME类型是用来干什么的呢?
首先,MIME类型主要是Activity的Intent-filter的data域;比如下面这个Activity:

 

<activity
    android:name=".SecondActivity"
    android:label="@string/title_activity_second" >
    <intent-filter>
        <action android:name="harvic.test.qijian"/>
        <category android:name="android.intent.category.DEFAULT"/>
        <data android:mimeType="image/bmp"/>
    </intent-filter>
</activity>

这里指定了data域的MimeType值是"image/bmp",即在利用隐式Intent匹配时,只有指定MimeType是"image/bmp"时,才能启用这个Activity,也就是说,这个Activity只能打开image/bmp类型的文件!!!!这才是MIME类型匹配的重点;
所以MIME类型在Activity中是用来指定,当前的Activity所支持打开的文件类型!!

三、getType()

 

1、概述

现在再回过来看看ContentProvider中的getType()函数,这个函数会根据传进来的URI,生成一个代表MimeType的字符串;而此字符串的生成也有规则:

  • 如果是单条记录应该返回以vnd.android.cursor.item/ 为首的字符串
  • 如果是多条记录,应该返回vnd.android.cursor.dir/ 为首的字符串

至于自符串/后的字符就随便定义了。

 

这里考虑一个问题,为什么我们返回的MimeType,要以vnd.android.cursor.item/ 或vnd.android.cursor.dir/ 开头?
我们知道,MIME类型其实就是一个字符串,中间有一个 “/” 来隔开,“/”前面的部分是系统识别的部分,就相当于我们定义一个变量时的变量数据类型,通过这个“数据类型”,系统能够知道我们所要表示的是个什么东西。至于 “/” 后面的部分就是我们自已来随便定义的“变量名”了。

2、getType()与Activity的关系

上面我们讲了MIME存在于Activity的intent-filter中,那我们的getType() 跟Activity的intent-filter之间又有什么关系呢?
其实,getType()返回的MIME类型,主要就是用来隐式匹配Intent的MIMETYPE域来启动Activity的。
下面来看看通过URI来启用Activity的方式:

 

Intent intent = new Intent();
intent.setAction("harvic.test.qijian");
intent.setData(mCurrentURI);
startActivity(intent);

其中:

public static final String AUTHORITY = "com.harvic.provider.PeopleContentProvider";
public static final Uri CONTENT_URI_FIRST = Uri.parse("content://" + AUTHORITY + "/first");
public static Uri mCurrentURI = CONTENT_URI_FIRST;

在上面的代码中,我们设置了action 和 content uri;
这里利用Content URI来启用隐式启用Activity又是怎样一个流程呢?

 

  • (1)首先,第三方应用通过content Uri和action来隐式匹配Intent来启用Activity.

 

 

Intent intent = new Intent();
intent.setAction("harvic.test.qijian");
intent.setData(mCurrentURI);
startActivity(intent);
  • (2)、系统通过URI中的Authority来匹配ContentProvider,从而找到我们的PeopleContentProvider。
  • (3)在找到PeopleContentProvider,由于我们是来匹配Intent的,所以这时候会调用getType(uri)来返回URI类型:
static {
     sUriMatcher = new UriMatcher(UriMatcher.NO_MATCH);
     sUriMatcher.addURI(AUTHORITY, "first", MATCH_FIRST);
     sUriMatcher.addURI(AUTHORITY, "second", MATCH_SECOND);
    }

上面是UriMather的构造方法,由上面的代码可知,当匹配"/first"时返回MATCH_FIRST即数值1,匹配“/second”时返回MATCH_SECOND,即数值2
所以:
1、当匹配"/fist"时,我们返回自定义的MIME类型:vnd.android.cursor.dir/harvic.first
2、当匹配“/second”时,返回MIME类型:vnd.android.cursor.item/harvic.second
代码如下:

public static final String CONTENT_FIRST_TYPE = "vnd.android.cursor.dir/harvic.first";
public static final String CONTENT_SECOND_TYPE = "vnd.android.cursor.item/harvic.second";
public String getType(Uri uri) {
    switch (sUriMatcher.match(uri)){
        case MATCH_FIRST:{
            return CONTENT_FIRST_TYPE;
        }
        case MATCH_SECOND:{
            return CONTENT_SECOND_TYPE;
        }
    }
    return null;
}
  • (4)下面就是根据Action和MIME类型来匹配Intent了

我们到现在在ContentProviderBlog项目中还没有一个Activity能匹配这个Action和MIME类型的,所以我们新建一个SecondActivity;

3、新建SecondActivity用来通过URI启动

在这个Activity中,我们只利用TextView来标识当前这个Activity来自ContentProviderBlog的secondActivity;
XML代码:所以,我们在TextView中,将其Text属性改为"ContentProviderBlog的secondActivity"以便识别这个Activity;

 

 

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <TextView
        android:text="ContentProviderBlog的secondActivity"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" />

</RelativeLayout>

4、AndroidManifest.xml

在AndroidManifest.xml中,为SecondActivity添加上隐式匹配所需要的Intent-filter;注意我们在getType()里根据不同的URI返回了两种MIME类型,而这里的SecondActivity的data域只添加一个mimeType:vnd.android.cursor.dir/harvic.first;即当我们使用content://com.harvic.provider.PeopleContentProvider/second来隐式匹配Intent时,是没办法启用SecondActivity的,因为MIME类型不匹配!

 

 

<activity
    android:name=".SecondActivity"
    android:label="@string/title_activity_second">
    <intent-filter>
        <action android:name="harvic.test.qijian" />
        <category android:name="android.intent.category.DEFAULT" />
        <data android:mimeType="vnd.android.cursor.dir/harvic.first" />
    </intent-filter>
</activity>

四、结果展示

下面我们看看在使用不同的URI来启用Activity时,会出现什么结果;

 

使用content://com.harvic.provider.PeopleContentProvider/first,结果如下:
点击“thirdPart”,通过URI调起Activity

  

使用content://com.harvic.provider.PeopleContentProvider/second,由于MIME不匹配,导致无法调起Activity

 

 

同样,源码包含两部分内容:
(先装ContentProviderBlog,再装UseProvider;利用UseProvider操作ContentProviderBlog的数据库,看打出来的LOG)

1、《ContentProviderBlog》:这个是提供共享数据库接口的APP;
2、《UseProvider》:第三方通过URI来操作数据库的APP;

 

如果本文有帮到你,记得关注哦。

源码地址:http://download.csdn.net/detail/harvic880925/8532205

请大家尊重原创者版权,转载请标明出处:http://blog.csdn.net/harvic880925/article/details/44620851  谢谢!

 

如果你喜欢我的文章,你可能更喜欢我的公众号

启舰杂谈

  • 12
    点赞
  • 26
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值