手机卫士08-获取手机联系人

简介: <div id="wp" class="wp" style="word-wrap:break-word; margin:0px auto; width:1322.015625px; min-width:960px; color:rgb(68,68,68); font-family:Tahoma,'Microsoft Yahei',Simsun; line-height:18px"> <d

首先,我把把昨天忘记了的两张设置向导的图片放出来先

   


我们从上面的第一张图片可以看到,我们有一个选择联系人这一操作,那么怎样才能获取到手机里面的联系人呢,其实方法有很多的,现在我们来讲一下我们这个项目里面用到的方法

其实要想知道怎样获取手机里面的联系人,去看一下Android自己的源码就知道的了

我们只要把platform/packages/providers/ContactsProvider这一部分的内容下载下来看看就可以的啦

下面是我下载之后,打开里面的AndroidManifest的内容

  1. <manifest xmlns:android="http://schemas.android.com/apk/res/android"
  2.         package="com.android.providers.contacts"
  3.         android:sharedUserId="android.uid.shared"
  4.         android:sharedUserLabel="@string/sharedUserLabel">

  5.     <permission
  6.             android:name="com.android.voicemail.permission.READ_WRITE_ALL_VOICEMAIL"
  7.             android:label="@string/read_write_all_voicemail_label"
  8.             android:description="@string/read_write_all_voicemail_description"
  9.             android:permissionGroup="android.permission-group.PERSONAL_INFO"
  10.             android:protectionLevel="signature"
  11.             />

  12.     <uses-permission android:name="android.permission.READ_CONTACTS" />
  13.     <uses-permission android:name="android.permission.WRITE_CONTACTS" />
  14.     <uses-permission android:name="android.permission.GET_ACCOUNTS" />
  15.     <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
  16.     <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
  17.     <uses-permission android:name="android.permission.BIND_DIRECTORY_SEARCH" />
  18.     <uses-permission android:name="android.permission.UPDATE_APP_OPS_STATS" />
  19.     <uses-permission android:name="android.permission.READ_SYNC_SETTINGS" />
  20.     <uses-permission android:name="com.android.voicemail.permission.ADD_VOICEMAIL" />
  21.     <uses-permission android:name="com.android.voicemail.permission.READ_WRITE_ALL_VOICEMAIL" />

  22.     <application android:process="android.process.acore"
  23.         android:label="@string/app_label"
  24.         android:icon="@drawable/app_icon"
  25.         android:allowBackup="false">

  26.         <provider android:name="ContactsProvider2"
  27.             android:authorities="contacts;com.android.contacts"
  28.             android:label="@string/provider_label"
  29.             android:multiprocess="false"
  30.             android:exported="true"
  31.             android:readPermission="android.permission.READ_CONTACTS"
  32.             android:writePermission="android.permission.WRITE_CONTACTS">
  33.             <path-permission
  34.                     android:pathPrefix="/search_suggest_query"
  35.                     android:readPermission="android.permission.GLOBAL_SEARCH" />
  36.             <path-permission
  37.                     android:pathPrefix="/search_suggest_shortcut"
  38.                     android:readPermission="android.permission.GLOBAL_SEARCH" />
  39.             <path-permission
  40.                     android:pathPattern="/contacts/.*/photo"
  41.                     android:readPermission="android.permission.GLOBAL_SEARCH" />
  42.             <grant-uri-permission android:pathPattern=".*" />
  43.         </provider>

  44.         <provider android:name="CallLogProvider"
  45.             android:authorities="call_log"
  46.             android:syncable="false" android:multiprocess="false"
  47.             android:exported="true"
  48.             android:readPermission="android.permission.READ_CALL_LOG"
  49.             android:writePermission="android.permission.WRITE_CALL_LOG">
  50.         </provider>

  51.         <provider android:name="VoicemailContentProvider"
  52.             android:authorities="com.android.voicemail"
  53.             android:syncable="false" android:multiprocess="false"
  54.             android:exported="true"
  55.             android:permission="com.android.voicemail.permission.ADD_VOICEMAIL">
  56.         </provider>

  57.         <!-- Handles database upgrades after OTAs, then disables itself -->
  58.         <receiver android:name="ContactsUpgradeReceiver">
  59.             <!-- This broadcast is sent after the core system has finished
  60.                  booting, before the home app is launched or BOOT_COMPLETED
  61.                  is sent. -->
  62.             <intent-filter>
  63.                 <action android:name="android.intent.action.PRE_BOOT_COMPLETED"/>
  64.             </intent-filter>
  65.         </receiver>

  66.         <receiver android:name="PackageIntentReceiver">
  67.             <intent-filter>
  68.                 <action android:name="android.intent.action.PACKAGE_ADDED" />
  69.                 <data android:scheme="package" />
  70.             </intent-filter>
  71.             <intent-filter>
  72.                 <action android:name="android.intent.action.PACKAGE_REPLACED" />
  73.                 <data android:scheme="package" />
  74.             </intent-filter>
  75.             <intent-filter>
  76.                 <action android:name="android.intent.action.PACKAGE_REMOVED" />
  77.                 <data android:scheme="package" />
  78.             </intent-filter>
  79.             <intent-filter>
  80.                 <action android:name="android.intent.action.PACKAGE_CHANGED" />
  81.                 <data android:scheme="package" />
  82.             </intent-filter>
  83.         </receiver>

  84.         <receiver android:name="LocaleChangeReceiver">
  85.             <intent-filter>
  86.                 <action android:name="android.intent.action.LOCALE_CHANGED"/>
  87.             </intent-filter>
  88.         </receiver>

  89.         <service android:name="VoicemailCleanupService"/>

  90.         <activity android:name=".debug.ContactsDumpActivity"
  91.                 android:label="@string/debug_dump_title"
  92.                 android:theme="@android:style/Theme.Holo.Dialog"
  93.                 >
  94.             <intent-filter>
  95.                 <action android:name="com.android.providers.contacts.DUMP_DATABASE"/>
  96.                 <category android:name="android.intent.category.DEFAULT"/>
  97.             </intent-filter>
  98.         </activity>

  99.         <provider android:name=".debug.DumpFileProvider"
  100.             android:authorities="com.android.contacts.dumpfile"
  101.             android:exported="true">
  102.         </provider>

  103.     </application>
  104. </manifest>
