android 获取通讯录[BUG速记]

前言

最近开发中有读取手机通讯录的需求,傻的很认真的我,以为可以打开通讯录就代表不用再次动态申请权限,还是太天真,顾记录这次傻的很天真的日常,为了我的日常小鱼干,速记一下。

一.获取通讯录需要权限

1.android SDK>=23[6.0.0]的时候,需要权限,只需要加入即可
<uses-permission android:name="android.permission.READ_CONTACTS"/>
2.android SDK<23【6.0.0】的时候,需要动态申请权限
 <uses-permission android:name="android.permission.GET_ACCOUNTS"/>
3.权限扩展[防止以后写新功能]

group:android.permission-group.CONTACTS(联系人组)
android.permission.WRITE_CONTACTS(写入联系人)
android.permission.GET_ACCOUNTS(查找设备上的帐户)
android.permission.READ_CONTACTS(读取联系人)
android.permission.READ_CALL_LOG(读取通话记录)
android.permission.READ_PHONE_STATE(读取电话状态)
android.permission.CALL_PHONE(拨打电话)
android.permission.WRITE_CALL_LOG(修改通话记录)
android.permission.USE_SIP(SIP视频服务)
android.permission.PROCESS_OUTGOING_CALLS(程序监视,修改或放弃拨出电话)
com.android.voicemail.permission.ADD_VOICEMAIL(允许应用程序添加系统中的语音邮件)

group:android.permission-group.SMS(短信)
android.permission.READ_SMS(读取短信)
android.permission.RECEIVE_WAP_PUSH(接收WAP PUSH信息)
android.permission.RECEIVE_MMS()
android.permission.RECEIVE_SMS(接收短信权限)
android.permission.SEND_SMS(发送短信)
android.permission.READ_CELL_BROADCASTS(获取小区广播)

二.代码实现打开通讯录

因为本人项目是html与原生对接,顾

在通用html对接类中写入

/*
* 打开通讯录
* @param function
*/
@JavascriptInterface
public void openTelePhoneList(String function){
Logs.e(TAG,”openTelePhoneList——>”);
if(activity instanceof WebViewActivity) {
((WebViewActivity) activity).openTelePhoneList(function);
}
}

在WebViewActivity中写入打开通讯录代码

/*
* 打开通讯录
* @param function
*/
public void openTelePhoneList(String function){
if(!isFastDoubleClick()) {
if(!StringUtlis.isEmpty(function)) {
this.telePhoneBack=function;
Intent intent = new Intent();
intent.setAction(“android.intent.action.PICK”);
intent.addCategory(“android.intent.category.DEFAULT”);
intent.setType(“vnd.android.cursor.dir/phone_v2”);
activity.startActivityForResult(intent, ConstansCode.PICK_CONTACT);
}
}
}

在WebViewActivity中写入数据返回处理

@Override
public void onActivityResult(int requestCode, int resultCode, final Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (Activity.RESULT_OK == resultCode) {
if (requestCode==ConstansCode.PICK_CONTACT) {//选择通讯录
new Thread(new Runnable() {
@Override
public void run() {
if (StringUtlis.isEmpty(telePhoneBack)) {
return;
}
if (data != null) {
Uri uri = data.getData();
String phoneNum = null;
String contactName = null;
// 创建内容解析者
ContentResolver contentResolver = getContentResolver();
Cursor cursor = null;
if (uri != null) {
cursor = contentResolver.query(uri,
new String[]{“display_name”,”data1”}, null, null, null);
}
while (cursor.moveToNext()) {
contactName = cursor.getString(cursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME));
phoneNum = cursor.getString(cursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER));
}
cursor.close();
// 把电话号码中的 - 符号 替换成空格
if (phoneNum != null) {
phoneNum = phoneNum.replaceAll(“-“, ” “);
// 空格去掉 为什么不直接-替换成”” 因为测试的时候发现还是会有空格 只能这么处理
phoneNum= phoneNum.replaceAll(” “, “”);
}
if(StringUtlis.isEmpty(phoneNum)){
phoneNum=”“;
}
if(StringUtlis.isEmpty(contactName)){
contactName=”“;
}
final String telePhone=phoneNum,teleName=contactName;
activity.runOnUiThread(new Runnable() {
public void run() {
webView.loadUrl(“javascript:” + telePhoneBack + “(’ ” + teleName + “’,’”+telePhone+”’)”);
}
});
}
}
}).start();
}
}
}

在assets中写入index.html并调用该方法

<html xmlns:o="urn:schemas-microsoft-com:office:office"
      xmlns:w="urn:schemas-microsoft-com:office:word"
      xmlns:m="http://schemas.microsoft.com/office/2004/12/omml"
      xmlns="http://www.w3.org/TR/REC-html40">
<head>
    <title>测试打开通讯录</title>
    <script type="text/javascript">
    function test(){
       xxxxx.openTelePhoneList("ff");
     }
    function test1(dd,aa){
      xxxx.openTelePhoneList("ff");
    }
    function ff(aa,bb){
      alert("success"+aa+","+bb);
    }
    </script>
