關於讀取通訊錄時應用秒退的問題

最近在學習Android內容提供商(Content Providers)這部分時,模仿書上的獲取通訊錄的程序,基本一樣的程序代碼,打開應用卻秒退了:
這裏寫圖片描述
看了一下運行記錄,有以下這段錯誤提示:

“Caused by: java.lang.SecurityException: Permission Denial:
opening provider com.android.providers.contacts.ContactsProvider2 from
ProcessRecord{ea02adc 6872:com.example.administrator.phonebook/u0a85}
(pid=6872, uid=10085) requires android.permission.READ_CONTACTS or
android.permission.WRITE_CONTACTS”

錯誤來源是下面這句獲取通訊錄信息的代碼:

Cursor cursor = this.getContentResolver().query(contacts,null,null,null,null);

看到permission就大概知道是權限的問題了,在網上查了一下,好像要在Manifest裏面添加下面這句標籤:

<uses-permission android:name="android.permission.READ_CONTACTS" />

然後又滿懷期待地運行了一下。。。還是停止運行+一樣的問題提示。突然間就覺得碰上大麻煩了,權限已經允許了,卻還是給我報告權限問題,大白天見鬼了?
經過一個晚上的資料查找,加上貢獻自己的主用機小米做試驗,終於知道了問題產生的原因:


Android系統的SDK在23以上的版本對於權限的獲取需要開發者自己添加代碼去詢問用戶!
換句話說,在Android 6.0 以下的版本,在安裝app時,會有一堆一般人不會去看的權限獲取提示,而這顯得不安全,於是在Android 6.0 以上版本,安裝app時不再有顯示權限,取而代之的是在應用運行時會彈出提示框讓用戶自己確認是否運行應用的該項權限。


像我這裏用的Android 7.0允許環境既沒有允許獲取通訊錄的權限,又沒有加入異常處理機制,所以就直接秒退了。
雖然知道了原因,解決辦法也找了很長時間,需要在獲取通訊錄操作前加如下代碼:

//判斷是否有某種權限
        if (PackageManager.PERMISSION_GRANTED == ContextCompat.checkSelfPermission(MainActivity.this,android.Manifest.permission.READ_CONTACTS)) {
            //has permission, do operation directly
            Toast.makeText(this,"有權限了",Toast.LENGTH_SHORT).show();
        }
        else
        {
            Toast.makeText(this,"沒有權限",Toast.LENGTH_SHORT).show();
            //沒有權限在此處獲取權限
            ActivityCompat.requestPermissions(this, new String[]{android.Manifest.permission.READ_CONTACTS},1);
            //return;
        }

總之權限只要詢問一次被允許了,以後就不會再被禁止,除非用戶手動關閉,ActivityCompat.requestPermissions的最後一個參數”1”是一個與權限狀態返回相關的代碼,是自己隨便定義的,最好用一個final宏代替。

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