复制代码
我们可以看一下第一个provider,里面就有我们想要的uri还有它已经写好了的类了,各位有兴趣的可以去看一下是如何实现的, 其实我们要获取的东西,都是存放在一个数据库里面的,我们不妨把那个数据库拿出来看一下,拿到那个数据库也很简单,只要在Eclipse里面的ddms界面里面,在右上边  那个contacts2.db就是我们想要的东西啦我们可以把它导出来,然后用SQLite Database browser来打开它  获取手机里面的联系人,我们只要关注三个表就可以啦,一个是raw_contacts   data还有一个mime_type这三个表就行啦mime_type存放的就是一些类型,是电话,还是短信,还是E-mail这些data就是存放一些数据的东西raw_contacts就是存放一些命名什么的这三个表的关系就是下面一样的啦 从上面的可以看到,我们可以通过raw_contacts拿到那个id还有display_name然后就去data那里找到对应的raw_contact_id,这样就可以获得对应的数据啦,然后还可以通过mimetype_id在mime_type表里面找出想要的类型好啦,原理就是这样啦,下面我们来看一下代码怎么写我们先要用一个model类来存放我们的数据com.xiaobin.security.domain.ContactInfo
  1. package com.xiaobin.security.domain;

  2. public class ContactInfo
  3. {
  4.         private String name;
  5.         private String phone;
  6.         
  7.         public String getName()
  8.         {
  9.                 return name;
  10.         }
  11.         public void setName(String name)
  12.         {
  13.                 this.name = name;
  14.         }
  15.         public String getPhone()
  16.         {
  17.                 return phone;
  18.         }
  19.         public void setPhone(String phone)
  20.         {
  21.                 this.phone = phone;
  22.         }
  23.         
  24. }
复制代码
然后呢,我们就可以写我们获得手机联系人的代码啦新建一个类com.xiaobin.security.engine.ContactInfoService
  1. package com.xiaobin.security.engine;

  2. import java.util.ArrayList;
  3. import java.util.List;

  4. import android.content.ContentResolver;
  5. import android.content.Context;
  6. import android.database.Cursor;
  7. import android.net.Uri;

  8. import com.xiaobin.security.domain.ContactInfo;

  9. public class ContactInfoService
  10. {
  11.         private Context context;
  12.         
  13.         public ContactInfoService(Context context)
  14.         {
  15.                 this.context = context;
  16.         }
  17.         
  18.         public List<ContactInfo> getContactInfos()
  19.         {
  20.                 List<ContactInfo> infos = new ArrayList<ContactInfo>();
  21.                 ContactInfo info;
  22.                 
  23.                 ContentResolver contentResolver = context.getContentResolver();
  24.                 //在源码的AndroidManifest里面可以看到这些uri
  25.                 Uri uri = Uri.parse("content://com.android.contacts/raw_contacts");
  26.                 Uri dataUri = Uri.parse("content://com.android.contacts/data");
  27.                 Cursor cursor = contentResolver.query(uri, null, null, null, null);
  28.                 while(cursor.moveToNext())
  29.                 {
  30.                         info = new ContactInfo();
  31.                         String id = cursor.getString(cursor.getColumnIndex("_id"));
  32.                         String name = cursor.getString(cursor.getColumnIndex("display_name"));
  33.                         info.setName(name);
  34.                         //通过raw_contacts里面的id拿到data里面对应的数据
  35.                         Cursor dataCursor = contentResolver.query(dataUri, null, "raw_contact_id = ? ", new String[] {id}, null);
  36.                         while(dataCursor.moveToNext())
  37.                         {
  38.                                 String type = dataCursor.getString(dataCursor.getColumnIndex("mimetype"));
  39.                                 //根据类型,只要电话这种类型的数据
  40.                                 if(type.equals("vnd.android.cursor.item/phone_v2"))
  41.                                 {
  42.                                         String number = dataCursor.getString(dataCursor.getColumnIndex("data1"));//拿到数据
  43.                                         info.setPhone(number);
  44.                                 }
  45.                         }
  46.                         dataCursor.close();
  47.                         infos.add(info);
  48.                         info = null;
  49.                 }
  50.                 cursor.close();
  51.                 return infos;
  52.         }

  53. }
