Pro Android学习笔记(一)——ContentProvider(上)

原创 2015年07月09日 20:23:00

ContentProvider,Android四大组件之一。他是系统提供的一种抽象的数据服务。Android Developer对她的概述为:


  大概意思就是说ContentProvider(内容提供者)就是为应用程序提供数据。他压缩数据并通过ContentResolver接口提供给应用程序。当我们需要在多个应用程序之间共享数据的时候,我们才考虑使用ContentProvider,否则我们可以直接使用SQLiteDataBase。当一个URI形式的请求通过ContentResolver并且通过注册的Authority请求ContentProvider的时候,ContentProvider可以把URI解释成它想要的(这一段话我也不太会翻译,有不对的地方还望斧正)。

 我们看看这里面涉及到了哪些概念:

(1)ContentProvider,内容提供者。

(2)ContentResolver,用于数据操作的抽象类。

(3)URI,代表了要操作的数据,类似于HTTP URI。

(4)UriMatcher,Uri匹配器,对传递过来的URI进行分析匹配。

以后,还会涉及到

(5)ContentValue,存储键值对用于ContentResolver处理。

(6)Cursor,光标,可以想象成文本编辑器中的光标。

 官方的概述还是很难理解,我们慢慢来看。

(一)查看Android内置ContentProvider

  使用adb可以查看设备内部的ContentProvider。将手机(此处手机应为root之后)连接电脑或者打开模拟器,命令行打开adb。

使用adb devices可以查看所连接设备


在这里我使用的是Genymotion的模拟器,号称最快的模拟器。

然后键入adb shell就可以进入android设备的shell。


在这里我们就能进行一些linux命令的操作,但是,但是,对linux的命令支持并不全面,很多都没有。可以使用“ls /system/bin”命令查看可以执行哪些命令。


太多就不截了。

OK,通过命令"ls -l /data/data/"我们能够查看/data/data/目录下的文件,这里面就保存了应用程序的数据文件,包括数据库。

来看下联系人示例,联系人保存在"/data/data/com.android.providers.cantacts/"下,通过命令“ls /data/data/com.android.providers.contacts/”查看该文件下的数据


可以看到其中都保存了些什么,我们只关心database,所以执行“ls /data/data/com.android.providers.contacts/databases”


里面以数据库的格式保存了我们的联系人。

我们可以使用sqlite3对数据库进行操作,执行“sqlite3  /data/data/com.android.proviers.contacts/databases/contacts.db”


注意此处,由shell环境进入到了sqlite的操作环境。

执行".help"可以查看可执行命令了,在此不多说了。我们通过命令行查看数据库总是不方便,我们可以导出文件到本地电脑,然后通过图形化工具查看。首先,回退到windows的cmd环境底下,执行命令“adb pull /data/data/com.android.providers/contacts/contacts.db D:/”,这里我导出到了我本地磁盘D盘。

然后就可以用数据库工具查看了,Pro Android中使用的是Sqliteman。

记录一些常用数据库语言:

select * from table1; 
select count(*) from table1; 
select col1, col2 from table1; 
select distinct col1 from table1; 
select count(col1) from (select distinct col1  from table1); 
select count(*), col1 from table1 group by col1; 
select * from table1 t1, table2 t2 where t1.col1 = t2.col1; 
select * from table t1 left outer join table2 t2 on t1.col1 = t2.col1 where ....
    以上是我们查看Android设备中的ContentProvider,因为ContentProvider主要使用数据库存储,所以我们基本是查看的数据库。

(二)ContentProvider的架构

    我们在程序中使用ContentProvider的时候,首先需要注册,提供授权(Authority),
vnd.android.cursor.dir/vnd.<yourcompanyname.contenttype>

在AndroidManifest文件中进行注册
<provider android:name="SomeProvider"  android:authorities="com.your-company.SomeProvider" /> 
    其中,name即自定义ContentProvider的类名,可以省略包名;authorities即是为我们提供可使用的URI。
    注册之后,我们就可以使用content://com.your-company.SomeProvider/来进行访问了。
    在Android中,对于系统级程序我们可以使用简写的URI来进行访问,比如联系人可以直接使用contracts。然而对于我们自己的程序,则需要使用全称,否则无法使用。
    以下提供了系统的contacts的注册
<provider android:name="ContactsProvider2" 
    android:authorities="contacts;com.android.contacts" 
    android:label="@string/provider_label" 
    android:multiprocess="false" 
    android:readPermission="android.permission.READ_CONTACTS" 
    android:writePermission="android.permission.WRITE_CONTACTS"> 
    <path-permission 
            android:pathPrefix="/search_suggest_query" 
            android:readPermission="android.permission.GLOBAL_SEARCH"/> 
    <path-permission 
            android:pathPrefix="/search_suggest_shortcut" 
            android:readPermission="android.permission.GLOBAL_SEARCH"/> 
    <path-permission 
            android:pathPattern="/contacts/.*/photo"                                                                                                                                                                                                                                                                       
            android:readPermission="android.permission.GLOBAL_SEARCH"/> 
    <grant-uri-permission android:pathPattern=".*" /> 
</provider>
    URI:上面提到的“content://com.your-company.SomeProvider/”就是一个URI,有没有一种很眼熟的感觉,对,他就像HTTP一样,因为ContentProvider才用了REST和Web服务的抽象机制。
