安卓学习笔记36:内容提供者

文章目录

  • 一、内容提供者
    • (一)概述
    • (二)作用
  • 二、案例演示 - 显示系统联系人
    • (一)运行效果
    • (二)涉及知识点
    • (三)实现步骤
      • 1、创建安卓应用【DisplayContacts】
      • 2、将背景图片拷贝到drawable目录
      • 3、主布局资源文件activity_main.xml
      • 4、创建联系人列表项模板contact_list_item.xml
      • 5、主界面类 - MainActivity
      • 6、在项目清单文件里授权读写联系人
      • 7、启动应用,查看效果

零、学习目标

  1. 会利用内容提供者获取与操作系统数据
  2. 能创建、注册并使用自定义内容提供者

一、内容提供者

(一)概述

安卓核心组件内容提供者(Content Provider)提供了对外部数据进行增、删、改、查的功能。实际上,它就相当于跨应用的数据操作,也可以看作是操作数据库的代理。

(二)作用

Content Provider相当于数据的接口,通过它可以将程序内部使用的数据向其它程序公开,这样其它程序就可以通过Context.getContentResolver方法获得ContentResolver对象,并使用该对象提供的insert、delete、update、query方法对程序内部的数据进行增、删、改、查操作。

  1. 通过它可以使外部程序访问私有数据,有点类似实体类利用getter与setter方法来访问私有属性。
  2. 隐藏了内部数据库的复杂结构,只需通过insert、delete、update、query四个方法来操作即可。
  3. 它作为应用程序与操作系统之间的一层,可以有效地控制应用程序的访问权限。

二、案例演示 - 显示系统联系人

(一)运行效果

安卓学习笔记36:内容提供者_第1张图片
安卓学习笔记36:内容提供者_第2张图片

(二)涉及知识点

  1. 线性布局(LinearLayout)
  2. 列表控件(ListView)
  3. 游标(Cursor)
  4. 简单游标适配器(SimpleCursorAdapter)
  5. 内容提供者(ContentProvider)
  6. 内容解析者(ContentResolver)
  7. 系统联系人数据库(contacts2.db)
  • 打开手机联系人,添加五个联系人(姓名、电话、邮箱)
    安卓学习笔记36:内容提供者_第3张图片
  • 在DDMS里查看系统联系人数据库 - data\data\com.android.providers.contacts\databases\contacts2.db
    安卓学习笔记36:内容提供者_第4张图片
  • 将contacts.db数据拉到电脑上,然后利用NaviCat打开它
    安卓学习笔记36:内容提供者_第5张图片
  • 单击【确定】,关注三张表:data、contacts、raw_contacts
    安卓学习笔记36:内容提供者_第6张图片

(三)实现步骤

1、创建安卓应用【DisplayContacts】

安卓学习笔记36:内容提供者_第7张图片
安卓学习笔记36:内容提供者_第8张图片

2、将背景图片拷贝到drawable目录

安卓学习笔记36:内容提供者_第9张图片

3、主布局资源文件activity_main.xml

安卓学习笔记36:内容提供者_第10张图片


<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:android1="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="@drawable/background"
    android:orientation="vertical">

    <ListView
        android:id="@+id/lvContact"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"/>
LinearLayout>

4、创建联系人列表项模板contact_list_item.xml

安卓学习笔记36:内容提供者_第11张图片


<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    android:padding="10dp" >

    <TextView
        android:id="@+id/tvContactName"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:textColor="#0000ff"
        android:textSize="20sp" />

    <TextView
        android:id="@+id/tvContactPhone"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginLeft="15dp"
        android:textColor="#555555"
        android:textSize="15sp" />
LinearLayout>

5、主界面类 - MainActivity

安卓学习笔记36:内容提供者_第12张图片

  • 声明变量
    安卓学习笔记36:内容提供者_第13张图片
  • 通过资源标识符获取控件实例
    安卓学习笔记36:内容提供者_第14张图片
  • 删除全部联系人
    安卓学习笔记36:内容提供者_第15张图片
  • 添加若干联系人
    安卓学习笔记36:内容提供者_第16张图片
  • 通过内容解析者获取联系人游标
    安卓学习笔记36:内容提供者_第17张图片
  • 创建简单游标适配器
    安卓学习笔记36:内容提供者_第18张图片
  • 给列表控件设置适配器
    安卓学习笔记36:内容提供者_第19张图片
  • 查看主界面类完整源代码
package net.hw.display_contacts;

import android.content.ContentResolver;
import android.content.ContentUris;
import android.content.ContentValues;
import android.database.Cursor;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.provider.ContactsContract;
import android.widget.ListView;
import android.widget.SimpleCursorAdapter;

