Android快速获取联系人

Android快速获取联系人,第1张

获取联系人在Android开发中经常会遇到,最近项目需要用到获取手机联系人的功能,于是写了一个先查询联系人id然后再根据id查询手机号demo,结果慢到怀疑人生(亲测联系人数据1500+)。最后经过优化查询方式后,查询时间在200ms左右(亲测联系人数据1500+)在这里分享给大家,以方便自己好直接拿来用。国际惯例,注:以下测试只查询名字和手机号码

1、查询所有联系人

2、通过姓名获取联系人

3、通过手机号码查询联系人

最后附上源码:

在Android开发中,我经常会遇到需要获取手机通讯录联系人信息,Android手机的通讯录联系人全部都存在系统的数据库中,如果须要获得通讯里联系人的信息就须要访问系统的数据库,才能将信息获取出来。

下面直接贴出代码供大家参考:

程序文件java代码:

import javaioInputStream;

import javautilArrayList;

import androidappListActivity;

import androidcontentContentResolver;

import androidcontentContentUris;

import androidcontentContext;

import androidcontentIntent;

import androiddatabaseCursor;

import androidgraphicsBitmap;

import androidgraphicsBitmapFactory;

import androidnetUri;

import androidosBundle;

import androidproviderContactsContract;

import androidproviderContactsContractCommonDataKindsPhone;

import androidproviderContactsContractCommonDataKindsPhoto;

import androidtextTextUtils;

import androidviewLayoutInflater;

import androidviewView;

import androidviewViewGroup;

import androidwidgetAdapterView;

import androidwidgetBaseAdapter;

import androidwidgetImageView;

import androidwidgetListView;

import androidwidgetTextView;

import androidwidgetAdapterViewOnItemClickListener;

public class ContactsActivity extends ListActivity {

Context mContext = null;

/获取库Phon表字段/

private static final String[] PHONES_PROJECTION = new String[] {

PhoneDISPLAY_NAME, PhoneNUMBER, PhotoPHOTO_ID,PhoneCONTACT_ID };

/联系人显示名称/

private static final int PHONES_DISPLAY_NAME_INDEX = 0;

/电话号码/

private static final int PHONES_NUMBER_INDEX = 1;

/头像ID/

private static final int PHONES_PHOTO_ID_INDEX = 2;

/联系人的ID/

private static final int PHONES_CONTACT_ID_INDEX = 3;

/联系人名称/

private ArrayList<String> mContactsName = new ArrayList<String>();

/联系人头像/

private ArrayList<String> mContactsNumber = new ArrayList<String>();

/联系人头像/

private ArrayList<Bitmap> mContactsPhonto = new ArrayList<Bitmap>();

ListView mListView = null;

MyListAdapter myAdapter = null;

@Override

public void onCreate(Bundle savedInstanceState) {

mContext = this;

mListView = thisgetListView();

/得到手机通讯录联系人信息/

getPhoneContacts();

myAdapter = new MyListAdapter(this);

setListAdapter(myAdapter);

mListViewsetOnItemClickListener(new OnItemClickListener() {

@Override

public void onItemClick(AdapterView<> adapterView, View view,

int position, long id) {

//调用系统方法拨打电话

Intent dialIntent = new Intent(IntentACTION_CALL, Uri

parse("tel:" + mContactsNumberget(position)));

startActivity(dialIntent);

}

});

superonCreate(savedInstanceState);

}

/得到手机通讯录联系人信息/

private void getPhoneContacts() {

ContentResolver resolver = mContextgetContentResolver();

// 获取手机联系人

Cursor phoneCursor = resolverquery(PhoneCONTENT_URI,PHONES_PROJECTION, null, null, null);

if (phoneCursor != null) {

while (phoneCursormoveToNext()) {

//得到手机号码

String phoneNumber = phoneCursorgetString(PHONES_NUMBER_INDEX);

//当手机号码为空的或者为空字段 跳过当前循环

if (TextUtilsisEmpty(phoneNumber))

continue;

//得到联系人名称

String contactName = phoneCursorgetString(PHONES_DISPLAY_NAME_INDEX);

//得到联系人ID

Long contactid = phoneCursorgetLong(PHONES_CONTACT_ID_INDEX);

//得到联系人头像ID

Long photoid = phoneCursorgetLong(PHONES_PHOTO_ID_INDEX);

//得到联系人头像Bitamp

Bitmap contactPhoto = null;

//photoid 大于0 表示联系人有头像 如果没有给此人设置头像则给他一个默认的

if(photoid > 0 ) {

Uri uri =ContentUriswithAppendedId(ContactsContractContactsCONTENT_URI,contactid);

InputStream input = ContactsContractContactsopenContactPhotoInputStream(resolver, uri);

contactPhoto = BitmapFactorydecodeStream(input);

}else {

contactPhoto = BitmapFactorydecodeResource(getResources(), Rdrawablecontact_photo);

}

mContactsNameadd(contactName);

mContactsNumberadd(phoneNumber);

mContactsPhontoadd(contactPhoto);

}

phoneCursorclose();

}

}

/得到手机SIM卡联系人人信息/

private void getSIMContacts() {

ContentResolver resolver = mContextgetContentResolver();

// 获取Sims卡联系人

Uri uri = Uriparse("content://icc/adn");

Cursor phoneCursor = resolverquery(uri, PHONES_PROJECTION, null, null,

null);

if (phoneCursor != null) {

while (phoneCursormoveToNext()) {

// 得到手机号码

String phoneNumber = phoneCursorgetString(PHONES_NUMBER_INDEX);

// 当手机号码为空的或者为空字段 跳过当前循环

if (TextUtilsisEmpty(phoneNumber))

continue;

// 得到联系人名称

String contactName = phoneCursor

getString(PHONES_DISPLAY_NAME_INDEX);

//Sim卡中没有联系人头像

mContactsNameadd(contactName);

mContactsNumberadd(phoneNumber);

}

phoneCursorclose();

}

}

class MyListAdapter extends BaseAdapter {

public MyListAdapter(Context context) {

mContext = context;

}

public int getCount() {

//设置绘制数量

return mContactsNamesize();

}

@Override

public boolean areAllItemsEnabled() {

return false;

}

public Object getItem(int position) {

return position;

}

public long getItemId(int position) {

return position;

}

public View getView(int position, View convertView, ViewGroup parent) {

ImageView iamge = null;

TextView title = null;

TextView text = null;

if (convertView == null) {

convertView = LayoutInflaterfrom(mContext)inflate(

Rlayoutcolorlist, null);

iamge = (ImageView) convertViewfindViewById(Ridcolor_image);

title = (TextView) convertViewfindViewById(Ridcolor_title);

text = (TextView) convertViewfindViewById(Ridcolor_text);

}

//绘制联系人名称

titlesetText(mContactsNameget(position));

//绘制联系人号码

textsetText(mContactsNumberget(position));

//绘制联系人头像

iamgesetImageBitmap(mContactsPhontoget(position));

return convertView;

}

}

}

