標籤:mis length lis strong ast self oncreate hang check
內容提供器的用法一般有兩種,一種是使用現有的內容來讀取和操作相應程式中的資料,另一種是建立自己的內容提供器給我們程式的資料提供外部存取介面。首先,我們來學習第一種。
如果一個應用通過內容提供器對自己的資料提供了外部存取的介面,那麼其他的應用程式都可以對這部分資料進行訪問。Android系統內建的電話簿、簡訊、媒體庫等程式都提供了類似的外部介面,這就使得第三方的應用程式可以充分的利用這部分資料來實現更好的功能。
1.ContentResolver的基本用法
對一個每一個應用程式來說,如果想要訪問內容提供器中共用的資料,就一定要藉助ContextResolver類,可以通過Context類中的getContentResolver()方法來擷取ContentResolver類的對象。ContentResolver類中提供了一些類似於資料庫的操作。
不同於SQLiteDataBase,ContentResolver中的增刪改查方法都不是接收表名的參數,而是使用一個Uri參數來代替,這個參數被稱為內容URI。
內容URI給內容提供器中的資料提供了唯一的標識符,它主要有兩部分組成:authority和path。authority是用於對不同的應用程式做區分的,一般為了衝突,都會採用應用程式的包名的方式來進行命名。比如某個程式的包名是com.example.demo,那麼該程式對應的authority就可以命名為com.example.demo.provider。path則是用於對同一個應用程式中不同的表做區分的,通常會添加到authority的後面。比如某一個應用程式的資料中有兩張表:table1、table2,這時就可以將path命名為/table1和/table2,然後再將authority和path進行組合,內容URI變成了com.example.demo.provider/table1和com.example.demo.provider/table2。不過目前還很難的辨認出這兩個字串就是兩個內容URI,所以我們還需要在字串的頭部加上協議聲明。因此,內容URI最標準的格式為:
content://com.example.demo.provider/table1
在得到了內容URI字串之後,我們還需要將它解析成URI對象才可以作為參數傳入。我們可以通過Uri中parse方法來進行解析
Uri uri = Uri.parse("content://com.example.demo.provider/table1");
(1).查詢資料
現在我們就可以使用這個對象對table1表中的資料進行查詢
Cursor cursor = getContentResolver().query(final Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder, CancellationSignal cancellationSignal)
1.uri,指定查詢某一個程式下的某一張表
2.projection,指定查詢的列名
3.selection,指定查詢條件,相當於sql語句中where後面的條件
4.selectionArgs,給selection中的預留位置提供具體的值
5.orderBy,指定查詢結果排序方式
6.cancellationSignal,取消進行中操作的訊號量
(2).插入資料
ContentValues values = new ContentValues();
values.put();
getContentResolver.insert(uri,values);
(3).更新資料
ContentValues values = new ContentValues();
values.put();
getContentResolver.update(uri, values, "column1 = ? and column2 = ?", new String[]{"text", "1"});
注意上面使用了selection和selectionArgs參數來對想要更新的資料進行了約束,以防止所有的行都會影響。
(4).刪除資料
getContentResolver().delete(uri, "column2 = ?", new String[]{"1"});
2.讀取連絡人
現在我們使用之前的知識來做一個小demo,來讀取手機電話薄的連絡人
1 public class MainActivity extends AppCompatActivity implements View.OnClickListener { 2 private Button buttonCall = null; 3 private RecyclerView myRecyclerView = null; 4 private MyAdapter myAdapter = null; 5 private List<Bean> datas = null; 6 7 @Override 8 protected void onCreate(@Nullable Bundle savedInstanceState) { 9 super.onCreate(savedInstanceState);10 setContentView(R.layout.activity_main);11 initView();12 }13 14 private void initView() {15 buttonCall = (Button) findViewById(R.id.id_button_readContacts);16 buttonCall.setOnClickListener(this);17 myRecyclerView = (RecyclerView) findViewById(R.id.id_recyclerView);18 datas = new ArrayList<>();19 myAdapter = new MyAdapter(this, datas);20 myRecyclerView.setLayoutManager(new LinearLayoutManager(this, LinearLayoutManager.VERTICAL, false));21 myRecyclerView.setAdapter(myAdapter);22 }23 24 @Override25 public void onClick(View v) {26 if (ContextCompat.checkSelfPermission(this, Manifest.permission.READ_CONTACTS) != PackageManager.PERMISSION_GRANTED) {27 ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.READ_CONTACTS}, 1);28 }29 else30 {31 readContacts();32 }33 }34 35 @Override36 public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {37 if (requestCode == 1) {38 if (permissions.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {39 readContacts();40 } else {41 Toast.makeText(this, "許可權不允許!", Toast.LENGTH_SHORT).show();42 }43 }44 }45 46 private void readContacts() {47 Cursor cursor = null;48 try {49 cursor = getContentResolver().query(ContactsContract.CommonDataKinds.Phone.CONTENT_URI, null, null, null, null);50 if(cursor != null)51 {52 while(cursor.moveToNext())53 {54 String name = cursor.getString(cursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME));55 String phoneNumber = cursor.getString(cursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER));56 Bean bean = new Bean(name, phoneNumber);57 datas.add(bean);58 }59 }60 Log.i("main", "size = " + datas.size());61 myAdapter.notifyDataSetChanged();62 }63 catch(Exception e)64 {65 e.printStackTrace();66 }finally{67 if(cursor != null)68 {69 cursor.close();70 }71 }72 }73 }
布局檔案代碼:
1 <?xml version="1.0" encoding="utf-8"?> 2 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 3 android:layout_width="match_parent" 4 android:layout_height="match_parent" 5 android:gravity="center" 6 android:orientation="vertical"> 7 <android.support.v7.widget.RecyclerView 8 android:id="@+id/id_recyclerView" 9 android:layout_weight="10"10 android:layout_width="match_parent"11 android:layout_height="0dp"></android.support.v7.widget.RecyclerView>12 <Button13 android:layout_weight="1"14 android:id="@+id/id_button_readContacts"15 android:text="讀取"16 android:textSize="20sp"17 android:layout_width="wrap_content"18 android:layout_height="0dp" />19 </LinearLayout>
效果展示:
Android-Android內容提供器之訪問其他程式的資料