需求:实现通话记录和短信同步,需要对应手机卡槽ID。
public List<CallRecordsEntity> getPhoneList(Context context) {
try {
Map<Integer, Integer> simInfo = BaseApp.getInstance().getSimInfo();
ContentResolver contentResolver = context.getContentResolver();
//调用query方法,传入URI参数,即CallLog.Calls.CONTENT_URI
//本节希望读取电话号码与事件两个字段,传入一个包含字段名的数组
Cursor cursor = contentResolver.query(CallLog.Calls.CONTENT_URI
, new String[]{
CallLog.Calls._ID,
CallLog.Calls.NUMBER,// 通话记录的电话号码
CallLog.Calls.DATE,// 通话记录的日期
CallLog.Calls.DURATION,// 通话时长
CallLog.Calls.TYPE, // 通话类型
"simid"// 卡槽ID
}
, null,
null
, CallLog.Calls.DEFAULT_SORT_ORDER// 按照时间逆序排列,最近打的最先显示
);
if (null == cursor) {
LogUtils.e("TAG_通话记录", "无通话记录");
return null;
}
//系统拨出通话记录集合
List<CallRecordsEntity> systemList = new ArrayList<>();
while (cursor.moveToNext()) {
@SuppressLint("Range") int simid = cursor.getInt(cursor.getColumnIndexOrThrow("simid"));
int slot_id = simInfo.containsKey(simid) ? simInfo.get(simid) : -1;//-1为以前插入的卡现在已经移除了 0为卡槽1 1为卡槽2 ...
@SuppressLint("Range") int type = cursor.getInt(cursor.getColumnIndexOrThrow(CallLog.Calls.TYPE));//传入(1),传出(2)和错过(3),4(语音邮件),5(拒绝)和6(拒绝列表)
@SuppressLint("Range") String number1 = cursor.getString(cursor.getColumnIndexOrThrow(CallLog.Calls.NUMBER));
// LogUtils.e("TAG_获取系统通话记录", "number=" + number1+";slot_id="+slot_id);
//只获取卡槽一
if (slot_id == 0) {
long l = System.currentTimeMillis();
long stateTime= Long.parseLong(cursor.getString(cursor.getColumnIndexOrThrow(CallLog.Calls.DATE)));
Long num = (l - stateTime)/86400000;//时间戳相差的毫秒数
// LogUtils.e("TAG_通话记录相差时间="+num);
if (num <= 30){
@SuppressLint("Range") String id = cursor.getString(cursor.getColumnIndexOrThrow(CallLog.Calls._ID));
@SuppressLint("Range") String number = cursor.getString(cursor.getColumnIndexOrThrow(CallLog.Calls.NUMBER));
@SuppressLint("Range") int duration = cursor.getInt(cursor.getColumnIndexOrThrow(CallLog.Calls.DURATION));
CallRecordsEntity systemEntity = new CallRecordsEntity();
systemEntity.setCallId(Long.valueOf(id));
systemEntity.setNumber(number);
systemEntity.setStartTime(stateTime);
systemEntity.setDuration(duration);
systemEntity.setType(type);
systemList.add(systemEntity);
// LogUtils.e("TAG_获取卡槽集合", "systemEntity="+systemEntity.toString());
}else {
return systemList;
}
}
}
return systemList;
} catch (NumberFormatException e) {
e.printStackTrace();
ToastUtil.showToast("无法匹配卡一通话清单!");
}
return null;
}
根据SimInfo获取卡槽信息,比对后,卡槽0对应卡槽1,自测后数据获取完整。
测试机为小米手机。
结果交给客户使用后,华为、vivo、OPPO、锤子都出现闪退现象。日志抓取后,发现部分机型无法获取simid。
通过不同机型录音文件的存储路径不同,猜测不同机型的simid命名不同。
public void editToFile(String str){
File file = new File(Environment.getExternalStorageDirectory(), "fileOut.txt");
LogUtils.e("TAG_记录file="+file);
try{
BufferedWriter writer = new BufferedWriter(new FileWriter(file,true));
writer.write(str);
writer.newLine();
writer.flush();
writer.close();
}
catch (IOException e) {
e.printStackTrace();
}
}
public void getCallLogs(){
StringBuffer buffer = new StringBuffer();
final String[] projection = null;
final String selection = null;
final String[] selectionArgs = null;
final String sortOrder = "DATE DESC";
Cursor cursor = getContentResolver().query(Uri.parse("content://call_log/calls"),projection,selection,selectionArgs,sortOrder);
int j=0;
//mEdit is EditText
if (cursor != null) {
int L=cursor.getColumnCount();
for(int i=0;i<L;i++)
buffer.append(cursor.getColumnName(i) + "\t");
buffer.append("\n");
while (cursor.moveToNext()) {
j++;
if(j>=5)
break;
for(int i=0;i<L;i++){
String callField = cursor.getString(i);
buffer.append(callField + "\t");
}
buffer.append("\n");
}
}
editToFile(buffer.toString());
}
通过上面代码可以获取本地通话清单所有字段,文件存储路径为根目录下:fileOut.txt。比对发现,锤子手机确实没有simid这个字段,而小米手机有。
华为、vivo、OPPO暂无测试机进行测试,有遇到相同问题的小伙伴可以测试后将结果告知与我,感谢