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

Content Provider:内容提供者

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

定义

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

ContentProvider实现过程

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


系统提供的Provider

第六周随笔(2)--Content Provider_第1张图片
系统提供的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 stringList = new ArrayList<>();      
        ArrayAdapter 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后面还以加上 *** 或 #分别表示:

  • *:表示匹配任意长度的任意字符
  • #:表示匹配任意长度的数字

  1. DataBase:创建一个继承SQLiteOpenHelper的类,并创建userbook两个表。

    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


    第六周随笔(2)--Content Provider_第2张图片
    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:
    要注意的是authorities的值是与上面的AUTHORITY的值一样;
    exported设置为true可以跨应用使用这个ContentProvider。


    声明ContentProvider

你可能感兴趣的:(第六周随笔(2)--Content Provider)