Android 製作通訊錄(ContactsContract)

推薦一個網站,學Android時常常會去參考:
GiveMePasS's Android惡補筆記

原因:
  1. 全繁體中文,介面友善
  2. 分類明確,東西紮實
  3. 步驟清析,照著做就會學到東西
這次試做通訊錄,使其能完成以下功能:
新增、刪除、修改、撥打電話、傳送簡訊

補充:
最近學到JavaScript的jQuery
不學不知道,學了覺得實在逆天的好啊!
簡單方便好上手好操作,未來會試著在blog中多加應用
可以參考→ w3school(簡體)

像下面的按鈕就是很簡單的操作






這次真的挺苦手的
打電話、傳簡訊都還容易
倒是去撈聯絡人及撈出電話卡了好久
ContactsContract這個類真的不太好搞
好像是聯絡人是一個表
而聯絡人的資料又會對應到另一個表
而規範這些表單的類型又是一個表
學過資料庫就知道了
聯絡人就像是「訂單」
而聯絡人的資料就是「訂單名細」

一個訂單只對應一個客戶(聯絡人)
而訂單名細對應一個訂單

訂單名細可能有多種資料
像是一次訂了:
芭樂 1 箱
香蕉 2 箱

而聯絡人資料也是一樣:
手機 09xxxxxxx
市話 07xxxxxx
信箱 aa@bb.cc

參考表:
類型 說明
ContactsContract.Contacts 聯絡人
ContactsContract.RawContacts 單一行的聯絡人
ContactsContract.Data 聯絡人的資料
像是電話、信箱
ContactsContract.CommonDataKinds 聯絡人表中的類型格式
像是電話的類型等等
*警告:這是我自已整理,不負任何責任*


影片說明:


除了主程式,因為對聯絡人資料庫操作程式碼太長
所以參考了givemepass惡補筆記的做法,另做一個叫HandlePhoneBook
專則處理增、改、刪 等動作

注意事項:
  1. 記得設定user permission,READ_CONTACTS、CALL_PHONE
    WRITE_CONTACTS、SEND_SMS
  2. 其實有些地方還可以最佳化啦,像是dialog可以寫個方法在外面
    增加一個尋找的功能等等,只是我懶了…


HandlePhoneBook.class


public class HandlePhoneBook {

 private Context context;
 private Cursor contacts_name;
 private Cursor contacts_number;
 HashMap contactMap;
 ArrayList> contactsArrayList;
 
 public HandlePhoneBook(Context context){
  this.context = context;
 }
 //===============初始化撈出資料===========================
 public ArrayList> quary(){ 
  contactsArrayList = new ArrayList<>();
  String name = "";
  //查詢手機裡人名(查出來是cursor)
  contacts_name = context.getContentResolver().query(
    ContactsContract.Contacts.CONTENT_URI, null, null, null, null);
  
  while(contacts_name.moveToNext()){
   contactMap = new HashMap<>();
   String phoneNumber = "";
   //找出表內id
   long id = contacts_name.getLong(
     contacts_name.getColumnIndex(
     ContactsContract.Contacts._ID));
   //依id查出PhoneNumber表
   contacts_number = context.getContentResolver().query(
     ContactsContract.CommonDataKinds.Phone.CONTENT_URI,
     null,
     ContactsContract.CommonDataKinds.Phone.CONTACT_ID
     +"="+Long.toString(id)
     ,null
     ,null);
      
   while(contacts_number.moveToNext()){
    //提取電話
    phoneNumber= contacts_number.getString(
      contacts_number.getColumnIndex(
      ContactsContract.CommonDataKinds.Phone.NUMBER));
   }
   contacts_number.close();
   //提取姓名
   name = contacts_name.getString(
    contacts_name.getColumnIndex(
    ContactsContract.Contacts.DISPLAY_NAME));
   //放入Map中
   contactMap.put("NAME", name);
   contactMap.put("NUMBER",phoneNumber);
   contactMap.put("ID",Long.toString(id));
   //將Map放入ArrayList
   contactsArrayList.add(contactMap);

  }
  contacts_name.close();
  return contactsArrayList; 
 }
 
 public String getid(int position){
  return contactsArrayList.get(position).get("ID");
 }
 
