您的位置:首页 > 移动开发 > Android开发

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

2011-09-26 08:43 369 查看
对做应用的来说,数据存储很重要,在【安卓进化十三】中有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>







                                            
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: