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.