1.编写内容提供者
步骤:
1.在工程里创建一个类,继承ContentProvider,重写了onCreate和增删改查的方法;
2.在清单文件中配置一个provider,需要这个数据authorities,用来唯一标识内容者的,在android4.1版本之后需要exported="true"的属性,否则其他应用程序没有权限访问这个内容提供者;
3.在onCreate方法里得到数据库的帮助类;
2.内容提供者工作的原理
模版代码:
//uri匹配正时返回的匹配码
int code = mUriMatcher.match(uri);
if(code == INSERT){
System.out.println("你好,你添加多少都可以");
SQLiteDatabase db = helper.getWritableDatabase();
db.insert("account", null, values);
db.close();
}else
{
System.out.println("密码不正确!");
}
3.内容提供者的增删改查的实现
内容提供者:
package com.qaa.accountdb;
import android.content.ContentProvider;
import android.content.ContentValues;
import android.content.UriMatcher;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.net.Uri;
public class AccountContentProvider extends ContentProvider {
private static final int INSERT = 1;
private static final int DELETE = 2;
private static final int UPDATE = 3;
private static final int QUERY = 4;
private AccountDBHelper helper;
//添加一个管理者,用来检查应用程序提供的uri路径是否正确
public static UriMatcher mUriMatcher = new UriMatcher(UriMatcher.NO_MATCH);
//管理者培训,认识指定的口令
static{
mUriMatcher.addURI("com.qaa.accountdb", "insert", INSERT);
mUriMatcher.addURI("com.qaa.accountdb", "delete", DELETE);
mUriMatcher.addURI("com.qaa.accountdb", "update", UPDATE);
mUriMatcher.addURI("com.qaa.accountdb", "query", QUERY); }
@Override
public boolean onCreate() {
helper = new AccountDBHelper(getContext()); return false; }
@Override
public Uri insert(Uri uri, ContentValues values) {
//uri匹配正时返回的匹配码
int code = mUriMatcher.match(uri);
if(code == INSERT){
System.out.println("你好,你添加多少都可以");
SQLiteDatabase db = helper.getWritableDatabase();
db.insert("account", null, values);
db.close();
}else{
System.out.println("密码不正确!");
}
return null;
}
@Override
public Cursor query(Uri uri, String[] projection, String selection,
String[] selectionArgs, String sortOrder) {
//uri匹配正时返回的匹配码
int code = mUriMatcher.match(uri);
if(code == QUERY){
System.out.println("你好,你查询多少都可以");
SQLiteDatabase db = helper.getWritableDatabase();
Cursor cursor = db.query("account", projection, selection, selectionArgs, null, null, null);
return cursor;
}else{
System.out.println("密码不正确!");
return null;
}
}
@Override
public int update(Uri uri, ContentValues values, String selection,
String[] selectionArgs) {
int code = mUriMatcher.match(uri);
if(code == UPDATE){
System.out.println("你好,你修改多少都可以");
SQLiteDatabase db = helper.getWritableDatabase();
int n = db.update("account", values, selection, selectionArgs);
db.close();
return n;
}else{
System.out.println("密码不正确!");
return 0;
}
}
@Override
public int delete(Uri uri, String selection, String[] selectionArgs) {
int code = mUriMatcher.match(uri);
if(code == DELETE){
System.out.println("你好,你删除多少都可以");
SQLiteDatabase db = helper.getWritableDatabase();
int n = db.delete("account", selection, selectionArgs);
db.close();
return n;
}else{
System.out.println("密码不正确!");
return 0;
}
}
@Override
public String getType(Uri uri) {
return null;
}
}
在清单文件中配置内容提供者:
<!-- 在android4.1版本之后需要exported="true"的属性,否则其他应用程序没有权限访问这个内容提供者 -->
<provider android:name="com.qaa.accountdb.AccountContentProvider"
android:authorities="com.qaa.accountdb"
android:exported="true">
</provider>
其他应用程序访问内容提供者:
package com.qaa.bankboss;
import android.app.Activity;
import android.content.ContentResolver;
import android.content.ContentValues;
import android.database.Cursor;
import android.net.Uri;
import android.os.Bundle;
import android.view.View;
public class MainActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
public void insert(View view){
//得到内容提供者的解析器,用来匹配内容提供者
ContentResolver resolver = getContentResolver();
Uri uri = Uri.parse("content://com.qaa.accountdb/insert");
ContentValues values = new ContentValues();
values.put("name", "王");
values.put("money", "10000000");
//调用内容提供者,在数据库中添加一条数据
resolver.insert(uri, values);
}
public void update(View view){
//得到内容提供者的解析器,用来匹配内容提供者
ContentResolver resolver = getContentResolver();
Uri uri = Uri.parse("content://com.qaa.accountdb/update");
ContentValues values = new ContentValues();
values.put("money", "20000000");
//调用内容提供者,在数据库中添加一条数据
resolver.update(uri, values, "name=?", new String[]{"王"});
}
public void query(View view){
//得到内容提供者的解析器,用来匹配内容提供者
ContentResolver resolver = getContentResolver();
Uri uri = Uri.parse("content://com.qaa.accountdb/query");
//调用内容提供者,
Cursor cursor = resolver.query(uri, new String[]{"name","money"}, "name=?", new String[]{"王"}, null);
while(cursor.moveToNext()){
String name = cursor.getString(0);
String money = cursor.getString(1);
System.out.println("name="+name+"; money="+money);
}
cursor.close();
}
public void delete(View view){
//得到内容提供者的解析器,用来匹配内容提供者
ContentResolver resolver = getContentResolver();
Uri uri = Uri.parse("content://com.qaa.accountdb/delete");
resolver.delete(uri, "name=?", new String[]{"行长"});
}
}
4.内容提供者的使用场景
内容提供者:主要是在自己的应用程序中提供访问数据库的接口(内容提供者);
内容提供者的解析器:主要是在别的应用程序中访问其他应用程序的内容提供者;
5.插入短信
address:电话号码
date:时间
type:1表示接收的短信,2发送出去的短信
body:短信内容
代码:
public void insert(View view){
String phone = et_phone.getText().toString().trim();
String content = et_content.getText().toString().trim();
ContentResolver resolver = getContentResolver();
Uri uri = Uri.parse("content://sms/");
ContentValues values = new ContentValues();
values.put("address", phone);
values.put("date", System.currentTimeMillis());
values.put("type", 1);
values.put("body", content);
resolver.insert(uri, values);
}
6.内容提供者uri的写法
uri:content://sms/ 查询手机上所有的短信列表;
7.短信的备份
1.得到内容提供者的解析器,访问短信应用的内容提供者,查询手机上短信的列表:
(1)得到内容提供者的解析器
(2)访问短信应用的内容提供者,查询手机上短信的列表
2.把短信列表序列化到xml格式的文件上:
(1)得到一个xml的序列化器:
(2)初始化:
(3)把短信数据一条一条的序列化到xml格式的文件:
代码:
package cn.itcast.smsbackup;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.Date;
import org.xmlpull.v1.XmlSerializer;
import android.app.Activity;
import android.content.ContentResolver;
import android.database.Cursor;
import android.net.Uri;
import android.os.Bundle;
import android.os.Environment;
import android.util.Xml;
import android.view.View;
import android.widget.Toast;
public class MainActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
// 点击按钮,备份手机系统里面的所有的短信
public void click(View view) {
try {
//得到内容提供者的解析器
ContentResolver resolver = getContentResolver();
Uri uri = Uri.parse("content://sms/");
//得到一个xml的序列化器
XmlSerializer serializer = Xml.newSerializer();
//初始化
File file = new File(Environment.getExternalStorageDirectory(),"backup.xml");
FileOutputStream os = new FileOutputStream(file);
serializer.setOutput(os, "utf-8");
//写备份文件的xml头
serializer.startDocument("utf-8", true);
serializer.startTag(null, "info");
//访问短信应用的内容提供者,查询手机上短信的列表
Cursor cursor = resolver.query(uri, new String[] { "address", "date", "type", "body" }, null, null, null);
while (cursor.moveToNext()) {
serializer.startTag(null, "sms");
String address = cursor.getString(0);
String date = cursor.getString(1);
String type = cursor.getString(2);
String body = cursor.getString(3);
serializer.startTag(null, "address");
serializer.text(address);
serializer.endTag(null, "address");
serializer.startTag(null, "date");
serializer.text(date);
serializer.endTag(null, "date");
serializer.startTag(null, "type");
serializer.text(type);
serializer.endTag(null, "type");
serializer.startTag(null, "body");
serializer.text(body);
serializer.endTag(null, "body");
serializer.endTag(null, "sms");
System.out.println("---------------");
}
cursor.close();
serializer.endTag(null, "info");
serializer.endDocument();
os.close();
Toast.makeText(this, "备份成功", 0).show();
} catch (Exception e) {
e.printStackTrace();
}
}
}
8.短信的还原操作
代码:
package cn.qaa.smsrestore;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import org.xmlpull.v1.XmlPullParser;
import android.app.Activity;
import android.app.AlertDialog;
import android.app.AlertDialog.Builder;
import android.content.ContentResolver;
import android.content.ContentValues;
import android.content.DialogInterface;
import android.content.DialogInterface.OnClickListener;
import android.net.Uri;
import android.os.Bundle;
import android.os.Environment;
import android.util.Xml;
import android.view.View;
import android.widget.Toast;
public class MainActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
public void click(View view) {
final ContentResolver resolver = getContentResolver();
final Uri uri = Uri.parse("content://sms/");
// 还原短信, 把短信的内容插入到数据库.
// 为了避免短信的重复,在还原短信之前,提示用户是否删除旧的短信.
AlertDialog.Builder builder = new Builder(this);
builder.setTitle("提醒");
builder.setMessage("是否删除旧的短信?");
builder.setPositiveButton("删除", new OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
resolver.delete(uri, null, null);
// 还原短信
restoreSms();
} });
builder.setNegativeButton("不删除", new OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
// 还原短信
restoreSms();
}
});
builder.show();
}
/**
* 还原短信
*/
private void restoreSms() {
try {
ContentResolver resolver = getContentResolver();
Uri uri = Uri.parse("content://sms");
// 读取sd卡的备份文件 xml文件.
File file = new File(Environment.getExternalStorageDirectory(),
"backup.xml");
FileInputStream fis = new FileInputStream(file);
// 解析xml文件.
XmlPullParser parser = Xml.newPullParser();
parser.setInput(fis, "utf-8");
int type = parser.getEventType();
SmsInfo smsInfo = null;
while (type != XmlPullParser.END_DOCUMENT) {
switch (type) {
case XmlPullParser.START_TAG:
if("sms".equals(parser.getName())){
smsInfo = new SmsInfo();
}else if("address".equals(parser.getName())){
smsInfo.address = parser.nextText();
}else if("date".equals(parser.getName())){
smsInfo.date = parser.nextText();
}else if("type".equals(parser.getName())){
smsInfo.type = parser.nextText();
}else if("body".equals(parser.getName())){
smsInfo.body = parser.nextText();
}
break;
case XmlPullParser.END_TAG:
if("sms".equals(parser.getName())){//一条短信结束.
ContentValues values = new ContentValues();
values.put("address", smsInfo.address);
values.put("date", smsInfo.date);
values.put("type", smsInfo.type);
values.put("body", smsInfo.body);
resolver.insert(uri, values);
}
break;
}
type = parser.next();
}
Toast.makeText(this, "还原短信成功", 0).show();
fis.close();
} catch (Exception e) {
e.printStackTrace();
}
}
class SmsInfo{
String body;
String address;
String type;
String date;
}
}
9.联系人数据库的表结构
raw_contacts:联系人的表 可以得到联系人的ID:contact_id
data:联系人的数据的表,每一天记录表示联系人的一个信息字段
mimetypes:联系人信息字段的类型
1.查看联系人应用提供的内容提供者,得到一个uri:
content://com.android.contacts/contacts
2.访问联系人应用的内容提供者,得到联系人列表:
代码:
package com.qaa.readcontacts;
import android.app.Activity;
import android.content.ContentResolver;
import android.database.Cursor;
import android.net.Uri;
import android.os.Bundle;
import android.view.View;
public class MainActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
public void readContacts(View v) {
ContentResolver resolver = getContentResolver();
Uri uri = Uri.parse("content://com.android.contacts/raw_contacts");
// 1、通过内容提供者去读raw_contacts中的数据
Cursor cursor = resolver.query(uri, new String[] { "contact_id" }, null, null, null);
while (cursor.moveToNext()) {
long contact_id = cursor.getLong(0);
System.out.println("contact_id==" + contact_id);
// 2、通过内容提供者去读data中的数据
Uri dataUri = Uri.parse("content://com.android.contacts/data/#"+contact_id);
Cursor dataCursor = resolver.query(dataUri, new String[] { "raw_contact_id", "mimetype", "data1" }, null, null, null);
while(dataCursor.moveToNext()){
long raw_contact_id = dataCursor.getLong(0);
String mimetype = dataCursor.getString(1);
String data = dataCursor.getString(2);
System.out.println("raw_contact_id=="+raw_contact_id);
System.out.println("mimetype=="+mimetype);
System.out.println("data=="+data);
}
dataCursor.close();
System.out.println("----------------------------------");
}
cursor.close();
}
}
10.联系人的还原
向raw_contacts、data
11.内容观察者&短信listener
内容观察者可以看到内容提供者中数据变化;
12.内容观察者
package com.qaa.contentobserver;
import java.util.Date;
import android.app.Activity;
import android.content.ContentResolver;
import android.database.ContentObserver;
import android.database.Cursor;
import android.net.Uri;
import android.os.Bundle;
import android.os.Handler;
public class MainActivity extends Activity {
private ContentResolver resolver;
private Uri uri;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
resolver = getContentResolver();
uri = Uri.parse("content://sms/");
resolver.registerContentObserver(uri, true, new MyContentObserver(
new Handler())); }
private class MyContentObserver extends ContentObserver {
public MyContentObserver(Handler handler) {
super(handler);
}
/**
* 内容提供者中数据发生变后调用这个方法
*/
@Override
public void onChange(boolean selfChange) {
Cursor cursor = resolver.query(uri, new String[] { "address",
"date", "type", "body" }, null, null, "date desc");
cursor.moveToNext();
String phone = cursor.getString(0);
long date = cursor.getLong(1);
String type = cursor.getString(2);
String body = cursor.getString(3);
System.out.println("phone==="+phone);
System.out.println("date==="+new Date(date).toLocaleString());
System.out.println("type==="+type);
System.out.println("body==="+body);
cursor.close();
super.onChange(selfChange);
}
}
}