 //=====================刪除===========================
 public void delete(int position){
  String id = getid(position).trim();
  Log.e("id資訊", id);
  Uri deleteUri = Uri.withAppendedPath(
    ContactsContract.RawContacts.CONTENT_URI, id);
  context.getContentResolver().delete(
    deleteUri,null,null);
  /*
  //這刪除方法不完全
  context.getContentResolver().delete(
    ContactsContract.RawContacts.CONTENT_URI,//要用RawContacts才刪得掉
    ContactsContract.Contacts._ID + "=?",
    new String[]{id});
  */  
 }
 
 //=====================修改===========================
 public void editdetal(int position,String name,String phone){
  String id  = getid(position).trim();
  //設定名字
  ContentValues Values = new ContentValues();
  Values.put(ContactsContract.Contacts.DISPLAY_NAME, name);
  //更新名字
  context.getContentResolver().update(
    ContactsContract.RawContacts.CONTENT_URI,
    Values,
    ContactsContract.Contacts._ID + "=?",
    new String[]{id}); 
  //設定電話
  Values.clear();
  Values.put(ContactsContract.CommonDataKinds.Phone.NUMBER, phone);
  context.getContentResolver().update(
    ContactsContract.Data.CONTENT_URI,
    Values,
    ContactsContract.Data.RAW_CONTACT_ID + "=? and "+
    ContactsContract.Data.MIMETYPE + "=?",
    new String[]{id,ContactsContract.CommonDataKinds.Phone.CONTENT_ITEM_TYPE});

 }
 
 //=====================新增===========================
 public void insertDetel(String name,String phone){
  ContentValues values = new ContentValues();
  //先insert一筆空值,獲得系統返回的RawContactId
  Uri rawContactUri = context.getContentResolver()
    .insert(ContactsContract.RawContacts.CONTENT_URI, values);
  
  //取得id
  long RawContactId = ContentUris.parseId(rawContactUri);
  
  //往data表插入姓名數據
  values.clear();
  values.put(ContactsContract.Data.RAW_CONTACT_ID, RawContactId);
  values.put(ContactsContract.Data.MIMETYPE,
    ContactsContract.CommonDataKinds.StructuredName.CONTENT_ITEM_TYPE);
  values.put(ContactsContract.CommonDataKinds.StructuredName.GIVEN_NAME,name);
  context.getContentResolver().insert(
    ContactsContract.Data.CONTENT_URI, values);
  
  //往data表中插入電話數據
  values.clear();
  values.put(ContactsContract.Data.RAW_CONTACT_ID, RawContactId);
  values.put(ContactsContract.Data.MIMETYPE,
    ContactsContract.CommonDataKinds.Phone.CONTENT_ITEM_TYPE);
  values.put(ContactsContract.CommonDataKinds.Phone.NUMBER, phone);
  values.put(ContactsContract.CommonDataKinds.Phone.TYPE, 
     ContactsContract.CommonDataKinds.Phone.TYPE_MOBILE);
  context.getContentResolver().insert(
    ContactsContract.Data.CONTENT_URI, values);   
 }
 
}

主程式:


public static class PlaceholderFragment extends Fragment {
 
 ArrayList> contactsArrayList;//放listview資料
 HandlePhoneBook phoneBook;
 ListView listView;
 AlertDialog.Builder updateInsertDialog; //更新及插入dialog
 EditText newName,newNumber;
 LinearLayout ll;
 public PlaceholderFragment() {
 }

 @Override
 public View onCreateView(LayoutInflater inflater, ViewGroup container,
   Bundle savedInstanceState) {
  View rootView = inflater.inflate(R.layout.fragment_main, container,
    false);
  listView =(ListView) rootView.findViewById(R.id.listView1);
  phoneBook =new HandlePhoneBook(getActivity());
  resetAdapter();
     
  listView.setOnItemClickListener(new OnItemClickListener() {
    
   @Override
   public void onItemClick(AdapterView parent, View view,
     final int position, long id) {
    final String name = contactsArrayList.get(position).get("NAME");
    final String number = contactsArrayList.get(position).get("NUMBER");
    
    //設定點選Item時的反應
    DialogInterface.OnClickListener diaClickListener = 
      new DialogInterface.OnClickListener() {
     @Override
     public void onClick(DialogInterface dialog, int which) {
      switch (which) {
      case 0://打電話----------------------------------------------
       Intent call = new Intent(
         Intent.ACTION_CALL,Uri.parse("tel:"+number));
       startActivity(call);
       break;
      case 1://更新------------------------------------------------
       updateInsertDialog = new AlertDialog.Builder(getActivity());
       ll = (LinearLayout) getActivity()
         .getLayoutInflater().inflate(R.layout.detail, null);
       newName= (EditText) ll.findViewById(R.id.newName);
       newNumber=(EditText)ll.findViewById(R.id.newNumber);
       newName.setText(name);
       newNumber.setText(number);
       updateInsertDialog.setView(ll);
       updateInsertDialog.setTitle("更新聯絡人");
       updateInsertDialog.setNegativeButton("Cencal", null);
       updateInsertDialog.setPositiveButton("確定", 
         //設定點選Item中跳出的Dialog的反應
         new DialogInterface.OnClickListener() {
        
        @Override
        public void onClick(DialogInterface dialog, int which) {
         String nameString = newName.getText().toString();
         String numberString = newNumber.getText().toString();
         phoneBook.editdetal(position, nameString, numberString);
         resetAdapter();
        }
       });
       updateInsertDialog.create().show();
       break;
       
      case 2://傳簡訊
       //設定簡訊輸入畫面---------------------------------------
       final EditText msget = new EditText(getActivity());
       msget.setLines(5);
       msget.setHint("請在此輸入訊息內容:");
       msget.setGravity(Gravity.LEFT | Gravity.TOP);
       
       AlertDialog.Builder smsBuilder = new AlertDialog.Builder(getActivity());
       smsBuilder.setTitle(name);
       smsBuilder.setIcon(android.R.drawable.ic_dialog_info);
       smsBuilder.setView(msget);
       smsBuilder.setNegativeButton("Cancel", null);
       smsBuilder.setPositiveButton("確定",new DialogInterface.OnClickListener() {
        
        @Override
        public void onClick(DialogInterface dialog, int which) {
         PendingIntent pi = PendingIntent.getActivity(getActivity(), 0, new Intent(),0);
         SmsManager smsManager = SmsManager.getDefault();
         smsManager.sendTextMessage(number, null, msget.getText().toString(), pi, null);
         Toast.makeText(getActivity(), "簡訊已送出", Toast.LENGTH_SHORT).show();
        }
       });
       smsBuilder.create().show();
       break;
      case 3://刪除-----------------------------------------------
       phoneBook.delete(position);
       resetAdapter();
       break;
      }
     }};
    
    AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
    builder.setTitle(name)
        .setItems(new String[] {"call","Edit","Send Message","Delete"},diaClickListener)
        .setNegativeButton("Cancel",null);
    builder.show();  
   }
  });
  return rootView;
 }
 
 //重整畫面,每次增、刪、改都要呼叫此方法---------------------------
 public void resetAdapter(){
  contactsArrayList = phoneBook.quary();
  //設定ListView的表單內容
  SimpleAdapter adapter = new SimpleAdapter(
    getActivity(),
    contactsArrayList,
    android.R.layout.simple_list_item_2,
    new String[]{"NAME","NUMBER"},
    new int[]{android.R.id.text1,android.R.id.text2});
  
  listView.setAdapter(adapter);
 }

 @Override
 public void onCreate(Bundle savedInstanceState) {
  setHasOptionsMenu(true);
  //開啟可新增menu item
  super.onCreate(savedInstanceState);
 }

 @Override
 public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
  menu.clear();
  menu.add("新增");
  super.onCreateOptionsMenu(menu, inflater);
 }

 @Override
 public boolean onOptionsItemSelected(MenuItem item) {
  switch (item.getItemId()) {
  case 0://按下menu中新增-------------------------------------
   updateInsertDialog = new AlertDialog.Builder(getActivity());
   ll = (LinearLayout) getActivity()
     .getLayoutInflater().inflate(R.layout.detail, null);
   newName= (EditText) ll.findViewById(R.id.newName);
   newNumber=(EditText)ll.findViewById(R.id.newNumber);
   updateInsertDialog.setView(ll);
   updateInsertDialog.setTitle("新增聯絡人");
   updateInsertDialog.setNegativeButton("Cencal", null);
   updateInsertDialog.setPositiveButton("確定",
     //設定點選Item中跳出的Dialog的反應
     new DialogInterface.OnClickListener() {
      @Override
      public void onClick(DialogInterface dialog, int which) {
       String nameString = newName.getText().toString();
       String numberString = newNumber.getText().toString();
       phoneBook.insertDetel(nameString, numberString);
       resetAdapter();
      }
     });
   updateInsertDialog.create().show();
   break;
  }
  return super.onOptionsItemSelected(item);
 }
}

留言

熱門文章