英文:
How to access missed calls on call log?
问题
我已经搜索了许多访问通话记录的解决方案,但其中大多数已被弃用,我真的需要访问通话记录并在我的毕业项目中获取未接来电的解决方案。
大多数代码都需要使用读取和写入通话记录的权限,但这也不起作用。
以下是使用权限的代码,并且我已经在清单中添加了权限。
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));// 获取号码
String name= c.getString(c.getColumnIndex(CallLog.Calls.CACHED_NAME));// 获取名称
String duration = c.getString(c.getColumnIndex(CallLog.Calls.DURATION));// 获取通话时长
int type = Integer.parseInt(c.getString(c.getColumnIndex(CallLog.Calls.TYPE)));// 获取通话类型,呼入或呼出。
Toast.makeText(MainActivity.this, num, Toast.LENGTH_SHORT).show();
错误:
java.lang.SecurityException: 权限拒绝:从ProcessRecord{6cd48b2 23881:com.example.d_actions/u0a108}(pid=23881,uid=10108)打开提供程序com.android.providers.contacts.CallLogProvider需要android.permission.READ_CALL_LOG或android.permission.WRITE_CALL_LOG
编辑:
managedQuery(allCalls, null, null, null, null);
已被弃用。
英文:
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.
答案1
得分: 0
在你的manifest.xml文件中<application>标签之前添加以下内容:
<uses-permission android:name="android.permission.READ_CALL_LOG"></uses-permission>
<uses-permission android:name="android.permission.WRITE_CALL_LOG"></uses-permission>
你还需要在6.0及以上的设备上获取运行时权限:
final String[] NECESSARY_PERMISSIONS = new String[] {Manifest.permission.GET_ACCOUNTS };
if (ContextCompat.checkSelfPermission(DialerHomeActivity.this,
Manifest.permission.GET_ACCOUNTS) == PackageManager.PERMISSION_GRANTED) {
//权限已授予
} else {
//请求权限
ActivityCompat.requestPermissions(
DialerHomeActivity.this,
NECESSARY_PERMISSIONS, 123);
}
英文:
Add this to your manifest.xml above <appication> 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);
}
答案2
得分: 0
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
}
}
英文:
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
}
}
专注分享java语言的经验与见解,让所有开发者获益!
评论