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 下一篇进行讲解