1. 程式人生 > >關於如何使用內容提供器Content Provider的簡介

關於如何使用內容提供器Content Provider的簡介

一、什麼情況下需要使用內容提供器?

內容提供器用來存放和獲取資料並使這些資料可以被所有的應用程式訪問。它們是應用程式之間共享資料的唯一方法,不存在所有Android軟體包都能訪問的公共儲存區域。

Android為常見資料型別(音訊,視訊,影象,個人聯絡人資訊,等等)裝載了很多內容提供器,在android.provider包裡列舉了一些。可以查詢這些提供器包含了什麼資料(儘管,對某些提供器,必須獲取合適的許可權來讀取資料)。

如果開發者想公開應用程式自己的資料,有兩個選擇:建立自己的內容提供器(一個ContentProvider子類) 或者 給已有的提供器新增資料(前提是存在一個控制同樣型別資料的內容提供器且你擁有寫的許可權)。

二、如何建立內容提供器?

要建立一個內容提供器,你必須:

1)建立一個儲存資料的系統。大多數內容提供器使用Android的檔案儲存方法或SQLite資料庫來存放它們的資料,但是你可以用任何你想要的方式來存放資料。Android提供SQLiteOpenHelper類來幫助你建立一個數據庫以及SQLiteDatabase類來管理它。

3)在清單manifest檔案中為你的應用程式宣告這個內容提供器(AndroidManifest.xml)。

三、content URI的重要內容

 

A.標準字首表明這個資料被一個內容提供器所控制。它不會被修改。

B.URI的許可權部分;它標識這個內容提供器。對於第三方應用程式,這應該是一個全稱類名(小寫)以確保唯一性。

許可權在<provider>元素的許可權屬性中進行宣告:

<provider name=".TransportationProvider"

         authorities="com.example.transportationprovider"

          . . .  >

C.用來判斷請求資料型別的路徑。這可以是0或多個段長。如果內容提供器只暴露了一種資料型別(比如,只有火車),這個分段可以沒有。如果提供器暴露若干型別,包括子型別,那它可以是多個分段長-例如,提供"land/bus","land/train", "sea/ship", "sea/submarine"

4個可能的值。

D.被請求的特定記錄的ID,如果有的話。這是被請求記錄的_ID數值。如果這個請求不侷限於單個記錄,這個分段和尾部的斜線會被忽略:

content://com.example.transportationprovider/trains

四、例子

第一步:建立資料儲存系統

/**
 * 資料庫操作幫助類 安裝版本:SDSQLiteOpenHelper 
 * 模擬測試版本 :SQLiteOpenHelper
 * 
 * @author Jessica
 * @date 2013-5-18
 */
public class DatabaseHelper extends SQLiteOpenHelper {
	private static final int DATABASE_VERSION = 2;
	private static final String DATABASE_NAME = "info.db";

	private static final String TABLE_CREATE = "CREATE TABLE info "
			+ "(_id INTEGER PRIMARY KEY, zc_code1 TEXT,zc_code2 TEXT, zc_nums TEXT);";

	public DatabaseHelper(Context context) {	
		super(context, DATABASE_NAME, null, DATABASE_VERSION);
		Log.v("DatabaseHelper","----create database end---------");
	}

	@Override
	public void onCreate(SQLiteDatabase db) {
		Log.v("DatabaseHelper","----create table begin --------");
		db.execSQL(TABLE_CREATE);	
		Log.v("DatabaseHelper","----create table end --------");
		
		Log.v("DatabaseHelper","----init data begin --------");
		db.execSQL("insert into info values(1,'BX','CD','10A');");
		db.execSQL("insert into info values(2,'BX','CD','10B');");
		Log.v("DatabaseHelper","----init data end --------");
		
	}

	@Override
	public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
		if (newVersion != oldVersion) {
			db.execSQL("DROP TABLE IF EXISTS info");
			onCreate(db);
		}
		Log.v("DatabaseHelper","----update database end --------");
	}
}
public class InfoProvider extends ContentProvider {
	
	private static final String INFO_TABLE_NAME = "info";
	
	private static final int INFOS = 1; 
	
	private DatabaseHelper mOpenHelper;
	
	private static final UriMatcher sUriMatcher;

	/*
	 * 建立資料庫
	 * 
	 * @see android.content.ContentProvider#onCreate()
	 */
	@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 INFOS:
			qb.setTables(INFO_TABLE_NAME);
			break;		
		default:
			throw new IllegalArgumentException("Unknown URI " + uri);
		}

		// Get the database and run the query
		SQLiteDatabase db = mOpenHelper.getReadableDatabase();
		if (sortOrder != null) {
			Cursor c = qb.query(db, projection, selection, selectionArgs, sortOrder, null, null);
			return c;
		}
		Cursor c = qb.query(db, projection, selection, selectionArgs, null, null, null);

		return c;
	}

	@Override
	public int delete(Uri uri, String selection, String[] selectionArgs) {
		// TODO Auto-generated method stub
		return 0;
	}

	@Override
	public String getType(Uri uri) {
		// TODO Auto-generated method stub
		return null;
	}

	@Override
	public Uri insert(Uri uri, ContentValues values) {
		// TODO Auto-generated method stub
		return null;
	}	

	@Override
	public int update(Uri uri, ContentValues values, String selection,
			String[] selectionArgs) {
		// TODO Auto-generated method stub
		return 0;
	}
	
	static {
		sUriMatcher = new UriMatcher(UriMatcher.NO_MATCH);
		sUriMatcher.addURI(Info.AUTHORITY, "info", INFOS);
	}
}

第三步:使用資料訪問介面
public class MainActivity extends Activity {
	private Intent intent;

	public static final String[] infoProjection = new String[] { Infos._ID, Infos.CODE1, Infos.CODE2,
			Infos.NUMS };
	EditText txtCode1 = null;
	EditText txtCode2 = null;
	EditText txtNums = null;

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);
		txtCode1 = (EditText) this.findViewById(R.id.txt_code1);
		txtCode2 = (EditText) this.findViewById(R.id.txt_code2);
		txtNums = (EditText) this.findViewById(R.id.txt_nums);
		intent = getIntent();
		// 初始化資料
		this.initData();
	}

	@Override
	public boolean onCreateOptionsMenu(Menu menu) {
		getMenuInflater().inflate(R.menu.main, menu);
		return true;
	}

	private void initData() {
		intent.setData(Infos.CONTENT_URI);
		Cursor c = managedQuery(getIntent().getData(), infoProjection, null, null, null);
		
		if (c.getCount() != 0) {
			c.moveToFirst();				
			while (!c.isLast()) {
				 txtCode1.setText(c.getString(c.getColumnIndex(Infos.CODE1)));
				 txtCode2.setText(c.getString(c.getColumnIndex(Infos.CODE2)));
				 txtNums.setText(c.getString(c.getColumnIndex(Infos.NUMS)));
				 c.moveToNext();
			}
		} 
	}
}