Android中ContentResolver進(jìn)行數(shù)據(jù)查詢的三種方式
在Android開發(fā)中,??ContentResolver?? 是一個(gè)非常重要的組件,它用于訪問和操作其他應(yīng)用程序的數(shù)據(jù)。通過 ??ContentResolver??,我們可以跨應(yīng)用查詢、插入、更新和刪除數(shù)據(jù)。本文將詳細(xì)介紹 ??ContentResolver?? 查詢數(shù)據(jù)的三種方式。
1. 基本查詢
最基本的查詢方式是使用 ??query?? 方法,該方法允許你指定要查詢的內(nèi)容提供者 URI、需要返回的列、選擇條件等參數(shù)。以下是一個(gè)簡單的例子:
// 獲取ContentResolver對象
ContentResolver contentResolver = getContentResolver();
// 定義查詢的URI
Uri uri = Uri.parse("content://com.example.provider/table");
// 定義需要查詢的列
String[] projection = {"_id", "name", "email"};
// 定義選擇條件
String selection = "name = ?";
String[] selectionArgs = {"John"};
// 執(zhí)行查詢
Cursor cursor = contentResolver.query(uri, projection, selection, selectionArgs, null);
if (cursor != null) {
while (cursor.moveToNext()) {
int id = cursor.getInt(cursor.getColumnIndex("_id"));
String name = cursor.getString(cursor.getColumnIndex("name"));
String email = cursor.getString(cursor.getColumnIndex("email"));
Log.d("ContentResolver", "ID: " + id + ", Name: " + name + ", Email: " + email);
}
cursor.close();
}在這個(gè)例子中,我們指定了要查詢的列(??projection??)、選擇條件(??selection??)以及選擇條件的參數(shù)(??selectionArgs??)。最后,通過遍歷 ??Cursor?? 對象來獲取查詢結(jié)果。
2. 使用Loader進(jìn)行異步查詢
在Android中,直接在主線程上執(zhí)行耗時(shí)操作(如數(shù)據(jù)庫查詢)會(huì)導(dǎo)致UI卡頓。為了在后臺線程中執(zhí)行查詢,可以使用 ??Loader??。??Loader?? 可以自動(dòng)處理生命周期問題,并在數(shù)據(jù)變化時(shí)重新加載數(shù)據(jù)。
首先,需要?jiǎng)?chuàng)建一個(gè) ??LoaderManager?? 的實(shí)例,并實(shí)現(xiàn) ??LoaderManager.LoaderCallbacks<Cursor>?? 接口:
public class MainActivity extends AppCompatActivity implements LoaderManager.LoaderCallbacks<Cursor> {
private static final int LOADER_ID = 1;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// 初始化Loader
getSupportLoaderManager().initLoader(LOADER_ID, null, this);
}
@NonNull
@Override
public Loader<Cursor> onCreateLoader(int id, @Nullable Bundle args) {
return new CursorLoader(this,
Uri.parse("content://com.example.provider/table"),
new String[]{"_id", "name", "email"},
"name = ?",
new String[]{"John"},
null);
}
@Override
public void onLoadFinished(@NonNull Loader<Cursor> loader, Cursor data) {
if (data != null && data.moveToFirst()) {
do {
int id = data.getInt(data.getColumnIndex("_id"));
String name = data.getString(data.getColumnIndex("name"));
String email = data.getString(data.getColumnIndex("email"));
Log.d("ContentResolver", "ID: " + id + ", Name: " + name + ", Email: " + email);
} while (data.moveToNext());
}
}
@Override
public void onLoaderReset(@NonNull Loader<Cursor> loader) {
// 當(dāng)數(shù)據(jù)不再有效時(shí)調(diào)用
}
}在這個(gè)例子中,??CursorLoader?? 在后臺線程中執(zhí)行查詢,并在查詢完成后調(diào)用 ??onLoadFinished?? 方法。
3. 使用LiveData和Room進(jìn)行響應(yīng)式查詢
隨著Android架構(gòu)組件的發(fā)展,??LiveData?? 和 ??Room?? 成為了現(xiàn)代Android應(yīng)用中的常用工具。??LiveData?? 可以自動(dòng)管理生命周期,而 ??Room?? 則提供了強(qiáng)大的數(shù)據(jù)庫訪問功能。
首先,定義一個(gè) ??Dao?? 接口:
@Dao
public interface MyDao {
@Query("SELECT * FROM table WHERE name = :name")
LiveData<List<MyEntity>> loadEntitiesByName(String name);
}然后,在 ??Repository?? 中使用 ??ContentResolver?? 進(jìn)行查詢,并將結(jié)果封裝到 ??LiveData?? 中:
public class MyRepository {
private MyDao myDao;
public MyRepository(Application application) {
AppDatabase db = Room.databaseBuilder(application, AppDatabase.class, "database-name").build();
myDao = db.myDao();
}
public LiveData<List<MyEntity>> getEntitiesByName(String name) {
return myDao.loadEntitiesByName(name);
}
}最后,在 ??ViewModel?? 中暴露 ??LiveData??,并在 ??Activity?? 或 ??Fragment?? 中觀察數(shù)據(jù)變化:
public class MyViewModel extends AndroidViewModel {
private MyRepository repository;
private LiveData<List<MyEntity>> entities;
public MyViewModel(Application application) {
super(application);
repository = new MyRepository(application);
entities = repository.getEntitiesByName("John");
}
public LiveData<List<MyEntity>> getEntities() {
return entities;
}
}
public class MainActivity extends AppCompatActivity {
private MyViewModel viewModel;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
viewModel = new ViewModelProvider(this).get(MyViewModel.class);
viewModel.getEntities().observe(this, entities -> {
for (MyEntity entity : entities) {
Log.d("ContentResolver", "ID: " + entity.getId() + ", Name: " + entity.getName() + ", Email: " + entity.getEmail());
}
});
}
}這種方式不僅實(shí)現(xiàn)了異步查詢,還能夠自動(dòng)處理數(shù)據(jù)變化和生命周期管理。
4.方法補(bǔ)充
下面介紹了 ??ContentResolver??? 查詢數(shù)據(jù)的三種方式:基本查詢、使用 ??Loader??? 進(jìn)行異步查詢以及使用 ??LiveData??? 和 ??Room?? 進(jìn)行響應(yīng)式查詢。每種方式都有其適用場景,開發(fā)者可以根據(jù)實(shí)際需求選擇合適的方法在Android開發(fā)中,??ContentResolver??? 是一個(gè)非常重要的組件,它用于訪問和操作由內(nèi)容提供者(Content Provider)提供的數(shù)據(jù)。內(nèi)容提供者可以管理不同應(yīng)用之間的數(shù)據(jù)共享,如聯(lián)系人、媒體文件等。下面我將展示三種使用 ??ContentResolver?? 查詢數(shù)據(jù)的示例代碼:
1. 查詢聯(lián)系人
假設(shè)你想從設(shè)備的聯(lián)系人列表中獲取所有聯(lián)系人的姓名和電話號碼,可以使用以下代碼:
import android.content.ContentResolver;
import android.database.Cursor;
import android.net.Uri;
import android.provider.ContactsContract;
public class ContactQueryExample {
public void queryContacts(ContentResolver contentResolver) {
// 定義查詢的URI
Uri uri = ContactsContract.CommonDataKinds.Phone.CONTENT_URI;
// 定義需要查詢的列
String[] projection = new String[] {
ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME,
ContactsContract.CommonDataKinds.Phone.NUMBER
};
// 執(zhí)行查詢
Cursor cursor = contentResolver.query(uri, projection, null, null, null);
if (cursor != null && cursor.moveToFirst()) {
do {
// 獲取每一行的數(shù)據(jù)
String displayName = cursor.getString(cursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME));
String number = cursor.getString(cursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER));
// 處理數(shù)據(jù)
System.out.println("Name: " + displayName + ", Number: " + number);
} while (cursor.moveToNext());
}
if (cursor != null) {
cursor.close();
}
}
}2. 查詢媒體文件
如果你想查詢設(shè)備上的所有圖片,可以使用以下代碼:
import android.content.ContentResolver;
import android.database.Cursor;
import android.net.Uri;
import android.provider.MediaStore;
public class MediaQueryExample {
public void queryImages(ContentResolver contentResolver) {
// 定義查詢的URI
Uri uri = MediaStore.Images.Media.EXTERNAL_CONTENT_URI;
// 定義需要查詢的列
String[] projection = new String[] {
MediaStore.Images.Media._ID,
MediaStore.Images.Media.DISPLAY_NAME,
MediaStore.Images.Media.DATA
};
// 執(zhí)行查詢
Cursor cursor = contentResolver.query(uri, projection, null, null, null);
if (cursor != null && cursor.moveToFirst()) {
do {
// 獲取每一行的數(shù)據(jù)
long id = cursor.getLong(cursor.getColumnIndex(MediaStore.Images.Media._ID));
String displayName = cursor.getString(cursor.getColumnIndex(MediaStore.Images.Media.DISPLAY_NAME));
String data = cursor.getString(cursor.getColumnIndex(MediaStore.Images.Media.DATA));
// 處理數(shù)據(jù)
System.out.println("ID: " + id + ", Name: " + displayName + ", Path: " + data);
} while (cursor.moveToNext());
}
if (cursor != null) {
cursor.close();
}
}
}3. 查詢自定義內(nèi)容提供者
假設(shè)你有一個(gè)自定義的內(nèi)容提供者,用于存儲(chǔ)用戶的筆記信息,你可以這樣查詢:
import android.content.ContentResolver;
import android.database.Cursor;
import android.net.Uri;
public class CustomProviderQueryExample {
public void queryNotes(ContentResolver contentResolver) {
// 假設(shè)自定義內(nèi)容提供者的URI為 "content://com.example.notesprovider/notes"
Uri uri = Uri.parse("content://com.example.notesprovider/notes");
// 定義需要查詢的列
String[] projection = new String[] {
"_id",
"title",
"content"
};
// 執(zhí)行查詢
Cursor cursor = contentResolver.query(uri, projection, null, null, null);
if (cursor != null && cursor.moveToFirst()) {
do {
// 獲取每一行的數(shù)據(jù)
int id = cursor.getInt(cursor.getColumnIndex("_id"));
String title = cursor.getString(cursor.getColumnIndex("title"));
String content = cursor.getString(cursor.getColumnIndex("content"));
// 處理數(shù)據(jù)
System.out.println("ID: " + id + ", Title: " + title + ", Content: " + content);
} while (cursor.moveToNext());
}
if (cursor != null) {
cursor.close();
}
}
}以上三個(gè)示例展示了如何使用 ??ContentResolver?? 進(jìn)行不同類型的數(shù)據(jù)查詢。每個(gè)示例都包括了定義查詢的 URI、選擇需要的列、執(zhí)行查詢以及處理查詢結(jié)果的基本步驟。希望這些示例對你有所幫助!在Android開發(fā)中,??ContentResolver?? 是一個(gè)非常重要的類,它用于訪問和操作由內(nèi)容提供者(Content Provider)提供的數(shù)據(jù)。通過 ??ContentResolver??,應(yīng)用可以跨進(jìn)程訪問其他應(yīng)用的數(shù)據(jù),而無需直接與數(shù)據(jù)庫或其他數(shù)據(jù)存儲(chǔ)機(jī)制交互。??ContentResolver?? 提供了多種方法來查詢、插入、更新和刪除數(shù)據(jù)。
4.查詢數(shù)據(jù)的三種方式
- 基本查詢:這是最簡單的查詢方式,通常用于獲取所有記錄或特定條件下的記錄。
- 帶選擇參數(shù)的查詢:這種查詢方式允許你指定更復(fù)雜的條件來過濾結(jié)果。
- 帶排序和分頁的查詢:除了基本的篩選條件外,還可以對結(jié)果進(jìn)行排序和分頁處理。
1. 基本查詢
基本查詢通常用于獲取所有記錄或基于簡單的條件獲取記錄。以下是一個(gè)示例代碼:
// 獲取ContentResolver實(shí)例
ContentResolver contentResolver = getContentResolver();
// 定義要查詢的內(nèi)容URI
Uri uri = ContactsContract.Contacts.CONTENT_URI;
// 執(zhí)行查詢
Cursor cursor = contentResolver.query(uri, null, null, null, null);
if (cursor != null && cursor.moveToFirst()) {
do {
// 獲取聯(lián)系人ID
String id = cursor.getString(cursor.getColumnIndex(ContactsContract.Contacts._ID));
// 獲取聯(lián)系人名稱
String name = cursor.getString(cursor.getColumnIndex(ContactsContract.Contacts.DISPLAY_NAME));
// 輸出聯(lián)系人信息
Log.d("Contact", "ID: " + id + ", Name: " + name);
} while (cursor.moveToNext());
}
// 關(guān)閉Cursor
if (cursor != null) {
cursor.close();
}2. 帶選擇參數(shù)的查詢
帶選擇參數(shù)的查詢允許你指定更復(fù)雜的條件來過濾結(jié)果。例如,你可以只查詢名字包含特定字符串的聯(lián)系人。以下是一個(gè)示例代碼:
// 獲取ContentResolver實(shí)例
ContentResolver contentResolver = getContentResolver();
// 定義要查詢的內(nèi)容URI
Uri uri = ContactsContract.Contacts.CONTENT_URI;
// 定義投影(即要返回的列)
String[] projection = {ContactsContract.Contacts._ID, ContactsContract.Contacts.DISPLAY_NAME};
// 定義選擇條件
String selection = ContactsContract.Contacts.DISPLAY_NAME + " LIKE ?";
String[] selectionArgs = {"%John%"};
// 執(zhí)行查詢
Cursor cursor = contentResolver.query(uri, projection, selection, selectionArgs, null);
if (cursor != null && cursor.moveToFirst()) {
do {
// 獲取聯(lián)系人ID
String id = cursor.getString(cursor.getColumnIndex(ContactsContract.Contacts._ID));
// 獲取聯(lián)系人名稱
String name = cursor.getString(cursor.getColumnIndex(ContactsContract.Contacts.DISPLAY_NAME));
// 輸出聯(lián)系人信息
Log.d("Contact", "ID: " + id + ", Name: " + name);
} while (cursor.moveToNext());
}
// 關(guān)閉Cursor
if (cursor != null) {
cursor.close();
}3. 帶排序和分頁的查詢
帶排序和分頁的查詢不僅允許你指定篩選條件,還可以對結(jié)果進(jìn)行排序和分頁處理。這對于處理大量數(shù)據(jù)時(shí)非常有用。以下是一個(gè)示例代碼:
// 獲取ContentResolver實(shí)例
ContentResolver contentResolver = getContentResolver();
// 定義要查詢的內(nèi)容URI
Uri uri = ContactsContract.Contacts.CONTENT_URI;
// 定義投影(即要返回的列)
String[] projection = {ContactsContract.Contacts._ID, ContactsContract.Contacts.DISPLAY_NAME};
// 定義選擇條件
String selection = ContactsContract.Contacts.DISPLAY_NAME + " LIKE ?";
String[] selectionArgs = {"%John%"};
// 定義排序條件
String sortOrder = ContactsContract.Contacts.DISPLAY_NAME + " ASC";
// 定義分頁參數(shù)(從第0條記錄開始,取10條記錄)
int limit = 10;
int offset = 0;
// 構(gòu)建完整的分頁查詢
String limitClause = offset + "," + limit;
// 執(zhí)行查詢
Cursor cursor = contentResolver.query(uri, projection, selection, selectionArgs, sortOrder + " LIMIT " + limitClause);
if (cursor != null && cursor.moveToFirst()) {
do {
// 獲取聯(lián)系人ID
String id = cursor.getString(cursor.getColumnIndex(ContactsContract.Contacts._ID));
// 獲取聯(lián)系人名稱
String name = cursor.getString(cursor.getColumnIndex(ContactsContract.Contacts.DISPLAY_NAME));
// 輸出聯(lián)系人信息
Log.d("Contact", "ID: " + id + ", Name: " + name);
} while (cursor.moveToNext());
}
// 關(guān)閉Cursor
if (cursor != null) {
cursor.close();
}總結(jié)
通過 ??ContentResolver?? 的不同查詢方式,你可以靈活地獲取和處理來自內(nèi)容提供者的數(shù)據(jù)。無論是簡單的全表查詢,還是帶有復(fù)雜條件的篩選、排序和分頁,都可以通過 ??ContentResolver?? 輕松實(shí)現(xiàn)。希望這些示例代碼能幫助你在實(shí)際開發(fā)中更好地使用 ??ContentResolver??。
到此這篇關(guān)于Android中ContentResolver進(jìn)行數(shù)據(jù)查詢的三種方式的文章就介紹到這了,更多相關(guān)Android ContentResolver數(shù)據(jù)查詢內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Android中通過反射實(shí)現(xiàn)圓角ImageView代碼實(shí)例
這篇文章主要介紹了Android中通過反射實(shí)現(xiàn)圓角ImageView代碼實(shí)例,本文直接給出核心實(shí)現(xiàn)代碼,需要的朋友可以參考下2015-04-04
深入Android HandlerThread 使用及其源碼完全解析
這篇文章主要介紹了深入Android HandlerThread 使用及其源碼完全解析,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2018-08-08
Android標(biāo)題欄上添加多個(gè)Menu按鈕的實(shí)例
這篇文章主要介紹了Android標(biāo)題欄上添加多個(gè)Menu按鈕的實(shí)例的相關(guān)資料,這里提供簡單實(shí)例說明如何添加多個(gè)menu按鈕的方法,需要的朋友可以參考下2017-09-09
Android實(shí)現(xiàn)監(jiān)聽音量的變化
這篇文章主要為大家詳細(xì)介紹了Android實(shí)現(xiàn)監(jiān)聽音量的變化,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2021-05-05
android編程實(shí)現(xiàn)系統(tǒng)圖片剪裁的方法
這篇文章主要介紹了android編程實(shí)現(xiàn)系統(tǒng)圖片剪裁的方法,涉及Android針對圖片的獲取、修改、保存等操作的相關(guān)技巧,具有一定參考借鑒價(jià)值,需要的朋友可以參考下2015-11-11
Kotlin學(xué)習(xí)教程之協(xié)程Coroutine
這篇文章主要給大家介紹了關(guān)于Kotlin學(xué)習(xí)教程之協(xié)程Coroutine的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2018-05-05