复制代码
因为我们是点击按钮,然后打开一个activity,然后选择好了之后,再把值返回到原来的activity那里的,所以我们就要用到startActivityForResult这个方法啦好,我们来看一下setup_guide3这个向导页面的逻辑是怎样写的com.xiaobin.security.ui.SetupGuide3Activity
  1. package com.xiaobin.security.ui;

  2. import android.app.Activity;
  3. import android.content.Context;
  4. import android.content.Intent;
  5. import android.content.SharedPreferences;
  6. import android.content.SharedPreferences.Editor;
  7. import android.os.Bundle;
  8. import android.view.View;
  9. import android.view.View.OnClickListener;
  10. import android.widget.Button;
  11. import android.widget.EditText;
  12. import android.widget.Toast;

  13. import com.xiaobin.security.R;

  14. public class SetupGuide3Activity extends Activity implements OnClickListener
  15. {
  16.         private Button bt_next;
  17.         private Button bt_pervious;
  18.         private Button bt_select;
  19.         private EditText et_phoneNumber;
  20.         private SharedPreferences sp;
  21.         
  22.         @Override
  23.         protected void onCreate(Bundle savedInstanceState)
  24.         {
  25.                 super.onCreate(savedInstanceState);
  26.                 setContentView(R.layout.setup_guide3);
  27.                 
  28.                 sp = getSharedPreferences("config", Context.MODE_PRIVATE);
  29.                 
  30.                 bt_next = (Button) findViewById(R.id.bt_guide_next);
  31.                 bt_pervious = (Button) findViewById(R.id.bt_guide_pervious);
  32.                 bt_select = (Button) findViewById(R.id.bt_guide_select);
  33.                 bt_next.setOnClickListener(this);
  34.                 bt_pervious.setOnClickListener(this);
  35.                 bt_select.setOnClickListener(this);
  36.                 
  37.                 et_phoneNumber = (EditText) findViewById(R.id.et_guide_phoneNumber);
  38.         }
  39.         
  40.         //重写这个方法,从acitivty里面拿到数据
  41.         @Override
  42.         protected void onActivityResult(int requestCode, int resultCode, Intent data)
  43.         {
  44.                 super.onActivityResult(requestCode, resultCode, data);
  45.                 //resultCode是乃至区分拿到的activity是从那一个activity里面拿到的
  46.                 
  47.                 if(data != null)
  48.                 {
  49.                         String number = data.getStringExtra("number");
  50.                         et_phoneNumber.setText(number);
  51.                 }
  52.         }

  53.         @Override
  54.         public void onClick(View v)
  55.         {
  56.                 switch(v.getId())
  57.                 {
  58.                         case R.id.bt_guide_select : 
  59.                                 Intent selectIntent = new Intent(this, SelectContactActivity.class);
  60.                                 //启动一个activity来获取数据,获取到的数据是在重写的onActivityResult这个方法里面拿到的
  61.                                 startActivityForResult(selectIntent, 1);
  62.                                 break;
  63.                                 
  64.                         case R.id.bt_guide_next : 
  65.                                 String number = et_phoneNumber.getText().toString().trim();
  66.                                 if(number.equals(""))
  67.                                 {
  68.                                         Toast.makeText(this, "安全号码不能为空", Toast.LENGTH_SHORT).show();
  69.                                 }
  70.                                 else
  71.                                 {
  72.                                         Editor editor = sp.edit();
  73.                                         editor.putString("number", number);
  74.                                         editor.commit();
  75.                                         
  76.                                         Intent intent = new Intent(this, SetupGuide4Activity.class);
  77.                                         finish();
  78.                                         startActivity(intent);
  79.                                         //这个是定义activity切换时的动画效果的
  80.                                         overridePendingTransition(R.anim.translate_in, R.anim.translate_out);
  81.                                 }
  82.                                 break;
  83.                         case R.id.bt_guide_pervious : 
  84.                                 
  85.                                 Intent i = new Intent(this, SetupGuide2Activity.class);
  86.                                 finish();
  87.                                 startActivity(i);
  88.                                 //这个是定义activity切换时的动画效果的
  89.                                 overridePendingTransition(R.anim.alpha_in, R.anim.alpha_out);
  90.                                 break;
  91.                                 
  92.                         default : 
  93.                                 break;
  94.                 }
  95.         }

  96. }
复制代码
我们还要新建一个类用来做为选择的呢com.xiaobin.security.ui.SelectContactActivity
  1. package com.xiaobin.security.ui;

  2. import java.util.List;

  3. import android.app.Activity;
  4. import android.content.Intent;
  5. import android.os.Bundle;
  6. import android.view.View;
  7. import android.view.ViewGroup;
  8. import android.widget.AdapterView;
  9. import android.widget.AdapterView.OnItemClickListener;
  10. import android.widget.BaseAdapter;
  11. import android.widget.ListView;
  12. import android.widget.TextView;

  13. import com.xiaobin.security.R;
  14. import com.xiaobin.security.domain.ContactInfo;
  15. import com.xiaobin.security.engine.ContactInfoService;

  16. public class SelectContactActivity extends Activity
  17. {
  18.         private ListView lv;
  19.         private List<ContactInfo> infos;
  20.         
  21.         @Override
  22.         protected void onCreate(Bundle savedInstanceState)
  23.         {
  24.                 super.onCreate(savedInstanceState);
  25.                 setContentView(R.layout.select_contact);
  26.                 
  27.                 infos = new ContactInfoService(this).getContactInfos();
  28.                 
  29.                 lv = (ListView) findViewById(R.id.lv_select_contact);
  30.                 lv.setAdapter(new SelectContactAdapter());
  31.                 lv.setOnItemClickListener(new OnItemClickListener()
  32.                 {
  33.                         @Override
  34.                         public void onItemClick(AdapterView<?> parent, View view, int position, long id)
  35.                         {
  36.                                 String number = infos.get(position).getPhone();
  37.                                 Intent intent = new Intent();
  38.                                 intent.putExtra("number", number);
  39.                                 //把要返回的数据设置进去,便通过onActivityResult(int, int, Intent)拿到
  40.                                 setResult(1, intent);
  41.                                 finish();
  42.                         }
  43.                 });
  44.         }
  45.         
  46.         //=================================================================================
  47.         
  48.         private class SelectContactAdapter extends BaseAdapter
  49.         {

  50.                 @Override
  51.                 public int getCount()
  52.                 {
  53.                         return infos.size();
  54.                 }

  55.                 @Override
  56.                 public Object getItem(int position)
  57.                 {
  58.                         return infos.get(position);
  59.                 }

  60.                 @Override
  61.                 public long getItemId(int position)
  62.                 {
  63.                         return position;
  64.                 }

  65.                 @Override
  66.                 public View getView(int position, View convertView, ViewGroup parent)
  67.                 {
  68.                         ContactInfo info = infos.get(position);
  69.                         View view;
  70.                         ContactViews views;
  71.                         if(convertView == null)
  72.                         {
  73.                                 views = new ContactViews();
  74.                                 view = View.inflate(SelectContactActivity.this, R.layout.contact_item, null);
  75.                                 views.tv_name = (TextView) view.findViewById(R.id.tv_contact_name);
  76.                                 views.tv_number = (TextView) view.findViewById(R.id.tv_contact_number);
  77.                                 views.tv_name.setText("联系人:" + info.getName());
  78.                                 views.tv_number.setText("联系电话:" + info.getPhone());
  79.                                 
  80.                                 view.setTag(views);
  81.                         }
  82.                         else
  83.                         {
  84.                                 view = convertView;
  85.                         }
  86.                         return view;
  87.                 }
  88.                 
  89.         }
  90.         
  91.         private class ContactViews
  92.         {
  93.                 TextView tv_name;
  94.                 TextView tv_number;
  95.         }

  96. }
复制代码
这个类是非常简单的,只有一个listView大家也可以看到,这个类里面有一个adapter,这个是为了方便,所以写在里面的,而且那个listview我们也用到了上一次的优化方法如果有什么不了解的,可以回去看一下我们前面的那个Android项目实战--手机卫士06--GridView的优化与修改Button的显示样式好啦,下面是activity的布局文件,还有listview的布局文件select_contact.xml
  1. <?xml version="1.0" encoding="utf-8"?>
  2. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  3.     android:layout_width="match_parent"
  4.     android:layout_height="match_parent"
  5.     android:background="@android:color/white"
  6.     android:orientation="vertical" >
  7.     
  8.     <ListView 
  9.         android:id="@+id/lv_select_contact"
  10.         android:layout_width="match_parent"
  11.         android:layout_height="match_parent" />

  12. </LinearLayout>
复制代码
contact_item.xml
  1. <?xml version="1.0" encoding="utf-8"?>
  2. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  3.     android:layout_width="match_parent"
  4.     android:layout_height="match_parent"
  5.     android:orientation="vertical" >
  6.     
  7.     <TextView 
  8.         android:id="@+id/tv_contact_name"
  9.         android:layout_width="match_parent"
  10.         android:layout_height="wrap_content"/>
  11.     
  12.     <TextView 
  13.         android:id="@+id/tv_contact_number"
  14.         android:layout_width="match_parent"
  15.         android:layout_height="wrap_content"/>

  16. </LinearLayout>
