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的時候,就提示,沒有獲取權限或者爲沒有手機號即可,哎,研究了好久,最後才知道並不能,,,

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章