获取手机通话记录流程:
1、 获取ContentResolver;
ContentResolver resolver = getContentResolver();
2、resolver.query(*);
需要传入通话记录的URI:CallLog.Calls.CONTENT_URI
3、对查询得到的Cursor进行数据获取.
主要代码如下:
MainActivity
public class MainActivity extends AppCompatActivity {
private ListView slvItem;
private List<Map<String, String>> dataList;
private ContentResolver resolver;
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};// 通话类型}
private ImpowerAdapter impowerAdapter;
private String mobile;//被授权人电话号码
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
initView();
getPersimmionInfo();
}
private void initView() {
slvItem = findViewById(R.id.slv_impower_item);
}
//**************授权信息
private void getPersimmionInfo() {
if (Build.VERSION.SDK_INT >= 23) {
//1. 检测是否添加权限 PERMISSION_GRANTED 表示已经授权并可以使用
if (ContextCompat.checkSelfPermission(this, Manifest.permission.READ_CALL_LOG) != PackageManager.PERMISSION_GRANTED) {
//手机为Android6.0的版本,权限未授权去i请授权
//2. 申请请求授权权限
//1. Activity
// 2. 申请的权限名称
// 3. 申请权限的 请求码
ActivityCompat.requestPermissions(this, new String[]
{Manifest.permission.READ_CALL_LOG//通话记录
}, 1005);
} else {//手机为Android6.0的版本,权限已授权可以使用
// 执行下一步
initContacts();
}
} else {//手机为Android6.0以前的版本,可以使用
initContacts();
}
}
private void initContacts() {
dataList = getDataList();
impowerAdapter = new ImpowerAdapter(this, dataList);
slvItem.setAdapter(impowerAdapter);
slvItem.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
mobile = dataList.get(position).get("number")
.replaceAll(" ", "")
.replaceAll("\\+", "")
.replaceAll("-", "");
String nameStr = dataList.get(position).get("name");
Toast.makeText(MainActivity.this, "=mobile:" + mobile + "=nameStr:" + nameStr, Toast.LENGTH_SHORT).show();
}
});
}
/**
* 读取数据
*
* @return 读取到的数据
*/
private List<Map<String, String>> getDataList() {
// 1.获得ContentResolver
resolver = getContentResolver();
if (ContextCompat.checkSelfPermission(this, Manifest.permission.READ_CALL_LOG) != PackageManager.PERMISSION_GRANTED) {
}
// 2.利用ContentResolver的query方法查询通话记录数据库
/**
* @param uri 需要查询的URI,(这个URI是ContentProvider提供的)
* @param projection 需要查询的字段
* @param selection sql语句where之后的语句
* @param selectionArgs ?占位符代表的数据
* @param sortOrder 排序方式
*/
Cursor cursor = resolver.query(callUri, // 查询通话记录的URI
columns
, null, null, CallLog.Calls.DEFAULT_SORT_ORDER// 按照时间逆序排列,最近打的最先显示
);
// 3.通过Cursor获得数据
List<Map<String, String>> list = new ArrayList<>();
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));
String dayCurrent = new SimpleDateFormat("dd").format(new Date());
String dayRecord = new SimpleDateFormat("dd").format(new Date(dateLong));
String typeString = "";
switch (type) {
case CallLog.Calls.INCOMING_TYPE:
//"打入"
typeString = "打入";
break;
case CallLog.Calls.OUTGOING_TYPE:
//"打出"
typeString = "打出";
break;
case CallLog.Calls.MISSED_TYPE:
//"未接"
typeString = "未接";
break;
default:
break;
}
if (MobileUtil.isMobileNO(number)) {
String dayString = "";
if ((Integer.parseInt(dayCurrent)) == (Integer.parseInt(dayRecord))) {
//今天
dayString = "今天";
} else if ((Integer.parseInt(dayCurrent) - 1) == (Integer.parseInt(dayRecord))) {
//昨天
dayString = "昨天";
} else {
//前天
dayString = "前天";
}
long day_lead = TimeStampUtil.compareDayTime(date);
if (day_lead < 2) {//只显示48小时以内通话记录,防止通 //话记录数据过多影响加载速度
Map<String, String> map = new HashMap<>();
//"未备注联系人"
map.put("name", (name == null) ? "未备注联系人" : name);//姓名
map.put("number", number);//手机号
map.put("date", date);//通话日期
// "分钟"
map.put("duration", (duration / 60) + "分钟");//时长
map.put("type", typeString);//类型
map.put("time", time);//通话时间
map.put("day", dayString);//
map.put("time_lead", TimeStampUtil.compareTime(date));//
list.add(map);
} else {
return list;
}
}
}
return list;
}
}
Adapter
public class ImpowerAdapter extends BaseAdapter {
private Context context;
private List<Map<String, String>> list;
public ImpowerAdapter(Context context, List<Map<String, String>> list) {
this.context = context;
this.list = list;
}
@Override
public int getCount() {
return list.size();
}
@Override
public Object getItem(int position) {
return list.get(position);
}
@Override
public long getItemId(int position) {
return position;
}
private ImpowerCustomHolder holder;
@Override
public View getView(int position, View convertView, ViewGroup parent) {
if (convertView == null) {
convertView = LayoutInflater.from(context).inflate(R.layout.slv_impower_item, parent, false);
holder = new ImpowerCustomHolder();
holder.ivImg = convertView.findViewById(R.id.iv_impower_item_img);
holder.tvName = convertView.findViewById(R.id.tv_impower_item_name);
holder.tvDuration = convertView.findViewById(R.id.tv_impower_item_duration);
holder.tvTimeLead = convertView.findViewById(R.id.tv_impower_item_time_lead);
convertView.setTag(holder);
} else {
holder = (ImpowerCustomHolder) convertView.getTag();
}
/**
* 通话类型
*/
if (TextUtils.equals((list.get(position).get("type") + ""), "打入")) { //"打入"
holder.ivImg.setImageResource(R.drawable.phone_receive);
holder.tvDuration.setTextColor(context.getResources().getColor(R.color.primary_font_title));
holder.tvDuration.setText(list.get(position).get("duration") + "");// 通话时长
} else if (TextUtils.equals((list.get(position).get("type") + ""), "打出")) { //"打出"
holder.ivImg.setImageResource(R.drawable.phone_call);
holder.tvDuration.setTextColor(context.getResources().getColor(R.color.primary_font_title));
holder.tvDuration.setText(list.get(position).get("duration") + "");// 通话时长
} else if (TextUtils.equals((list.get(position).get("type") + ""), "未接")) { //"未接"
holder.ivImg.setImageResource(R.drawable.phone_no);
holder.tvDuration.setTextColor(context.getResources().getColor(R.color.primary_red,null));
holder.tvDuration.setText("未接通");// 通话时长
} else {
holder.ivImg.setImageResource(R.drawable.phone_no);
holder.tvDuration.setTextColor(context.getResources().getColor(R.color.primary_red));
holder.tvDuration.setText("未接通");// 通话时长
}
/**
* 通话记录的联系人
*/
if (TextUtils.equals((list.get(position).get("name") + ""), "未备注联系人")) {// 通话记录的联系人
holder.tvName.setText(list.get(position).get("number"));// 通话记录的联系人
} else {
holder.tvName.setText(list.get(position).get("name") + "(" + list.get(position).get("number") + ")");// 通话记录的联系人
}
holder.tvTimeLead.setText(list.get(position).get("day") + " " + list.get(position).get("time"));// 通话距离
return convertView;
}
class ImpowerCustomHolder {
private ImageView ivImg;//图标
private TextView tvName,//名字
tvDuration,//时长
tvTimeLead;//时间差
}
}
主布局activity_main.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context=".MainActivity">
<ListView
android:id="@+id/slv_impower_item"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/primary_white"
android:divider="@color/gray"
android:dividerHeight="1dp" />
</LinearLayout>
在清单文件中注册读取通话记录的权限:
<uses-permission android:name="android.permission.READ_CALL_LOG" />