【问题标题】:Crash : requires android.permission.READ_CALL_LOG or android.permission.WRITE_CALL_LOG On some devices崩溃:在某些设备上需要 android.permission.READ_CALL_LOG 或 android.permission.WRITE_CALL_LOG
【发布时间】:2017-11-22 07:28:25
【问题描述】:

我制作了一个使用 ContentObserver 和服务在后台跟踪呼叫日志的应用程序(在前台运行)。 Manifest.permission.CALL_PHONE 这是我正在检查的权限

if (CallTrackingHelper.isCallPermissionEnabled(appContext)) {
        val task = OneoffTask.Builder()
                .setService(CallLogService::class.java)
                .setExecutionWindow(0, 6)
                .setTag("call-track")
                .setRequiredNetwork(Task.NETWORK_STATE_ANY)
                .setRequiresCharging(false)
                .setUpdateCurrent(true)
                .build()

        val mGcmNetworkManager = GcmNetworkManager.getInstance(appContext)
        mGcmNetworkManager.schedule(task)
    }

我启动了一个 gcmtaskservice 将呼叫日志上传到服务器

 override fun onRunTask(p0: TaskParams?): Int {
    val callLogs = CallTrackingHelper.getCallLog(lastSyncedIndex, this)
    //
}

在服务中我获取联系人

 fun getCallLog(id: Long, service: CallLogService): ArrayList<CallLogModel> {
    val callLogList = ArrayList<CallLogModel>()
    if (!isCallPermissionEnabled(service)) {
        return callLogList
    }
    var mCursor: Cursor? = null
    try {
        val args = arrayOf(id.toString())
        if (id != 0L) {
            mCursor = UCApplication
                    .getInstance()
                    .applicationContext
                    .contentResolver
                    .query(
                            CallLog.Calls.CONTENT_URI,
                            null,
                            "_id > ? ",
                            args,
                            null
                    )
        } else {
            mCursor = UCApplication
                    .getInstance()
                    .applicationContext
                    .contentResolver
                    .query(
                            CallLog.Calls.CONTENT_URI,
                            null,
                            null,
                            null,
                            CallLog.Calls._ID + " DESC" + " LIMIT 200 "
                    )
        }
    } catch (e: SecurityException) {
        //
    }
  //
    return callLogList
}

fun isCallPermissionEnabled(context: Context?): Boolean {
    if (context == null || ContextCompat.checkSelfPermission(context, PERMISSIONS)
            != PackageManager.PERMISSION_GRANTED) {
        return false
    }
    return true
}

我仍然收到很多 securityException,所以我必须添加 try and catch

