一.前些日期研究了下Android下ContentProvider的使用,先将具体的使用方法记下来,方便以后的实际使用扩展。
1.新建工程TestContentProvider此工程是独立的ContentProvider类类似如系统内置的ContactProvider,新建包名com.test.content。
2.文件DataBaseOpen.java,代码如下,主要用于建立数据库,表,及进行数据库的操作等。
package com.test.content;
import android.content.Context;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteDatabase.CursorFactory;
import android.database.sqlite.SQLiteOpenHelper;
public class DataBaseOpen extends SQLiteOpenHelper {
private final static String DB_NAME = "test.db";
public static final int DB_VERSION = 1;
public DataBaseOpen(Context context, String name, CursorFactory factory,
int version) {
super(context, name, factory, version);
// TODO Auto-generated constructor stub
}
public DataBaseOpen(Context context) {
super(context, DB_NAME, null, DB_VERSION);
// TODO Auto-generated constructor stub
}
@Override
public void onCreate(SQLiteDatabase arg0) {
// TODO Auto-generated method stub
String sql = "CREATE TABLE IF NOT EXISTS student (id integer PRIMARY KEY autoincrement,stuId text NOT NULL unique,name text NOT NULL)";
arg0.execSQL(sql);
sql = "CREATE TABLE IF NOT EXISTS score (id integer PRIMARY KEY autoincrement,stuId text NOT NULL unique,name text NOT NULL)";
arg0.execSQL(sql);
}
@Override
public void onUpgrade(SQLiteDatabase arg0, int arg1, int arg2) {
// TODO Auto-generated method stub
onCreate(arg0);
}
}
2.TestProvider.java继承ContentProvider定义外部访问的规则,具体如下
package com.test.content;
import org.apache.http.client.utils.URIUtils;
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 TestProvider extends ContentProvider {
//数据集的MIME类型字符串则应该以vnd.android.cursor.dir/开头
public static final String STUDENTS_TYPE = "vnd.android.cursor.dir/student";
//单一数据的MIME类型字符串应该以vnd.android.cursor.item/开头
public static final String STUDENTS_ITEM_TYPE = "vnd.android.cursor.item/student";
public static final String SCORES_TYPE = "vnd.android.cursor.dir/score";
//单一数据的MIME类型字符串应该以vnd.android.cursor.item/开头
public static final String SCORES_ITEM_TYPE = "vnd.android.cursor.item/score";
public static final String AUTHORITY = "com.android.provider.studentprovider";
/*自定义匹配码*/
public static final int STUDENTS = 1;
/*自定义匹配码*/
public static final int STUDENT = 2;
public static final int SCORES = 3;
/*自定义匹配码*/
public static final int SCORE = 4;
public static final Uri STUDENTS_URI = Uri.parse("content://" + AUTHORITY + "/student");
public static final Uri SCORES_URI = Uri.parse("content://" + AUTHORITY + "/score");
/*这里UriMatcher是用来匹配Uri的类,使用match()方法匹配路径时返回匹配码*/
private static final UriMatcher sMatcher;
protected SQLiteDatabase mDb;
static {
sMatcher = new UriMatcher(UriMatcher.NO_MATCH);//常量UriMatcher.NO_MATCH表示不匹配任何路径的返回码
//如果match()方法匹配content://cn.android.provider.personprovider/person路径,返回匹配码为PERSONS
sMatcher.addURI(AUTHORITY, "student", STUDENTS);
//如果match()方法匹配content://cn.android.provider.personprovider/person/230路径,返回匹配码为PERSON
sMatcher.addURI(AUTHORITY, "student/#", STUDENT);
sMatcher.addURI(AUTHORITY, "score", SCORES);
sMatcher.addURI(AUTHORITY, "score/#", SCORE);
}
private DataBaseOpen databaseHelper;
@Override
public int delete(Uri arg0, String arg1, String[] arg2) {
// TODO Auto-generated method stub
return 0;
}
@Override
public String getType(Uri uri) {
// TODO Auto-generated method stub
switch (sMatcher.match(uri))
{
case STUDENTS:
return STUDENTS_TYPE;
case STUDENT:
return STUDENTS_ITEM_TYPE;
case SCORES:
return SCORES_TYPE;
case SCORE:
return SCORES_ITEM_TYPE;
default:
return null;
}
}
@Override
public Uri insert(Uri uri, ContentValues values) {
// TODO Auto-generated method stub
switch (sMatcher.match(uri))
{
case STUDENTS:
mDb = databaseHelper.getWritableDatabase();
long rowId = 0;
try
{
rowId = mDb.insertOrThrow("student", "stuId", values);
}
catch(Exception e)
{
e.printStackTrace();
}
return ContentUris.withAppendedId(STUDENTS_URI, rowId);
case STUDENT:
return null;
case SCORES:
mDb = databaseHelper.getWritableDatabase();
long Id = 0;
try
{
Id = mDb.insertOrThrow("score", "stuId", values);
}
catch(Exception e)
{
e.printStackTrace();
}
return ContentUris.withAppendedId(SCORES_URI, Id);
case SCORE:
return null;
default:
return null;
}
}
@Override
public boolean onCreate() {
// TODO Auto-generated method stub
databaseHelper = new DataBaseOpen(this.getContext());
return false;
}
@Override
public Cursor query(Uri uri, String[] projection, String selection,
String[] selectionArgs, String sortOrder) {
// TODO Auto-generated method stub
return null;
}
@Override
public int update(Uri uri, ContentValues values, String selection,
String[] selectionArgs) {
// TODO Auto-generated method stub
return 0;
}
}
3.AndroidManifest.xml 配置自定义的ContentProvider如下
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.test.content"
android:versionCode="1"
android:versionName="1.0" >
<uses-sdk android:minSdkVersion="8" />
<application
android:icon="@drawable/ic_launcher"
android:label="@string/app_name" >
<provider android:name=".TestProvider" android:authorities="com.android.provider.studentprovider"/>
</application>
</manifest>
二.编写测试范文自定义的ContentProvider
1.新建工程TestProviderClient。包名com.test.client
其中一个测试入口的Activiy TestProviderClientActivity.java代码如下
package com.test.client;
import android.app.Activity;
import android.content.ContentResolver;
import android.content.ContentValues;
import android.content.Context;
import android.net.Uri;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
public class TestProviderClientActivity extends Activity {
/** Called when the activity is first created. */
private Button mStu;
private Button mSco;
private EditText mMsg;
private EditText mNum;
TextView mRet;
private Context mConText;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
mMsg = (EditText)this.findViewById(R.id.msgId);
mNum = (EditText)this.findViewById(R.id.num);
mStu = (Button)this.findViewById(R.id.btnStu);
mSco = (Button)this.findViewById(R.id.btnSco);
mRet = (TextView)this.findViewById(R.id.ret);
mConText = this.getBaseContext();
View.OnClickListener l = new View.OnClickListener() {
@Override
public void onClick(View v) {
// TODO Auto-generated method stub
int id = v.getId();
String msg = mMsg.getText().toString();
String num = mNum.getText().toString();
if(null == msg || null == num)return;
ContentValues value = new ContentValues();
ContentResolver cr = mConText.getContentResolver();
value.clear();
value.put("stuId", msg);
value.put("name", num);
Uri uri = null;
try {
if(id == R.id.btnStu)
{
uri = cr.insert(Uri.parse("content://com.android.provider.studentprovider/student"), value);
}
else if(id == R.id.btnSco)
{
uri = cr.insert(Uri.parse("content://com.android.provider.studentprovider/score"), value);
}
mRet.setText(uri.toString());
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
};
mStu.setOnClickListener(l);
mSco.setOnClickListener(l);
}
}
2.布局文件如下main.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical" >
<EditText android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:id="@+id/msgId"
android:singleLine="true"/>
<EditText android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:id="@+id/num"
android:inputType="number"
android:singleLine="true"/>
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="horizontal" >
<Button android:layout_width="wrap_content" android:layout_height="wrap_content"
android:id = "@+id/btnStu"
android:text="插入到学生表"
android:layout_weight="1"/>
<Button android:layout_width="wrap_content" android:layout_height="wrap_content"
android:id = "@+id/btnSco"
android:text="插入到成绩表"
android:layout_weight="1"/>
</LinearLayout>
<TextView android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:id="@+id/ret"/>
</LinearLayout>
3.工程的AndroidManifest.xml文件如下
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.test.client"
android:versionCode="1"
android:versionName="1.0" >
<uses-sdk android:minSdkVersion="8" />
<application
android:icon="@drawable/ic_launcher"
android:label="@string/app_name" >
<activity
android:name=".TestProviderClientActivity"
android:label="@string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
三1.总结一下,本实例不够完整,只是测试了下调用ContenProvider的插入数据的操作,且系统没有该自定义ContentProvider会报错(可以检查系统是否已经有了自定义的ContentProvider的安装包如存在则进行后续的操作,无可以提示安装)。
2.ContenProvider可以随运用一起发布,方便其他运用访问数据,对数据库的操作可以采用事务处理。