衣百惠 發表於 2025-7-3 08:22:32

Android中ContentResolver进行数据查询的三种方式

<div id="navCategory"><h5 class="catalogue">目录</h5><ul class="first_class_ul"><li>1. 基本查询</li><li>2. 使用Loader进行异步查询</li><li>3. 使用LiveData和Room进行响应式查询</li><li>4.方法补充</li><ul class="second_class_ul"><li>1. 查询联系人</li><li>2. 查询媒体文件</li><li>3. 查询自定义内容提供者</li><li>4.查询数据的三种方式</li></ul><li>总结</li><ul class="second_class_ul"></ul></ul></div><p>在Android开发中,​<code>​ContentResolver​</code>​ 是一个非常重要的组件,它用于访问和操作其他应用程序的数据。通过 ​<code>​ContentResolver​</code>​,我们可以跨应用查询、插入、更新和删除数据。本文将详细介绍 ​<code>​ContentResolver​</code>​ 查询数据的三种方式。</p>
<p class="maodian"></p><h2>1. 基本查询</h2>
<p>最基本的查询方式是使用 ​<code>​query​</code>​ 方法,该方法允许你指定要查询的内容提供者 URI、需要返回的列、选择条件等参数。以下是一个简单的例子:</p>
<div class="jb51code"><pre class="brush:java;">// 获取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"};

// 执行查询
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();
}</pre></div>
<p>在这个例子中,我们指定了要查询的列(​<code>​projection​</code>​)、选择条件(​<code>​selection​</code>​)以及选择条件的参数(​<code>​selectionArgs​</code>​)。最后,通过遍历 ​<code>​Cursor​</code>​ 对象来获取查询结果。</p>
<p class="maodian"></p><h2>2. 使用Loader进行异步查询</h2>
<p>在Android中,直接在主线程上执行耗时操作(如数据库查询)会导致UI卡顿。为了在后台线程中执行查询,可以使用 ​<code>​Loader​</code>​。​<code>​Loader​</code>​ 可以自动处理生命周期问题,并在数据变化时重新加载数据。</p>
<p>首先,需要创建一个 ​<code>​LoaderManager​</code>​ 的实例,并实现 ​<code>​LoaderManager.LoaderCallbacks&lt;Cursor&gt;​</code>​ 接口:</p>
<div class="jb51code"><pre class="brush:java;">public class MainActivity extends AppCompatActivity implements LoaderManager.LoaderCallbacks&lt;Cursor&gt; {

    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&lt;Cursor&gt; 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&lt;Cursor&gt; loader, Cursor data) {
      if (data != null &amp;&amp; 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&lt;Cursor&gt; loader) {
      // 当数据不再有效时调用
    }
}</pre></div>
<p>在这个例子中,​<code>​CursorLoader​</code>​ 在后台线程中执行查询,并在查询完成后调用 ​<code>​onLoadFinished​</code>​ 方法。</p>
<p class="maodian"></p><h2>3. 使用LiveData和Room进行响应式查询</h2>
<p>随着Android架构组件的发展,​<code>​LiveData​</code>​ 和 ​<code>​Room​</code>​ 成为了现代Android应用中的常用工具。​<code>​LiveData​</code>​ 可以自动管理生命周期,而 ​<code>​Room​</code>​ 则提供了强大的数据库访问功能。</p>
<p>首先,定义一个 ​<code>​Dao​</code>​ 接口:</p>
<div class="jb51code"><pre class="brush:java;">@Dao
public interface MyDao {
    @Query("SELECT * FROM table WHERE name = :name")
    LiveData&lt;List&lt;MyEntity&gt;&gt; loadEntitiesByName(String name);
}</pre></div>
<p>然后,在 ​<code>​Repository​</code>​ 中使用 ​<code>​ContentResolver​</code>​ 进行查询,并将结果封装到 ​<code>​LiveData​</code>​ 中:</p>
<div class="jb51code"><pre class="brush:java;">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&lt;List&lt;MyEntity&gt;&gt; getEntitiesByName(String name) {
      return myDao.loadEntitiesByName(name);
    }
}</pre></div>
<p>最后,在 ​<code>​ViewModel​</code>​ 中暴露 ​<code>​LiveData​</code>​,并在 ​<code>​Activity​</code>​ 或 ​<code>​Fragment​</code>​ 中观察数据变化:</p>
<div class="jb51code"><pre class="brush:java;">public class MyViewModel extends AndroidViewModel {
    private MyRepository repository;
    private LiveData&lt;List&lt;MyEntity&gt;&gt; entities;

    public MyViewModel(Application application) {
      super(application);
      repository = new MyRepository(application);
      entities = repository.getEntitiesByName("John");
    }

    public LiveData&lt;List&lt;MyEntity&gt;&gt; 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 -&gt; {
            for (MyEntity entity : entities) {
                Log.d("ContentResolver", "ID: " + entity.getId() + ", Name: " + entity.getName() + ", Email: " + entity.getEmail());
            }
      });
    }
}</pre></div>
<p>这种方式不仅实现了异步查询,还能够自动处理数据变化和生命周期管理。</p>
<p class="maodian"></p><h2>4.方法补充</h2>
<p>下面介绍了 ​<code>​ContentResolver​</code>​​ 查询数据的三种方式:基本查询、使用 ​<code>​Loader​</code>​​ 进行异步查询以及使用 ​<code>​LiveData​</code>​​ 和 ​<code>​Room​</code>​ 进行响应式查询。每种方式都有其适用场景,开发者可以根据实际需求选择合适的方法在Android开发中,​<code>​ContentResolver​</code>​​ 是一个非常重要的组件,它用于访问和操作由内容提供者(Content Provider)提供的数据。内容提供者可以管理不同应用之间的数据共享,如联系人、媒体文件等。下面我将展示三种使用 ​<code>​ContentResolver​</code>​ 查询数据的示例代码:</p>
<p class="maodian"></p><h3>1. 查询联系人</h3>
<p>假设你想从设备的联系人列表中获取所有联系人的姓名和电话号码,可以使用以下代码:</p>
<div class="jb51code"><pre class="brush:java;">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
      };
      // 执行查询
      Cursor cursor = contentResolver.query(uri, projection, null, null, null);
      
      if (cursor != null &amp;&amp; cursor.moveToFirst()) {
            do {
                // 获取每一行的数据
                String displayName = cursor.getString(cursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME));
                String number = cursor.getString(cursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER));
                // 处理数据
                System.out.println("Name: " + displayName + ", Number: " + number);
            } while (cursor.moveToNext());
      }
      if (cursor != null) {
            cursor.close();
      }
    }
}</pre></div>
<p class="maodian"></p><h3>2. 查询媒体文件</h3>
<p>如果你想查询设备上的所有图片,可以使用以下代码:</p>
<div class="jb51code"><pre class="brush:java;">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
      };
      // 执行查询
      Cursor cursor = contentResolver.query(uri, projection, null, null, null);
      
      if (cursor != null &amp;&amp; cursor.moveToFirst()) {
            do {
                // 获取每一行的数据
                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));
                // 处理数据
                System.out.println("ID: " + id + ", Name: " + displayName + ", Path: " + data);
            } while (cursor.moveToNext());
      }
      if (cursor != null) {
            cursor.close();
      }
    }
}</pre></div>
<p class="maodian"></p><h3>3. 查询自定义内容提供者</h3>
<p>假设你有一个自定义的内容提供者,用于存储用户的笔记信息,你可以这样查询:</p>
<div class="jb51code"><pre class="brush:java;">import android.content.ContentResolver;
import android.database.Cursor;
import android.net.Uri;

