美文网首页
第六周随笔(2)--Content Provider

第六周随笔(2)--Content Provider

作者: 關kwan | 来源:发表于2016-06-19 23:54 被阅读0次

    Content Provider:内容提供者

    • 应用程序间共享数据的一种方式
    • 为存储和获取数据提供了统一的接口
    • Android为常见的一些数据提供了默认的 Content Provider
    • 四大组件之一

    定义

    • 内容提供者将一些特定的应用程序数据供给其他应用程序使用
    • 数据可以存储于文件系统、SQLite数据库或其他方式
    • 内容提供者继承于ContentProvider基类,为其他应用程序取用和存储它管理的数据实现了一套标准方法
    • 应用程序并不是直接调用这些方法,而是使用ContentResolver对象,调用它的方法作为替代
    • ContentResolver 可以与任意内容提供者进行会话,与其合作来对所有相关交互通讯进行管理

    ContentProvider实现过程

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


    系统提供的Provider

    系统提供的Provider
    获取系统的通讯录信息
    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);  
    
            //查询通讯录数据
            //由于要读取通讯录,所以要在manifest中加上"android.permission.READ_CONTACTS"的权限 
            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>:表示匹配任意长度的数字

    1. DataBase:创建一个继承SQLiteOpenHelper的类,并创建<code>user</code>、<code>book</code>两个表。

      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:创建UriList.java


      UriList.Java
    3. 创建一个继承ContentProvider的类,然后设置UriMatcher和完善重构方法:

      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() {  
           //获取数据库
           mDataBaseHelper = new DataBaseHelper(getContext());  
               return true;   
           } 
           @Nullable
           @Override
           public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder) { 
              //从数据库中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)”:这个方法负责把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. 设置完ContentProvider之后就可以在相应功能里进行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>设置为<code>true</code>可以跨应用使用这个ContentProvider。


      声明ContentProvider

    相关文章

      网友评论

          本文标题:第六周随笔(2)--Content Provider

          本文链接:https://www.haomeiwen.com/subject/wyesdttx.html