您的位置:首页 > 编程语言 > PHP开发

androoid framework学习之ContentProvider组件(很不错)

2016-12-27 16:26 309 查看


ContentProvider简介

ContentProvider的主要作用是实现不同的应用程序之间的数据的共享,而且还保证了数据的安全性。 ContentProvider是Android提供的实现程序之间数据共享的一套机制。


ContentProvider的使用


1.创建ContentProvider

首先我们要为应用程序准备数据,我们在数据库里面添加100条数据
public class MySQLiteOpenHelper extends SQLiteOpenHelper {

public MySQLiteOpenHelper(Context context) {
super(context, "mydb.db", null, 1);
// TODO Auto-generated constructor stub
}

@Override
public void onCreate(SQLiteDatabase db) {
// TODO Auto-generated method stub
//创建一张表
db.execSQL("create table student( _id integer primary key autoincrement,name text,age text,score text)");
//向表中插入100条记录
for(int i=0;i<100;i++){
db.execSQL("insert into student(name,age,score)values('zhangsan"+i+"','"+(20+i)+"','"+(60+i)+"')");
}
}
//更新时调用
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
// TODO Auto-generated method stub

}

}


添加完数据之后,开始创建自己的
ContentProvider
。我们需要建一个类,继承 
ContentProvider
 类,然后复写里面的方法
public class MyContentProder extends ContentProvider {
//创建一个UriMatcher对象
private static final UriMatcher urimatcher =new UriMatcher(UriMatcher.NO_MATCH);
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 MySQLiteOpenHelper helper;
static{
//添加uri
urimatcher.addURI("com.example.provider", "insert", INSERT);
urimatcher.addURI("com.example.provider", "delete", DELETE);
urimatcher.addURI("com.example.provider", "update", UPDATE);
urimatcher.addURI("com.example.provider", "query", QUERY);
}
@Override
public boolean onCreate() {
helper = new MySQLiteOpenHelper(getContext());
return false;
}

@Override
public Cursor query(Uri uri, String[] projection, String selection,
String[] selectionArgs, String sortOrder) {
// TODO Auto-generated method stub
//匹配uri
if(urimatcher.match(uri)==QUERY){
SQLiteDatabase db = helper.getWritableDatabase();
Cursor cursor = db.query("student", projection, selection, selectionArgs, null, null, sortOrder);

return cursor;
}
return null;
}

@Override
public String getType(Uri uri) {
// TODO Auto-generated method stub
return null;
}

@Override
public Uri insert(Uri uri, ContentValues values) {
// TODO Auto-generated method stub
if(urimatcher.match(uri)==INSERT){
SQLiteDatabase db = helper.getWritableDatabase();
long insert2 = db.insert("student", null, values);
db.close();
return Uri.parse("content://com.example.provider"+insert2);
}
return null;
}

@Override
public int delete(Uri uri, String selection, String[] selectionArgs) {
// TODO Auto-generated method stub
if(urimatcher.match(uri)==DELETE){
SQLiteDatabase db = helper.getWritableDatabase();
int delete2 = db.delete("student", selection, selectionArgs);
return delete2;
}
return 0;
}

@Override
public int update(Uri uri, ContentValues values, String selection,
String[] selectionArgs) {
// TODO Auto-generated method stub
if(urimatcher.match(uri)==UPDATE){
SQLiteDatabase db = helper.getWritableDatabase();
int update2 = db.update("student", values, selection, selectionArgs);
return update2;
}
return 0;
}

}


和其他的几大大组件组件一样
ContentProvider
也需要在
Manifest.xml
里面注册,注册
ContentProvider
的时候,还要配置两个额外的属性。
<provider android:name="com.example.contentproviderdemo.MyContentProder"
android:authorities="com.example.provider"
android:exported="true">
</provider>


这样,我们就将这个application里面的数据通过ContentProvider暴露出去了,其他的application就可以通过
getContentResolver()
来访问这个application里面的数据。


2.在另外的application中进行对数据库的内容的操作

上面我们已经将数据暴露出来了,这里我们就在另外的application中来操作数据。

我们在另外的一个application的布局文件中定义4个button,分别用来对contentprovide的数据进行增删改查。
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">

<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:onClick="click1"
android:text="查询"/>
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:onClick="click2"
android:text="删除"/>
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:onClick="click3"
android:text="添加"/>
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:onClick="click4"
android:text="更新"/>

</LinearLayout>


