總網頁瀏覽量

關於我自己

我的相片
人生的必修課是接受無常,人生的選修課是放下執著。

2012年1月11日 星期三

撈出聯絡人資料 ~ 照片 ContactsContract.Contacts.PHOTO_ID







要讀取聯絡人資料記得Manifest.xml中要加入


ContactPhotoActivity.java

package com.tsots.ContactPhotoActivity;

import java.io.ByteArrayOutputStream;
import java.util.ArrayList;
import java.util.List;
import android.app.Activity;
import android.database.Cursor;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.net.Uri;
import android.os.Bundle;
import android.provider.ContactsContract;
import android.provider.ContactsContract.Contacts;
import android.widget.GridView;
  
public class ContactPhotoActivity extends Activity 
{  
 GridView g1;
 String photoId;
 Bitmap photoBitmap;
 List contact_name= new ArrayList();
 List contact_photo= new ArrayList();
 int num_contact=0;
 int num_contact_photo=0;
 Bitmap tmp_photoBitmap;
 
 /** Called when the activity is first created. */  
 @Override  
    public void onCreate(Bundle savedInstanceState) 
 {  
  super.onCreate(savedInstanceState);  
  setContentView(R.layout.main);  
  g1 = (GridView) findViewById (R.id.gridview1);  
  Uri contacts = Contacts.CONTENT_URI;
  //陣列內容: 從contact撈出有顯示名稱的資料
  String[] selectNameColumn = new String[]{
                                        ContactsContract.Contacts._ID, 
                                        ContactsContract.Contacts.DISPLAY_NAME
                                       };
        Cursor cur = getContentResolver().query(  
                   contacts,          //要查詢的表格
                   selectNameColumn,  //要回傳的欄位組合
                   null,  
                   null,  
                   null
                    );  
        try
        {
         if (cur.moveToFirst()) 
         {                  
          int idColumn = cur.getColumnIndex(ContactsContract.Contacts._ID);
          int nameColumn = cur.getColumnIndex(ContactsContract.Contacts.DISPLAY_NAME); 
          do
          {                  
           String contactId = cur.getString(idColumn);//回傳有DISPLAY_NAME的資料,個人Device有103筆                  
           try
           {
            byte[] photo = getPhoto(contactId);   //只回傳有PHOTO_ID的資料,個人Device有24筆
            num_contact++;
            //將byte轉成Bitmap
                  Bitmap map = BitmapFactory.decodeByteArray(photo, 0, photo.length);                      
                  contact_name.add(num_contact + " " + String.valueOf(cur.getString(nameColumn)));
                  contact_photo.add(map);
              }
                 catch(Exception e)
                 {
                   
                 }
             }while(cur.moveToNext());
                 
             PhotoAdapter adapter = new PhotoAdapter(
                           this,   
                           contact_name,
                           contact_photo
                  );
             g1.setNumColumns(3);    //每列3筆資料
             g1.setAdapter(adapter); //自訂的Adapter
         }
        }
        finally
        {
         cur.close();
        }
 }
 
 /*
  * 這個function負責從聯絡人中撈出有PHOTO_ID的資料, 並以byte[]的型態回傳
  */
 public byte[] getPhoto(String people_id) 
 {
  byte[] contactIcon = null;
  String photo_id = null;
  String select_name = ContactsContract.Contacts._ID + " = " + people_id; 
  Cursor cur_select_name = getContentResolver().query(
                 ContactsContract.Contacts.CONTENT_URI, 
                 null, 
                 select_name, 
                 null,
                 null
                   );
  //會丟入103筆資料    
  if (cur_select_name.getCount() > 0) 
  {
   cur_select_name.moveToFirst();
   photo_id = cur_select_name.getString(cur_select_name.getColumnIndex(ContactsContract.Contacts.PHOTO_ID));
  }
  String[] projection = new String[] {ContactsContract.Data.DATA15}; 
  String select_photo = ContactsContract.Data._ID + " = " + photo_id;  //只抓有photo的data
  //String selection = ContactsContract.Data._ID;        //抓所有有名字的data, 且沒有抓到photo值

  Cursor cur_select_photo = getContentResolver().query(
                     ContactsContract.Data.CONTENT_URI, //要查詢的表格        
                     projection,                        //要回傳的欄位組合
                     select_photo,                      //符合這個限制資料的才會回傳
                     null,                              //前一個參數的參數
                     null                               //排序
               );
  //會丟入59筆資料    
  cur_select_photo.moveToFirst();
  /*
   * 若由DISPLAY_NAME過濾後的資料裡, 沒有聯絡人圖片的, 統一給一個圖示, 從.png裡抓
   */
  if(cur_select_photo.getCount() == 0)
  {
   tmp_photoBitmap = BitmapFactory.decodeResource(getResources(), R.drawable.widget_stock_addnewstock_btn_normal);  //將圖檔轉成Bitmap
   ByteArrayOutputStream baos = new ByteArrayOutputStream();
   tmp_photoBitmap.compress(Bitmap.CompressFormat.PNG, 100, baos); //將.png的圖檔轉成Bitmap
   contactIcon = baos.toByteArray();
   return contactIcon;
  }
  else
  {
   //只會得到24筆資料
   contactIcon = cur_select_photo.getBlob(0);
   return contactIcon;
  }
 }
 } //