</head>
<body>
<p/>
<p/>
<input id="data" type="text" name="lname"/>
<p/>
<input type="submit" value="测试" onclick="test()"/>
<p/>
<p/>
<p/>
<button type="submit" onclick="test1()">测试Native js</button>
<p/>
<p/>
<p/>
<input type="text" id="testInput"/>
</body>
</html>

在WebViewActivity中加载这个html

WebSettings webSettings = webView.getSettings();
webSettings.setTextZoom(100);//设置web端界面不随html改变
webSettings.setDomStorageEnabled(true); // 使用localStorage
webSettings.setLoadWithOverviewMode(true); // 设置页面自适应屏幕
webSettings.setJavaScriptEnabled(true); // 支持javascript
webSettings.setNeedInitialFocus(false); // 阻止内部节点获取焦点
// 修复加载资源失败BUG start add by dlzhang 2015-03-26
//在API18以上已废弃。未来将不支持插件,不要使用。告诉WebView启用、禁用或者有即用
// (on demand)的插件,即用模式是指如果存在一个可以处理嵌入内容的插件,会显示一个占位图标,点击时开启。默认值OFF。
webSettings.setPluginState(PluginState.ON);
webSettings.setAllowFileAccess(true);
webSettings.setAllowContentAccess(true);
webSettings.setAllowFileAccessFromFileURLs(true);
webSettings.setAllowUniversalAccessFromFileURLs(true);
// 修复加载资源失败BUG end
webSettings.setSavePassword(false);
// SDK3.0以上开启硬件加速,部分机器
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
webView.setLayerType(View.LAYER_TYPE_SOFTWARE, null);
}
webView.setScrollBarStyle(View.SCROLLBARS_OUTSIDE_OVERLAY);
webView.setHorizontalScrollBarEnabled(false);//水平不显示
webView.setVerticalScrollBarEnabled(false); //垂直不显示
webView.requestFocusFromTouch();
webView.setFocusable(true);
webView.setLongClickable(true);
if (Build.VERSION.SDK_INT >= 21) {//添加这一句https和http都兼容,但其实中并没有什么用,只是为了防止有问题填写的
webSettings.setMixedContentMode(WebSettings.MIXED_CONTENT_ALWAYS_ALLOW);
}
webSettings.setDomStorageEnabled(true);
webSettings.setAppCacheMaxSize(1024 * 1024 * 8);//设置缓冲大小,我设的是8M
String appCacheDir = context.getDir(“cache”, Context.MODE_PRIVATE).getPath();
webSettings.setAppCachePath(appCacheDir);
webSettings.setRenderPriority(WebSettings.RenderPriority.HIGH);
webSettings.setAllowFileAccess(true);
webSettings.setAppCacheEnabled(true);
webSettings.setDomStorageEnabled(true);
webSettings.setCacheMode(WebSettings.LOAD_DEFAULT);
url=”file:///android_asset/index.html”;
webView.loadUrl(url);

上面的webviewSetting只需要支持javaScript即可,效果就可以打开通讯录了,并且可以选择,并且弹出name和tel,但是还缺少权限判断。

三.动态权限申请

我有两个项目,一个使用的tagAPI为18,一个为23,也就是说18的默认是打开的,这就很尴尬,天真的我尽然以为不需要动态申请权限,也是可爱的一逼,现在想想也是蛮傻的,算了,记录下,方便下次ctrl+c vs ctrl+v,哎,生活在于ctrl+c vs ctrl+v,之前谢了一个监听者模式的权限监听,然而编译的时候提示有非安全性操作,build的生成日志,顾准备写一个比较基础的,as编译套路多,哎,其实并不影响什么,就是看着不舒服,我要给他写个基础的,非安全性操作编译日志打出个人觉得还是很严重的,顾有了下面的代码。
if (ContextCompat.checkSelfPermission(this, android.Manifest.permission.READ_CONTACTS)
                != PackageManager.PERMISSION_GRANTED) {
            //申请权限  第二个参数是一个 数组 说明可以同时申请多个权限
            ActivityCompat.requestPermissions(this, new String[]{android.Manifest.permission.READ_CONTACTS}, 1);
        } else {//已授权
            obtionContacts();
        }`

上面判断权限是随便 copy的别人的代码,然而本人觉得然并卵,当然我也试了很多种其他方法,并不能够呵很好判断

&特别重要

结果,只是会获取第一次安装的结果,比如开启,或者关闭,当你认为点击设置关闭or开启之后,通过代码得到的状态一直都是true,哎,顾,本人参考了一些其他app的做法,就是当打开通讯录,然后选择到我们的界面获取得到的通讯录是null的时候,就提示,没有获取权限或者为没有手机号即可,哎,研究了好久,最后才知道并不能,,,

猜你喜欢

转载自blog.csdn.net/onlymetagain/article/details/80511126