import androidx.annotation.RequiresApi;
import androidx.appcompat.app.AppCompatActivity;

public class MainActivity extends AppCompatActivity {
     

    private ListView lvContact; // 联系人列表控件
    private SimpleCursorAdapter adapter; // 简单游标适配器
    private Cursor cursor; // 游标
    final private int REQUEST_CODE_ASK_PERMISSIONS = 123;

    @RequiresApi(api = Build.VERSION_CODES.M)
    @Override
    protected void onCreate(Bundle savedInstanceState) {
     
        super.onCreate(savedInstanceState);
        // 利用布局资源文件设置用户界面
        setContentView(R.layout.activity_main);

        // 通过资源标识符获取控件实例
        lvContact = findViewById(R.id.lvContact);

        // 删除全部联系人
        deleteAllContacts();

        // 添加若干联系人
        addContact("李红玉", "15890903456", "[email protected]");
        addContact("石破天", "13945667788", "[email protected]");
        addContact("费玉清", "15867788965", "[email protected]");
        addContact("郑智化", "15823232324", "[email protected]");
        addContact("张曼玉", "13990903678", "[email protected]");
        addContact("林青霞", "18590903242", "[email protected]");
        addContact("钟楚红", "15994543543", "[email protected]");

        // 通过内容解析者获取联系人游标
        cursor = getContentResolver().query(ContactsContract.CommonDataKinds.Phone.CONTENT_URI,
                null, null, null, null);

        // 创建简单游标适配器
        adapter = new SimpleCursorAdapter(this, R.layout.contact_list_item, cursor,
                new String[]{
     ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME,
                        ContactsContract.CommonDataKinds.Phone.NUMBER},
                new int[]{
     R.id.tvContactName, R.id.tvContactPhone},
                SimpleCursorAdapter.FLAG_REGISTER_CONTENT_OBSERVER);

        // 给列表控件设置适配器
        lvContact.setAdapter(adapter);
    }

    /**
     * 添加联系人
     *
     * @param name
     * @param phone
     * @param email
     */
    private void addContact(String name, String phone, String email) {
     
        // 获取内容解析者
        ContentResolver resolver = getContentResolver();

        // 获取raw_contacts表的uri
        Uri rawContactsUri = Uri.parse("content://com.android.contacts/raw_contacts");
        // 创建内容值对象
        ContentValues values = new ContentValues();
        // 往raw_contacts插入一条新记录,然后解析出它的id
        long id = ContentUris.parseId(resolver.insert(rawContactsUri, values));

        // 获取data表的uri
        Uri dataUri = Uri.parse("content://com.android.contacts/data");

        // 添加联系人姓名
        values.put("raw_contact_id", id);
        values.put("data2", name);
        values.put("mimetype", "vnd.android.cursor.item/name");
        resolver.insert(dataUri, values);

        // 添加联系人电话
        values.clear(); // 清空上一次的数据
        values.put("raw_contact_id", id);
        values.put("data1", phone);
        values.put("data2", "2");
        values.put("mimetype", "vnd.android.cursor.item/phone_v2");
        resolver.insert(dataUri, values);

        // 添加联系人邮箱
        values.clear(); // 清空上一次的数据
        values.put("raw_contact_id", id);
        values.put("data1", email);
        values.put("data2", "1");
        values.put("mimetype", "vnd.android.cursor.item/email_v2");
        resolver.insert(dataUri, values);
    }


    /**
     * 删除所有联系人
     */
    private void deleteAllContacts() {
     
        Uri uri = Uri.parse("content://com.android.contacts/raw_contacts");
        getContentResolver().delete(uri, null, null);

        uri = Uri.parse("content://com.android.contacts/data");
        getContentResolver().delete(uri, null, null);

        uri = Uri.parse("content://com.android.contacts/contacts");
        getContentResolver().delete(uri, null, null);
    }
}

6、在项目清单文件里授权读写联系人

安卓学习笔记36:内容提供者_第20张图片

7、启动应用,查看效果

安卓学习笔记36:内容提供者_第21张图片
安卓学习笔记36:内容提供者_第22张图片

  • 在Android 7.0模拟器上运行,虽然在项目清单文件里授权了读写联系人,但是依然报错。
  • 添加检查通讯录读写权限检查
    安卓学习笔记36:内容提供者_第23张图片
  • 重启应用,查看效果
    安卓学习笔记36:内容提供者_第24张图片
    安卓学习笔记36:内容提供者_第25张图片

你可能感兴趣的:(安卓应用开发)