1)mainActivity.java 功能文件
2)AndroidManifest.xml 添加相关权限
3)activity_main.xml 布局文件
添加一个button
package recognizerdemo.speech.baidu.com.mycalllog;
import android.Manifest;
import android.content.ContentValues;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.database.Cursor;
import android.net.Uri;
import android.provider.CallLog;
import android.provider.Settings;
import android.support.v4.app.ActivityCompat;
import android.support.v4.content.ContextCompat;
import android.support.v7.app.AlertDialog;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
public class MainActivity extends AppCompatActivity implements View.OnClickListener {
private String TAG = "MainActivity: ";
private List unPermissionList = new ArrayList(); //申请未得到授权的权限列表
private AlertDialog mPermissionDialog;
private String mPackName ; //获取 a'p'k 包名
private Button button;
private String[] permissionList = new String[]{ //申请的权限列表
Manifest.permission.READ_CALL_LOG,
Manifest.permission.WRITE_CALL_LOG
};
private Uri callUri = CallLog.Calls.CONTENT_URI;
private String[] columns = {CallLog.Calls.CACHED_NAME// 通话记录的联系人
, CallLog.Calls.NUMBER// 通话记录的电话号码
, CallLog.Calls.DATE// 通话记录的日期
, CallLog.Calls.DURATION// 通话时长
, CallLog.Calls.TYPE};// 通话类型}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
checkPermission(); //检查权限
addCallLOg(); //添加一个通话记录
button = (Button) findViewById(R.id.but_id);
button.setOnClickListener(this);
}
//权限判断和申请
public void checkPermission() {
unPermissionList.clear();//清空申请的没有通过的权限
//逐个判断是否还有未通过的权限
for (int i = 0; i < permissionList.length; i++) {
if (ContextCompat.checkSelfPermission(this, permissionList[i]) !=
PackageManager.PERMISSION_GRANTED) {
unPermissionList.add(permissionList[i]);//添加还未授予的权限到unPermissionList中
}
}
//有权限没有通过,需要申请
if (unPermissionList.size() > 0) {
ActivityCompat.requestPermissions( this,permissionList, 100);
Log.i(TAG, "check 有权限未通过");
} else {
//权限已经都通过了,可以将程序继续打开了
Log.i(TAG, "check 权限都已经申请通过");
}
}
/**
* 5.请求权限后回调的方法
*
* @param requestCode 是我们自己定义的权限请求码
* @param permissions 是我们请求的权限名称数组
* @param grantResults 是我们在弹出页面后是否允许权限的标识数组,数组的长度对应的是权限
* 名称数组的长度,数组的数据0表示允许权限,-1表示我们点击了禁止权限
*/
@Override
public void onRequestPermissionsResult(int requestCode, String[] permissions,
int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
Log.i(TAG,"申请结果反馈");
boolean hasPermissionDismiss = false;
if (100 == requestCode) {
for (int i = 0; i < grantResults.length; i++) {
if (grantResults[i] == -1) {
hasPermissionDismiss = true; //有权限没有通过
Log.i(TAG,"有权限没有被通过");
break;
}
}
}
if (hasPermissionDismiss) {//如果有没有被允许的权限
showPermissionDialog();
} else {
//权限已经都通过了,可以将程序继续打开了
Log.i(TAG, "onRequestPermissionsResult 权限都已经申请通过");
}
}
/**
* 不再提示权限时的展示对话框
*/
private void showPermissionDialog() {
Log.i(TAG,"mPackName: " + mPackName);
if (mPermissionDialog == null) {
mPermissionDialog = new AlertDialog.Builder(this)
.setMessage("已禁用权限,请手动授予")
.setPositiveButton("设置", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
cancelPermissionDialog();
Uri packageURI = Uri.parse("package:" + mPackName); //去设置里面设置
Intent intent = new Intent(Settings.
ACTION_APPLICATION_DETAILS_SETTINGS, packageURI);
startActivity(intent);
}
})
.setNegativeButton("取消", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
//关闭页面或者做其他操作
cancelPermissionDialog();
}
})
.create();
}
mPermissionDialog.show();
}
private void cancelPermissionDialog() {
mPermissionDialog.cancel();
}
@Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.but_id:
Log.i(TAG,"clock button");
getContentCallLog();
break;
default:
break;
}
}
private void addCallLOg() { //添加通话记录
Log.i(TAG,"添加通话 alog");
ContentValues values = new ContentValues();
values.clear();
values.put(CallLog.Calls.CACHED_NAME, "lum");
values.put(CallLog.Calls.NUMBER, 123456789);
values.put(CallLog.Calls.TYPE, "1");
/* values.put(CallLog.Calls.DATE, calllog.getmCallLogDate());
values.put(CallLog.Calls.DURATION, calllog.getmCallLogDuration());*/
values.put(CallLog.Calls.NEW, "0");// 0已看1未看 ,由于没有获取默认全为已读
getContentResolver().insert(CallLog.Calls.CONTENT_URI, values);
}
//获取通话记录
private void getContentCallLog() {
Cursor cursor = getContentResolver().query(callUri, // 查询通话记录的URI
columns
, null, null, CallLog.Calls.DEFAULT_SORT_ORDER// 按照时间逆序排列,最近打的最先显示
);
Log.i(TAG,"cursor count:" + cursor.getCount());
while (cursor.moveToNext()) {
String name = cursor.getString(cursor.getColumnIndex(CallLog.Calls.CACHED_NAME)); //姓名
String number = cursor.getString(cursor.getColumnIndex(CallLog.Calls.NUMBER)); //号码
long dateLong = cursor.getLong(cursor.getColumnIndex(CallLog.Calls.DATE)); //获取通话日期
String date = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date(dateLong));
String time = new SimpleDateFormat("HH:mm").format(new Date(dateLong));
int duration = cursor.getInt(cursor.getColumnIndex(CallLog.Calls.DURATION));//获取通话时长,值为多少秒
int type = cursor.getInt(cursor.getColumnIndex(CallLog.Calls.TYPE)); //获取通话类型:1.呼入2.呼出3.未接
String dayCurrent = new SimpleDateFormat("dd").format(new Date());
String dayRecord = new SimpleDateFormat("dd").format(new Date(dateLong));
Log.i(TAG,"Call log: " + "\n"
+ "name: " + name +"\n"
+ "phone number: " + number + "\n"
);
}
}
}
我们知道手机联系人通话记录是两张不同的数据表保存的
添加联系人权限
这个会获取手机里面联系人的姓名 、手机号,注意 手机号码再数据库里的保存格式
比如:
1-123-456-7890
//获取联系人
private void getConnect() {
Cursor cursor = getContentResolver().query(ContactsContract.CommonDataKinds.Phone.CONTENT_URI,
new String[] { "display_name", "sort_key", "contact_id",
"data1" }, null, null, null);
Log.i(TAG,"cursor connect count:" + cursor.getCount());
// moveToNext方法返回的是一个boolean类型的数据
while (cursor.moveToNext()) {
//读取通讯录的姓名
String name = cursor.getString(cursor
.getColumnIndex(ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME));
//读取通讯录的号码
String number = cursor.getString(cursor
.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER));
Log.i(TAG,"获取的通讯录是: " + name + "\n"
+ " number : " + number);
}
cursor.close();
}
private String[] projection = { ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME, ContactsContract.CommonDataKinds.Phone.NUMBER };
//根据手机号码查询联系人姓名
private void getConName() {
String displayName;
Cursor cursor = getContentResolver().query(ContactsContract.CommonDataKinds.Phone.CONTENT_URI, projection,
ContactsContract.CommonDataKinds.Phone.NUMBER + "=?",
new String[]{"1-123-456-7890"}, null);
Log.i(TAG,"cursor displayName count:" + cursor.getCount());
if (cursor != null) {
while (cursor.moveToNext()) {
displayName = cursor.getString(cursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME));
if (!TextUtils.isEmpty(displayName)) {
Log.i(TAG,"获取的通讯录 姓名是 : " + displayName);
break;
}
}
}
}
文件参考:
Android获取手机通话记录的方法
https://blog.csdn.net/qq_36158551/article/details/83829659
Android通过ContentProvider获取通话记录
https://blog.csdn.net/qq_34858228/article/details/69446911
android 读取手机通话记录
https://blog.csdn.net/fengpeihao/article/details/77749627
Android开发之获取通话记录
https://blog.csdn.net/monkey988/article/details/77529940/