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. ubuntun安装ssh,并远程链接服务器操作

    SSH是一种以安全.加密方式连接远程主机或服务器的方法.SSH服务器接受从有SSH的客户机的连接,允许操作者象在本地一样地登录系统.你可以用SSH从远程运行shell和X程序. (1)安装SSH服务器 ...

  2. 【转】declare-styleable的使用(自定义控件) 以及declare-styleable中format详解

    原文网址:http://www.cnblogs.com/622698abc/p/3348692.html declare-styleable是给自定义控件添加自定义属性用的 1.首先,先写attrs. ...

  3. 编程式事务、XML配置事务、注解实现事务

    Spring2.0框架的事务处理有两大类: 1 编码式事务 , 这个不说. 2 声明式事务 , 就说这个. 声明式事务又有三种实现方法: 1 (第一种) 最早的方法,用TransactionProxy ...

  4. SQL删除数据库里所有表的外键,同时删除所有用户表

    SQL删除数据库里所有表的外键,同时删除所有用户表 删除所有的用户表的外键,直接将下面的代码拷贝到数据库里执行即可: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 ...

  5. 【LeetCode 207】Course Schedule

    There are a total of n courses you have to take, labeled from 0 to n - 1. Some courses may have prer ...

  6. Face++接口封装

    本节使用doCurlGetRequest函数来封装Face++的接口请求.我们在class文件夹下的faceStub.php文件中实现 一个faceStub类,封装请求Face++的相关接口. 实现代 ...

  7. hive 安装教程

    1. 下载hadoop-1.2.1-bin.tar.gz 解压,修改名称为hive mv 到 /opt/hive 2.配置hive cp hive-default.xml.template hive- ...

  8. PHP:PHP5.4连接SQLSERVER

    在PHP5.4的环境下要连接SQLSERVER(2005/2008)数据库,需要以下步骤: 1.下载PHP5.4连接SQLSERVER的驱动(两个动态连接库)http://www.microsoft. ...

  9. <Chapter 2>2-1-2.安装Java SDK

    Java运行时环境的App Engine SDK运行在任何运行了Java SE开发工具(JDK)的电脑上.Java SDK App Engine 支持JDK 6,并且当运行App Engine的时候, ...

  10. AIM Tech Round 3

    题目链接:(做出几道说几道^_^) A.Juicer B.Checkpoints C.Letters Cyclic Shift 思路: A题每次加上橘子的体积,超过就清零,计数器加1 B题比较 (lo ...