Android 系统内建的 ContentProvider

大多时候,我们使用 ContentProvider 并不是自己暴露自己的数据,而是通过 ContentResolver 来读取其它应用的信息,比如读取系统 APP,信息,联系人,多媒体信息

Android 系统内建的 ContentProvider

Android 系统提供了大量的内建 ContentProvider ,如果你想调用某个,就需要自己去查了

为什么我不一一列出?

是因为不同的版本,可能对应着不同的 URL,根本没法列

这里只提供如何获取 URL 与对应的数据库表的字段的方法

我们拿最常用的联系人为例

  1. 系统源码文件下: all-src.rar -> TeleponeProvider -> AndroidManifest.xml 查找对应 API

  2. 打开模拟器的 file exploer/data/data/com.android.providers.contacts/databases/contact2.db

  3. 导出后使用 SQLite 图形工具查看,三个核心的表: raw_contact 表 , data 表 , mimetypes

从内建的 ContentProvider 中读取数据

我们写一个 demo 从常用的 ContentProvider 中读取数据

首先创建一个 空的 Android 项目 cn.twle.android.SystemProvider

简单的读取收件箱信息

  1. 修改 MainActivity.java 读取收件箱信息

    package cn.twle.android.systemprovider;
    
    import android.content.ContentResolver;
    import android.database.Cursor;
    import android.net.Uri;
    import android.os.Bundle;
    import android.support.v7.app.AppCompatActivity;
    
    public class MainActivity extends AppCompatActivity {
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
    
            getMsgs();
        }
    
        private void getMsgs() {
            Uri uri = Uri.parse("content://sms/");
            ContentResolver resolver = getContentResolver();
            //获取的是哪些列的信息
            Cursor cursor = resolver.query(uri, new String[]{"address","date","type","body"}, null, null, null);
            while(cursor.moveToNext())
            {
                String address = cursor.getString(0);
                String date = cursor.getString(1);
                String type = cursor.getString(2);
                String body = cursor.getString(3);
                System.out.println("地址:" + address);
                System.out.println("时间:" + date);
                System.out.println("类型:" + type);
                System.out.println("内容:" + body);
                System.out.println("======================");
            }
            cursor.close();
        }
    }
    
  2. 然后修改 AndroidManifest.xml 加入读取收件箱的权限

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

运行后截图如下

往收件箱里插入一条信息

  1. 修改 MainActivity.java 往收件箱里插入一条信息

    package cn.twle.android.systemprovider;
    
    import android.content.ContentResolver;
    import android.content.ContentValues;
    import android.net.Uri;
    import android.os.Bundle;
    import android.support.v7.app.AppCompatActivity;
    import android.widget.Toast;
    
    public class MainActivity extends AppCompatActivity {
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
            insertMsg();
        }
    
        private void insertMsg() {
    
            ContentResolver resolver = getContentResolver();
            Uri uri = Uri.parse("content://sms/");
            ContentValues conValues = new ContentValues();
            conValues.put("address", "123456789");
            conValues.put("type", 1);
            conValues.put("date", System.currentTimeMillis());
            conValues.put("body", "简单教程,简单编程");
            resolver.insert(uri, conValues);
    
            Toast.makeText(MainActivity.this,"短信插入完毕~",Toast.LENGTH_LONG).show();
        }
    }
    
  2. 然后修改 AndroidManifest.xml 加入写入收件箱的权限

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

运行效果图如下


注意:

在 Android 4.4 以下都可以实现写入短信的功能,而 5.0上 有可能无法写入
从 5.0 开始,默认短信应用外的软件不能以写入短信数据库的形式发短信

读取手机联系人

  1. 修改 MainActivity.java 读取手机联系人

    package cn.twle.android.systemprovider;
    
    import android.content.ContentResolver;
    import android.database.Cursor;
    import android.net.Uri;
    import android.os.Bundle;
    import android.provider.ContactsContract;
    import android.support.v7.app.AppCompatActivity;
    
    public class MainActivity extends AppCompatActivity {
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
    
            getContacts();
        }
    
        private void getContacts(){
    
            // 1. 查询 raw_contacts 表获得联系人的 id
            ContentResolver resolver = getContentResolver();
            Uri uri = ContactsContract.CommonDataKinds.Phone.CONTENT_URI;
    
            //查询联系人数据
            Cursor cursor = resolver.query(uri, null, null, null, null);
            while(cursor.moveToNext())
            {
                //获取联系人姓名,手机号码
                String cName = cursor.getString(cursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME));
                String cNum = cursor.getString(cursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER));
                System.out.println("姓名:" + cName + " 号码:" + cNum);
            }
            cursor.close();
        }
    }
    
  2. 然后修改 AndroidManifest.xml 加入读联系人的权限

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

