Android中ContentProvider简介【安卓进化二十七】

对做应用的来说,数据存储很重要,在【安卓进化十三】中有SharedPreferences简单键值存储形式,以xml格式存储在手机中,这个是简单,方便,好操作的数据存储工具,只能存简单的数据,如果存储大量数据这个就不方便了。在【安卓进化十四】中,我写了个sqlite的数据库保存数据的通讯录的例子,sqlite对大量数据进行存储,方便操作,是关系型数据库的一种。数据存储还有file文件存储,network存储,以后我会写例子的。现在我要讲一下自己对ContentProviders的理解,前面说的SharedPreferences,sqlite,等等,都是针对每个应用程序来说的,就是说你的不能跨越工程,只能这个工程能用,但是手机有些程序是需要数据共享的,不能只单独让一个工程用,(例如:android手机的短信和通讯录等都是数据共享的,源码写了它们对应的ContentProvider提供给我们这个接口,我们就可以对其进行操作)这时候就需要ContentProviders了,它是多有应用程序之间数据存储和检索的一个桥梁,主要作用就是使得各个应用程序之间实现数据共享。系统提供了音频、视频、图像、个人联系信息等几个常用的ContentProviders。这就是泛讲ContentProviders。


下面分步骤讲解一下ContentsProviders:

一、创建ContentsProvider:

首先要在ContentsProviders类中定义一个公共的、静态的常量:CONTENT_URI来代表这个地址,该地址必须是唯一的:public static final Uri CONTENT_URI = Uri.parse("content://" + AUTHORITY + "/notes");必须定义你要返回给客户端的数据列名。如果你正在使用sqlite数据库,则数据列的使用方式和你以往所熟悉的其他数据库一样。但是,你必须为其定义一个叫_id的列,它用来表示每条记录的唯一性,模式使用“INTEGER PRIMARY KEY AUTOINCREMENT”自动更新。

特别说明一下:如果你处理的数据类型是一种比较新的类型,你就必须定义一个新的MIME类型,以提供ContentProvider.getType(uri)来返回。MIME类型有两种类型,一种是为指定的单个记录的;另一种是为指定多条记录的。
另外一定不要忘记在AndroidMenifest.xml中使用<provider>标签来设置Content Provider。

<provider android:name="NotePadProvider" android:authorities="com.cn.daming.proider.NotePad"/>

二、ContentResolver这个类,应用通过这个类来使用具体的某个ContentProvider,
ContentResolver crs = getContentResolver();得到一个ContentResolver对象,然后可以通过这个类的方法进行数据的增删改查操作,具体方法参照sdk的api帮助文档。
三、讲一下URI,每个ContentProvider都会对外提供一个公共的URI(包装成Uri对象),数据共享的时候,就需要使用ContentProvider为这些数据定义的URI,然后其他的应用程序就可以通过ContentProvider传入这个URI来对数据进行操作。URI由3部分组成:“content://”,数据的路径,标示ID(可选),举个系统的URI:

content://contacts/Mms/3(获取短信表中ID为3的联系人记录)

content://contacts/Mms/(这个URI将返回设备上的所有短信的信息)

为了方便理解,在android.provider包下提供了一系列辅助类,其中包含了以类变量形式给出的查询字符串,上面的可以改为:

Uri person = ContentUris.withAppendedId(Mms.CONTENT_URI,3);

特别说明:在数据共享的查询语句中:where ...And ...OR,可以同时使用,多个And,和一个或多个Or同时使用,或多个Or和一个And或多个And同时使用,使用的时候用小括号括起来,这样看的比较明了,注意:有Or和And同时使用的时候查询的效率很低,速度有点慢。尤其再和like一起使用的情况下,效率会更慢。 有问题的,想要代码的可以留言,转载请标明出处:http://blog.csdn.net/wdaming1986/article/details/6820442

看例子:ContentProviderDemo 这个例子

先看效果图:读取插入数据库中的值:

代码奉上,代码说明一切:

在com.cn.daiming包下面的类

一、NotePad.java类中的代码:

package com.cn.daming

import android.net.Uri;
import android.provider.BaseColumns;

public class NotePad {

	public static final String AUTHORITY = "com.cn.daming.proider.NotePad";
	private NotePad(){}
	
	public static final class Notes implements BaseColumns
	{
		private Notes(){}
		public static final Uri CONTENT_URI = Uri.parse("content://" + AUTHORITY + "/notes");
		//new mime many
		public static final String CONTENT_TYPE = "daming.android.cursor.dir/cn.daming.note";
		//new mime one
		public static final String CONTENT_ITEM_TYPE = "daming.android.cursor.item/cn.daming.note";
		public static final String DEFAULT_SORT_ORDER = "modified DESC";
		
		//column
		public static final String TITLE = "title";
		public static final String NOTE = "note";
		public static final String CREATEDDATE = "created";
		public static final String MODIFIEDDATE = "modified";
	}
}
 

二、NotePadProvider.java类中的代码:

package com.cn.daming; import java.util.HashMap; import android.content.ContentProvider; import android.content.ContentUris; import android.content.ContentValues; import android.content.Context; import android.content.UriMatcher; import android.content.res.Resources; 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.text.TextUtils; import com.cn.daming.NotePad.Notes; public class NotePadProvider extends ContentProvider{ private static final String TAG = "NotePadProvider"; //database name private static final String DATABASE_NAME = "notepad_db"; private static final int DATABASE_VERSION = 2; //table name private static final String NOTES_TABLE_NAME = "notes"; private static HashMap<String, String> sNotesProjectionMap; private static final int NOTES = 1; private static final int NOTE_ID = 2; private static final UriMatcher sUriMatcher; private DatabaseHelper mOpenHelper; private static final String CREATE_TABLE = "CREATE TABLE " + NOTES_TABLE_NAME +" ("+Notes._ID +" INTEGER PRIMARY KEY, " +Notes.TITLE +" TEXT," +Notes.NOTE +" TEXT, " +Notes.CREATEDDATE +" INTEGER," +Notes.MODIFIEDDATE +" INTEGER" + ");"; static { sUriMatcher = new UriMatcher(UriMatcher.NO_MATCH); sUriMatcher.addURI(NotePad.AUTHORITY, "notes", NOTES); sUriMatcher.addURI(NotePad.AUTHORITY, "notes/#", NOTE_ID); sNotesProjectionMap = new HashMap<String, String>(); sNotesProjectionMap.put(Notes._ID, Notes._ID); sNotesProjectionMap.put(Notes.TITLE, Notes.TITLE); sNotesProjectionMap.put(Notes.NOTE, Notes.NOTE); sNotesProjectionMap.put(Notes.CREATEDDATE, Notes.CREATEDDATE); sNotesProjectionMap.put(Notes.MODIFIEDDATE, Notes.MODIFIEDDATE); } private static class DatabaseHelper extends SQLiteOpenHelper { //create Database DatabaseHelper(Context context) { super(context, DATABASE_NAME, null, DATABASE_VERSION); } //create tables @Override public void onCreate(SQLiteDatabase db) { db.execSQL(CREATE_TABLE); } //update Database @Override public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { db.execSQL("DROP TABLE IF EXISTS notes"); onCreate(db); } } @Override public boolean onCreate() { mOpenHelper = new DatabaseHelper(getContext()); return true; } @Override public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder) { SQLiteQueryBuilder qb = new SQLiteQueryBuilder(); switch(sUriMatcher.match(uri)) { case NOTES: qb.setTables(NOTES_TABLE_NAME); qb.setProjectionMap(sNotesProjectionMap); break; case NOTE_ID: qb.setTables(NOTES_TABLE_NAME); qb.setProjectionMap(sNotesProjectionMap); qb.appendWhere(Notes._ID + "="+ uri.getPathSegments().get(1)); break; default: throw new IllegalArgumentException("Unknown URI"+uri); } String orderBy; if(TextUtils.isEmpty(sortOrder)) { orderBy = NotePad.Notes.DEFAULT_SORT_ORDER; } else { orderBy = sortOrder; } SQLiteDatabase db = mOpenHelper.getReadableDatabase(); Cursor cursor = qb.query(db, projection, selection, selectionArgs, null, null, orderBy); cursor.setNotificationUri(getContext().getContentResolver(), uri); return cursor; } //if you difine the class,must get the mothod @Override public String getType(Uri uri) { switch(sUriMatcher.match(uri)) { case NOTES: return Notes.CONTENT_TYPE; case NOTE_ID: return Notes.CONTENT_ITEM_TYPE; default: throw new IllegalArgumentException("Unknown URI "+uri); } } @Override public Uri insert(Uri uri, ContentValues initialValues) { if(sUriMatcher.match(uri) != NOTES) { throw new IllegalArgumentException("Unknown URI "+uri); } ContentValues values; if(initialValues != null) { values = new ContentValues(initialValues); } else { values = new ContentValues(); } Long now = Long.valueOf(System.currentTimeMillis()); if(values.containsKey(NotePad.Notes.CREATEDDATE) == false) { values.put(NotePad.Notes.CREATEDDATE, now); } if(values.containsKey(NotePad.Notes.MODIFIEDDATE) == false) { values.put(NotePad.Notes.MODIFIEDDATE, now); } if(values.containsKey(NotePad.Notes.TITLE) == false) { Resources recource = Resources.getSystem(); values.put(NotePad.Notes.TITLE, recource.getString(android.R.string.untitled)); } if(values.containsKey(NotePad.Notes.NOTE) == false) { values.put(NotePad.Notes.NOTE, ""); } SQLiteDatabase db = mOpenHelper.getWritableDatabase(); long rowId = db.insert(NOTES_TABLE_NAME, Notes.NOTE, values); if(rowId > 0) { Uri noteUri = ContentUris.withAppendedId(NotePad.Notes.CONTENT_URI, rowId); getContext().getContentResolver().notifyChange(noteUri, null); return noteUri; } throw new SQLException("Failed to insert row into "+uri); } @Override public int delete(Uri uri, String where, String[] whereArgs) { SQLiteDatabase db = mOpenHelper.getWritableDatabase(); int count; switch(sUriMatcher.match(uri)) { case NOTES: count = db.delete(NOTES_TABLE_NAME, where, whereArgs); break; case NOTE_ID: String noteId = uri.getPathSegments().get(1); count = db.delete(NOTES_TABLE_NAME, Notes._ID + "=" + noteId + (!TextUtils.isEmpty(where) ? " " + " AND (" + where + ')' : ""), whereArgs); break; default: throw new IllegalArgumentException("Unknown URI "+uri); } getContext().getContentResolver().notifyChange(uri, null); return count; } @Override public int update(Uri uri, ContentValues values, String where, String[] whereArgs) { SQLiteDatabase db = mOpenHelper.getWritableDatabase(); int count; switch(sUriMatcher.match(uri)) { case NOTES: count = db.update(NOTES_TABLE_NAME, values, where, whereArgs); break; case NOTE_ID: String noteId = uri.getPathSegments().get(1); count = db.update(NOTES_TABLE_NAME, values, Notes._ID + "=" + noteId + (!TextUtils.isEmpty(where)?"" + "AND(" + where + ')' : ""), whereArgs); break; default: throw new IllegalArgumentException("Unknown URI " + uri); } getContext().getContentResolver().notifyChange(uri, null); return count; } }

三、MainActivity.java类中的代码:

package com.cn.daming; import android.app.Activity; import android.content.ContentValues; import android.database.Cursor; import android.graphics.Color; import android.net.Uri; import android.os.Bundle; import android.widget.TextView; public class MainActivity extends Activity { private TextView show_text_view1; private TextView show_text_view2; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); //insert value ContentValues values = new ContentValues(); values.put(NotePad.Notes.TITLE, "From Daming"); values.put(NotePad.Notes.NOTE, "This is Daming Make!"); getContentResolver().insert(NotePad.Notes.CONTENT_URI, values); values.clear(); values.put(NotePad.Notes.TITLE, "Daming blog"); values.put(NotePad.Notes.NOTE, "http://blog.csdn.net/wdaming1986/article/details/6820442!"); getContentResolver().insert(NotePad.Notes.CONTENT_URI, values); //show the display showDisplayNote(); } //show the display private void showDisplayNote() { String columns[] = new String[]{ NotePad.Notes._ID, NotePad.Notes.TITLE, NotePad.Notes.NOTE, NotePad.Notes.CREATEDDATE, NotePad.Notes.MODIFIEDDATE }; Uri myUri = NotePad.Notes.CONTENT_URI; show_text_view1 = (TextView)findViewById(R.id.show_textview1); show_text_view2 = (TextView)findViewById(R.id.show_textview2); Cursor cursor = managedQuery(myUri, columns, null, null, null); if(cursor.moveToFirst()) { String title = null; String note = null; for(int i=0;i<cursor.getCount();i++) { if(cursor.moveToPosition(i)) { title = cursor.getString(cursor.getColumnIndex(NotePad.Notes.TITLE)); note = cursor.getString(cursor.getColumnIndex(NotePad.Notes.NOTE)); if(i==0) { show_text_view2.setText("TITLE:"+title+"\n"+"NOTE:"+note); show_text_view2.setTextColor(Color.GREEN); } if(i==1) { show_text_view1.setText("TITLE:"+title+"\n"+"NOTE:"+note); show_text_view1.setTextColor(Color.BLUE); } } } } } }

在layout下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:gravity="center_vertical|center_horizontal" android:layout_marginTop="10dip" android:text="@string/hello" android:textSize="8pt" /> <TextView android:id="@+id/show_textview1" android:layout_width="fill_parent" android:layout_height="wrap_content" android:gravity="center_vertical|center_horizontal" android:layout_marginTop="20dip" android:textSize="10pt" /> <TextView android:id="@+id/show_textview2" android:layout_width="fill_parent" android:layout_height="wrap_content" android:gravity="center_vertical|center_horizontal" android:layout_marginTop="20dip" android:textSize="10pt" /> </LinearLayout>

在Manifest.xml中的代码:【一定注意要对ContentProvider进行声明】

<?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.cn.daming" android:versionCode="1" android:versionName="1.0"> <uses-sdk android:minSdkVersion="8" /> <application android:icon="@drawable/icon" android:label="@string/app_name"> <provider android:name="NotePadProvider" android:authorities="com.cn.daming.proider.NotePad"/> <activity android:name=".MainActivity" android:label="@string/app_name"> <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> <intent-filter> <data android:mimeType="daming.android.cursor.dir/cn.daming.note"/> </intent-filter> <intent-filter> <data android:mimeType="daming.android.cursor.item/cn.daming.note"/> </intent-filter> </activity> </application> </manifest>







                
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值