这是实现后的效果图,懒得去找图片,能看就行了

android 的历史记录 安卓查看历史记录_数据

实现思路

1,通过内容提供者扫描手机的通话记录,并按照手机号进行排序,升序或降序都可以,再按照通话日期排序

Cursor cursor = cr.query(CallLog.Calls.CONTENT_URI,
                        null, null, null, CallLog.Calls.NUMBER + "," + CallLog.Calls.DATE + " DESC");

这里说明一下,按照手机号排序的原因是,为了方便整合同一个手机号的通话记录,日期排序是为了方便记录最后通话日期

这是我的bean

public class CallLogBean {
    /**
     * 通话类型 0为,未接,1为 拨出,2,为 拨入
     */
    private int type;
    /**
     * 备注名称
     */
    private String remarkName;
    /**
     * 通话日期
     */
    private String dates;
    /**
     * 通话时间
     */
    private String duration;

    public void setDuration(String duration) {
        this.duration = duration;
    }
    public String getDuration() {
        return duration;
    }

    /**
     * 通话类型 0为,未接,1为 拨出,2,为 拨入
     */
    public int getType() {
        return type;
    }
    /**
     * 通话类型 0为,未接,1为 拨出,2,为 拨入
     */
    public void setType(int type) {
        this.type = type;
    }

    public String getRemarkName() {
        return remarkName;
    }

    public void setRemarkName(String remarkName) {
        this.remarkName = remarkName;
    }


    public String getDates() {
        return dates;
    }

    public void setDates(String dates) {
        this.dates = dates;
    }

    @Override
    public String toString() {
        return "CallLogBean{" +
                "type=" + type +
                ", remarkName='" + remarkName + '\'' +
                ", dates=" + dates +
                '}';
    }
}



扫描之后就开始拿数据了,我这里存数据的类是用TreeMap<String,ArrayList<CallLogBean>>

然后再定义一个变量记录每次拿到的号码,用来判断这次的号码是否和上次拿到的号码一样,如果一样就用put

具体实现

if(number.equals(lastPhone)){
	ArrayList<CallLogBean> callLogBeens = callLogs.get(number);
	callLogBeens.add(callLogBean);
}else{
	ArrayList<CallLogBean> callLogBeens = new ArrayList<>();
	callLogBeens.add(callLogBean);
	callLogs.put(number,callLogBeens);
}
lastPhone = number;

接下来就是把拿到的数据存起来,剩下的没什么代码了,所以直接贴全部代码

private TreeMap<String, ArrayList<CallLogBean>> getCallLogs() {
        TreeMap<String, ArrayList<CallLogBean>> callLogs = new TreeMap<>();
        String lastPhone = "";
        //用于记录每个号码的最后通话日期
        ContentResolver cr = getActivity().getContentResolver();
        try (
                Cursor cursor = cr.query(CallLog.Calls.CONTENT_URI, // 查询通话记录的URI
                        null, null, null, CallLog.Calls.NUMBER + "," + CallLog.Calls.DATE + " DESC");
        ) {
            if (cursor == null) {
                return callLogs;
            }
            while (cursor.moveToNext()) {
                CallLogBean callLogBean = new CallLogBean();
                //备注名称
                callLogBean.setRemarkName(cursor.getString(cursor.getColumnIndex(CallLog.Calls.CACHED_NAME)));
                //通话类型
                int type = cursor.getInt(cursor.getColumnIndex(CallLog.Calls.TYPE));
                switch (type) {
                    case CallLog.Calls.INCOMING_TYPE:
                        callLogBean.setType(2);
                        break;
                    case CallLog.Calls.OUTGOING_TYPE:
                        callLogBean.setType(1);
                        break;
                    case CallLog.Calls.MISSED_TYPE:
                        callLogBean.setType(0);
                        break;
                }
                //通话日期
                String date = cursor.getString(cursor.getColumnIndexOrThrow(CallLog.Calls.DATE));
                callLogBean.setDates(date);
                //通话时间
                callLogBean.setDuration(cursor.getString(cursor.getColumnIndexOrThrow(CallLog.Calls.DURATION)));
                //通话号码
                String number = cursor.getString(cursor.getColumnIndex(CallLog.Calls.NUMBER));
                LogUtils.v("PhoneFragmentmsg",number + "   " + callLogBean);
                //如果号码存在就继续存通话记录

                if(number.equals(lastPhone)){
                    ArrayList<CallLogBean> callLogBeens = callLogs.get(number);
                    callLogBeens.add(callLogBean);
                }else{
                    ArrayList<CallLogBean> callLogBeens = new ArrayList<>();
                    callLogBeens.add(callLogBean);
                    callLogs.put(number,callLogBeens);
                }
                lastPhone = number;
            }
        }
        return callLogs;
    }

那个备注名是为了方便,所以存了很多次

通过这些代码就拿到全部的通话记录,并将同一个号码的通话记录都整合起来

剩下的就是如何把最后的通话类型,通话时间,电话号码等信息显示到listView上

这里再创建一个bean,用来存储要显示的数据

