ContentProvider介绍

ContentProvider是不同应用程序之间进行交换数据的标志API

也就是说:一个应用程序通过ContentProvider暴露自己的数据操作接口,那么无论该应用是否启动(一定部署),其它应用程序能够通过该接口来操作该应用的内部数据,包含添加数据,删除数据,改动数据。查询数据等。

当应用继承ContentProvider类,并重写该类用于提供数据和存储数据的方法,就能够向其它应用共享其数据。

尽管使用其它方法也能够对外共享数据,但数据訪问方式会因数据存储的方式而不同

如:採用文件方式对外共享数据,须要进行文件操作读写数据。

採用sharedpreferences共享数据。须要使用sharedpreferences API读写数据。

而使用ContentProvider共享数据的优点是统一了数据訪问方式。

通过ContentProvider对外共享数据步骤:

继承ContentProvider并重写以下方法

public class PersonContentProvider extends ContentProvider{

public boolean onCreate()

public Uri insert(Uri uri, ContentValues values)

public int delete(Uri uri, String selection, String[] selectionArgs)

public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs)

public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder)

public String getType(Uri uri)

}

方法介绍

public boolean onCreate()

在UserContentProvider创建之后,就会被调用,当其它应用程序第一次訪问contentPrivider时。该ContentProvider就会被创建出来

public String getType(Uri uri)

返回操作的类型 假设操作多条记录那么MINE类型vnd.android.cursor.dir/开头

假设操作的数据仅仅有一条记录那么MINE类型vnd.android.cursor.item/开头

public Uri insert(Uri uri, ContentValues values)

插入操作

public int delete(Uri uri, String selection, String[] selectionArgs)

删除操作

public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs)

改动操作

public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder)

查询操作


在AndroidManifest.xml使用<provider>对该ContentProvider进行配置

为了能让其它应用找到该ContentProvider 。 ContentProvider 採用了authorities(主机名/域名)对它进行唯一标识,你能够把 ContentProvider看作是一个站点(想想,站点也是提供数据者),authorities 就是他的域名:

<manifest .... >

    <application android:icon="@drawable/icon" android:label="@string/app_name">

        <provider android:name=".PersonContentProvider" android:authorities="cn.itcast.provider.personprovider"/>

    </application>

</manifest>

注意:一旦应用继承了ContentProvider类,后面我们就会把这个应用称为ContentProvider(内容提供者)。

Uri介绍

Uri代表了要操作的数据

Uri主要包括了两部分信息:
  1. 须要操作的ContentProvider 。
  2. 对ContentProvider中的什么数据进行操作

Uri组成部分


  • scheme:ContentProvider(内容提供者)的scheme已经由Android所规定, scheme为:content://
  • 主机名(或叫Authority):用于唯一标识这个ContentProvider,外部调用者能够依据这个标识来找到它。
  • 路径(path):能够用来表示我们要操作的数据。路径的构建应依据业务而定。
    • 要操作person表中id为10的记录,能够构建这种路径:/person/10
    • 要操作person表中id为10的记录的name字段, person/10/name
    • 要操作person表中的全部记录,能够构建这种路径:/person
    • 要操作xxx表中的记录。能够构建这种路径:/xxx
    • 当然要操作的数据不一定来自数据库。也能够是文件、xml或网络等他存储方式,例如以下:
    • 要操作xml文件里person节点下的name节点。能够构建这种路径:/person/name
当别的应用程序要訪问此项目的时候,就须要一个訪问地址,uri就充当的这个角色,和我们訪问的url一样。例如以下:

URL:    http://www.baidu.com/index.html 
http://:
http协议訪问站点
www.baidu.com域名部分
 /index.html:站点资源 
URI:     content://www.csdn.com.provider.userContentProvider/user
content://android的ContentProvider的规定

www.csdn.com.provider.userContentProvider:文件汇中自己配置的authorities

user: 资源部分(数据部分)当訪问者须要訪问不同的资源时,这个部分是动态改变.这个部分能够自定义


parse()

假设要把一个字符串转换成Uri
Uri uri = Uri.parse("content://cn.itcast.provider.personprovider/person")

