android中的数据持久化技术(数据存储技术)存在一定的制约,包括文件存储、SharedPreferences存储以及数据库(SQLite)存储,该三类存储方式只能在当前应用程序中访问。如果要实现跨程序数据共享的功能,需要使用android四大组件之一的内容提供器contentprovider。以下是通过内容提供器来实现一个应用访问另外一个应用的SQLite数据库的功能(主要实现添加数据和查询数据的功能),代码如下:
一. 创建内容提供器MycontentProvider——给程序的数据提供外部访问接口
包名:com.example.mycontentprovider
1.继承SQLiteOpenHelper,重写oncreat()和onUpgrade()对数据库进行创建和升级
package com.example.mycontentprovider;
import android.content.Context;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteDatabase.CursorFactory;
import android.database.sqlite.SQLiteOpenHelper;
public class MyDatabaseHelper extends SQLiteOpenHelper {
public static final String CREATE_BOOK = "create table book("
+"id integer primary key autoincrement, "
+"name text, "
+"price real) "; //创建一个表,id为主键,自动生成,name文本类,price 实数类
public MyDatabaseHelper(Context context, String name,
CursorFactory factory, int version) {
super(context, name, factory, version);
// TODO Auto-generated constructor stub
}
@Override
public void onCreate(SQLiteDatabase db) {
// TODO Auto-generated method stub
db.execSQL(CREATE_BOOK); //执行SQL语句,创建book表
}
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
// TODO Auto-generated method stub
}
2. 自定义一个继承与ContentProvider的MyDatabaseProvider类,重现insert(),query()等方法,提供数据添加和查询等接口
package com.example.mycontentprovider;
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 MyDatabaseProvider extends ContentProvider {
//定义BOOK_DIR和BOOK_ITEM两个自定义代码,前者表示访问表中所有数据,后者表示访问表中某条数据
public static final int BOOK_DIR = 0;
public static final int BOOK_ITEM = 1;
//定义权限 AUTHORITY
public static final String AUTHORITY = "com.example.mycontentprovider.provider";
//定义对uri进行匹配的类UriMatcher
private static UriMatcher uriMatcher;
private MyDatabaseHelper dbHelper;
//通过addURI方法添加权限和路径,以及自定义代码,当调用urimatcher的match()方法时,传入一个uri对象后返回此处定义的自定义代码,据此来判断是访问哪个表还是哪条数据
static {
uriMatcher = new UriMatcher(UriMatcher.NO_MATCH);
uriMatcher.addURI(AUTHORITY, "book", BOOK_DIR);
uriMatcher.addURI(AUTHORITY, "book/#", BOOK_ITEM);
}
@Override
public int delete(Uri arg0, String arg1, String[] arg2) {
// TODO Auto-generated method stub
return 0;
}
@Override
public String getType(Uri arg0) {
// TODO Auto-generated method stub
return null;
}
@Override
public Uri insert(Uri arg0, ContentValues arg1) {
// TODO Auto-generated method stub
//获取对数据库的可操作对象db
SQLiteDatabase db = dbHelper.getWritableDatabase();
Uri uriReturn = null;
switch (uriMatcher.match(arg0)) {
case BOOK_DIR:
case BOOK_ITEM:
long newBookId = db.insert("book", null, arg1);//插入arg1数据到book表中
uriReturn = Uri.parse("content://"+AUTHORITY+"/book/"+newBookId);
break;
default:
break;
}
return uriReturn;
}
//创建MyDatabaseHelper类对象,定义数据库名“BookStore.db”
@Override
public boolean onCreate() {
// TODO Auto-generated method stub
dbHelper = new MyDatabaseHelper(getContext(), "BookStore.db", null, 1);
return true;
}
@Override
public Cursor query(Uri arg0, String[] arg1, String arg2, String[] arg3,
String arg4) {
// TODO Auto-generated method stub
SQLiteDatabase db = dbHelper.getReadableDatabase();
Cursor cursor = null;
switch (uriMatcher.match(arg0)) {
case BOOK_DIR:
cursor = db.query("book", null, null, null, null, null, null);
break;
case BOOK_ITEM:
String bookId = arg0.getPathSegments().get(1);
cursor = db.query("book", null, "id = ?", new String[]{bookId}, null, null, null);
break;
default:
break;
}
return cursor;
}
@Override
public int update(Uri arg0, ContentValues arg1, String arg2, String[] arg3) {
// TODO Auto-generated method stub
return 0;
}
}
3.在androidmanifest里注册之前定义的MyDatabaseProvider,四大组件都必须在manifest里进行注册才能生效
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.mycontentprovider"
android:versionCode="1"
android:versionName="1.0" >
<uses-sdk
android:minSdkVersion="8"
android:targetSdkVersion="21" />
<application
android:allowBackup="true"
android:icon="@drawable/ic_launcher"
android:label="@string/app_name"
android:theme="@style/AppTheme" >
<provider
android:name="com.example.mycontentprovider.MyDatabaseProvider"
android:authorities="com.example.mycontentprovider.provider"
android:exported="true" >
</provider>
</application>
</manifest>
二. 创建MycontentResolver应用,对以上应用的数据进行添加和查询操作:
package com.example.mycontentresolver;
import android.app.Activity;
import android.content.ContentValues;
import android.database.Cursor;
import android.net.Uri;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
public class MainActivity extends Activity {
Button add_Button;
Button query_Button;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
add_Button = (Button)findViewById(R.id.addDataButton);
query_Button = (Button)findViewById(R.id.queryDataButton);
add_Button.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View arg0) {
// TODO Auto-generated method stub
Uri uri = Uri.parse("content://com.example.mycontentprovider.provider/book");
ContentValues values = new ContentValues();
values.put("name", "张三");
values.put("price", 18.9);
Uri myUri = getContentResolver().insert(uri, values);
Log.d("myUri",""+ myUri);//打印log日志,判断是否成功插入,若成功插入,会得到插入的地址myUri
}
});
query_Button.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
// TODO Auto-generated method stub
Uri uri = Uri.parse("content://com.example.mycontentprovider.provider/book");
Cursor cursor = getContentResolver().query(uri, null, null, null, null);
if(cursor != null){
while (cursor.moveToNext()) {
String name = cursor.getString(cursor.getColumnIndex("name"));
Double price = cursor.getDouble(cursor.getColumnIndex("price"));
Log.d("name", name);
Log.d("price", ""+price); //打印log日志,判断是否成功查询获取到表中的name和price
}
cursor.close();
}
}
});
}
}
下面就来运行下代码:
先运行MycontentProvider,再运行MycontentResolver
在MycontentResolver界面中点击Add_Data
查看log,得到添加的数据的uri,之前已经添加过10条了,显示了第11条,说明已经添加成功:
点击Query_Data
查看log,查询得到表中所有数据,共11条,显示查询成功: