第六周隨筆(2)--Content Provider

Content Provider:內(nèi)容提供者

  • 應(yīng)用程序間共享數(shù)據(jù)的一種方式
  • 為存儲和獲取數(shù)據(jù)提供了統(tǒng)一的接口
  • Android為常見的一些數(shù)據(jù)提供了默認(rèn)的 Content Provider
  • 四大組件之一

定義

  • 內(nèi)容提供者將一些特定的應(yīng)用程序數(shù)據(jù)供給其他應(yīng)用程序使用
  • 數(shù)據(jù)可以存儲于文件系統(tǒng)雕拼、SQLite數(shù)據(jù)庫或其他方式
  • 內(nèi)容提供者繼承于ContentProvider基類,為其他應(yīng)用程序取用和存儲它管理的數(shù)據(jù)實(shí)現(xiàn)了一套標(biāo)準(zhǔn)方法
  • 應(yīng)用程序并不是直接調(diào)用這些方法擂送,而是使用ContentResolver對象小腊,調(diào)用它的方法作為替代
  • ContentResolver 可以與任意內(nèi)容提供者進(jìn)行會話也颤,與其合作來對所有相關(guān)交互通訊進(jìn)行管理

ContentProvider實(shí)現(xiàn)過程

Database --> Uri --> UriMatcher --> ContentProvider -- > query/insert/update/delete --> AndroidManifest.xml


系統(tǒng)提供的Provider

系統(tǒng)提供的Provider

獲取系統(tǒng)的通訊錄信息

public class PhoneBookInfo extends AppCompatActivity {
   @Override    
   protected void onCreate(Bundle savedInstanceState) { 
        super.onCreate(savedInstanceState);      
        setContentView(R.layout.activity_phone_book_info);  
        ListView lvInfo = (ListView) findViewById(R.id.phoneBookInfo_lvInfo);        
        List<String> stringList = new ArrayList<>();      
        ArrayAdapter<String> arrayAdapter = new ArrayAdapter<>(this, android.R.layout.simple_list_item_1, stringList); 
        lvInfo.setAdapter(arrayAdapter);  

        //查詢通訊錄數(shù)據(jù)
        //由于要讀取通訊錄,所以要在manifest中加上"android.permission.READ_CONTACTS"的權(quán)限 
        Cursor cursor = getContentResolver().query(      
                  ContactsContract.CommonDataKinds.Phone.CONTENT_URI,                
                  null,null,null,null);  
        if (cursor!=null && cursor.moveToFirst()){  
            for (int i = 0; i < cursor.getCount(); i++) {   
                String disPlayName = cursor.getString(            
                        cursor.getColumnIndexOrThrow(ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME) 
                        );
                String number = cursor.getString(
                        cursor.getColumnIndexOrThrow(ContactsContract.CommonDataKinds.Phone.NUMBER)  
                        );    
                arrayAdapter.add(disPlayName + "\n" + number);     
                cursor.moveToNext(); 
             }
         }
     }
  }

自定義Content Provider

URI后面還以加上 *** 或 #分別表示:

  • *:表示匹配任意長度的任意字符
  • <code>#</code>:表示匹配任意長度的數(shù)字

  1. DataBase:創(chuàng)建一個(gè)繼承SQLiteOpenHelper的類,并創(chuàng)建<code>user</code>黍翎、<code>book</code>兩個(gè)表凉驻。

    public class DataBaseHelper extends SQLiteOpenHelper {
        public static final String DATABASE = "test.db"; 
        public static final int VERSION = 1;
        public static final String TABLENAME_USER = "user";
        public static final String USER_NAME = TABLENAME_USER + "_name"; 
        public static final String USER_AGE = TABLENAME_USER + "_age";  
        public static final String TABLENAME_BOOK = "book";
        public static final String BOOK_NAME = TABLENAME_BOOK + "_name"; 
        public static final String BOOK_WRITER = TABLENAME_BOOK + "_writer";
        public DataBaseHelper(Context context) {
           super(context, DATABASE, null, VERSION);
        } 
        @Override
        public void onCreate(SQLiteDatabase db) {
           db.execSQL("create table " + TABLENAME_USER + " (" + USER_NAME + " TEXT not null, " +
                          USER_AGE + " TEXT not null  )"   
                     ); 
           db.execSQL("create table " + TABLENAME_BOOK + " (" + BOOK_NAME + " TEXT not null, " + 
                          BOOK_WRITER + " TEXT not null ) " 
                     ); 
        }
        @Override
        public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {  
        }
    }
    
  2. Uri:創(chuàng)建UriList.java


    UriList.Java
  3. 創(chuàng)建一個(gè)繼承ContentProvider的類腻要,然后設(shè)置UriMatcher和完善重構(gòu)方法:

    public class TestContentProvider extends ContentProvider {  
       //初始UriMatcher
       private static UriMatcher sUriMatcher; 
       public static final int UriMatcher_CODE_USER = 1; 
       public static final int UriMatcher_CODE_BOOK = 2; 
       static {
           sUriMatcher = new UriMatcher(UriMatcher.NO_MATCH);  
           sUriMatcher.addURI(UriList.AUTHORITY, DataBaseHelper.TABLENAME_USER, UriMatcher_CODE_USER);   
           sUriMatcher.addURI(UriList.AUTHORITY, DataBaseHelper.TABLENAME_BOOK, UriMatcher_CODE_BOOK); 
       } 
    
      private DataBaseHelper mDataBaseHelper; 
      @Override    
      public boolean onCreate() {  
         //獲取數(shù)據(jù)庫
         mDataBaseHelper = new DataBaseHelper(getContext());  
             return true;   
         } 
         @Nullable
         @Override
         public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder) { 
            //從數(shù)據(jù)庫中query
            Cursor cursor = mDataBaseHelper.getReadableDatabase().query(getTableName(uri), projection, selection, selectionArgs, null, null, sortOrder);  
            return cursor;  
         }
         @Nullable
         @Override
         public String getType(Uri uri) {
            return null;
         } 
         @Nullable 
         @Override 
         public Uri insert(Uri uri, ContentValues values) {
            SQLiteDatabase sqLiteDatabase = mDataBaseHelper.getWritableDatabase(); 
            Long id; 
            id = sqLiteDatabase.insert(getTableName(uri), null, values);  
            //“withAppendedId”:將uri和id連接起來(即uri/id)
            //“parseId(Uri contentUri)”:這個(gè)方法負(fù)責(zé)把contentURI 后邊的id解析出來,即返回值是“id”
            return ContentUris.withAppendedId(uri, id); 
         } 
         @Override  
         public int delete(Uri uri, String selection, String[] selectionArgs) {  
            if(TextUtils.isEmpty(getTableName(uri))){ 
                return -1;  
            }
            int count = mDataBaseHelper.getWritableDatabase().delete(getTableName(uri), selection, selectionArgs);        return count;  
         }
         @Override 
         public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) { 
            return mDataBaseHelper.getWritableDatabase().update(getTableName(uri), values, selection, selectionArgs); 
         }
         //獲取表名
         private String getTableName(Uri uri) {
             int code = sUriMatcher.match(uri);  
             String tableName = "";
             switch (code) {  
                 case UriMatcher_CODE_USER:  
                      tableName = DataBaseHelper.TABLENAME_USER;     
                      break; 
                 case UriMatcher_CODE_BOOK:  
                      tableName = DataBaseHelper.TABLENAME_BOOK;    
                      break; 
             }
             return tableName;
        }
    }
    
  4. 設(shè)置完ContentProvider之后就可以在相應(yīng)功能里進(jìn)行query/insert/update/delete方法涝登,如:

    @Override
    public void onClick(View v) {  
       ContentResolver contentResolver = getContentResolver(); 
       switch (v.getId()){ 
       //查詢    
       case R.id.provider_btnQuery:  
           mStringList.clear(); 
           Cursor cursor = contentResolver.query(UriList.Book_Uri,null,null,null,null);   
           if (cursor!= null && cursor.moveToFirst()){  
                String KeyValue1 = cursor.getString(cursor.getColumnIndexOrThrow(DataBaseHelper.BOOK_NAME));             
                String KeyValue2 = cursor.getString(cursor.getColumnIndexOrThrow(DataBaseHelper.BOOK_WRITER));        
                mStringList.add(KeyValue1+"\n"+KeyValue2);   
                cursor.moveToNext();  
           }     
           mAdapter.notifyDataSetChanged();  
           break; 
       //刪除
       case R.id.provider_btnDelet:   
           contentResolver.delete(UriList.Book_Uri, null, null);     
           break;  
       //插入 
       case R.id.provider_btnInsert:     
           ContentValues contentValues = new ContentValues();  
           contentValues.put(DataBaseHelper.BOOK_NAME, mEdtKeyValue1.getText().toString());    
           contentValues.put(DataBaseHelper.BOOK_WRITER, mEdtKeyValue2.getText().toString());      
           contentResolver.insert(UriList.Book_Uri, contentValues); 
           break; 
       //修改   
       case R.id.provider_btnUpdate: 
           ContentValues values = new ContentValues();       
           values.put(DataBaseHelper.BOOK_NAME, mEdtKeyValue1.getText().toString());  
           values.put(DataBaseHelper.BOOK_WRITER, mEdtKeyValue2.getText().toString());      
           contentResolver.update(UriList.Book_Uri, values, null, null);   
           break; 
       }
    }
    
  5. 最后記得在manifest.xml中聲明ContentProvider:
    要注意的是<code>authorities</code>的值是與上面的<code>AUTHORITY</code>的值一樣雄家;
    <code>exported</code>設(shè)置為<code>true</code>可以跨應(yīng)用使用這個(gè)ContentProvider。


    聲明ContentProvider
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末胀滚,一起剝皮案震驚了整個(gè)濱河市趟济,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌咽笼,老刑警劉巖顷编,帶你破解...
    沈念sama閱讀 221,576評論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異剑刑,居然都是意外死亡媳纬,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,515評論 3 399
  • 文/潘曉璐 我一進(jìn)店門施掏,熙熙樓的掌柜王于貴愁眉苦臉地迎上來钮惠,“玉大人,你說我怎么就攤上這事七芭∷赝欤” “怎么了?”我有些...
    開封第一講書人閱讀 168,017評論 0 360
  • 文/不壞的土叔 我叫張陵狸驳,是天一觀的道長预明。 經(jīng)常有香客問我缩赛,道長,這世上最難降的妖魔是什么撰糠? 我笑而不...
    開封第一講書人閱讀 59,626評論 1 296
  • 正文 為了忘掉前任均函,我火速辦了婚禮淮韭,結(jié)果婚禮上饺饭,老公的妹妹穿的比我還像新娘惯悠。我一直安慰自己,他們只是感情好遮斥,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,625評論 6 397
  • 文/花漫 我一把揭開白布峦失。 她就那樣靜靜地躺著,像睡著了一般术吗。 火紅的嫁衣襯著肌膚如雪尉辑。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 52,255評論 1 308
  • 那天较屿,我揣著相機(jī)與錄音隧魄,去河邊找鬼。 笑死隘蝎,一個(gè)胖子當(dāng)著我的面吹牛购啄,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播嘱么,決...
    沈念sama閱讀 40,825評論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼狮含,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了曼振?” 一聲冷哼從身側(cè)響起几迄,我...
    開封第一講書人閱讀 39,729評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎冰评,沒想到半個(gè)月后映胁,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 46,271評論 1 320
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡甲雅,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,363評論 3 340
  • 正文 我和宋清朗相戀三年解孙,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片务荆。...
    茶點(diǎn)故事閱讀 40,498評論 1 352
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡妆距,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出函匕,到底是詐尸還是另有隱情,我是刑警寧澤蚪黑,帶...
    沈念sama閱讀 36,183評論 5 350
  • 正文 年R本政府宣布盅惜,位于F島的核電站中剩,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏抒寂。R本人自食惡果不足惜结啼,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,867評論 3 333
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望屈芜。 院中可真熱鬧郊愧,春花似錦、人聲如沸井佑。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,338評論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽躬翁。三九已至焦蘑,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間盒发,已是汗流浹背例嘱。 一陣腳步聲響...
    開封第一講書人閱讀 33,458評論 1 272
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留宁舰,地道東北人拼卵。 一個(gè)月前我還...
    沈念sama閱讀 48,906評論 3 376
  • 正文 我出身青樓,卻偏偏與公主長得像蛮艰,于是被迫代替她去往敵國和親间学。 傳聞我的和親對象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,507評論 2 359

推薦閱讀更多精彩內(nèi)容