【问题讨论】:

  • 请粘贴您得到的安全例外。
  • java.lang.Exception: Permission Denial: 从 ProcessRecord{d34d85f 31295 打开提供程序 com.android.providers.contacts.CallLogProvider: (pid=31295, uid=10132) 需要 android.permission.READ_CALL_LOG 或android.permission.WRITE_CALL_LOG
  • 你是否在清单中添加这些权限

标签: android


【解决方案1】:

您需要在 6.0 > 设备中获得运行时权限

像这样获得运行时权限:

    final String[] NECESSARY_PERMISSIONS = new String[] {Manifest.permission.GET_ACCOUNTS };

    if (ContextCompat.checkSelfPermission(DialerHomeActivity.this,
                    Manifest.permission.GET_ACCOUNTS) == PackageManager.PERMISSION_GRANTED) {

        //Permission is granted

    } else {

        //ask for permission

        ActivityCompat.requestPermissions(
                DialerHomeActivity.this,
                NECESSARY_PERMISSIONS, 123);
    }

【讨论】:

    【解决方案2】:

    将此添加到您的 manifest.xml 上面的 &lt;appication&gt; 标签:

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

    您可以阅读更多内容:here

    【讨论】:

    • 这两个都是他们的,但我为什么要需要 call_log 的联系权限
    • 啊,谢谢。抱歉,是我的错。 :D 你之前加过这个吗?
    【解决方案3】:

    问题是如果用户已经有一个应用程序 <uses-permission android:name="android.permission.READ_CALL_LOG"></uses-permission> <uses-permission android:name="android.permission.WRITE_CALL_LOG"></uses-permission>

    在清单中并提供通话权限或电话权限,更新后是否在更新通话/电话权限中添加这些权限仍然是他们的,但通话记录权限不是,所以您需要再次询问。 全新安装对我来说效果很好

    【讨论】:

    • 这条评论给了我类似问题的提示。如果您忘记“使用权限”然后添加它,除非您删除并重新安装应用程序,否则它不会更改。
    【解决方案4】:

    您是否请求了运行时权限?

    // Here, thisActivity is the current activity
    if (ContextCompat.checkSelfPermission(thisActivity,
                Manifest.permission.READ_CONTACTS)
        != PackageManager.PERMISSION_GRANTED) {
    
    // Should we show an explanation?
    if (ActivityCompat.shouldShowRequestPermissionRationale(thisActivity,
            Manifest.permission.READ_CONTACTS)) {
    
        // Show an explanation to the user *asynchronously* -- don't block
        // this thread waiting for the user's response! After the user
        // sees the explanation, try again to request the permission.
    
    } else {
    
        // No explanation needed, we can request the permission.
    
        ActivityCompat.requestPermissions(thisActivity,
                new String[]{Manifest.permission.READ_CONTACTS},
                MY_PERMISSIONS_REQUEST_READ_CONTACTS);
    
        // MY_PERMISSIONS_REQUEST_READ_CONTACTS is an
        // app-defined int constant. The callback method gets the
        // result of the request.
    }
    

    }

    检查一下:

    https://developer.android.com/training/permissions/requesting.html

    【讨论】:

    • 我不想请求我只是想检查是否允许他们做我的工作
    • java.lang.Exception: Permission Denial: 从 ProcessRecord{d34d85f 31295 打开提供程序 com.android.providers.contacts.CallLogProvider: (pid=31295, uid=10132) 需要 android.permission.READ_CALL_LOG 或android.permission.WRITE_CALL_LOG
    【解决方案5】:

    我也遇到了同样的问题。将此代码用于运行时权限:

    private static final int PHONE_LOG = 1;
    
    private void checkCallLogPermission() {
    
        if (ActivityCompat.checkSelfPermission(this, Manifest.permission.READ_CALL_LOG) != PackageManager.PERMISSION_GRANTED
                && ActivityCompat.checkSelfPermission(this, Manifest.permission.WRITE_CALL_LOG) != PackageManager.PERMISSION_GRANTED) {
            ActivityCompat.requestPermissions(this,
                    new String[]{Manifest.permission.READ_CALL_LOG, Manifest.permission.WRITE_CALL_LOG},PHONE_LOG);
    
            return;
        }
    }
    

    【讨论】:

      【解决方案6】:

      您可以使用此代码访问您手机的所有联系人日志

      private static final int PHONE_LOG_PERMISSION= 1;
      
      private void checkCallLogPermission() {
      
          if (ActivityCompat.checkSelfPermission(this, Manifest.permission.READ_CALL_LOG) != PackageManager.PERMISSION_GRANTED
                  && ActivityCompat.checkSelfPermission(this, Manifest.permission.WRITE_CALL_LOG) != PackageManager.PERMISSION_GRANTED) {
              ActivityCompat.requestPermissions(this,
                      new String[]{Manifest.permission.READ_CALL_LOG, Manifest.permission.WRITE_CALL_LOG},PHONE_LOG_PERMISSION);
      
              return;
          }
      }
      
      @Override
          public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
              if (requestCode == PHONE_LOG_PERMISSION) {
                  if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                      // Permission is granted
                      showContacts();
                  } else {
                      Toast.makeText(this, "Until you grant the permission, we canot display the names", Toast.LENGTH_SHORT).show();
                  }
              }
          }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2016-05-14
        • 1970-01-01
        • 2022-06-11
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2023-04-04
        相关资源
        最近更新 更多