1、ContentProvider的基本概念
1> ContentProvider为存储和读取数据提供了统一的接口
2> 使用ContentProvider,应用程序可以实现数据共享
3> android内置的许多数据都是使用ContentProvider形式,供开发者调用的(如视频,音频,图片,通讯录等)
2、Uri
1> 每一个ContentProvider都拥有一个公共的Uri,这个Uri用于表示这个ContentProvider提供的数据
2> Android所提供的ContentProvider都存放在andriod.provider这个包里面
3、ContentProvider提供的函数
1> query() 查询
2> insert() 插入
3> update() 更新
4> delete() 删除
5> getType() 得到数据类型
6> onCreate() 创建时的回调函数
4、实现ContentProvider的过程
1> 定义一个COTENT_URI常量
2> 定义一个类,继承ContentProvider
3> 实现query(),delete(),update(),insert(),onCreate(),getType()方法
4> 在AndroidMainfest.xml中申明
下面以两个实例(一个是ContentProvider所在的应用,另一个是使用ContentProvider的应用),说明如何使用ContentProvider
5、ContentProvider所在的应用
1>定义一个类,里面定义一些常量
package com.dxt;
import android.net.Uri;
import android.provider.BaseColumns;
public class MyUsers {
public static final String AUTHORITY = "com.dxt.MyContentProvider";
// <provider android:name=".android.MyContentProvider" android:authorities="com.dxt.android.MyContentProvider" />
//BaseColumn类中已经包含了_id字段
public static final class User implements BaseColumns
{
//定义Uri
public static final Uri CONTENT_URI = Uri.parse("content://" + AUTHORITY);
//定义数据表列
public static String USER_NAME = "_Name";
public static String USER_TEL = "_Tel";
}
}
2>定义一个继承ContentProvider的子类,实现其方法
package com.dxt; import android.content.ContentProvider; import android.content.ContentUris; import android.content.ContentValues; import android.content.Context; import android.database.Cursor; import android.database.SQLException; import android.database.sqlite.SQLiteDatabase; import android.database.sqlite.SQLiteOpenHelper; import android.database.sqlite.SQLiteQueryBuilder; import android.net.Uri; import android.util.Log; /* * MyContentProvider继承ContentProvider类,实现其insert,update,delete,getType,onCreate等方法 */ public class MyContentProvider extends ContentProvider { //定义一个SQLiteDatabase变量 private SQLiteDatabase sqlDB; //定义一个DatabaseHelper变量 private DatabaseHelper dbHelper; //数据库名 private static final String DATABASE_NAME = "Users.db"; //数据库版本 private static final int DATABASE_VERSION = 1; //表名 private static final String TABLE_NAME = "User"; //标签 private static final String TAG = "MyContentProvider"; /* * 定义一个内部类 * * 这个内部类继承SQLiteOpenHelper类,重写其方法 */ public static class DatabaseHelper extends SQLiteOpenHelper { //构造方法 public DatabaseHelper(Context context) { //父类构造方法 super(context, DATABASE_NAME, null, DATABASE_VERSION); } //当第一次创建数据库的时候调用该方法,可以为数据库增加一些表,和初始化一些数据 @Override public void onCreate(SQLiteDatabase db) { //在数据库里生成一张表 String sql = "CREATE TABLE IF NOT EXISTS " + TABLE_NAME + " (_id integer primary key autoincrement, "+MyUsers.User.USER_NAME+" text, "+MyUsers.User.USER_TEL+" text);"; db.execSQL(sql); Log.d(TAG, "DatabaseHelper--->oncreate"); // db.execSQL("Create table " // + TABLE_NAME // + "( _id INTEGER PRIMARY KEY AUTOINCREMENT, USER_NAME TEXT);"); } //当更新数据库版本的时候,调用该方法。可以删除,修改表的一些信息 @Override public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { db.execSQL("DROP TABLE IF EXISTS " + TABLE_NAME); onCreate(db); } } //这是一个回调函数,当生成所在类的对象时,这个方法被调用,创建一个数据库 @Override public boolean onCreate() { dbHelper = new DatabaseHelper(getContext()); return (dbHelper == null) ? false : true; } //查询 @Override public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder) { SQLiteDatabase db = dbHelper.getReadableDatabase(); // qb.setTables(TABLE_NAME); Cursor c = db.query(TABLE_NAME, projection, selection, selectionArgs, null, null, sortOrder); // query(USER_TABLE, null,null, null, null, null, " _id desc");//asc desc c.setNotificationUri(getContext().getContentResolver(), uri); Log.d(TAG, "query----->"+c.getCount()); db.close(); return c; } //取得类型 @Override public String getType(Uri uri) { return null; } //插入数据 @Override public Uri insert(Uri uri, ContentValues contentvalues) { SQLiteDatabase db = dbHelper.getWritableDatabase(); long rowId = db.insert(TABLE_NAME, "", contentvalues); db.close(); if (rowId > 0) { Uri rowUri = ContentUris.appendId( MyUsers.User.CONTENT_URI.buildUpon(), rowId).build(); getContext().getContentResolver().notifyChange(rowUri, null); Log.d(TAG, "insert----->" + rowUri); return rowUri; } throw new SQLException("Failed to insert row into" + uri); } //删除数据 @Override public int delete(Uri uri, String selection, String[] selectionArgs) { SQLiteDatabase db = dbHelper.getReadableDatabase(); int rowId = db.delete(TABLE_NAME, selection, selectionArgs); Log.i(TAG, "delete item && row id = " + rowId); db.close(); return rowId; } //更新数据 @Override public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) { SQLiteDatabase db = dbHelper.getWritableDatabase(); int rows = db.update(TABLE_NAME, values, selection, selectionArgs); db.close(); Log.i(TAG, "update item && rows = " + rows); return rows; } }
3>定义一个默认加载的Activity,里面对ContentProvider进行数据加载
package com.dxt;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.widget.Toast;public class MyContentDemo extends Activity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); for (int i = 0; i < 500; i++) { insertRecord("name"+ i,"100000000"+i); }// insertRecord("MyUser","100000000");// insertRecord("YangYuLin","222222222"); displayRecords(); } private void insertRecord(String userName,String telephone) { ContentValues values = new ContentValues(); values.put(MyUsers.User.USER_NAME, userName); values.put(MyUsers.User.USER_TEL, telephone); getContentResolver().insert(MyUsers.User.CONTENT_URI, values); } private void displayRecords() { String columns[] = new String[] { MyUsers.User._ID, MyUsers.User.USER_NAME ,MyUsers.User.USER_TEL}; Uri myUri = MyUsers.User.CONTENT_URI; Cursor cur = managedQuery(myUri, columns, null, null, null); if (cur.moveToFirst()) { String id = null; String userName = null; String tel = null; do { id = cur.getString(cur.getColumnIndex(MyUsers.User._ID)); userName = cur.getString(cur .getColumnIndex(MyUsers.User.USER_NAME)); tel = cur.getString(cur.getColumnIndex(MyUsers.User.USER_TEL));// Toast.makeText(this, id + " " + userName + " " + tel, Toast.LENGTH_LONG)// .show(); Log.d("tag", "name = " + userName + "\ntel = " + tel); } while (cur.moveToNext()); } }}
4>在AndroidMainfest.xml里注册
<?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.dxt" android:versionCode="1" android:versionName="1.0"> <application android:icon="@drawable/icon" android:label="@string/app_name"> <provider android:name=".MyContentProvider" android:authorities="com.dxt.MyContentProvider" /> <activity android:name="com.dxt.MyContentDemo" 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>
6、做另一个App.使用上面ContentProvider提供的数据package com.CPClientActitity.dxt;
import android.app.Activity;
import android.os.Bundle;
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.text.Editable;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
public class CPClientActitity extends Activity {
public static final String AUTHORITY = "com.dxt.MyContentProvider";
private Button insertButton = null;
//访问ContentProvider的Uri
Uri CONTENT_URI = Uri.parse("content://" + AUTHORITY);
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
//得到ContentProvider对于表的所有数据,以游标格式保存
// Cursor c = managedQuery(CONTENT_URI,new String[]{"_id","_Name","_Tel"},null,null,null);
Cursor c = getContentResolver().query(CONTENT_URI, null, null,null, "_id desc");
//循环打印ContentProvider的数据
if(c.moveToFirst())
{
String _id = null;
String user_name = null;
String tel_num = null;
do
{
//得到_id列,USER_NAME列
_id = c.getString(c.getColumnIndex("_id"));
user_name = c.getString(c.getColumnIndex("_Name"));
tel_num = c.getString(c.getColumnIndex("_Tel"));
Log.d("tag", "_id = " + _id +", _Name = " + user_name + "_Tel = " + tel_num);
}while(c.moveToNext());
}Toast.makeText(getApplicationContext(), "数据添加完成!!!", Toast.LENGTH_SHORT).show();
if(c != null){
Toast.makeText(getApplicationContext(), "cursor已经关闭了啊 !!!", Toast.LENGTH_SHORT).show();
c.close();
}
//根据Id得到控件对象
insertButton = (Button)findViewById(R.id.Insert);
//给按钮绑定事件监听器
insertButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
//得到EditText输入的数据
String username = ((EditText)findViewById(R.id.userName)).getText().toString();
String tel_num = ((EditText)findViewById(R.id.tel_num)).getText().toString();
//生成一个ContentResolver对象
ContentResolver cr = getContentResolver();
//生成一个ContentValues对象
ContentValues values = new ContentValues();
//将EditText输入的值,保存到ContentValues对象中
values.put("_Name", username);
values.put("_Tel", tel_num);
//插入数据
cr.insert(CONTENT_URI, values);
}
});
}
}
文章出处:http://www.cnblogs.com/-cyb/articles/2098338.html
AsyncQuerHandler 下一篇进行讲解