复制代码
好啦,获取联系人的操作,我们也差不多完成的啦,现在还要加上两个权限
  1.     <uses-permission android:name="android.permission.READ_CONTACTS" />
  2.     <uses-permission android:name="android.permission.WRITE_CONTACTS"/>
复制代码
到现在为止,获取联系人的操作就完成的啦,因为之前都是清一色的切换效果,所以我现写多了两个切换效果,大家可以看看,也是很简单的至于怎么写那些效果,那就要看一下我们的前一篇文章啦translate_in.xml
  1. <?xml version="1.0" encoding="utf-8"?>
  2. <translate xmlns:android="http://schemas.android.com/apk/res/android"
  3.     android:fromXDelta="100%p"
  4.     android:toXDelta="0"
  5.     android:duration="400" >
  6.     <!-- 100%p是指从看不到的地方进入到0这个地方 -->

  7. </translate>
复制代码
translate_out.xml
  1. <?xml version="1.0" encoding="utf-8"?>
  2. <translate xmlns:android="http://schemas.android.com/apk/res/android"
  3.     android:fromXDelta="0"
  4.     android:toXDelta="-100%p"
  5.     android:duration="400" >
  6.     <!-- 100%p是指从看不到的地方进入到0这个地方 -->

  7. </translate>
复制代码
好啦,今天要说的基本上已经说完的啦如果有什么不明白的,或有什么指导的,欢迎留言  Security_08获取手机联系人.rar (641.15 KB, 下载次数: 116) 
2013-10-9 15:24 上传
点击文件名下载附件 
下载积分: 下载豆 -2



这里是快速回复,赶紧试试哦

我知道了
   
 
   

该用户从未签到

0

主题

171

帖子

3341

积分

Android伯爵

积分
3341
沙发
  发表于 2013-10-9 22:08:37  |  只看该作者
看了楼主的帖子,如沐春风






 
 
   

该用户从未签到

0

主题

16

帖子

46

积分

Android感染者

积分
46
地板
  发表于 2013-10-10 13:33:13  |  只看该作者
上限是多少呢
 
 
   
TA的每日心情
难过
2013-10-12 14:19

签到天数: 1 天

连续签到: 1 天

[LV.1]初来乍到

0

主题

8

帖子

18

积分

Android感染者

菜鸟

积分
18

社区QQ达人

6#
  发表于 2013-10-12 14:13:36  |  只看该作者
这东西真好
 
 
   
TA的每日心情
开心
昨天 10:21

签到天数: 35 天

连续签到: 2 天

[LV.5]常住居民I

1

主题

237

帖子

567

积分

Android男爵

积分
567
7#
  发表于 2013-10-13 09:58:08  |  只看该作者
xue xi xue xi
 
 
   

该用户从未签到

0

主题

16

帖子

46

积分

Android感染者

积分
46
9#
  发表于 2013-10-14 09:58:55  |  只看该作者
简单的实现
 
 
   
1 2 3  / 3 页 下一页
返回列表 发新帖 回复

本版积分规则

 本地化远程图片
回帖后跳转到最后一页

目录
相关文章
|
3月前
|
5G 芯片 流计算
5g手机有什么推荐
5g手机有什么推荐
25 0
|
6月前
手机,具有以下特点
手机,具有以下特点
96 0
|
数据安全/隐私保护 iOS开发
小技巧 - iPhone手机(IOS系统)玩游戏时关闭所有消息提醒
小技巧 - iPhone手机(IOS系统)玩游戏时关闭所有消息提醒
818 0
小技巧 - iPhone手机(IOS系统)玩游戏时关闭所有消息提醒
|
人工智能 缓存 搜索推荐
如果给自己的手机增寿,只需要这样做
其实随着技术的进步,智能手机的使用寿命也大幅延长了。所以别急着换手机,应该先来一次“断 舍 离”试试。
144 0
如果给自己的手机增寿,只需要这样做
|
数据安全/隐私保护 iOS开发
|
存储 内存技术

热门文章

最新文章