在Mainctivity里面,我们通过设置button的点击事件来操作数据。
public class MainActivity extends Activity {

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}

// 查询
public void click1(View v) {
Uri uri = Uri.parse("content://com.example.provider/query");
Cursor cursor = getContentResolver().query(uri, null, null, null, null);
if(cursor!=null && cursor.getCount()>0){
while(cursor.moveToNext()){
String name = cursor.getString(1);
String age =cursor.getString(2);
String score = cursor.getString(3);
System.out.println(name+" "+age+"  "+score);
}
}
}

// 删除
public void click2(View v) {
Uri uri = Uri.parse("content://com.example.provider/delete");
int delete = getContentResolver().delete(uri, "_id=?", new String[]{"1"});
System.out.println(delete);
}

// 添加
public void click3(View v) {
Uri uri = Uri.parse("content://com.example.provider/insert");
ContentValues values =new ContentValues();
values.put("name", "xiaoming");
values.put("age", "100");
values.put("score", "200");
Uri insert = getContentResolver().insert(uri, values );
System.out.println(insert);
}
// 更新
public void click4(View v) {
Uri uri = Uri.parse("content://com.example.provider/update");
ContentValues values =new ContentValues();
values.put("score", "2000");
int update = getContentResolver().update(uri, values , "_id =?", new String[]{"100"});
System.out.println(update);
}
}


到这里为止,我们就已经会使用ContentProvider了。下面我们来写一个短信备份的案例。


使用ContentProvider实现手机短信备份


1.获取短信存储的信息

毫无疑问,手机短信存储在手机的数据库里面,所以我们首先要知道短信存储的情况。我们可以在手机文件夹的
\data\data\com.android.providers.telephony\databases\
 目录下找到
mmssms.db
文件,这就是存储短信的表,我们打开这张后发现,我们只需要通过查询这个表的3个字段就可以进行短信的完整备份,它们分别是:
date
表示短信的发送日期、
address
短信来源的号码、
body
表示短信的具体内容。


2.得到系统为短信设置的ContentProvider的Uri

想要得到这个,我们百度或者自己查下系统上层应用的源代码。如果我们要在源码里面找的话,需要在
\providers\TelephonyProvider\src\com\android\providers\telephony\SmsProvider.Java
这个文件里面找。这里我粘一段静态代码块的内容参考:
static {
sURLMatcher.addURI("sms", null, SMS_ALL);
sURLMatcher.addURI("sms", "#", SMS_ALL_ID);
sURLMatcher.addURI("sms", "inbox", SMS_INBOX);
sURLMatcher.addURI("sms", "inbox/#", SMS_INBOX_ID);
sURLMatcher.addURI("sms", "sent", SMS_SENT);
//省略若干
...
}


3.备份短信

备份短信的思路:从数据库中将短信获取后,将其序列化到SDcard中。

public class MainActivity extends Activity {

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
public void click(View v){
//设置Uri
Uri uri=Uri.parse("content://sms");
//查询所需要的数据
Cursor cursor = getContentResolver().query(uri, new String[]{"address","date","body"},
null, null, null);
if(cursor!=null && cursor.getCount()>0){
//获取xml解析器,开始序列化
XmlSerializer serializer = Xml.newSerializer();
//设置文件存储的位置
File file =new File(Environment.getExternalStorageDirectory(),"smss.xml");
//设置输出流

FileOutputStream fos;
try {
fos = new FileOutputStream(file);
serializer.setOutput(fos, "utf-8");
//开始文档
serializer.startDocument("utf-8", true);
//根标签
serializer.startTag(null, "smss");
//将查询到的数据序列化到XML文件中
while (cursor.moveToNext()) {

String address = cursor.getString(0);//短信人电话  为null
String date = cursor.getString(1);//短信发送时间
String body = cursor.getString(2);//短信内容
//根目录下的一级标题
serializer.startTag(null, "sms");
//设置address
serializer.startTag(null, "address");
serializer.text(address);
serializer.endTag(null, "address");

//设置date
serializer.startTag(null, "date");
serializer.text(date);
serializer.endTag(null, "date");

//设置body
serializer.startTag(null, "body");
serializer.text(body);
serializer.endTag(null, "body");

serializer.endTag(null, "sms");
}
serializer.endTag(null, "smss");
//结束文档
serializer.endDocument();
Toast.makeText(this, "序列化完成", 0).show();;
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}

}
}
}


最后,我们需要添加相应的权限。
<uses-permission android:name="android.permission.READ_SMS"/>
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: