对做应用的来说,数据存储很重要,在【安卓进化十三】中有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"/> <span style="font-size:18px;color:#333333;"> </span>
二、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类中的代码:
<pre class="java" name="code">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类中的代码:
<span style="font-size:13px;color:#000000;">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;
}
}</span>
三、MainActivity.java类中的代码:
<span style="font-size:13px;color:#000000;">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);
}
}
}
}
}
}</span>
在layout下main.xml布局文件下的代码:
<span style="font-size:13px;color:#000000;"><?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></span>
在Manifest.xml中的代码:【一定注意要对ContentProvider进行声明】
<span style="font-size:13px;color:#000000;"><?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>
</span>