1. 程式人生 > >Android-插入/查詢聯絡人/簡訊收到提醒(內容觀察者)

Android-插入/查詢聯絡人/簡訊收到提醒(內容觀察者)

聯絡人資料庫

  • raw_contacts表:
    • contact_id:聯絡人id
  • data表:聯絡人的具體資訊,一個資訊佔一行
    • data1:資訊的具體內容
    • raw_contact_id:聯絡人id,描述資訊屬於哪個聯絡人
    • mimetype_id:描述資訊是屬於什麼型別
  • mimetypes表:通過mimetype_id到該表檢視具體型別

讀取聯絡人

  • 先查詢raw_contacts表拿到聯絡人id

    Cursor cursor = cr.query(Uri.parse("content://com.android.contacts/raw_contacts"), new String[]{"contact_id"}, null, null, null);
    
  • 然後拿著聯絡人id去data表查詢屬於該聯絡人的資訊

    Cursor c = cr.query(Uri.parse("content://com.android.contacts/data"), new String[]{"data1", "mimetype"}, "raw_contact_id = ?", new String[]{contactId}, null);
    
  • 得到data1欄位的值,就是聯絡人的資訊,通過mimetype判斷是什麼型別的資訊

    while(c.moveToNext()){
        String data1 = c.getString(0);
        String mimetype = c.getString(1);
        if("vnd.android.cursor.item/email_v2".equals(mimetype)){
            contact.setEmail(data1);
        }
        else if("vnd.android.cursor.item/name".equals(mimetype)){
            contact.setName(data1);
        }
        else if("vnd.android.cursor.item/phone_v2".equals(mimetype)){
            contact.setPhone(data1);
        }
    }
    

插入聯絡人

  • 先查詢raw_contacts表,確定新的聯絡人的id應該是多少
  • 把確定的聯絡人id插入raw_contacts表

    cv.put("contact_id", _id);
    cr.insert(Uri.parse("content://com.android.contacts/raw_contacts"), cv);
    
  • 在data表插入資料

    • 插3個欄位:data1、mimetype、raw_contact_id

      cv = new ContentValues();
      cv.put("data1", "趙六");
      cv.put("mimetype", "vnd.android.cursor.item/name");
      cv.put("raw_contact_id", _id);
      cr.insert(Uri.parse("content://com.android.contacts/data"), cv);
      
      cv = new ContentValues();
      cv.put("data1", "1596874");
      cv.put("mimetype", "vnd.android.cursor.item/phone_v2");
      cv.put("raw_contact_id", _id);
      cr.insert(Uri.parse("content://com.android.contacts/data"), cv);
      

內容觀察者

  • 當資料庫資料改變時,內容提供者會發出通知,在內容提供者的uri上註冊一個內容觀察者,就可以收到資料改變的通知

    cr.registerContentObserver(Uri.parse("content://sms"), true, new MyObserver(new Handler()));
    
    class MyObserver extends ContentObserver{
    
        public MyObserver(Handler handler) {
            super(handler);
            // TODO Auto-generated constructor stub
        }
    
        //內容觀察者收到資料庫發生改變的通知時,會呼叫此方法
        @Override
        public void onChange(boolean selfChange) {
    
        }
    
    }
    
  • 在內容提供者中發通知的程式碼

    ContentResolver cr = getContext().getContentResolver();
    //發出通知,所有註冊在這個uri上的內容觀察者都可以收到通知
    cr.notifyChange(uri, null);

許可權:

<span style="font-family:KaiTi_GB2312;font-size:18px;">    <uses-permission android:name="android.permission.WRITE_CONTACTS" />
    <uses-permission android:name="android.permission.READ_CONTACTS" /></span>
佈局程式碼:
<span style="font-family:KaiTi_GB2312;font-size:18px;"><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:orientation="vertical"
    android:paddingTop="@dimen/activity_vertical_margin"
    android:gravity="center"
    tools:context=".MainActivity">

    <Button
        android:onClick="click1"
        android:text="插入聯絡人"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" />
    <Button
        android:text="查詢聯絡人"
        android:onClick="click2"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" />

</LinearLayout>
</span>


