Android教程網
  1. 首頁
  2. Android 技術
  3. Android 手機
  4. Android 系統教程
  5. Android 游戲
 Android教程網 >> Android技術 >> 關於Android編程 >> Android四大組件-ContentProvider

Android四大組件-ContentProvider

編輯:關於Android編程

ContentProvider:內容提供者

ContentProvider簡介:
當應用繼承ContentProvider類,並重寫該類用於提供數據和存儲數據的方法,就可以向其他應用共享其數據。雖然使用其他方法也可以對外共享數據,但數據訪問方式會因數據存儲的方式而不同,如:采用文件方式對外共享數據,需要進行文件操作讀寫數據;采用sharedpreferences共享數據,需要使用sharedpreferences API讀寫數據。而使用ContentProvider共享數據的好處是統一了數據訪問方式。
Uri類簡介
Uri代表了要操作的數據,Uri主要包含了兩部分信息:1.需要操作的ContentProvider ,2.對ContentProvider中的什麼數據進行操作,一個Uri由以下幾部分組成:
1.scheme:ContentProvider(內容提供者)的scheme已經由Android所規定為:content://。
2.主機名(或Authority):用於唯一標識這個ContentProvider,外部調用者可以根據這個標識來找到它。
3.路徑(path):可以用來表示我們要操作的數據,路徑的構建應根據業務而定,如下:
• 要操作contact表中id為10的記錄,可以構建這樣的路徑:/contact/10
• 要操作contact表中id為10的記錄的name字段, contact/10/name
• 要操作contact表中的所有記錄,可以構建這樣的路徑:/contact

本篇主要圍繞通話記錄和聯系人講解ContentProvider的使用。

首先來了解一下通話記錄和聯系人的表結構。
這是手機中部分表:
這裡寫圖片描述
通話記錄在calls表中,聯系人表主要有三個:raw_contacts、data、mimetype表。
–聯系人記錄
–存放聯系人信息的表(注意表結構):
聯系人信息表:raw_contacts
–_id
–display_name聯系人名稱<喎?/kf/ware/vc/" target="_blank" class="keylink">vcD4NCjxwPsGqz7XIy8r9vt2x7aO6ZGF0YTxiciAvPg0KJm5kYXNoO19pZDxiciAvPg0KJm5kYXNoO3Jhd19jb250YWN0X2lkKM3ivPyjrHJhd19jb250YWN0c7HttcRfaWQpPGJyIC8+DQombmRhc2g7ZGF0YTE8YnIgLz4NCiZuZGFzaDtkYXRhMjxiciAvPg0KJm5kYXNoO21pbWV0eXBlX2lkKMr9vt3A4NDNo6zI57Xnu7CjrNPKz+SjrLXY1rcgzeK8/KOobWltZXlwZXOjqSk8L3A+DQo8cD7K/b7dwODQzbHto7ptaW1leXBlczxiciAvPg0KJm5kYXNoO19pZDxiciAvPg0KJm5kYXNoO21pbWV0eXBlPGJyIC8+DQo8aW1nIGFsdD0="這裡寫圖片描述" src="/uploadfile/Collfiles/20150915/20150915091622149.png" title="\" />
數據類型表中需要注意的是name、phone_v2、email_v2字段,對應id是7、5、1;


一、ContentResolver的使用

1)定義ContentProvieder組件提供的內容的Uri接口
2)定義被訪問的表中的字段
3)添加訪問權限

簡單使用1:查詢最近聯系人記錄

// 訪問撥號應用下的ContentProvieder組件提供的內容的Uri接口
private Uri callUri = CallLog.Calls.CONTENT_URI;
// 被訪問的表中的字段
private String[] columns = { CallLog.Calls._ID, CallLog.Calls.NUMBER,
CallLog.Calls.DATE, CallLog.Calls.TYPE };

private void loadData() {
        // 使用ContentResolver訪問撥號記錄應用下的ContentProvider組件提供的數據庫中表的數據
        // 得到ContentResolver對象
        ContentResolver resolver = getContentResolver();
        // 查詢uri代表的資源(從 Uri代表的表中進行查詢)
        Cursor cursor = resolver.query(callUri, columns, null, null, null);
        while (cursor.moveToNext()) {
            long id = cursor.getLong(0);
            String number = cursor.getString(1);
            long time = cursor.getLong(2);
            int type = cursor.getInt(3);
            String date = new SimpleDateFormat(yyyy-MM-dd E HH:mm:ss)
                    .format(new Date(time));
            String types = (type == 1 ? 撥入 : (type == 2 ? 撥出 : 未接));
            datas.add(new CallInfo(id, number, date, types));
        }
        adapter.notifyDataSetChanged();
    }

簡單使用2:查詢手機聯系人,然後執行增刪改操作
需要了解聯系人數據庫中有哪些表及表的結構:通過adb shell可以查看。
–聯系人記錄
–存放聯系人信息的表(注意表結構):
聯系人信息表:raw_contacts
–_id
–display_name聯系人名稱
聯系人數據表:data
–_id
–raw_contact_id(外鍵,raw_contacts表的_id)
–data1:電話、郵箱、姓名等信息
–data2
–mimetype_id(數據類型,如電話,郵箱,地址 外鍵(mimeypes))
數據類型表:mimeypes
–_id
–mimetype
– mimetype_id=1:郵箱
– mimetype_id=5:電話
– mimetype_id=7:姓名

// 訪問raw_contacts這張表的Uri
    private Uri contactUri = Uri            .parse(content://com.android.contacts/raw_contacts);
    private String[] conColumn = { _id, display_name };
    // //訪問data這張表的Uri
    private Uri dataUri = Uri.parse(content://com.android.contacts/data);
    private String[] dataColumn = { data1 };

—>增刪該查操作都是第一步得到ContentResolver操作對象,第二步執行已經定義好的方法。


    
    

2.1添加聯系人:
// 向聯系人表raw_contacts中添加新的聯系人信息

ContentValues value = new ContentValues();
value.put(display_name, name);
value.put(display_name_alt, name);
// 返回新插入的記錄Uri,Uri中包含了_id
// content://com.android.contacts/raw_contacts/#8
    Uri datasUri = getContentResolver().insert(contactUri,value);

這個方法值得注意的是返回的是一個uri,也就是新增的這條數據的uri,如果想得到該條記錄的id可以調用這個方法:
long _id = ContentUris.parseId(datasUri);

–姓名:
value.put(“data1”, name);
value.put(“mimetype”,”vnd.android.cursor.item/name”);
–電話:
value.put(“data1”, phone);
value.put(“mimetype”,”vnd.android.cursor.item/phone_v2”);
–郵件:
value.put(“data1”, email);
value.put(“mimetype”,”vnd.android.cursor.item/email_v2”);

2.2刪除聯系人:都是很簡單的操作
// 再從聯系人表中刪除信息
getContentResolver().delete(contactUri, “_id=” + id,null);

2.3修改聯系人:

value.put(display_name, name);
value.put(display_name_alt, name);
long id = Long.parseLong(String.valueOf(datas.get(curItemPosition).get(id)));
// 更新聯系人信息
getContentResolver().update(contactUri, value,_id= + id, null);

2.4查詢所有聯系人

ContentResolver resolver = getContentResolver();
// 先從聯系人表中查詢所有人的信息
Cursor cursor = resolver.query(contactUri, conColumn, null, null, null);

二、自定義ContentProvider

1.步驟:
1)聲明該contentProvider的唯一標識,通常使用包名加數據庫名,必須小寫
2)為該組件中可以被外界訪問的數據庫中的資源定義Code標識,不對外界開放的不用定義
3)定義訪問資源的Uri的匹配器對象–使用該類生成被訪問的資源的Uri
4)UriMatcher添加訪問uri
5)清單文件中注冊組件 name authorities
6)聲明訪問該組件的權限
7)重寫provider的增刪改查方法

2.實現
1)自定義數據庫

