2017-04-26 40 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

相关问题