ContentResolver.query詳解

1.查詢手機的聯繫人
    public void getContacts() {
        ContentResolver contentResolver = this.getContentResolver();
        Cursor cursor = contentResolver.query(android.provider.ContactsContract.Contacts.CONTENT_URI,
                null, null, null, null);
        if (cursor != null && cursor.moveToFirst()) {
            do {
                Log.d(TAG,cursor.getString(cursor.getColumnIndex(android.provider.ContactsContract.Contacts._ID)));
                Log.d(TAG,cursor.getString(cursor.getColumnIndex(android.provider.ContactsContract.Contacts.DISPLAY_NAME)));
            } while (cursor.moveToNext());
        }
        cursor.close();
    }

記得開權限

 <uses-permission android:name="android.permission.READ_CONTACTS" />
    <uses-permission android:name="android.permission.WRITE_CONTACTS" />

log

05-08 16:20:08.639 7447-7447/com.bbk.contentprovidertest D/notecontent: 1
05-08 16:20:08.639 7447-7447/com.bbk.contentprovidertest D/notecontent: 阿大
05-08 16:20:08.639 7447-7447/com.bbk.contentprovidertest D/notecontent: 2
05-08 16:20:08.639 7447-7447/com.bbk.contentprovidertest D/notecontent: 阿牛
05-08 16:20:08.639 7447-7447/com.bbk.contentprovidertest D/notecontent: 3
05-08 16:20:08.639 7447-7447/com.bbk.contentprovidertest D/notecontent: 阿虎
05-08 16:20:08.639 7447-7447/com.bbk.contentprovidertest D/notecontent: 4
05-08 16:20:08.639 7447-7447/com.bbk.contentprovidertest D/notecontent: 海哥
cusor的正確遍歷方式

查詢得到的cursor是指向第一條記錄之前的,因此查詢得到cursor後第一次調用moveToFirst或moveToNext都可以將cursor移動到第一條記錄上。但是爲了規避一些可能存在的情況,下面這種寫法比較保險

if (cursor != null && cursor.moveToFirst())
{
      do{

      }while(cursor.moveToNext());
}
cursor.close();

這篇文章主要講解ContentResolver的query方法。

ContentResolver直譯爲內容解析器,什麼東東?Android中程序間數據的共享是通過Provider/Resolver進行的。提供數據(內容)的就叫Provider,Resovler提供接口對這個內容進行解讀。

根據Android文檔,

public final Cursor query (Uri uri, String[] projection,String selection,String[] selectionArgs,String sortOrder)

第一個參數,uri

uri是什麼呢?好吧,上面我們提到了Android提供內容的叫Provider,那麼在Android中怎麼區分各個Provider?有提供聯繫人的,有提供圖片的等等。所以就需要有一個唯一的標識來標識這個Provider,Uri就是這個標識,android.provider.ContactsContract.Contacts.CONTENT_URI就是提供聯繫人的內容提供者,可惜這個內容提供者提供的數據很少。

第二個參數,projection,

這個參數告訴Provider要返回的內容(列Column),比如Contacts Provider提供了聯繫人的ID和聯繫人的NAME等內容,如果我們只需要NAME,那麼我們就應該使用:

Cursor cursor = contentResolver.query(android.provider.ContactsContract.Contacts.CONTENT_URI,  
    new String[]{android.provider.ContactsContract.Contacts.DISPLAY_NAME}, null, null, null);  

當然,下面打印的你就只能顯示NAME了,因爲你返回的結果不包含ID。用null表示返回Provider的所有內容(列Column)。
Log

05-08 16:00:55.587 13524-13524/com.bbk.contentprovidertest D/notecontent: 阿大
05-08 16:00:55.588 13524-13524/com.bbk.contentprovidertest D/notecontent: 阿牛
05-08 16:00:55.588 13524-13524/com.bbk.contentprovidertest D/notecontent: 阿虎
05-08 16:00:55.588 13524-13524/com.bbk.contentprovidertest D/notecontent: 海哥

第三個參數,selection,

設置條件,相當於SQL語句中的where。null表示不進行篩選。如果我們只想返回名稱爲“海哥”的數據,第三個參數應該設置爲:

 Cursor cursor = contentResolver.query(android.provider.ContactsContract.Contacts.CONTENT_URI,
                new String[]{ContactsContract.Contacts.DISPLAY_NAME}, ContactsContract.Contacts.DISPLAY_NAME + "= '海哥'", null, null);//注意‘海哥’ 

獲取到的結果,Log

05-08 16:05:16.264 20723-20723/com.bbk.contentprovidertest D/notecontent: 海哥

例如查詢手機中以.txt結尾的文件

Cursor cursor = getContentResolver().query(
                Uri.parse("content://media/external/file"),
                projection,
                MediaStore.Files.FileColumns.DATA + " like ?" ,
                new String[]{"%.txt"},
                null);

SQL模糊查詢語句

先看下面這個函數,查詢手機中以.txt結尾的文件以及文檔大小要超過500KB的文檔。

  private void queryBooks() {
        String[] projection = new String[]{MediaStore.Files.FileColumns._ID, MediaStore.Files.FileColumns.DATA, MediaStore.Files.FileColumns.SIZE};
        //查詢以.txt結尾的文件以及文件大小超過1024*500(500KB)
        //注意 AND  倆邊空格 
        Cursor cursor = getContentResolver().query(
                Uri.parse("content://media/external/file"),
                projection,
                MediaStore.Files.FileColumns.DATA + " like ?" + " AND " + MediaStore.Files.FileColumns.SIZE + " >= ?",
                new String[]{"%.txt", "512000"},
                null);
        if (cursor != null && cursor.moveToFirst()) {
            do {
                int ctitle = cursor.getColumnIndex(MediaStore.Files.FileColumns.DATA);
                int csize = cursor.getColumnIndex(MediaStore.Files.FileColumns.SIZE);
                Recommend.RecommendBooks books = new Recommend.RecommendBooks();
                long size = cursor.getLong(csize);
                String title = cursor.getString(ctitle);
                int dot = title.lastIndexOf("/");
                String name = title.substring(dot + 1);
                if (name.lastIndexOf(".") > 0) {
                    name = name.substring(0, name.lastIndexOf("."));
                }
                books.title = name;
                books.lastChapter = FileUtils.formatFileSizeToString(size);
                books.isFromSD = true;
                mList.add(books);
            } while (cursor.moveToNext());
          
        }
        cursor.close();
        mAdapter.setListItems(mList);
        mAdapter.notifyDataSetChanged();
        mListView.setAdapter(mAdapter);

    }

上面這段代碼直接在查詢時,就明確了要求,查詢效率也大幅度提升,比在查詢後根據size再次判斷快了200多毫秒。

SQL模糊查詢,使用like比較字,加上SQL裏的通配符:

like使用:

下面一些實例演示了 帶有 ‘%’ 和 ‘_’ 運算符的 LIKE 子句不同的地方:

語句 描述
WHERE SALARY LIKE ‘200%’ 查找以 200 開頭的任意值
WHERE SALARY LIKE ‘%200%’ 查找任意位置包含 200 的任意值
WHERE SALARY LIKE ‘_00%’ 查找第二位和第三位爲 00 的任意值
WHERE SALARY LIKE ‘2_%_%’ 查找以 2 開頭,且長度至少爲3個字符的任意值
WHERE SALARY LIKE ‘%2’ 查找以 2 結尾的任意值
WHERE SALARY LIKE ‘_2%3’ 查找第二位爲 2,且以 3 結尾的任意值
WHERE SALARY LIKE ‘2___3’ 查找長度爲 5位數,且以2開頭以3結尾的任意值

第四個參數,selectionArgs,

這個參數是要配合第三個參數使用的,如果你在第三個參數裏面有?,那麼你在selectionArgs寫的數據就會替換掉?,

  Cursor cursor = contentResolver.query(android.provider.ContactsContract.Contacts.CONTENT_URI,
                new String[]{ContactsContract.Contacts.DISPLAY_NAME}, ContactsContract.Contacts.DISPLAY_NAME + "= ?", new String[]{"海哥"}, null);

效果和上面一句的效果一樣。

第五個參數,sortOrder,

按照什麼進行排序,相當於SQL語句中的Order by。如果想要結果按照ID的降序排列:

Cursor cursor = contentResolver.query(android.provider.ContactsContract.Contacts.CONTENT_URI,  
                null, null,null, android.provider.ContactsContract.Contacts._ID + " DESC");

Log

05-08 16:18:11.061 4921-4921/com.bbk.contentprovidertest D/notecontent: 海哥
05-08 16:18:11.061 4921-4921/com.bbk.contentprovidertest D/notecontent: 阿虎
05-08 16:18:11.061 4921-4921/com.bbk.contentprovidertest D/notecontent: 阿牛
05-08 16:18:11.061 4921-4921/com.bbk.contentprovidertest D/notecontent: 阿大

升序,默認排序是升序,也可+" ASC":


Cursor cursor = contentResolver.query(android.provider.ContactsContract.Contacts.CONTENT_URI,  
                null, null,null, android.provider.ContactsContract.Contacts._ID + " ASC"); 

Log

05-08 16:18:53.787 6316-6316/com.bbk.contentprovidertest D/notecontent: 阿大
05-08 16:18:53.787 6316-6316/com.bbk.contentprovidertest D/notecontent: 阿牛
05-08 16:18:53.787 6316-6316/com.bbk.contentprovidertest D/notecontent: 阿虎
05-08 16:18:53.787 6316-6316/com.bbk.contentprovidertest D/notecontent: 海哥

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章