运行后截图如下

不用怀疑,我的确只有一个中国移动的联系人...

查询指定电话的联系人信息

  1. 修改 MainActivity.java 查询指定电话的联系人信息

    package cn.twle.android.systemprovider;
    
    import android.content.ContentResolver;
    import android.database.Cursor;
    import android.net.Uri;
    import android.os.Bundle;
    import android.support.v7.app.AppCompatActivity;
    
    public class MainActivity extends AppCompatActivity {
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
    
            // 你需要修改要查询的电话号码,因为你那里不一定保留了 中国移动
            queryContact("10086");
        }
    
        private void queryContact(String number){
                Uri uri = Uri.parse("content://com.android.contacts/data/phones/filter/" + number);
                ContentResolver resolver = getContentResolver();
                Cursor cursor = resolver.query(uri, new String[]{"display_name"}, null, null, null);
                if (cursor.moveToFirst()) {
                    String name = cursor.getString(0);
                    System.out.println(number + " 对应的联系人名称 :" + name);
                }
            cursor.close();
        }
    }
    
  2. 然后修改 AndroidManifest.xml 加入读联系人的权限

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

运行后截图如下

添加一个新的联系人

  1. 修改 activity_main.xml 添加一个按钮

    <?xml version="1.0" encoding="utf-8" ?>
    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:gravity="center_horizontal" 
        android:orientation="vertical" >
    
        <Button
            android:text="添加联系人"
            android:id="@+id/btn_add"
            android:layout_width="wrap_content" 
            android:layout_height="wrap_content" />
    
    </LinearLayout>
    
  2. 修改 MainActivity.java 添加一个新的联系人

    package cn.twle.android.systemprovider;
    
    import android.content.ContentProviderOperation;
    import android.content.ContentResolver;
    import android.content.OperationApplicationException;
    import android.net.Uri;
    import android.os.Bundle;
    import android.os.RemoteException;
    import android.support.v7.app.AppCompatActivity;
    import android.view.View;
    import android.widget.Toast;
    import android.widget.Button;
    
    import java.util.ArrayList;
    
    public class MainActivity extends AppCompatActivity {
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
    
            Button btn_add = findViewById(R.id.btn_add);
    
            btn_add.setOnClickListener(new View.OnClickListener(){
    
                @Override
                public void onClick( View view )
                {
    
                    try {
                        AddContact();
                    } catch (Exception e){}
                }
            });  
        }
    
        private void AddContact() throws RemoteException, OperationApplicationException {
    
            //使用事务添加联系人
            Uri uri = Uri.parse("content://com.android.contacts/raw_contacts");
            Uri dataUri =  Uri.parse("content://com.android.contacts/data");
    
            ContentResolver resolver = getContentResolver();
            ArrayList<ContentProviderOperation> operations = new ArrayList<ContentProviderOperation>();
            ContentProviderOperation op1 = ContentProviderOperation.newInsert(uri)
                    .withValue("account_name", null)
                    .build();
            operations.add(op1);
    
            //依次是姓名,号码,邮编
            ContentProviderOperation op2 = ContentProviderOperation.newInsert(dataUri)
                    .withValueBackReference("raw_contact_id", 0)
                    .withValue("mimetype", "vnd.android.cursor.item/name")
                    .withValue("data2", "中国联通")
                    .build();
            operations.add(op2);
    
            ContentProviderOperation op3 = ContentProviderOperation.newInsert(dataUri)
                    .withValueBackReference("raw_contact_id", 0)
                    .withValue("mimetype", "vnd.android.cursor.item/phone_v2")
                    .withValue("data1", "100010")
                    .withValue("data2", "2")
                    .build();
            operations.add(op3);
    
            ContentProviderOperation op4 = ContentProviderOperation.newInsert(dataUri)
                    .withValueBackReference("raw_contact_id", 0)
                    .withValue("mimetype", "vnd.android.cursor.item/email_v2")
                    .withValue("data1", "kf@10010.com")
                    .withValue("data2", "2")
                    .build();
            operations.add(op4);
            //将上述内容添加到手机联系人中~
            resolver.applyBatch("com.android.contacts", operations);
            Toast.makeText(getApplicationContext(), "添加成功", Toast.LENGTH_SHORT).show();
        }
    }
    
  3. 修改 AndroidManifest.xml 加入读写联系人信息权限

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

运行效果如下


参考文档

  1. Android ContentProvider

Android 基础教程

关于   |   FAQ   |   我们的愿景   |   广告投放   |  博客

  简单教程,简单编程 - IT 入门首选站

Copyright © 2013-2022 简单教程 twle.cn All Rights Reserved.