简体   繁体   中英

How to access missed calls on call log?

I have searched for many solutions to access call logs but most of them was deprecated, and I really need the solution for accessing the call log and get the missed calls for my graduation project most of the codes had to have uses permission read and write call log but it didn't work too

Here's the code the uses permission and I have added in the manifest.

Uri allCalls = Uri.parse("content://call_log/calls");
                Cursor c = managedQuery(allCalls, null, null, null, null);
                String num= c.getString(c.getColumnIndex(CallLog.Calls.NUMBER));// for  number
                String name= c.getString(c.getColumnIndex(CallLog.Calls.CACHED_NAME));// for name
                String duration = c.getString(c.getColumnIndex(CallLog.Calls.DURATION));// for duration
                int type = Integer.parseInt(c.getString(c.getColumnIndex(CallLog.Calls.TYPE)));// for call type, Incoming or out going.
                Toast.makeText(MainActivity.this, num, Toast.LENGTH_SHORT).show();

Error:

java.lang.SecurityException: Permission Denial: opening provider com.android.providers.contacts.CallLogProvider from ProcessRecord{6cd48b2 23881:com.example.d_actions/u0a108} (pid=23881, uid=10108) requires android.permission.READ_CALL_LOG or android.permission.WRITE_CALL_LOG

Edit: the managedQuery(allCalls, null, null, null, null); is deprecated.

Add this to your manifest.xml above tag:

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

You also need to get run time permission in 6.0 > devices

  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);
    }

1. Manifest.xml

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

NOTE: Google Play restricts the use of high risk or sensitive permissions, including the SMS or Call Log permission groups. So in short, even if you ask permission at runtime, there's a high chance that your app will not be allowed in Google Play.

You can apply for an exception though. Google Play will review the request and grant exceptions on a case by case basis. The criteria for allowing an exception are mentioned here .

2 Sample

class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    setContentView(R.layout.activity_main)
    checkLogList()
}

private fun checkLogList() {
    if (checkPermission()) {
        readCallHistory()
    } else {
        requestPermission()
    }
}

private fun requestPermission() {
    ActivityCompat.requestPermissions(
        this,
        arrayOf(permission.READ_CALL_LOG),
        PERMISSION_REQUEST_CODE
    )
}

private fun checkPermission(): Boolean {
    val result = ContextCompat.checkSelfPermission(applicationContext, permission.READ_CALL_LOG)
    return result == PackageManager.PERMISSION_GRANTED
}

override fun onRequestPermissionsResult(
    requestCode: Int,
    permissions: Array<String>,
    grantResults: IntArray
) {
    super.onRequestPermissionsResult(requestCode, permissions, grantResults)
    when (requestCode) {
        PERMISSION_REQUEST_CODE -> if (grantResults.size > 0) {
            val locationAccepted = grantResults[0] == PackageManager.PERMISSION_GRANTED
            if (locationAccepted) Snackbar.make(
                findViewById(android.R.id.content),
                "Permission Granted, Now you can access log list",
                Snackbar.LENGTH_LONG
            ).show() else {
                Snackbar.make(
                    findViewById(android.R.id.content),
                    "Permission Denied, You cannot access log list.",
                    Snackbar.LENGTH_LONG
                ).show()
                if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
                    if (shouldShowRequestPermissionRationale(permission.READ_CALL_LOG)) {
                        showMessageOKCancel(
                            "You need to allow access to the permissions"
                        ) { dialog, which ->
                            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
                                requestPermissions(
                                    arrayOf(permission.READ_CALL_LOG),
                                    PERMISSION_REQUEST_CODE
                                )
                            }
                        }
                        return
                    }
                }
            }
        }
    }
}

private fun showMessageOKCancel(message: String, okListener: DialogInterface.OnClickListener) {
    AlertDialog.Builder(this@MainActivity)
        .setMessage(message)
        .setPositiveButton("OK", okListener)
        .setNegativeButton("Cancel", null)
        .create()
        .show()
}

fun readCallHistory() {
    val managedCursor =
        this.contentResolver.query(CallLog.Calls.CONTENT_URI, null, null, null, null)
    val number = managedCursor!!.getColumnIndex(CallLog.Calls.NUMBER)
    val type = managedCursor.getColumnIndex(CallLog.Calls.TYPE)
    val date = managedCursor.getColumnIndex(CallLog.Calls.DATE)
    val duration = managedCursor.getColumnIndex(CallLog.Calls.DURATION)
    while (managedCursor.moveToNext()) {
        val phNumber = managedCursor.getString(number)
        val callType = managedCursor.getString(type)
        val callDate = managedCursor.getString(date)
        val callDayTime = Date(java.lang.Long.valueOf(callDate))
        val callDuration = managedCursor.getString(duration)
        var dir: String? = null
        val dircode: Int = callType.toInt()
        when (dircode) {
            CallLog.Calls.OUTGOING_TYPE -> dir = "OUTGOING"
            CallLog.Calls.INCOMING_TYPE -> dir = "INCOMING"
            CallLog.Calls.MISSED_TYPE -> dir = "MISSED"
        }
        Log.e("print_output", "Phone Number:--- $phNumber")
        Log.e("print_output", "Call Type:--- $dir")
        Log.e("print_output", "Call Date:--- $callDayTime")
        Log.e("print_output", "Call duration in sec :--- $callDuration")
    }
    managedCursor.close()
}

companion object {
    private const val PERMISSION_REQUEST_CODE = 200
}

}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM