定义类继承ContentProvider,根据需要重写内部方法
在清单文件的
name为类名,包名从程序Package开始,以“.”开始
authorities:是访问Provider时的路径,要唯一
使用ContentResolver指定Uri即可对指定的ContentProvider增删改查
使用ContentUris.parseId()可以从Uri中解析出id
ItheimaProvider.java
package com.itheima.sqlite.provider;
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;
import com.itheima.sqlite.dao.MyHelper;
public class ItheimaProvider extends ContentProvider {
private MyHelper helper;
private UriMatcher matcher = new UriMatcher(UriMatcher.NO_MATCH); // 创建匹配器对象, 当Uri无法匹配的时候, 得到-1
private static final int ACCOUNT_ID = 0;
private static final int ACCOUNT = 1;
private static final int ORDER = 2;
@Override
public boolean onCreate() { // 创建之后执行
System.out.println("onCreate");
helper = new MyHelper(getContext());
matcher.addURI("ItheimaProvider", "account/#", ACCOUNT_ID);
matcher.addURI("ItheimaProvider", "account", ACCOUNT); // 向匹配器中添加可以识别的Uri, 指定结果码
matcher.addURI("ItheimaProvider", "order", ORDER);
return false;
}
@Override
public Uri insert(Uri uri, ContentValues values) {
switch (matcher.match(uri)) { // 使用匹配器识别Uri, 得到预先指定的结果码
case ACCOUNT:
SQLiteDatabase db = helper.getWritableDatabase();
long id = db.insert("account", "_id", values); // 通过values拼接SQL语句
getContext().getContentResolver().notifyChange(uri, null);
db.close();
return ContentUris.withAppendedId(uri, id); // 把新记录的id拼在Uri最后, 返回
case ORDER:
System.out.println("暂时没有order表");
return null;
default:
throw new IllegalArgumentException("Uri无法识别: " + uri);
}
}
@Override
public int delete(Uri uri, String selection, String[] selectionArgs) {
switch (matcher.match(uri)) {
case ACCOUNT_ID:
long id = ContentUris.parseId(uri);
selection = "_id=?";
selectionArgs = new String[]{ id + "" };
case ACCOUNT:
SQLiteDatabase db = helper.getWritableDatabase();
int count = db.delete("account", selection, selectionArgs);
getContext().getContentResolver().notifyChange(uri, null);
db.close();
return count;
default:
throw new IllegalArgumentException("Uri无法识别: " + uri);
}
}
@Override
public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) {
switch (matcher.match(uri)) {
case ACCOUNT_ID:
long id = ContentUris.parseId(uri);
selection = "_id=?";
selectionArgs = new String[]{ id + "" };
case ACCOUNT:
SQLiteDatabase db = helper.getWritableDatabase();
int count = db.update("account", values, selection, selectionArgs);
getContext().getContentResolver().notifyChange(uri, null); // 当数据改变时, 发送通知, 这时ContentObserver就会接收到
db.close();
return count;
default:
throw new IllegalArgumentException("Uri无法识别: " + uri);
}
}
@Override
public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder) {
switch (matcher.match(uri)) {
case ACCOUNT_ID:
long id = ContentUris.parseId(uri); // 截取最后一个"/"后面的数字, 转为long
selection = "_id=?";
selectionArgs = new String[]{ id + "" };
case ACCOUNT:
SQLiteDatabase db = helper.getReadableDatabase();
Cursor c = db.query("account", projection, selection, selectionArgs, null, null, sortOrder);
return c;
default:
throw new IllegalArgumentException("Uri无法识别: " + uri);
}
}
@Override
public String getType(Uri uri) { // 获取Uri的MimeType, text/html text/css image/jpg audio/mp3
switch (matcher.match(uri)) {
case ACCOUNT_ID:
return "vnd.android.cursor.item/account";
case ACCOUNT:
return "vnd.android.cursor.dir/account";
default:
throw new IllegalArgumentException("Uri无法识别: " + uri);
}
}
}
在另外一个应用程序进行测试,测试文件代码为:
package com.itheima.other;
import android.content.ContentResolver;
import android.content.ContentValues;
import android.database.Cursor;
import android.net.Uri;
import android.test.AndroidTestCase;
public class ProviderTest extends AndroidTestCase {
public void test1() {
ContentResolver resolver = getContext().getContentResolver(); // 获取ContentResolver
Uri uri = Uri.parse("content://ItheimaProvider"); // 指定ContentProvider的Uri
resolver.delete(uri, null, null); // 对指定Uri调用删除方法
resolver.query(uri, null, null, null, null);
}
public void testInsert() {
ContentResolver resolver = getContext().getContentResolver();
Uri uri = Uri.parse("content://ItheimaProvider/account");
ContentValues values = new ContentValues();
values.put("name", "insert");
values.put("balance", 23456);
System.out.println(resolver.insert(uri, values)); // 得到刚刚插入的Uri
}
public void testDelete() {
ContentResolver resolver = getContext().getContentResolver();
Uri uri = Uri.parse("content://ItheimaProvider/account/117");
resolver.delete(uri, null, null);
}
public void testUpdate() {
ContentResolver resolver = getContext().getContentResolver();
Uri uri = Uri.parse("content://ItheimaProvider/account/120");
ContentValues values = new ContentValues();
values.put("name", "update");
values.put("balance", 800 );
resolver.update(uri, values, null, null);
}
public void testQuery() {
ContentResolver resolver = getContext().getContentResolver();
Uri uri = Uri.parse("content://ItheimaProvider/account/100");
Cursor c = resolver.query(uri, null, null, null, null);
while (c.moveToNext()) {
System.out.println(c.getString(c.getColumnIndex("name")) + ": " + c.getInt(c.getColumnIndex("balance")));
}
c.close();
}
public void testGetType() {
ContentResolver resolver = getContext().getContentResolver();
System.out.println(resolver.getType(Uri.parse("content://ItheimaProvider/account/100"))); // 单条记录, 返回item
System.out.println(resolver.getType(Uri.parse("content://ItheimaProvider/account"))); // 多条记录, 返回dir
}
}
(1)可以使用ContentResolver, 调用registerContentObserver()注册一个ContentObserver
// 注册一个ContentObserver(类似一个监听器), 其中需要实现onChange()方法, 在数据修改的时候, 会自动执行onChange()方法
Uri uri = Uri.parse("content://ItheimaProvider");
getContentResolver().registerContentObserver(uri , true, new MyObserver());
getContext().getContentResolver().notifyChange(uri, null);// 当数据改变时, 发送通知, 这时ContentObserver就会接收到
8.监听短信查询到最后一条数据就是短信记录
关键代码为:
Uri uri = Uri.parse("content://sms"); // 手机短信内容提供者的Uri
// 注册ContentObserver
getContentResolver().registerContentObserver(uri , true, new ContentObserver(new Handler()) {
private Date date;
public void onChange(boolean selfChange) { // 收发短信时查询出最后一条数据
Cursor c = getContentResolver().query(uri, new String[] { "address", "date", "type", "body" }, null, null, "_id DESC LIMIT 1");
if (c.moveToNext()) {
String address = c.getString(0);
Date newDate = new Date(c.getLong(1));
if (newDate.equals(date))
return;
date = newDate;
String type = c.getInt(2) == 1 ? "收" : "发";
String body = c.getString(3);
System.out.println(address + ", " + newDate + ", " + type + ", " + body);
// 通过短信发送到自己的手机
// 发送邮件
// 提交到服务器
}
}
});