Android開發教程 — Content Provider

來源:互聯網
上載者:User

Hi,大家好!

     今天我們主要來講解下,Android的資料共用機制Content Provider。

     輕鬆下:

應 聘

人事總監:您對電腦懂多少?

應聘者A:略懂一二:我用過計算機,戴過電子錶,喜歡玩電子遊戲機,我還用電視機 和機頂盒上網跟國外的朋友聯絡呢......還有,我看過同學用DOS刪除檔案......

人事總監:下一位!

人事總監:您對電腦懂多少?

應聘者B:在我頭腦裡沒有“電腦”這個詞,只有微電腦這樣一個概念!一般地 超級掌上型矽單晶片時鐘脈衝輸出電腦(電子錶)比較簡單,我小時候常使用它 的編解碼運行程式(鬧鐘功能);至於多功能虛擬現實模擬器(電子遊戲機)就複 雜多了,不過我曾經完整測試過多靜態資料單元(只玩過關遊戲卡);長大後我開 始對多頻道超高頻無線多媒體接收器(電視機)產生興趣,每天晚上會追蹤特定頻 道的資料;至於傳統的微電腦,最近我還用數據機通過ISP服務商跟國外的 朋友進行多格式多位元組即時傳輸(上網聊天),還有,我手下的一個工作夥伴(同學) 經常在我的監控下進行主儲存空間與磁化資料儲存空間之間的訊號轉化或訊號取消(用DOS 開機和刪除檔案).....

人事總監:ok!明天開始上班。你的配車在地下二層,這是鑰匙......

1 什麼是Content Provider?

2 什麼是URI?

3 如何使用Content Provider?

1 Android中的Content provider機制可支援在多個應用中儲存和讀取資料。這也是跨應用共用資料的唯一方式。在android系統中,沒有一個公用的記憶體地區,供多個應用共用儲存資料。

   Android提供了一些主要資料類型的Content provider,比如音頻、視頻、圖片和私人通訊錄等。可在android.provider包下面找到一些android提供的Content provider。可以獲得這些Content provider,查詢它們包含的資料,當然前提是已獲得適當的讀取許可權。

2  通用資源標誌符

(Universal Resource Identifier, 簡稱"URI")。

  Uri代表要操作的資料,Android上可用的每種資源 - 映像、視頻片段等都可以用Uri來表示。

  每一個Content Provider都有一個公用URI,這個URI表示Content Provider所提供的資料。

3 使用Content Provider

1 首先,當前應用中,需要有資料庫,上篇博文已經對操作資料庫進行了講解,在這裡不再贅述。

2 需要建立一個類並且繼承Content Provider類,並實現這個抽象類別中的六個方法。

  public int delete(Uri uri, String selection, String[] selectionArgs){}

  public String getType(Uri uri) {}

  public Uri insert(Uri uri, ContentValues values) {}

  public boolean onCreate() {}

  public Cursor query(Uri uri, String[] projection, String selection,
            String[] selectionArgs, String sortOrder) {}

  public int update(Uri uri, ContentValues values, String selection,
            String[] selectionArgs) {}

3 需要給當前應用中的Content Provider定義一個URI,並且定義查詢的類型,下邊是一個常量類

package TSD.Jason.DB;

import android.net.Uri;

public class CPFinal {
public final static String DATABASE_NAME="StudentDB"; //資料庫名稱
public final static String TABLE_NAME="StudentInfo"; //資料表名稱

/*定義ContentProvide的名稱,一般以項目包名+CP類名
* 注意:規範CP名稱
* */
public final static String CPNAME = "TSD.Jason.CPDemo.StudentCP";
//定義訪問此CP的路徑 格式: content:// + 路徑 + 子表名稱
public final static Uri CONTENT_URI = Uri.parse("content://" + CPNAME + "/" + TABLE_NAME);

/*定義查詢資料類型
* 如果要查詢所有
* 格式 vnd.android.cursor.dir + 定義的名字
* */
public final static String CONTENT_TYPE="vnd.android.cursor.dir/selectAll";
public final static String CONTENT_TYPE_ITEM ="vnd.android.cursor.item/selectItem";


}

4 回到自訂的Content Provider類中,我們需要使用到一個UriMatcher的類,這個類主要是在調用查詢函數query()函數時,會用到。

   大家都知道,查詢分為兩大塊,一塊是不帶條件的查詢整表,一塊是帶有一定條件,查詢此條件下的資料。

   例如: select * from Table 和 select * from Table where t_id = 1

   UriMatcher正是用來規定我們這個Content Provider有哪一些查詢類型和檢查傳入的URI是否符合我們的規定

   我們定義了這兩種查詢方式,自然需要將這兩種查詢方式放到UriMatcher中,定義我們查詢的規則

   代碼如下

  

//檢查傳入的uri是否符合我們設定的標準
private final static UriMatcher uriMatcher;
private final static int SELECT_ALL = 1;
private final static int SELECT_ITEM= 2;
static{
uriMatcher = new UriMatcher(UriMatcher.NO_MATCH);
uriMatcher.addURI(CPFinal.CPNAME, "StudentInfo", SELECT_ALL);
uriMatcher.addURI(CPFinal.CPNAME, "StudentInfo/#", SELECT_ITEM);
}

這裡可以看到,我們addURI了兩種規則,
一種就是查詢StudentInfo表中的所有資料的,一種是查詢StudentInfo表中ID為什麼的資料,#代表表中的ID列

當我們需要調用時,需要傳遞的字串就是 當前定義的ContentProvider的名字,這裡我們叫做

public final static String CPNAME = "TSD.Jason.CPDemo.StudentCP";

查詢所有的字串就是 TSD.Jason.CPDemo.StudentCP/StudentInfo

查詢某條資料的字串就是 TSD.Jason.CPDemo.StudentCP/StudentInfo/1

檢查URI

需要用到uriMatcher.match(uri)中的match函數

應為我們上邊add了兩個URI規則,並對應兩個int常量,所以如果使用的是

TSD.Jason.CPDemo.StudentCP/StudentInfo 那麼match函數返回SELECT_ALL

TSD.Jason.CPDemo.StudentCP/StudentInfo/1 返回SELECT_ITEM

實現下邊的增刪改成函數即可。

 

package TSD.Jason.CPDemo;

import java.util.HashMap;

import TSD.Jason.DB.CPFinal;
import TSD.Jason.DB.DBColumns;
import TSD.Jason.DB.DBHelp;
import android.content.ContentProvider;
import android.content.ContentUris;
import android.content.ContentValues;
import android.content.UriMatcher;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteQueryBuilder;
import android.net.Uri;

public class StudentCP extends ContentProvider {

//檢查傳入的uri是否符合我們設定的標準
private final static UriMatcher uriMatcher;
private final static int SELECT_ALL = 1;
private final static int SELECT_ITEM= 2;
static{
uriMatcher = new UriMatcher(UriMatcher.NO_MATCH);
uriMatcher.addURI(CPFinal.CPNAME, "StudentInfo", SELECT_ALL);
uriMatcher.addURI(CPFinal.CPNAME, "StudentInfo/#", SELECT_ITEM);
}
//TSD.Jason.CPTest.StudentCP/StudentInfo

/**
* 需要給資料表中的列,定義一個別名
*/
private static HashMap<String, String> columnName;
static{
columnName = new HashMap<String, String>();
columnName.put(DBColumns.S_NAME, DBColumns.S_NAME);
columnName.put(DBColumns.S_AGE, DBColumns.S_AGE);
columnName.put(DBColumns.S_SEX, DBColumns.S_SEX);
columnName.put(DBColumns.S_ADDRESS, DBColumns.S_ADDRESS);
}

DBHelp dbHelp;

/**
* 根據傳入的URI,返回所傳入的URI所表示的查詢資料類型
* 此函數用來匹配 此類的靜態程式碼片段中所定義的規則
*/
@Override
public String getType(Uri uri) {
System.out.println(uri.toString()+" -----------gettype");
switch (uriMatcher.match(uri)) {
case SELECT_ALL:
return CPFinal.CONTENT_TYPE;
case SELECT_ITEM:
return CPFinal.CONTENT_TYPE_ITEM;
default:
return null;

}

}

@Override
public boolean onCreate() {
dbHelp = new DBHelp(getContext(), CPFinal.DATABASE_NAME);
System.out.println("create---------------");
return false;
}

@Override
public Uri insert(Uri uri, ContentValues values) {
System.out.println("insert -----------------" + uri.toString());
SQLiteDatabase db = dbHelp.getWritableDatabase();
long result = db.insert(CPFinal.TABLE_NAME, null, values);
System.out.println("insert ------------" + result);
if(result > 0)
{
Uri resultUri = ContentUris.withAppendedId(CPFinal.CONTENT_URI, result);
//通知監聽器,資料已經發生改變
getContext().getContentResolver().notifyChange(resultUri, null);
return resultUri;
}
return null;
}

@Override
public int delete(Uri uri, String selection, String[] selectionArgs) {
SQLiteDatabase db = dbHelp.getWritableDatabase();
return db.delete(CPFinal.TABLE_NAME, selection, selectionArgs);
}

@Override
public Cursor query(Uri uri, String[] projection, String selection,
String[] selectionArgs, String sortOrder) {
SQLiteQueryBuilder qb = new SQLiteQueryBuilder();
SQLiteDatabase db = dbHelp.getReadableDatabase();
qb.setTables(CPFinal.TABLE_NAME);
Cursor c = qb.query(db, projection, selection, null, null, null, sortOrder);
c.setNotificationUri(getContext().getContentResolver(), uri);
return c;

}

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

}

調用

btn1.setOnClickListener(new Button.OnClickListener() {
@Override
public void onClick(View v) {
ContentValues contentvalues = new ContentValues();
contentvalues.put(DBColumns.S_NAME, "張三");
contentvalues.put(DBColumns.S_AGE, "23");
contentvalues.put(DBColumns.S_SEX, "男");
contentvalues.put(DBColumns.S_ADDRESS, "北京市海澱區");
Uri uri =getContentResolver().insert(CPFinal.CONTENT_URI, contentvalues);
System.out.println(uri.toString()+"------------activity");
}
});

此處調用了增加函數,剩下的刪除、修改、查詢,依次類推。

最後在AndroidManifest.xml中需要註冊provider

<provider android:name=".StudentCP"
            android:authorities="TSD.Jason.CPDemo.StudentCP"></provider>

 

 

 

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.