zoukankan      html  css  js  c++  java
  • 利用内容观察者操作系统的联系人(查询,加入)

    系统联系人的源代码包位于/data/data/com.android.providers.contacts文件夹下,导出contacts2,db。用SQLLite查看数据库结构:

    raw_contacts表:保存联系人的引用,当中contact_id存放联系人的id

    data表:联系人信息的详细数据

                    raw_contact_id与raw_contacts表中的contact_id相相应

                    data1表示联系人的详细数据信息,

                   mimetype_id表示详细的类型,与mimetypes表的id相应

    mimetypes表:数据的详细类型。

    所以联系人的信息要存放在数据库。须要使用三张表。

    获取联系人信息步骤:

    1、查询raw_contacts表,获取联系人的id

    2、依据id查询data表,得到联系人的详细数据

    3、依据数据类型,到mimetypes表中查询数据代表的是什么

    因为google在实现内容提供者时。对data和mimetypes表实现了关联查询,相应的ContactsProvider2.java中处理关联的源码为:

     第624行:sDataProjectionMap.put(Data.MIMETYPE, Data.MIMETYPE);

    所以查询操作仅仅有两步:

    处理代码为:

    public class MainActivity extends Activity {
    
    	@Override
    	protected void onCreate(Bundle savedInstanceState) {
    		super.onCreate(savedInstanceState);
    		setContentView(R.layout.fragment_main);
    //		queryContact();
    		insertContact();
    	}
    	private void insertContact() {
    		//1、向raw_contact表中加入一条id,获取此表中最大的id值进行加1
    		Uri uri=Uri.parse("content://com.android.contacts/raw_contacts");
    		Uri datauri=Uri.parse("content://com.android.contacts/data");
    		Cursor cursor=getContentResolver().query(uri, new String[]{"contact_id"}, null, null, null);
    		int id=1;
    		if(cursor.moveToLast()){
    			id=cursor.getInt(0);
    		}
    		int newid=id+1;
    		ContentValues values= new ContentValues();
    		values.put("contact_id", newid);
    		getContentResolver().insert(uri, values);
    		//2、向data表中插入数据
    		ContentValues nameValue=new ContentValues();
    		nameValue.put("raw_contact_id", newid);
    		nameValue.put("mimetype", "vnd.android.cursor.item/name");
    		nameValue.put("data1", "lili");
    		getContentResolver().insert(datauri, nameValue);
    		
    		ContentValues emailValue=new ContentValues();
    		emailValue.put("raw_contact_id", newid);
    		emailValue.put("mimetype", "vnd.android.cursor.item/email_v2");
    		emailValue.put("data1", "aa@163.com");
    		getContentResolver().insert(datauri, emailValue);
    		
    		ContentValues phoneValue=new ContentValues();
    		phoneValue.put("raw_contact_id", newid);
    		phoneValue.put("mimetype", "vnd.android.cursor.item/phone_v2");
    		phoneValue.put("data1", "18623567655");
    		getContentResolver().insert(datauri, phoneValue);
    	}
    
    	private void queryContact() {
    		//查询raw_contacts表【是操作另外应用程序的数据库。须要用到内容提供者,到系统源码中查找ContactsProvider清单文件,获得Uri】
    		//【查找ContactsProvider2.java知道系统源码数据库的表名怎样定义】
    		Uri uri=Uri.parse("content://com.android.contacts/raw_contacts");
    		//data表相应的uri
    		Uri datauri=Uri.parse("content://com.android.contacts/data");
    		//此处仅仅关心从raw_contacts表中获取联系人id
    		Cursor cursor=getContentResolver().query(uri, new String[]{"contact_id"}, null, null, null);
    	    while(cursor.moveToNext()){
    	    	String id=cursor.getString(0);
    	    	//依据获得的联系人id查询data表里的内容
    	    	Cursor dataCursor=getContentResolver().query(datauri, new String[]{"data1","mimetype"}, "raw_contact_id=?", new String[]{id}, null);
    	    	while(dataCursor.moveToNext()){
    	    		System.out.println(dataCursor.getString(0)+"  :     "+dataCursor.getString(1));
    	    	}
    	    	dataCursor.close();
    	    	System.out.println("=======================");
    	    }
    	    cursor.close();
    	}
    }

    附加:ContactsProvider项目清单文件内容能够查看URI和利用该内容提供者必须设置的权限:

            <provider android:name="ContactsProvider2"
                android:authorities="contacts;com.android.contacts"
                android:label="@string/provider_label"
                android:multiprocess="false"
                android:readPermission="android.permission.READ_CONTACTS"
                android:writePermission="android.permission.WRITE_CONTACTS">
                <path-permission
                        android:pathPrefix="/search_suggest_query"
                        android:readPermission="android.permission.GLOBAL_SEARCH" />
                <path-permission
                        android:pathPrefix="/search_suggest_shortcut"
                        android:readPermission="android.permission.GLOBAL_SEARCH" />
                <path-permission
                        android:pathPattern="/contacts/.*/photo"
                        android:readPermission="android.permission.GLOBAL_SEARCH" />
                <grant-uri-permission android:pathPattern=".*" />
            </provider>


    ContactsProvider2.java中数据库表名的定义:

    static {
            // Contacts URI matching table
            final UriMatcher matcher = sUriMatcher;
            matcher.addURI(ContactsContract.AUTHORITY, "contacts", CONTACTS);
            matcher.addURI(ContactsContract.AUTHORITY, "contacts/#", CONTACTS_ID);
            matcher.addURI(ContactsContract.AUTHORITY, "contacts/#/data", CONTACTS_DATA);
            matcher.addURI(ContactsContract.AUTHORITY, "contacts/#/suggestions",
                    AGGREGATION_SUGGESTIONS);
            matcher.addURI(ContactsContract.AUTHORITY, "contacts/#/suggestions/*",
                    AGGREGATION_SUGGESTIONS);
            matcher.addURI(ContactsContract.AUTHORITY, "contacts/#/photo", CONTACTS_PHOTO);
            matcher.addURI(ContactsContract.AUTHORITY, "contacts/filter/*", CONTACTS_FILTER);
            matcher.addURI(ContactsContract.AUTHORITY, "contacts/lookup/*", CONTACTS_LOOKUP);
            matcher.addURI(ContactsContract.AUTHORITY, "contacts/lookup/*/#", CONTACTS_LOOKUP_ID);
            matcher.addURI(ContactsContract.AUTHORITY, "contacts/as_vcard/*", CONTACTS_AS_VCARD);
            matcher.addURI(ContactsContract.AUTHORITY, "contacts/as_multi_vcard/*",
                    CONTACTS_AS_MULTI_VCARD);
            matcher.addURI(ContactsContract.AUTHORITY, "contacts/strequent/", CONTACTS_STREQUENT);
            matcher.addURI(ContactsContract.AUTHORITY, "contacts/strequent/filter/*",
                    CONTACTS_STREQUENT_FILTER);
            matcher.addURI(ContactsContract.AUTHORITY, "contacts/group/*", CONTACTS_GROUP);
    
            matcher.addURI(ContactsContract.AUTHORITY, "raw_contacts", RAW_CONTACTS);
            matcher.addURI(ContactsContract.AUTHORITY, "raw_contacts/#", RAW_CONTACTS_ID);
            matcher.addURI(ContactsContract.AUTHORITY, "raw_contacts/#/data", RAW_CONTACTS_DATA);
            matcher.addURI(ContactsContract.AUTHORITY, "raw_contacts/#/entity", RAW_CONTACT_ENTITY_ID);
    
            matcher.addURI(ContactsContract.AUTHORITY, "raw_contact_entities", RAW_CONTACT_ENTITIES);
    
            matcher.addURI(ContactsContract.AUTHORITY, "data", DATA);
            matcher.addURI(ContactsContract.AUTHORITY, "data/#", DATA_ID);
            matcher.addURI(ContactsContract.AUTHORITY, "data/phones", PHONES);
            matcher.addURI(ContactsContract.AUTHORITY, "data/phones/#", PHONES_ID);
            matcher.addURI(ContactsContract.AUTHORITY, "data/phones/filter", PHONES_FILTER);
            matcher.addURI(ContactsContract.AUTHORITY, "data/phones/filter/*", PHONES_FILTER);
            matcher.addURI(ContactsContract.AUTHORITY, "data/emails", EMAILS);
            matcher.addURI(ContactsContract.AUTHORITY, "data/emails/#", EMAILS_ID);
            matcher.addURI(ContactsContract.AUTHORITY, "data/emails/lookup/*", EMAILS_LOOKUP);
            matcher.addURI(ContactsContract.AUTHORITY, "data/emails/filter", EMAILS_FILTER);
            matcher.addURI(ContactsContract.AUTHORITY, "data/emails/filter/*", EMAILS_FILTER);
            matcher.addURI(ContactsContract.AUTHORITY, "data/postals", POSTALS);
            matcher.addURI(ContactsContract.AUTHORITY, "data/postals/#", POSTALS_ID);
    
            matcher.addURI(ContactsContract.AUTHORITY, "groups", GROUPS);
            matcher.addURI(ContactsContract.AUTHORITY, "groups/#", GROUPS_ID);
            matcher.addURI(ContactsContract.AUTHORITY, "groups_summary", GROUPS_SUMMARY);
    }


    
    
    
       
    
  • 相关阅读:
    [三]JavaIO之IO体系类整体设计思路 流的概念以及四大基础分类
    [二] JavaIO之File详解 以及FileSystem WinNTFileSystem简介
    [一]FileDescriptor文件描述符 标准输入输出错误 文件描述符
    [零] JavaIO入门简介 程序设计语言 为什么需要IO库
    装饰器模式 Decorator 结构型 设计模式 (十)
    适配器模式 adapter 结构型 设计模式(九)
    layui 鼠标悬停单元格显示全部
    mysql 日期总结
    区域块路由与全局路由兼容,双重路由
    JS-SDK相关参考
  • 原文地址:https://www.cnblogs.com/gcczhongduan/p/5140544.html
Copyright © 2011-2022 走看看