2017-04-26 109 views
0

我有一個應用程序需要請求獲取Android設備上的聯繫人權限。我所知道的,我需要檢查的許可......Android權限拒絕 - 應用程序在FutureTask上崩潰

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M && checkSelfPermission(READ_CONTACTS) != PackageManager.PERMISSION_GRANTED) { 
    requestPermissions(new String[]{READ_CONTACTS}, PERMISSIONS_REQUEST_READ_CONTACTS); 
} else { 
    loadContacts(); 
} 

我的問題是,如果用戶拒絕訪問我的應用程序崩潰

FATAL EXCEPTION: AsyncTask #2 
Process: xxxxxxxxx, PID: 10376 
java.lang.RuntimeException: An error occurred while executing doInBackground() 
     at android.os.AsyncTask$3.done(AsyncTask.java:309) 
     at java.util.concurrent.FutureTask.finishCompletion(FutureTask.java:354) 
     at java.util.concurrent.FutureTask.setException(FutureTask.java:223) 
     at java.util.concurrent.FutureTask.run(FutureTask.java:242) 
     at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1113) 
     at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:588) 
     at java.lang.Thread.run(Thread.java:818) 
     Caused by: java.lang.SecurityException: Permission Denial: opening provider com.android.providers.contacts.ContactsProvider2 from ProcessRecord{3ad4917 10376:xxxxxxxxx/u0a196} (pid=10376, uid=10196) requires android.permission.READ_CONTACTS or android.permission.WRITE_CONTACTS 
     at android.os.Parcel.readException(Parcel.java:1620) 
     at android.os.Parcel.readException(Parcel.java:1573) 
     at android.app.ActivityManagerProxy.getContentProvider(ActivityManagerNative.java:4241) 
     at android.app.ActivityThread.acquireProvider(ActivityThread.java:6392) 
     at android.app.ContextImpl$ApplicationContentResolver.acquireUnstableProvider(ContextImpl.java:2321) 
     at android.content.ContentResolver.acquireUnstableProvider(ContentResolver.java:1521) 
     at android.content.ContentResolver.query(ContentResolver.java:486) 
     at android.content.CursorLoader.loadInBackground(CursorLoader.java:64) 
     at android.content.CursorLoader.loadInBackground(CursorLoader.java:42) 
     at android.content.AsyncTaskLoader.onLoadInBackground(AsyncTaskLoader.java:312) 
     at android.content.AsyncTaskLoader$LoadTask.doInBackground(AsyncTaskLoader.java:69) 
     at android.content.AsyncTaskLoader$LoadTask.doInBackground(AsyncTaskLoader.java:57) 
     at android.os.AsyncTask$2.call(AsyncTask.java:295) 
     at java.util.concurrent.FutureTask.run(FutureTask.java:237) 
     at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1113)  
     at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:588)  
     at java.lang.Thread.run(Thread.java:818)  

我明白,我不沒有訪問,但肯定應用程序不應該崩潰,它應該只是意味着我無法讀取聯繫人?這似乎是在談論一個FutureTask,我不確定這是什麼?我已經嘗試將所有實際進行聯繫人訪問的代碼註釋掉,並且在它嘗試讀取聯繫人之前,它仍然崩潰。我只想優雅地處理這種情況,我似乎沒有機會?

該清單的權限設置

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

另外,如果我進入應用管理器並更改設置的應用,使該應用程序並訪問應用程序運行正常接觸,而且我仍然不能訪問的接觸還沒有,這純粹是在啓動時

+0

功能checkSelfPermission必須有上下文參數(https://developer.android.com/reference/android/支持/ V4 /內容/ ContextCompat.htm)。你可以在這裏找到示例:https://developer.android.com/training/permissions/requesting.html – Guillaume

+0

@Guillaume - 感謝您的建議,我申請了這一改變,但我仍然得到相同的錯誤 – Flexicoder

+1

@Flexicoder看着你日誌沒有問題,即使在權限被撤銷後,你的應用程序仍在崩潰,因爲它正在繼續讀取。 您可以通過'SecurityException'看到它正在嘗試從'ContactsProvider2'中讀取數據。 您還沒有提供完整的代碼,所以它比較困難,但是您應該驗證如何以「代碼路徑」結束 - 觸發android.content.CursorLoader.loadInBackground(CursorLoader。)中'CursorLoader'的loadInBackground方法。java:64) 從日誌中看起來確實是這樣的 – HenriqueMS

回答

1

請使用下面的代碼來檢查權限

調用isStoragePermissionGranted1()首先在你的onCreate方法AFTE [R的loadContacts()

@Override 
public void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 

    if(isStoragePermissionGranted1()) 
     { 
      loadContacts(); 
     } 
} 


    public boolean isStoragePermissionGranted1() { 
    if (Build.VERSION.SDK_INT >= 23) { 
     if (checkSelfPermission(Manifest.permission.READ_CONTACTS) 
       == PackageManager.PERMISSION_GRANTED && checkSelfPermission(Manifest.permission.WRITE_CONTACTS) 
       == PackageManager.PERMISSION_GRANTED) { 
      Log.v("TAG", "Permission is granted"); 
      return true; 
     } else { 
      Log.v("TAG", "Permission is revoked"); 
      ActivityCompat.requestPermissions(WelcomeActivity.this, new String[]{android.Manifest.permission.READ_CONTACTS, Manifest.permission.WRITE_CONTACTS}, 1); 
      return false; 
     } 
    } else { //permission is automatically granted on sdk<23 upon installation 
     Log.v("TAG", "Permission is granted"); 
     return true; 
    } 
} 

要檢查的權限被拒絕或批准,我們可以使用

@Override 
    public void onRequestPermissionsResult(int requestCode, 
    String permissions[], int[] grantResults) { 
     switch (requestCode) { 
     case MY_PERMISSIONS_REQUEST_READ_CONTACTS: { 
     if (grantResults[0] == PackageManager.PERMISSION_GRANTED) { 

      // permission was granted, yay! do the 
      // task you need to do. 

     } else { 

      // permission denied, boo! Disable the 
      // functionality that depends on this permission. 
     } 
     return; 
    } 

    // other 'switch' lines to check for other 
    // permissions this app might request 
} 

}

希望這將有助於

+0

'loadContacts '即使'isStoragePermissionGranted1'返回false也會被調用。這不應該發生。 –

+0

是的你對我們可以使用,如果條件檢查。 – sukhbir

+0

事情是它甚至沒有得到我的checkpermission代碼現在沒有崩潰 - 因爲我已經拒絕訪問它不讓我走得更遠 – Flexicoder

0

我建議你使用ActivityCompat,支持更好

if (ContextCompat.checkSelfPermission(this,Manifest.permission.WRITE_CONTACTS) != PermissionChecker.PERMISSION_GRANTED) { 
     ActivityCompat.requestPermissions(new String[]{Manifest.permission.WRITE_CONTACTS}, PERMISSIONS_REQUEST_READ_CONTACTS); 
    } else { 
     loadContacts(); 
    } 
+0

事情是它甚至沒有得到我的checkpermission代碼現在沒有崩潰 - 因爲我我們拒絕訪問它,不讓我走得更遠 – Flexicoder

相關問題