public class CallLogNeedAllBean implements Comparable<CallLogNeedAllBean>,Serializable{
    /**
     * 电话号码
     */
    private String number;
    /**
     * 备注名称
     */
    private String remarkName;
    /**
     * 通话次数
     */
    private int count;
    /**
     * 通话类型 0,未接 1.拨出 2,拨入
     */
    private int type;
    /**
     * 归属地
     */
    private String location;
    /**
     * 最后通话日期
     */
    private String lastDate;
    /**
     * 最后通话日期的Long值
     */
    private Long lastDateLong;

    private final long noLoseAccuracy = 14000000000L;

    public void setLastDateLong(Long lastDateLong) {
        this.lastDateLong = lastDateLong;
    }

    public Long getLastDateLong() {
        return lastDateLong;
    }

    public void setLastDate(String lastDate) {
        this.lastDate = lastDate;
    }

    public String getLastDate() {
        return lastDate;
    }

    public String getNumber() {
        return number;
    }

    public void setNumber(String number) {
        this.number = number;
    }

    public String getRemarkName() {
        return remarkName;
    }

    public void setRemarkName(String remarkName) {
        this.remarkName = remarkName;
    }

    public int getCount() {
        return count;
    }

    public void setCount(int count) {
        this.count = count;
    }

    public int getType() {
        return type;
    }

    public void setType(int type) {
        this.type = type;
    }

    public String getLocation() {
        return location;
    }

    public void setLocation(String location) {
        this.location = location;
    }

    @Override
    public String toString() {
        return "CallLogNeedAllBean{" +
                "number='" + number + '\'' +
                ", remarkName='" + remarkName + '\'' +
                ", count=" + count +
                ", type=" + type +
                ", location='" + location + '\'' +
                '}';
    }

    @Override
    public int compareTo(CallLogNeedAllBean callLogNeedAllBean) {
        return callLogNeedAllBean.lastDateLong.compareTo(lastDateLong);
    }
}

由于通话记录是按照日期降序排序的,所以这里用最后通话进行降序排序

最后再把拿到的数据封装成Tree<CallLogNeedAll,Tree<Long,CallLogDurationType>>

第1层的key为要显示的数据,value的key为通话日期,value为每次的通话时间和类型

我刚开始这样封装的目的是为了让通话日期逆序排序,但等我做完后才发现,其实也可以这样封装

TreeMap<CallLogNeedAll,XxxBean> XxxBean为,通话日期,通话时间,通话类型,因为这些数据在拿到的时候就已经排好序了,这样做有点多此一举

这是封装的代码

private void initListItem(TreeMap<String, ArrayList<CallLogBean>> simpleCallLogs, ArrayList<CallLogNeedAllBean> showItem) {
        Set<Map.Entry<String, ArrayList<CallLogBean>>> entry = simpleCallLogs.entrySet();
        for (Map.Entry<String, ArrayList<CallLogBean>> date : entry) {
            //电话号码
            String number = date.getKey();
            //备注名称
            String remarkName = date.getValue().get(0).getRemarkName();
            //最后通话日期
            Long lastDate = Long.valueOf(date.getValue().get(0).getDates());
            LogUtils.v("PhoneFragmentBkmsg","LastDate " + lastDate);
            //最后通话类型
            int lastType = date.getValue().get(0).getType();//因为已经排好序了,所以直接拿第一个就可以拿到最后通话类型
            //通话次数
            int count = date.getValue().size();
            CallLogNeedAllBean callLogNeedAllBean = new CallLogNeedAllBean();
            callLogNeedAllBean.setNumber(number);
            callLogNeedAllBean.setType(lastType);
            callLogNeedAllBean.setRemarkName(remarkName);
            callLogNeedAllBean.setCount(count);
            callLogNeedAllBean.setLastDateLong(lastDate);
            //最后通话日期,把他变成date对象
            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
            Date date1 = new Date(lastDate);
            String strDate = sdf.format(date1);
            callLogNeedAllBean.setLastDate(strDate);
            callLogNeedAllBean.setLocation(LocationDao.getLocation(getActivity(),number));
            //到这里Map的key就完成了
            //这是要存储的value,按照通话日期进行排序
            TreeMap<Long,CallLogDurationTypeBean> sortForDate = new TreeMap<>(new Comparator<Long>() {
                @Override
                public int compare(Long aLong, Long t1) {
                    return (int)(t1 - aLong);

                }
            });//这个应该看得懂吧
            for(CallLogBean callLogBean : date.getValue()){
                CallLogDurationTypeBean callLogDurationTypeBean = new CallLogDurationTypeBean();
                callLogDurationTypeBean.setType(callLogBean.getType());
                callLogDurationTypeBean.setDuration(callLogBean.getDuration());
                sortForDate.put(Long.valueOf(callLogBean.getDates()),callLogDurationTypeBean);
            }
            mAllCallLogMap.put(callLogNeedAllBean,sortForDate);
        }//单独写一个ArrayList,这样要做ListView显示就方便多了
        Set<Map.Entry<CallLogNeedAllBean,TreeMap<Long,CallLogDurationTypeBean>>> set = mAllCallLogMap.entrySet();
        for(Map.Entry<CallLogNeedAllBean,TreeMap<Long,CallLogDurationTypeBean>> s : set){
            showItem.add(s.getKey());
        }
    }

因为我的代码才写到这里,所以没有单个人的通话记录的代码,不过所有需要的数据都拿到了,所以剩下的应该都不是什么问题吧

大概的实现代码就这样,剩下的都比较简单,就不把代码贴出来了.