public class CustomProviderQueryExample {
    public void queryNotes(ContentResolver contentResolver) {
      // 假设自定义内容提供者的URI为 "content://com.example.notesprovider/notes"
      Uri uri = Uri.parse("content://com.example.notesprovider/notes");
      // 定义需要查询的列
      String[] projection = new String[] {
            "_id",
            "title",
            "content"
      };
      // 执行查询
      Cursor cursor = contentResolver.query(uri, projection, null, null, null);
      
      if (cursor != null &amp;&amp; cursor.moveToFirst()) {
            do {
                // 获取每一行的数据
                int id = cursor.getInt(cursor.getColumnIndex("_id"));
                String title = cursor.getString(cursor.getColumnIndex("title"));
                String content = cursor.getString(cursor.getColumnIndex("content"));
                // 处理数据
                System.out.println("ID: " + id + ", Title: " + title + ", Content: " + content);
            } while (cursor.moveToNext());
      }
      if (cursor != null) {
            cursor.close();
      }
    }
}</pre></div>
<p>以上三个示例展示了如何使用 ​<code>​ContentResolver​</code>​ 进行不同类型的数据查询。每个示例都包括了定义查询的 URI、选择需要的列、执行查询以及处理查询结果的基本步骤。希望这些示例对你有所帮助!在Android开发中,​<code>​ContentResolver​</code>​ 是一个非常重要的类,它用于访问和操作由内容提供者(Content Provider)提供的数据。通过 ​<code>​ContentResolver​</code>​,应用可以跨进程访问其他应用的数据,而无需直接与数据库或其他数据存储机制交互。​<code>​ContentResolver​</code>​ 提供了多种方法来查询、插入、更新和删除数据。</p>
<p class="maodian"></p><h3>4.查询数据的三种方式</h3>
<ul><li><strong>基本查询</strong>:这是最简单的查询方式,通常用于获取所有记录或特定条件下的记录。</li><li><strong>带选择参数的查询</strong>:这种查询方式允许你指定更复杂的条件来过滤结果。</li><li><strong>带排序和分页的查询</strong>:除了基本的筛选条件外,还可以对结果进行排序和分页处理。</li></ul>
<p><strong>1. 基本查询</strong></p>
<p>基本查询通常用于获取所有记录或基于简单的条件获取记录。以下是一个示例代码:</p>
<div class="jb51code"><pre class="brush:java;">// 获取ContentResolver实例
ContentResolver contentResolver = getContentResolver();