PhotoAdapter.java
package com.tsots.ContactPhotoActivity;

import java.util.List;
import android.content.Context;
import android.graphics.Bitmap;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.ImageView;
import android.widget.TextView;

public class PhotoAdapter extends BaseAdapter 
{ 
 private Context photoadapter;
 List _contact_name;
 List _contact_photo;
 String tag = "com.tsots.ContactPhotoActivity / PhotoAdapter.java"; 

 public PhotoAdapter(Context con,List contact_name, List contact_photo) 
 {
  photoadapter = con;
  _contact_name = contact_name;
  _contact_photo = contact_photo;
 }

 public int getCount()
 {
  //return _items.length;
  return _contact_name.size();
 }

 public Object getItem(int position)
 {
  return _contact_name.get(position);
 }

 public long getItemId(int position)
 {
  return position;
 }

 /*
  * 從layout contactactivity_adapter.xml中定義一個TextView與一個ImageView欄位來放置聯絡人圖片與名稱
  */

 public View getView(int position, View convertView, ViewGroup parent)
 {
     LayoutInflater factory = LayoutInflater.from(photoadapter);
     View v = (View) factory.inflate(R.layout.contactactivity_adapter, null);
     TextView tv = (TextView) v.findViewById(R.id.ItemText);
     ImageView iv = (ImageView) v.findViewById(R.id.ItemImage);
     tv.setText(_contact_name.get(position).toString());     

     try
     {
      iv.setImageBitmap(_contact_photo.get(position));
     }
     catch(Exception e)
     {
      Log.e(tag, String.valueOf(e));
     }    
     return v;
 } 
} 
main.xml的內容為
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    >
    <GridView 
     android:id="@+id/gridview1" 
     android:layout_height="wrap_content" 
     android:layout_width="fill_parent"
     android:numColumns="auto_fit"
     android:verticalSpacing="10dp"  
  android:horizontalSpacing="10dp"
  android:stretchMode="columnWidth"
     android:gravity="center"
    />
</LinearLayout>
 

16 則留言:

  1. 您好,可以請問一下這個範例的layout檔怎麼佈局嗎?

    回覆刪除
  2. 用GridView喔, main.xml的內容為:





    回覆刪除
  3. 可以告訴我R.drawable.widget_stock_addnewstock_btn_normal的內容是什麼嗎?
    另外我的List contact_photo= new ArrayList();這句也有錯
    錯在bitmap,可以告訴我為什麼嗎?
    謝謝!

    回覆刪除
    回覆
    1. R.drawable.widget_stock_addnewstock_btn_normal←這是一張圖檔喔
      因為這個範例放了很多額外的圖片資源,您也可以放一些小圖檔到 專案\res\drawable\裡
      R.drawable.widget_stock_addnewstock_btn_normal←就改成R.drawable.圖檔名稱

      List contact_photo= new ArrayList();←是不是還沒import對應的package呢?

      刪除
    2. 作者已經移除這則留言。

      刪除
  4. 謝謝,R.drawable.widget_stock_addnewstock_btn_normal我部分我放了一張圖,命名成一樣的就沒問題了,

    不過List contact_photo= new ArrayList();的部分我不太了解妳的意思耶,
    List contact_name= new ArrayList();的部分我是import com.example.XXX.R.string;,這個做法對嗎?
    那List contact_photo= new ArrayList();呢?

    回覆刪除
    回覆
    1. 我可能需要看到紅色錯誤的提示訊息是甚麼才有辦法解><

      附上完整程式碼供您參考~

      https://www.dropbox.com/s/ei5pgwz4vwhsy7u/GridView_Contact_ChangePhoto.zip?dl=0

      刪除
  5. 那可以請妳幫我看一下嗎? 對不起...麻煩妳一下...

    https://www.dropbox.com/s/4ph7nykjk53zent/CloudBean.zip?dl=0

    回覆刪除
    回覆
    1. 妳的ContactPhotoActivity.java檔阿,
      裡面的List contact_photo= new ArrayList();修改為List contact_photo= new ArrayList();
      就不會出錯囉,可以run

      刪除
  6. 請問版主知道重複聯絡人電話上面的連結是從哪個資料欄位來的嗎?
    如果匯入兩筆相同姓名電話的資料,電話簿上是顯示一筆,但是電話欄位
    會多出兩個小電話的圖示,代表有兩個相同的資料被關聯在一起,
    從ContactsContract.Contacts沒發現對應的資訊。謝謝。

    回覆刪除
  7. 回覆
    1. 我從
      Cursor phoneCur = getContentResolver().query(ContactsContract.CommonDataKinds.Phone.CONTENT_URI, null, ContactsContract.CommonDataKinds.Phone.CONTACT_ID + "=?", new String[]{id}, null);
      PhoneCur.moveToFirst();
      do {
      phone = phoneCur.getString(phoneCur.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER));
      phonetype = phoneCur.getString(phoneCur.getColumnIndex(ContactsContract.CommonDataKinds.Phone.TYPE));
      System.out.println("phonetype:" + phonetype + " phone:" + phone);
      } while(phoneCur.moveToNext());
      有印出相同的電話號碼,不知道系統電話簿APP是否就是用這個資訊建立連結的?
      謝謝。

      刪除
    2. 我不是很肯定,(沒有improve過google 電話簿AP)><

      刪除