ContactsContract.Contacts.CONTENT

xiaoxiao2021-02-28  131

需求:打开系统联系人,获取手机号码。 可能会遇到的问题:同一个用户多个手机号码 阅读本文会收获2个技能:

学会反编译Apk查看代码实现原理快速定位反编译后的代码

最开始我以为像类似获取系统图片那样去获取手机号码,很快解决,实际上也不是很难,方法对了就很快。 最开始根据Action事件在startActivityForResult中找到官方的文档说明(毕竟我觉得这种应该很容易去实现,一个Action就可以了)

public class MyActivity extends Activity { ... static final int PICK_CONTACT_REQUEST = 0; public boolean onKeyDown(int keyCode, KeyEvent event) { if (keyCode == KeyEvent.KEYCODE_DPAD_CENTER) { // When the user center presses, let them pick a contact. startActivityForResult( new Intent(Intent.ACTION_PICK, new Uri("content://contacts")), PICK_CONTACT_REQUEST); return true; } return false; } protected void onActivityResult(int requestCode, int resultCode, Intent data) { if (requestCode == PICK_CONTACT_REQUEST) { if (resultCode == RESULT_OK) { // A contact was picked. Here we will just display it // to the user. startActivity(new Intent(Intent.ACTION_VIEW, data)); } } } }

就是这么简单,然而现实是new Uri(“content://contacts”)报错了,Uri是个抽象类,不能这样实例化,然后我就像以前那样获取image那样处理

图片: Intent intent = new Intent(Intent.ACTION_PICK); intent.setType("image/*"); startActivityForResult(intent, requestCode); 联系人: Intent intent = new Intent(Intent.ACTION_PICK); intent.setType("content://contacts"); startActivityForResult(intent, GET_PHONENUM)

还是不行:No Activity found to handle Intent

然后找到网上一种通用的方法(很多人都这样写)

startActivityForResult( new Intent(Intent.ACTION_PICK, ContactsContract.Contacts.CONTENT_URI), GET_PHONENUM);

在onActivityResult中回调

// URI,每个ContentProvider定义一个唯一的公开的URI,用于指定到它的数据集 Uri contactData = data.getData(); // 查询就是输入URI等参数,其中URI是必须的,其他是可选的,如果系统能找到URI对应的ContentProvider将返回一个Cursor对象. Cursor cursor = managedQuery(contactData, null, null, null, null); cursor.moveToFirst(); // 获得DATA表中的名字 // username = cursor.getString(cursor.getColumnIndex(ContactsContract.Contacts.DISPLAY_NAME)); // 条件为联系人ID String contactId = cursor.getString(cursor.getColumnIndex(ContactsContract.Contacts._ID)); // 获得DATA表中的电话号码,条件为联系人ID,因为手机号码可能会有多个 Cursor phone = getContentResolver().query(ContactsContract.CommonDataKinds.Phone.CONTENT_URI, null,ContactsContract.CommonDataKinds.Phone.CONTACT_ID + " = "+ contactId, null, null); while (phone.moveToNext()) { String usernumber = phone.getString(phone.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER)); etPhone.setText(usernumber.replace(" ", "")); } if (!phone.isClosed()) { phone.close(); }

通过CONTACT_ID和cursor语句去获取联系人信息(读写联系人的权限要先有)

然而我的小米手机却只读到了一部分联系人,而且只有最近联系人才能获取到手机号码,系统栏上面显示“请选择联系人”,而饿了么打开之后是显示“请选择电话号码”。 既然这样,那应该是我的发起请求的 ContactsContract.Contacts.CONTENT_URI 不太准确 Contacts下面有很多种URI 在http://www.cnblogs.com/renyuan/archive/2012/08/28/2660297.html( 还有很多uri的集合) 找到了

ContactsContract.CommonDataKinds.Phone.CONTENT_URI

发现用了这个之后可以打开选择电话号码的页面了,但是可能因为联系人和电话号码不是在同个数据库,结果cursor没有找到联系人的号码,也就不会执行 phone.moveToNext()后的代码了。

还有这里managedQuery这个方法过时了,用CursorLoader处理。

然后,我决定还是去看看饿了么是怎么处理的(本来想应该很快解决的,毕竟反编译也要时间),解压apk后用dex2jar反编译dex,解压后有3个,用luyten查看源码,混淆加密是必须的,然后我就用adb命令

adb shell dumpsys activity | grep "mFocusedActivity"

获取当前的Activity(获取当前Activity也有个APP叫“当前Activity”,插一句,我发现酷安有很多好玩的软件,很程序员) 找到对应的包

这里的TYPE就是ContactsContract.CommonDataKinds.Phone.CONTENT_TYPE

然后回调,在aew类中的找到初始化的时候地址有setText,回调就没看到

这里有的类aew$3,在这个dex没找到

在另外的dex找到了,这里的e就是地址

完整代码

protected void onActivityResult(int requestCode, int resultCode, Intent intent) { super.onActivityResult(requestCode,resultCode,intent); if (requestCode == GET_PHONENUM) { if (resultCode == RESULT_OK) { final CursorLoader cursorLoader = new CursorLoader(this, intent.getData(), new String[] { "data1" }, null, null, null); cursorLoader.registerListener(1,new AddressCursorLoader()); cursorLoader.startLoading(); } } } public class AddressCursorLoader implements Loader.OnLoadCompleteListener<Cursor> { @Override public void onLoadComplete(Loader<Cursor> loader, Cursor cursor) { if (cursor == null) { return; } final int columnIndex = cursor.getColumnIndex("data1"); if (cursor.moveToFirst()) { final String string = cursor.getString(columnIndex); if (StringUtil.isValid(string)) { etPhone.setText(string.replace(" ","")); } } cursor.close(); }
转载请注明原文地址: https://www.6miu.com/read-25978.html

最新回复(0)