Content Provider初步
创建项目:TestCP
项目截图:
==>CPActivity.java
package mars.cp;
import mars.cp.FirstProviderMetaData.UserTableMetaData;
import android.app.Activity;
import android.content.ContentValues;
import android.database.Cursor;
import android.net.Uri;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
public class CPActivity extends Activity {
/** Called when the activity is first created. */
private Button insertButton = null;
private Button queryButton = null;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
queryButton = (Button) findViewById(R.id.query);
queryButton.setOnClickListener(new QueryListener());
insertButton = (Button) findViewById(R.id.insert);
insertButton.setOnClickListener(new InsertListener());
System.out.println(getContentResolver().getType(FirstProviderMetaData.UserTableMetaData.CONTENT_URI));
}
class InsertListener implements OnClickListener {
@Override
public void onClick(View v) {
// TODO Auto-generated method stub
ContentValues values = new ContentValues();
values.put(FirstProviderMetaData.UserTableMetaData.USER_NAME,
"zhangsan");
Uri uri = getContentResolver()
.insert(
FirstProviderMetaData.UserTableMetaData.CONTENT_URI,
values);
System.out.println("uri--->" + uri.toString());
}
}
class QueryListener implements OnClickListener {
@Override
public void onClick(View v) {
// TODO Auto-generated method stub
Cursor c = getContentResolver().query(
FirstProviderMetaData.UserTableMetaData.CONTENT_URI, null,
null, null, null);
while(c.moveToNext()){
System.out.println(c.getString(c.getColumnIndex(UserTableMetaData.USER_NAME)));
}
}
}
}
==>FirstContentProvider.java
package mars.cp;
import java.util.HashMap;
import mars.cp.FirstProviderMetaData.UserTableMetaData;
import mars.sqlite3.db.DatabaseHelper;
import android.content.ContentProvider;
import android.content.ContentUris;
import android.content.ContentValues;
import android.content.UriMatcher;
import android.database.Cursor;
import android.database.SQLException;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteQueryBuilder;
import android.net.Uri;
import android.text.TextUtils;
public class FirstContentProvider extends ContentProvider {
public static final UriMatcher uriMatcher;
public static final int INCOMING_USER_COLLECTION = 1;
public static final int INCOMING_USER_SINGLE = 2;
private DatabaseHelper dh;
static {
uriMatcher = new UriMatcher(UriMatcher.NO_MATCH);
uriMatcher.addURI(FirstProviderMetaData.AUTHORIY, "/users",
INCOMING_USER_COLLECTION);
uriMatcher.addURI(FirstProviderMetaData.AUTHORIY, "/users/#",
INCOMING_USER_SINGLE);
}
public static HashMap<String,String> userProjectionMap;
static
{
userProjectionMap = new HashMap<String,String>();
userProjectionMap.put(UserTableMetaData._ID,UserTableMetaData._ID);
userProjectionMap.put(UserTableMetaData.USER_NAME, UserTableMetaData.USER_NAME);
}
@Override
public int delete(Uri arg0, String arg1, String[] arg2) {
// TODO Auto-generated method stub
System.out.println("delete");
return 0;
}
//根据传入的URI,返回该URI所表示的数据类型
@Override
public String getType(Uri uri) {
// TODO Auto-generated method stub
System.out.println("getType");
switch(uriMatcher.match(uri)){
case INCOMING_USER_COLLECTION:
return UserTableMetaData.CONTENT_TYPE;
case INCOMING_USER_SINGLE:
return UserTableMetaData.CONTENT_TYPE_ITEM;
default:
throw new IllegalArgumentException("Unknown URI" + uri);
}
}
/**
* 该函数的返回值是一个Uri,这个Uri表示的是刚刚使用这个函数所插入的数据
* content://mars.cp.FirstContentProvider/users/1
*/
@Override
public Uri insert(Uri uri, ContentValues values) {
System.out.println("insert");
SQLiteDatabase db = dh.getWritableDatabase();
long rowId = db.insert(UserTableMetaData.TABLE_NAME, null, values);
if(rowId > 0){
Uri insertedUserUri = ContentUris.withAppendedId(UserTableMetaData.CONTENT_URI, rowId);
//通知监听器,数据已经改变
getContext().getContentResolver().notifyChange(insertedUserUri, null);
return insertedUserUri;
}
throw new SQLException("Failed to insert row into" + uri);
}
//是一个回调方法,所以说在ContentProvider创建的时候执行
@Override
public boolean onCreate() {
//打开数据库
dh = new DatabaseHelper(getContext(),FirstProviderMetaData.DATABASE_NAME);
System.out.println("onCreate");
return true;
}
@Override
public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs,
String sortOrder) {
SQLiteQueryBuilder qb = new SQLiteQueryBuilder();
switch(uriMatcher.match(uri)){
case INCOMING_USER_COLLECTION:
qb.setTables(UserTableMetaData.TABLE_NAME);
qb.setProjectionMap(userProjectionMap);
break;
case INCOMING_USER_SINGLE:
qb.setTables(UserTableMetaData.TABLE_NAME);
qb.setProjectionMap(userProjectionMap);
qb.appendWhere(UserTableMetaData._ID + "=" + uri.getPathSegments().get(1));
break;
}
String orderBy;
if(TextUtils.isEmpty(sortOrder)){
orderBy = UserTableMetaData.DEFAULT_SORT_ORDER;
}
else{
orderBy = sortOrder;
}
SQLiteDatabase db = dh.getWritableDatabase();
Cursor c = qb.query(db, projection, selection, selectionArgs, null, null, orderBy);
c.setNotificationUri(getContext().getContentResolver(), uri);
System.out.println("query");
return c;
}
@Override
public int update(Uri arg0, ContentValues arg1, String arg2, String[] arg3) {
// TODO Auto-generated method stub
System.out.println("update");
return 0;
}
}
==>FirstContentProviderMatadata.java
package mars.cp;
import android.net.Uri;
import android.provider.BaseColumns;
public class FirstProviderMetaData {
public static final String AUTHORIY = "mars.cp.FirstContentProvider";
//数据库名称
public static final String DATABASE_NAME = "FirstProvider.db";
//数据库的版本
public static final int DATABASE_VERSION = 1;
//表名
public static final String USERS_TABLE_NAME = "users";
public static final class UserTableMetaData implements BaseColumns{
//表名
public static final String TABLE_NAME = "users";
//访问该ContentProvider的URI
public static final Uri CONTENT_URI = Uri.parse("content://" + AUTHORIY + "/users");
//该ContentProvider所返回的数据类型的定义
public static final String CONTENT_TYPE = "vnd.android.cursor.dir/vnd.firstprovider.user";
public static final String CONTENT_TYPE_ITEM = "vnd.android.cursor.item/vnd.firstprovider.user";
//列名
public static final String USER_NAME = "name";
//默认的排序方法
public static final String DEFAULT_SORT_ORDER = "_id desc";
}
}
==>DatabaseHelper.java
package mars.sqlite3.db;
import mars.cp.FirstProviderMetaData;
import android.content.Context;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
import android.database.sqlite.SQLiteDatabase.CursorFactory;
//DatabaseHelper作为一个访问SQLite的助手类,提供两个方面的功能,
//第一,getReadableDatabase(),getWritableDatabase()可以获得SQLiteDatabse对象,通过该对象可以对数据库进行操作
//第二,提供了onCreate()和onUpgrade()两个回调函数,允许我们在创建和升级数据库时,进行自己的操作
public class DatabaseHelper extends SQLiteOpenHelper {
private static final int VERSION = 1;
// 在SQLiteOepnHelper的子类当中,必须有该构造函数
public DatabaseHelper(Context context, String name, CursorFactory factory,
int version) {
// 必须通过super调用父类当中的构造函数
super(context, name, factory, version);
// TODO Auto-generated constructor stub
}
public DatabaseHelper(Context context, String name) {
this(context, name, VERSION);
}
public DatabaseHelper(Context context, String name, int version) {
this(context, name, null, version);
}
// 该函数是在第一次创建数据库的时候执行,实际上是在第一次得到SQLiteDatabse对象的时候,才会调用这个方法
@Override
public void onCreate(SQLiteDatabase db) {
// TODO Auto-generated method stub
System.out.println("create a Database");
// execSQL函数用于执行SQL语句
db.execSQL("create table " + FirstProviderMetaData.USERS_TABLE_NAME
+ "(" + FirstProviderMetaData.UserTableMetaData._ID
+ " INTEGER PRIMARY KEY AUTOINCREMENT,"
+ FirstProviderMetaData.UserTableMetaData.USER_NAME
+ " varchar(20));");
}
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
// TODO Auto-generated method stub
System.out.println("update a Database");
}
}
==>main.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
>
<TextView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="@string/hello"
/>
<Button
android:id="@+id/insert"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="插入数据"
/>
<Button
android:id="@+id/query"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="查询数据"
/>
</LinearLayout>
==>AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="mars.cp" android:versionCode="1" android:versionName="1.0"> <application android:icon="@drawable/icon" android:label="@string/app_name"> <activity android:name=".CPActivity" android:label="@string/app_name"> <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> <provider android:name="mars.cp.FirstContentProvider" android:authorities="mars.cp.FirstContentProvider"/> </application> <uses-sdk android:minSdkVersion="4" /> </manifest>