public class DBHelper extends SQLiteOpenHelper {
    public DBHelper(Context context) {
        super(context, users.db, null, 1);
    }
    @Override
    public void onCreate(SQLiteDatabase db) {
        // TODO 初始化數據庫
        db.execSQL(create table t_user(_id integer primary key,uname,upass,money));
        db.execSQL(create table t_order(_id integer primary key,user_id,price,productname));
        db.execSQL(insert into t_user(uname,upass,money) values('lisa','123',200));
        db.execSQL(insert into t_user(uname,upass,money) values('zhangsan','1234',2000));
    }
    @Override
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
        // TODO 數據庫升級時執行該方法
        if (newVersion > oldVersion) {
            db.execSQL(drop table if exists t_user);
            db.execSQL(drop table if exists t_order);
            onCreate(db);
        }
    }
}

2)按上述步驟定義ContentProvider

public class UserContentProvider extends ContentProvider {
    // 聲明該ContentProvider的唯一標識--通常使用包名+數據庫名--必須小寫
    public static final String AUTHORITY = com.beiing.contentprovider_selfdefine.users;
    // 為該組件中可以被外界訪問的數據庫中的資源定義Code標識
    public static final int CODE_USER = 1;
    public static final int CODE_ORDER = 2;
    // 定義訪問資源的Uri的匹配器對象--使用該類生成被訪問的資源的Uri
    private static UriMatcher uriMatcher;
    static {
        uriMatcher = new UriMatcher(UriMatcher.NO_MATCH);
        // content://com.beiing.contentprovider_selfdefine.users/user
        uriMatcher.addURI(AUTHORITY, user, CODE_USER);
        // content://com.beiing.contentprovider_selfdefine.users/order
        uriMatcher.addURI(AUTHORITY, order, CODE_ORDER);
    }
    private DBHelper dbHelper;
    @Override
    public boolean onCreate() {
        // TODO 初始化 數據庫操作的工具類
        dbHelper = new DBHelper(getContext());
        return false;
    }
    @Override
    public Cursor query(Uri uri, String[] projection, String selection,
            String[] selectionArgs, String sortOrder) {
        SQLiteDatabase db = dbHelper.getReadableDatabase();
        Cursor cursor = null;
        int code = uriMatcher.match(uri);
        switch (code) {
        case CODE_USER:
            cursor = db.query(t_user, projection, selection, selectionArgs,
                    null, null, sortOrder);
            break;
        case CODE_ORDER:
            break;
        }
        return cursor;
    }
    @Override
    public Uri insert(Uri uri, ContentValues values) {
        // TODO 向數據庫中插入數據
        SQLiteDatabase db = dbHelper.getWritableDatabase();
        if (uriMatcher.match(uri) == CODE_USER) {
            long id = db.insert(t_user, null, values);
            // 返回新插入的記錄的 Uri,回憶插入新數據時可以通過返回的uri得到id
            // content://com.beiing.contentprovider_selfdefine.users/user/6
            return ContentUris.withAppendedId(uri, id);
        }
        return null;
    }
    @Override
    public int delete(Uri uri, String selection, String[] selectionArgs) {
        // TODO 刪除數據庫中的數據
        SQLiteDatabase db = dbHelper.getWritableDatabase();
        int num = 0;
        if (uriMatcher.match(uri) == CODE_USER) {
            num = db.delete(t_user, selection, selectionArgs);
        }
        return num;
    }
    @Override
    public int update(Uri uri, ContentValues values, String selection,
            String[] selectionArgs) {
        // TODO 修改數據庫中的數據
        SQLiteDatabase db = dbHelper.getWritableDatabase();
        if (uriMatcher.match(uri) == CODE_USER) {
            return db.update(t_user, values, selection, selectionArgs);
        }
        return 0;
    }
    @Override
    public String getType(Uri uri) {
        return null;
    }
}

3)清單文件中注冊內容提供器


注意:還需要添加訪問該provider的權限和修改的操作權限,否則其他程序不能訪問或操作


    

4)在其他程序中使用
和上面使用類似,不贅述了。

 

  1. 上一頁:
  2. 下一頁:
熱門文章
閱讀排行版
Copyright © Android教程網 All Rights Reserved