uri的格式如下:
content://<authority-name>/<path-segment1>/<path-segment2>/etc… 
例子:content://com.google.provider.NotePad/notes/23
    其中,notes就是path-segment,而23,就是我们要访问资源的ID。

    MIME Type:我们进行了一次URI请求之后就会返回数据,这类数据的类型就用MIME来表示。Android遵循了一定的约定来定义MIME类型。

    对于单条记录:

vnd.android.cursor.item/vnd.<yourcompanyname.contenttype>
    对于记录或行的集合:

vnd.android.cursor.dir/vnd.<yourcompanyname.contenttype>

    其中,vnd表示这些类型和子类型具有非标准的、供应商特定的形式。对于Android,本质上能识别项是“单个”还是“集合”项,作为程序员,我们只关心子类型,即
vnd.<yourcompanyname.contenttype>

    Cursor:游标是一个行集合,在读取数据之前,我们需要使用moveToFirst(),将游标放置第一行。使用游标的时候,需要知道列类型和列名称,在访问之前,需要将列名称转化为列编号,通过游标,可以获取行计数。

    以下示例演示了如何使用URI从ContentProvider获取一个游标

// An array specifying which columns to return
Sting[] projection = new String[] {
	Contacts._ID,
	Contacts.DISPLAY_NAME_PRIMARY
};
Uri mContactsUri = ContactsContract.Contacts.CONTENT_URI;

// Best way to retrieve a query; returns a managed query
Cursor managedCursor = managedQuery(mContactsUri,
				projection, // which columns to return
				null,       // where clause
				Contacts.DISPLAY_NAME_PRIMARY + " ASC"); // Order-by clause
    Where条件语句的用法:ContentProvider提供了两种方式来传递where字句

1、通过URI

Activity somActivity
// ..intialize someActivity
String moteUri = "content://com.google.provider.NotePad/notes/23";
Cursor managedCursor = someActivity.managedQuery(noteUri,
			projection, // Which columns to return.
			null,       // WHERE clause
			null);      // Order-by clause
2、通过string字句与一组可替换的字符串数据参数的组合

public final Cursor managedQuery(Uri uri,
	String[] projection,
	String selection,
	String[] seleciontArgs,
	String sortOrder)







    
版权声明:本文为博主原创文章,未经博主允许不得转载。

Android之通过ContentProvider共享文件

使用ContentProvider共享文件时,一定要重写openFile方法,否则会报异常。 如: public class ContentProviderDemo extends Content...
  • zhangyongfeiyong
  • zhangyongfeiyong
  • 2016年07月08日 11:09
  • 743

SQLite 和 ContentProvider的使用

1.SQLiteOpenHelper使用方法     getReadableDatabase() //创建或打开一个只读的数据库     getWriteableDatabase() //创建或打...
  • shuaijunqi
  • shuaijunqi
  • 2012年08月21日 07:40
  • 5792

利用ContentProvider获得本设备上所有的音/视频文件信息

笔记
  • ZLJ19911001
  • ZLJ19911001
  • 2016年12月16日 13:37
  • 536

关于“运行在主线程的ContentProvider为什么不会影响主线程”的记录

我们四大组件都是运行在UI线程上的,之前据我自己所看到的是主线程上有耗时的操作可能会造成ANR,今天做了一个实验,建立一个工程,主Activity有一个可以触发显示一个Toast的按钮,另外还有一个S...
  • miao309410364
  • miao309410364
  • 2016年03月02日 13:47
  • 2225

ContentProvider android:exported = “true”

今天学习使用ContentProvider,发现一个小问题,在其他应用中使用getContentResolver().query()的时候总是报:Permission Denial: opening ...
  • u013578042
  • u013578042
  • 2015年11月22日 15:54
  • 857

Pro Android学习笔记(十三):用户界面和控制(1):UI开发

UI开发 先理清一些UI概念: view、widget、control:这三个名词其实没有什么区别,都是一个UI元素,例如一个button。 Container(容器):包含其他view,例如grid...
  • flowingflying
  • flowingflying
  • 2013年08月13日 21:44
  • 4247

Android 通过ContentProvider数据库更新UI

这篇用到的知识点有几个:SQLiteOpenHelper,Cursor,CursorAdapter,ContentProvider,ContentObserver 对于数据库的操控一般都是用SQ...
  • jdsjlzx
  • jdsjlzx
  • 2015年02月10日 14:11
  • 3662

Android -- Contentprovider---listview 实现调用通讯录和短信接收

获取权限 注册
  • u010056396
  • u010056396
  • 2015年09月05日 09:40
  • 595

Android 进阶11:进程通信之 ContentProvider 内容提供者

学习启舰大神,每篇文章写一句励志的话,与大家共勉。When you are content to be simply yourself and don’t compare or compete, ev...
  • u011240877
  • u011240877
  • 2017年06月02日 23:24
  • 3078

ContentProvider跨APP读取数据失败

一、问题场景      现在有两个应用,一个是应用A,另一个是应用B,B是做为插件的形式存在,服务于A,当应用A需要数据时,则通过ContentProvider去拿数据回来。但是现在有个问题,就是在...
  • ballonge
  • ballonge
  • 2016年03月14日 12:05
  • 1449
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:Pro Android学习笔记(一)——ContentProvider(上)
举报原因:
原因补充:

(最多只允许输入30个字)