实现如下广播,并且在AndroidManifest中进行注册

public class PhoneReceiver extends BroadcastReceiver {

@Override

public void onReceive(Context context, Intent intent) {

Systemoutprintln("action"+intentgetAction());

//如果是去电

if(intentgetAction()equals(IntentACTION_NEW_OUTGOING_CALL)){

String phoneNumber = intent

getStringExtra(IntentEXTRA_PHONE_NUMBER);

Logd(TAG, "call OUT:" + phoneNumber);

}else{

//查了下android文档,貌似没有专门用于接收来电的action,所以,非去电即来电

//如果我们想要监听电话的拨打状况,需要这么几步 :

第一:获取电话服务管理器TelephonyManager manager = thisgetSystemService(TELEPHONY_SERVICE);

第二:通过TelephonyManager注册我们要监听的电话状态改变事件。managerlisten(new MyPhoneStateListener(),

PhoneStateListenerLISTEN_CALL_STATE);这里的PhoneStateListenerLISTEN_CALL_STATE就是我们想要

监听的状态改变事件,初次之外,还有很多其他事件哦。

第三步:通过extends PhoneStateListener来定制自己的规则。将其对象传递给第二步作为参数。

第四步:这一步很重要,那就是给应用添加权限。androidpermissionREAD_PHONE_STATE

TelephonyManager tm = (TelephonyManager)contextgetSystemService(ServiceTELEPHONY_SERVICE);

tmlisten(listener, PhoneStateListenerLISTEN_CALL_STATE);

//设置一个监听器

}

}

PhoneStateListener listener=new PhoneStateListener(){

@Override

public void onCallStateChanged(int state, String incomingNumber) {

//注意,方法必须写在super方法后面,否则incomingNumber无法获取到值。

superonCallStateChanged(state, incomingNumber);

switch(state){

case TelephonyManagerCALL_STATE_IDLE:

Systemoutprintln("挂断");

break;

case TelephonyManagerCALL_STATE_OFFHOOK:

Systemoutprintln("接听");

break;

case TelephonyManagerCALL_STATE_RINGING:

Systemoutprintln("响铃:来电号码"+incomingNumber);

//输出来电号码

break;

}

}

限制访问电话号码

在未首先获得 READ_CALL_LOG 权限的情况下,除了应用的用例需要的其他权限之外,运行于 Android 9 上的应用无法读取电话号码或手机状态。

与来电和去电关联的电话号码可在手机状态广播(比如来电和去电的手机状态广播)中看到,并可通过 PhoneStateListener 类访问。 但是,如果没有 READ_CALL_LOG 权限,则 PHONE_STATE_CHANGED 广播和 PhoneStateListener 提供的电话号码字段为空。

要从手机状态中读取电话号码,请根据您的用例更新应用以请求必要的权限:

要通过 PHONE_STATE Intent *** 作读取电话号码,同时需要 READ_CALL_LOG 权限和 READ_PHONE_STATE 权限。

要从 onCallStateChanged() 中读取电话号码,只需要 READ_CALL_LOG 权限。 不需要 READ_PHONE_STATE 权限。

Android的官方文档是没有提供相应的Api的,因为标准的Andoird是没有双卡的,好像也只有国内才会搞双卡双待的神器吧。以下记录一下做这个功能所学习到的东西。直接上代码:

import javalangreflectInvocationTargetException;

import javalangreflectMethod;

import javautilList;

import androidappActivity;

import androidcontentContext;

import androidcontentSharedPreferences;

import androidcontentSharedPreferencesEditor;

import androidosBundle;

import androidpreferencePreferenceManager;

import androidtelephonyCellInfo;

import androidtelephonyTelephonyManager;

import androidviewMenu;

import androidwidgetTextView;

public class MainActivity extends Activity

{

private TextView tv;

private TextView tv2;

// ///////////////////////////////////

static String ISDOUBLE;

static String SIMCARD;

static String SIMCARD_1;

static String SIMCARD_2;

static boolean isDouble;

// //////////////////////////////////

@Override

protected void onCreate(Bundle savedInstanceState)

{

superonCreate(savedInstanceState);

setContentView(Rlayoutactivity_main);

tv = (TextView) findViewById(Ridtext);

tv2 = (TextView) findViewById(Ridtext2);

tv2setText("不知道哪个卡可用!");

getNumber();

}

private void getNumber()

{

TelephonyManager tm = (TelephonyManager) thisgetSystemService(thisTELEPHONY_SERVICE);

String phoneNumber1 = tmgetLine1Number();

// String phoneNumber2 = tmgetGroupIdLevel1();

initIsDoubleTelephone(this);

if (isDouble)

{

// tvsetText("这是双卡手机!");

tvsetText("本机号码是:" + " " + phoneNumber1 + " " + "这是双卡手机!");

} else

{

// tvsetText("这是单卡手机");

tvsetText("本机号码是:" + " " + phoneNumber1 + " " + "这是单卡手机");

}

}

public void initIsDoubleTelephone(Context context)

{

isDouble = true;

Method method = null;

Object result_0 = null;

Object result_1 = null;

TelephonyManager tm = (TelephonyManager) contextgetSystemService(ContextTELEPHONY_SERVICE);

try

{

// 只要在反射getSimStateGemini 这个函数时报了错就是单卡手机(这是我自己的经验,不一定全正确)

method = TelephonyManagerclassgetMethod("getSimStateGemini", new Class[]

{ intclass });

// 获取SIM卡1

result_0 = methodinvoke(tm, new Object[]

{ new Integer(0) });

// 获取SIM卡2

result_1 = methodinvoke(tm, new Object[]

{ new Integer(1) });

} catch (SecurityException e)

{

isDouble = false;

eprintStackTrace();

// Systemoutprintln("1_ISSINGLETELEPHONE:"+etoString());

} catch (NoSuchMethodException e)

{

isDouble = false;

eprintStackTrace();

// Systemoutprintln("2_ISSINGLETELEPHONE:"+etoString());

} catch (IllegalArgumentException e)

{

isDouble = false;

eprintStackTrace();

} catch (IllegalAccessException e)

{

isDouble = false;

eprintStackTrace();

} catch (InvocationTargetException e)

{

isDouble = false;

eprintStackTrace();

} catch (Exception e)

{

isDouble = false;

eprintStackTrace();

// Systemoutprintln("3_ISSINGLETELEPHONE:"+etoString());

}

SharedPreferences sp = PreferenceManagergetDefaultSharedPreferences(context);

Editor editor = spedit();

if (isDouble)

{

// 保存为双卡手机

editorputBoolean(ISDOUBLE, true);

// 保存双卡是否可用

// 如下判断哪个卡可用双卡都可以用

if (result_0toString()equals("5") && result_1toString()equals("5"))

{

if (!spgetString(SIMCARD, "2")equals("0") && !spgetString(SIMCARD, "2")equals("1"))

{

editorputString(SIMCARD, "0");

}

editorputBoolean(SIMCARD_1, true);

editorputBoolean(SIMCARD_2, true);

tv2setText("双卡可用");

} else if (!result_0toString()equals("5") && result_1toString()equals("5"))

{// 卡二可用

if (!spgetString(SIMCARD, "2")equals("0") && !spgetString(SIMCARD, "2")equals("1"))

{

editorputString(SIMCARD, "1");

}

editorputBoolean(SIMCARD_1, false);

editorputBoolean(SIMCARD_2, true);

tv2setText("卡二可用");

} else if (result_0toString()equals("5") && !result_1toString()equals("5"))

{// 卡一可用

if (!spgetString(SIMCARD, "2")equals("0") && !spgetString(SIMCARD, "2")equals("1"))

{

editorputString(SIMCARD, "0");

}

editorputBoolean(SIMCARD_1, true);

editorputBoolean(SIMCARD_2, false);

tv2setText("卡一可用");

} else

{// 两个卡都不可用(飞行模式会出现这种种情况)

editorputBoolean(SIMCARD_1, false);

editorputBoolean(SIMCARD_2, false);

tv2setText("飞行模式");

}

} else

{

// 保存为单卡手机

editorputString(SIMCARD, "0");

editorputBoolean(ISDOUBLE, false);

}

editorcommit();

}

@Override

public boolean onCreateOptionsMenu(Menu menu)

{

// Inflate the menu; this adds items to the action bar if it is present

getMenuInflater()inflate(Rmenumain, menu);

return true;

}

}

不要忘记添加权限:<uses-permission android:name="androidpermissionREAD_PHONE_STATE" />

import cnteachcourseR;

/

  Created by postmaster@teachcoursecn on 2016/5/5

 /

public class PhoneNameActivity extends ActionBarActivity {

    private static final String TAG = PhoneNameActivityclassgetSimpleName();

    private EditText et;

    public static void start(Context context) {

        start(context, null);

    }

    public static void start(Context context, Intent extras) {

        Intent intent = new Intent();

        intentsetClass(context, PhoneNameActivityclass);

        intentaddFlags(IntentFLAG_ACTIVITY_CLEAR_TOP

                | IntentFLAG_ACTIVITY_SINGLE_TOP);

        if (extras != null) {

            intentputExtras(extras);

        }

        contextstartActivity(intent);

    }

    @Override

    protected void onCreate(Bundle savedInstanceState) {

        superonCreate(savedInstanceState);

        setContentView(Rlayoutactivity_phone_name);

        et = (EditText) thisfindViewById(Ridmobile);

    }

    public void getTelClick(View view) {

        String name = etgetText()toString()trim();

        number(name);

    }

    /

      通过输入获取电话号码

     /

    public void number(String name) {

        //使用ContentResolver查找联系人数据

        Cursor cursor = getContentResolver()query(ContactsContractContactsCONTENT_URI, null, null, null, null);

        //遍历查询结果,找到所需号码

        while (cursormoveToNext()) {

            //获取联系人ID

            String contactId = cursorgetString(cursorgetColumnIndex(ContactsContractContacts_ID));

            //获取联系人的名字

            String contactName = cursorgetString(cursorgetColumnIndex(ContactsContractCommonDataKindsPhoneDISPLAY_NAME));

            if (nameequals(contactName)) {

                //使用ContentResolver查找联系人的电话号码

                Cursor phone = getContentResolver()query(ContactsContractCommonDataKindsPhoneCONTENT_URI, null, ContactsContractCommonDataKindsPhoneCONTACT_ID + " = " + contactId, null, null);

                if (phonemoveToNext()) {

                    String phoneNumber = phonegetString(phonegetColumnIndex(ContactsContractCommonDataKindsPhoneNUMBER));

                    ToastmakeText(this, phoneNumber+"TeachCourse——blog。。。", ToastLENGTH_SHORT)show();

                    Logd(TAG, "电话:" + phoneNumber);

                    break;

                }

            }

        }

    }

}

1、修改getTelClick()方法

2、修改Toast面包屑提示

3、修改获取联系人名字方法

4、位置稍微调整

以上就是关于Android快速获取联系人全部的内容,包括:Android快速获取联系人、android开发怎样获取通讯录联系人信息、android开发怎么监控来电并监听等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/web/9265629.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-04-26
下一篇 2023-04-26

发表评论

登录后才能评论

评论列表(0条)

保存