// 定义要查询的内容URI
Uri uri = ContactsContract.Contacts.CONTENT_URI;

// 执行查询
Cursor cursor = contentResolver.query(uri, null, null, null, null);

if (cursor != null &amp;&amp; cursor.moveToFirst()) {
    do {
      // 获取联系人ID
      String id = cursor.getString(cursor.getColumnIndex(ContactsContract.Contacts._ID));
      // 获取联系人名称
      String name = cursor.getString(cursor.getColumnIndex(ContactsContract.Contacts.DISPLAY_NAME));
      // 输出联系人信息
      Log.d("Contact", "ID: " + id + ", Name: " + name);
    } while (cursor.moveToNext());
}

// 关闭Cursor
if (cursor != null) {
    cursor.close();
}</pre></div>
<p><strong>2. 带选择参数的查询</strong></p>
<p>带选择参数的查询允许你指定更复杂的条件来过滤结果。例如,你可以只查询名字包含特定字符串的联系人。以下是一个示例代码:</p>
<div class="jb51code"><pre class="brush:java;">// 获取ContentResolver实例
ContentResolver contentResolver = getContentResolver();

// 定义要查询的内容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%"};

// 执行查询
Cursor cursor = contentResolver.query(uri, projection, selection, selectionArgs, null);

if (cursor != null &amp;&amp; cursor.moveToFirst()) {
    do {
      // 获取联系人ID
      String id = cursor.getString(cursor.getColumnIndex(ContactsContract.Contacts._ID));
      // 获取联系人名称
      String name = cursor.getString(cursor.getColumnIndex(ContactsContract.Contacts.DISPLAY_NAME));
      // 输出联系人信息
      Log.d("Contact", "ID: " + id + ", Name: " + name);
    } while (cursor.moveToNext());
}

// 关闭Cursor
if (cursor != null) {
    cursor.close();
}</pre></div>
<p><strong>3. 带排序和分页的查询</strong></p>
<p>带排序和分页的查询不仅允许你指定筛选条件,还可以对结果进行排序和分页处理。这对于处理大量数据时非常有用。以下是一个示例代码:</p>
<div class="jb51code"><pre class="brush:java;">// 获取ContentResolver实例
ContentResolver contentResolver = getContentResolver();

// 定义要查询的内容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";

// 定义分页参数(从第0条记录开始,取10条记录)
int limit = 10;
int offset = 0;

// 构建完整的分页查询
String limitClause = offset + "," + limit;

// 执行查询
Cursor cursor = contentResolver.query(uri, projection, selection, selectionArgs, sortOrder + " LIMIT " + limitClause);

if (cursor != null &amp;&amp; cursor.moveToFirst()) {
    do {
      // 获取联系人ID
      String id = cursor.getString(cursor.getColumnIndex(ContactsContract.Contacts._ID));
      // 获取联系人名称
      String name = cursor.getString(cursor.getColumnIndex(ContactsContract.Contacts.DISPLAY_NAME));
      // 输出联系人信息
      Log.d("Contact", "ID: " + id + ", Name: " + name);
    } while (cursor.moveToNext());
}

// 关闭Cursor
if (cursor != null) {
    cursor.close();
}</pre></div>
<p class="maodian"></p><h2>总结</h2>
<p>通过 ​<code>​ContentResolver​</code>​ 的不同查询方式,你可以灵活地获取和处理来自内容提供者的数据。无论是简单的全表查询,还是带有复杂条件的筛选、排序和分页,都可以通过 ​<code>​ContentResolver​</code>​ 轻松实现。希望这些示例代码能帮助你在实际开发中更好地使用 ​<code>​ContentResolver​</code>​。</p>
<p>到此这篇关于Android中ContentResolver进行数据查询的三种方式的文章就介绍到这了,更多相关Android ContentResolver数据查询内容请搜索琼殿技术社区以前的文章或继续浏览下面的相关文章希望大家以后多多支持琼殿技术社区!</p>
                           
                            <div class="art_xg">
                              <b>您可能感兴趣的文章:</b><ul><li>android ContentResolver获取手机电话号码和短信内容</li><li>Android中ContentProvider和ContentResolver详解</li><li>android利用ContentResolver访问者获取手机联系人信息</li><li>android利用ContentResolver访问者获取手机短信信息</li><li>Android使用ContentResolver搜索手机通讯录的方法</li><li>android之ContentResolver与ContentProvider介绍</li><li>Android ContentResolver使用说明</li></ul>
                            </div>

                        </div>
                        <!--endmain-->
頁: [1]
查看完整版本: Android中ContentResolver进行数据查询的三种方式