MainActivity.java
<span style="font-family:KaiTi_GB2312;font-size:18px;">package com.example.yu_longji.android15;

import android.app.Activity;
import android.content.ContentResolver;
import android.content.ContentValues;
import android.database.ContentObserver;
import android.database.Cursor;
import android.net.Uri;
import android.os.Bundle;
import android.os.Handler;
import android.view.View;
import android.widget.Toast;

public class MainActivity extends Activity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        //註冊一個內容觀察者,監聽簡訊資料庫內容的改變
        ContentResolver cr = getContentResolver();
        //uri:監聽哪個uri上的內容提供者的通知
        //notifyForDescendents:如果是true,那麼只要以content://sms開頭的uri的資料改變,都能收到通知,比如content://sms/inbox
        cr.registerContentObserver(Uri.parse("content://sms"), true, new MyObserver(new Handler()));
    }

    //插入聯絡人
    public void click1(View view) {
        ContentResolver cr = getContentResolver();
        //先查詢raw_contacts表,獲取最新聯絡人的主鍵,然後主鍵+1,就是要插入的聯絡人的id
        Cursor cursorContactId = cr.query(Uri.parse("content://com.android.contacts/raw_contacts"), new String[]{"_id"}, null, null, null);
        //預設聯絡人id就是1
        int contact_id = 1;
        if (cursorContactId.moveToLast()) {
            //拿到主鍵
            int _id = cursorContactId.getInt(0);
            //主鍵+1,就是要插入的聯絡人id
            contact_id = ++_id;
        }

        ContentValues values = new ContentValues();
        values.put("contact_id", contact_id);
        //把聯絡人id插入raw_contacts資料庫
        cr.insert(Uri.parse("content://com.android.contacts/raw_contacts"), values);

        values.clear();
        //data表
        values.put("data1", "張三");
        values.put("mimetype", "vnd.android.cursor.item/name");
        values.put("raw_contact_id", contact_id);
        cr.insert(Uri.parse("content://com.android.contacts/data"), values);

        values.clear();
        values.put("data1", "1344567");
        values.put("mimetype", "vnd.android.cursor.item/phone_v2");
        values.put("raw_contact_id", contact_id);
        cr.insert(Uri.parse("content://com.android.contacts/data"), values);
    }

    //查詢聯絡人
    public void click2(View view) {
        ContentResolver cr = getContentResolver();
        Cursor cursorcontactId = cr.query(Uri.parse("content://com.android.contacts/raw_contacts"), new String[]{"contact_id"}, null, null, null);
        while (cursorcontactId.moveToNext()) {
            //獲取聯絡人id
            String contactId = cursorcontactId.getString(0);
            Cursor cursorData = cr.query(Uri.parse("content://com.android.contacts/data"), new String[]{"data1", "mimetype"}, "raw_contact_id = ?", new String[]{contactId}, null);
            //獲取所有欄位的名字
//    		String[] names = cursorData.getColumnNames();
//    		for (String string : names) {
//				System.out.println(string);
//			}
            Contact con = new Contact();
            while (cursorData.moveToNext()) {
                String data1 = cursorData.getString(0);
                String mimetype = cursorData.getString(1);
                //通過mimetype的判斷,把data1存入對應的屬性
                if ("vnd.android.cursor.item/email_v2".equals(mimetype)) {
                    con.setEmail(data1);
                } else if ("vnd.android.cursor.item/phone_v2".equals(mimetype)) {
                    con.setPhone(data1);
                } else if ("vnd.android.cursor.item/name".equals(mimetype)) {
                    con.setName(data1);
                }
            }
            System.out.println(con.toString());
        }
    }

    //監聽簡訊資料庫改變
    public class MyObserver extends ContentObserver {

        /**
         * Creates a content observer.
         *
         * @param handler The handler to run {@link #onChange} on, or null if none.
         */
        public MyObserver(Handler handler) {
            super(handler);
        }

        @Override
        public void onChange(boolean selfChange) {
            super.onChange(selfChange);
            Toast.makeText(MainActivity.this, "收到簡訊", Toast.LENGTH_SHORT).show();
        }
    }


}
</span>