操作Uri

由于Uri代表了要操作的数据,所以我们常常须要解析Uri,并从Uri中获取数据。Android系统提供了两个用于操作Uri的工具类。分别为UriMatcher 和ContentUris 。掌握它们的使用。会便于我们的开发工作。

UriMatcher类

  • uriMatcher.addURI(authority, path, code):匹配码是调用addURI()方法传入的第三个參数

    • 參数一authority:定义的authority路径
    • 參数二path:URI路径
    • 參数三code:返回的匹配码
  • 注冊完须要匹配的Uri后,就能够使用sMatcher.match(uri)方法对输入的Uri进行匹配,假设匹配就返回匹配码。
UriMatcher类用于匹配Uri。它的使用方法例如以下:

把你须要匹配Uri路径所有给注冊上,例如以下:

//常量UriMatcher.NO_MATCH表示不匹配不论什么路径的返回码

UriMatcher  sMatcher = new UriMatcher(UriMatcher.NO_MATCH);

//假设match()方法匹配content://cn.itcast.provider.personprovider/person路径,返回匹配码为1

sMatcher.addURI(“cn.itcast.provider.personprovider”, “person”, 1);//加入须要匹配uri。假设匹配就会返回匹配码

//假设match()方法匹配content://cn.itcast.provider.personprovider/person/230路径,返回匹配码为2

sMatcher.addURI(“cn.itcast.provider.personprovider”, “person/#”, 2);//#号为通配符

switch (sMatcher.match(Uri.parse("content://cn.itcast.provider.personprovider/person/10"))) { 

case 1

break;

case 2

break;

default://不匹配

break;

}

ContentUris类

ContentUris类用于获取Uri路径后面的ID部分,它有两个比較有用的方法:


  • withAppendedId(uri, id)用于为路径加上ID部分:

    • Uri uri = Uri.parse("content://cn.itcast.provider.personprovider/person")
    • Uri resultUri = ContentUris.withAppendedId(uri, 10);
    • //生成后的Uri为:content://cn.itcast.provider.personprovider/person/10
  • parseId(uri)方法用于从路径中获取ID部分:
    • Uri uri = Uri.parse("content://cn.itcast.provider.personprovider/person/10")
    • long personid = ContentUris.parseId(uri);
    • //获取的结果为:10

ContentProvider中方法实现步骤

  1. 继承ContentProvider类
  2. 声明操作的标志
  3. 定义uri解析返回的匹配码
  4. 使用UriMatcher类匹配Uri
  5. 在oncreate()中实例化数据库操作对象
  6. 查询方法
    1. 匹配URI 进行推断
    2. 匹配成功进行查询
  7. 加入方法
    1. 匹配URI 进行推断
    2. 匹配成功进行加入
    3. 返回:通过ContentUris.withAppendedId加入唯一的id值
  8. 删除方法
    1. 匹配URI 进行推断
    2. 匹配成功进行删除
    3. 关闭数据库
    4. 返回:删除的行数
  9. 改动方法
    1. 匹配URI 进行推断
    2. 匹配成功进行改动
    3. 关闭数据库
    4. 返回:改动的行数
ContentProvider中的增删改查都是依据android封装好的CURD

ContentProvider源代码:
package com.example.android_sqlite.provider;

import com.example.android_sqlite.database.DatabaseHelper;

import android.content.ContentProvider;
import android.content.ContentUris;
import android.content.ContentValues;
import android.content.UriMatcher;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.net.Uri; public class UserContentProvider extends ContentProvider {
// 1.操作的标志
private static final String AUTHORITIE = "www.csdn.com.provider.userContentProvider"; // 2.定义uri解析返回的匹配码
private static final int QUERY = 1;
private static final int INSERT = 2;
private static final int UPDATE = 3;
private static final int DELETE = 4; private static UriMatcher uriMatcher;
private DatabaseHelper dh; // 3.使用UriMatcher类匹配Uri
static {
//实例化UriMatcher对象。常量UriMatcher.NO_MATCH表示不匹配不论什么路径的返回码
uriMatcher = new UriMatcher(UriMatcher.NO_MATCH);
// 匹配的结果码
uriMatcher.addURI(AUTHORITIE, "query", QUERY);
uriMatcher.addURI(AUTHORITIE, "insert", INSERT);
uriMatcher.addURI(AUTHORITIE, "update", UPDATE);
uriMatcher.addURI(AUTHORITIE, "delete", DELETE);
} /**
* 在UserContentProvider创建之后,就会被调用,当其它应用程序第一次訪问contentPrivider时。
* 该ContentProvider就会被创建出来
*/
@Override
public boolean onCreate() {
dh = new DatabaseHelper(getContext());
return false;
} /**
* URL:http://www.baidu.com/index.html http://: http协议訪问站点
* www.baidu.com:域名部分 /index.html:站点资源
*
* URI:content://www.csdn.com.provider.userContentProvider/user
* content://android的ContentProvider的规定
* www.csdn.com.provider.userContentProvider:文件汇中自己配置的authorities
* user:资源部分(数据部分)当訪问者须要訪问不同的资源时,这个部分是动态改变.这个部分能够自定义
*
* UriMatcher:匹配uri
*/
/**
* 查询方法
*/
@Override
public Cursor query(Uri uri, String[] projection, String selection,
String[] selectionArgs, String sortOrder) { Cursor c = null;
// 匹配URI 进行推断
if (uriMatcher.match(uri) == QUERY) {
SQLiteDatabase db = dh.getReadableDatabase();
c = db.query("users", projection, selection, selectionArgs, null,
null, sortOrder);
} else {
System.out.println("查询操作的uri不匹配");
}
return c;
} /**
* 返回操作的类型 假设操作多条记录那么MINE类型vnd.android.cursor.div/开头
* 假设操作的数据仅仅有一条记录那么MINE类型vnd.android.cursor.item/开头
*/
@Override
public String getType(Uri arg0) {
return null; } /**
* 插入操作
*/
@Override
public Uri insert(Uri uri, ContentValues values) {
long rowId = 0;
if (uriMatcher.match(uri) == INSERT) {
SQLiteDatabase db = dh.getReadableDatabase();
rowId = db.insert("users", null, values);
db.close();
} else {
System.out.println("插入不匹配");
}
//通过ContentUris.withAppendedId增加唯一的id值
return ContentUris.withAppendedId(uri, rowId);
} /**
* 更新操作
*/
@Override
public int update(Uri uri, ContentValues values, String selection,
String[] selectionArgs) {
//更新几行
int count = 0;
if (uriMatcher.match(uri) == UPDATE) {
SQLiteDatabase db = dh.getWritableDatabase();
count = db.update("users", values, selection, selectionArgs);
db.close();
}
return count;
} /**
* 删除操作
*/
@Override
public int delete(Uri uri, String selection, String[] selectionArgs) {
//删除几行
int count = 0;
if (uriMatcher.match(uri) == DELETE) {
SQLiteDatabase db = dh.getWritableDatabase();
count = db.delete("users", selection, selectionArgs);
db.close();
}
return count;
} }

AndroidManifest.xml


<?

xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.android_sqlite"
android:versionCode="1"
android:versionName="1.0" > <uses-sdk
android:minSdkVersion="8"
android:targetSdkVersion="17" /> <instrumentation
android:name="android.test.InstrumentationTestRunner"
android:targetPackage="com.example.android_sqlite" >
</instrumentation> <application
android:allowBackup="true"
android:icon="@drawable/ic_launcher"
android:label="@string/app_name"
android:theme="@style/AppTheme" >
<activity
android:name="com.example.android_sqlite.MainActivitysss"
android:label="@string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity> <uses-library android:name="android.test.runner" />
<!-- 配置ContentProvider -->
<provider
android:name=".provider.UserContentProvider"
android:authorities="www.csdn.com.provider.userContentProvider"
android:exported="true" >
</provider>
</application> </manifest>






赵雅智_ContentProvider的更多相关文章

  1. 赵雅智_Fragment生命周期

    官网帮助文档链接:  http://developer.android.com/guide/components/fragments.html 主要看两张图.和跑代码 一,Fragment的生命周 w ...

  2. 赵雅智:js知识点汇总

    watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvemhhb3lhemhpMjEyOQ==/font/5a6L5L2T/fontsize/400/fill/I0 ...

  3. 赵雅智_ListView_BaseAdapter

    Android界面中有时候须要显示略微复杂的界面时,就须要我们自己定义一个adapter,而此adapter就要继承BaseAdapter,又一次当中的方法. Android中Adapter类事实上就 ...

  4. 赵雅智_BroadcastReceiver电话监听

    AndroidManifest.xml 注冊广播接收者 加入权限 <?xml version="1.0" encoding="utf-8"?> &l ...

  5. 赵雅智_BroadcastReceiver

    BroadcastReceiver  用于接收程序(包含用户开放的程序和系统内建程序)所发出的Broadcast intent 耗电量 开机启动 窃取别人短信 窃取别人电话 开发: 创建须要启动的Br ...

  6. 赵雅智:service_startService生命周期

    案例演示 布局文件 <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xm ...

  7. 赵雅智_BroadcastReceiver短信监听

    AndroidManifest.xml 注冊广播接收者 加入权限 <?xml version="1.0" encoding="utf-8"?> &l ...

  8. 赵雅智_Android编码规范

    凝视 导入mycodetemplates.xml统一凝视样式 须要加凝视的地方 类凝视(必加) 方法凝视(必加) 块凝视主要是数据结构和算法的描写叙述(必加) 类成员变量和常量凝视(选择性加入) 单行 ...

  9. 赵雅智:service与訪问者之间进行通信,数据交换

    服务类 中间人:service服务中的bind对象 创建中间人并通过onBinder方法的return暴露出去 watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQ ...

随机推荐

  1. https实现安全传输的流程

    HTTPS简介 HTTPS其实是有两部分组成:HTTP + SSL / TLS,也就是在HTTP上又加了一层处理加密信息的模块.服务端和客户端的信息传输都会通过TLS进行加密,所以传输的数据都是加密后 ...

  2. 【web】web欢迎页面执行servlet

    <!-- servlet名 --> <welcome-file-list> <welcome-file>Begin_page</welcome-file> ...

  3. ASP.NET CORE Web浏览器和Web服务器

    //web浏览器 //浏览器本质的原理:浏览器向服务器发请求,服务器把请求的内容返回给浏览器,然后浏览器把返回的内容绘制成一个图形化的界面 //Socket一种通讯交流的技术 //qq用户把信息通过s ...

  4. ASP.NET导出excel表方法汇总

    asp.net里导出excel表方法汇总  1.由dataset生成 public void CreateExcel(DataSet ds,string typeid,string FileName) ...

  5. javascript AES加密 C#AES解密实现

    首先需要引入js类库 crypto-js(开源),地址:http://code.google.com/p/crypto-js 现在很多人无法打开这个地址不要紧,下面我们会将全部代码贴出来 需要引入 a ...

  6. 双网卡bond

           使用双网卡虚拟为一块网卡: 服务器版本: [root@kel ~]# lsb_release -a LSB Version: :core-3.1-amd64:core-3.1-ia32: ...

  7. mybatis系列-08-动态sql

    8.1     什么是动态sql mybatis核心 对sql语句进行灵活操作,通过表达式进行判断,对sql进行灵活拼接.组装. 8.2     需求 用户信息综合查询列表和用户信息查询列表总数这两个 ...

  8. 【成都GamEver游戏公司诚邀服务器伙伴】【7~15k一年4次项目奖金】

    关于我们 我们厌倦了朝九晚五,一眼看到头的人生我们厌倦了耗费自己青春做的都是没有感情的项目平均从业经验5年以上行业顶尖美术和金牌制作人,资深欧美制作经验立志做中国的suppercell,公司小而美 我 ...

  9. Tkinter教程之Button篇(2)

    本文转载自:http://blog.csdn.net/jcodeer/article/details/1811300 # Tkinter教程之Button篇(2)'''5.指定Button的宽度与高度 ...

  10. android - python 自动化测试 移动互联网 - SegmentFault

    android - python 自动化测试 移动互联网 - SegmentFault splinter