android 通话记录的导入/导出

涉及到对通话记录的读和写、需要在sd卡上写存放通话记录数据的文件,所以需要加权限:

    <uses-permission android:name="android.permission.READ_CALL_LOG"/>
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
    <uses-permission android:name="android.permission.WRITE_CALL_LOG"/>

首先,通话记录的获取,只需要获取部分字段即可满足即可:

将数据保存到一个自定义的Model对象中。

Cursor cursor = mContext.getContentResolver().query(CallLog.Calls.CONTENT_URI, null, "date > ?", new String[] { "" + timestamp }, CallLog.Calls.DEFAULT_SORT_ORDER);
                while (cursor.moveToNext()) {
                    CalllogModel calllogModel = new CalllogModel();
                    // name
                    calllogModel.setName(cursor.getString(cursor.getColumnIndex(CallLog.Calls.CACHED_NAME)));
                    // start call datetime
                    calllogModel.setDatetime(cursor.getLong(cursor.getColumnIndex(CallLog.Calls.DATE)));
                    // phonenumber
                    calllogModel.setNumber(cursor.getString(cursor.getColumnIndex(CallLog.Calls.NUMBER)));
                    // duration
                    calllogModel.setDuration(cursor.getLong(cursor.getColumnIndex(CallLog.Calls.DURATION)));
                    // call type
                    calllogModel.setType(cursor.getInt(cursor.getColumnIndex(CallLog.Calls.TYPE)));
                    // is read
                    calllogModel.setIs_read(cursor.getInt(cursor.getColumnIndex(CallLog.Calls.IS_READ)));
                    modifyVector(0, calllogModel, ADD_VECTOR); //调用保存到文件的方法
                }
                cursor.close();
                cursor = null;

将通话记录导入到系统的数据库中:

                ContentResolver contentResolver = mContext.getContentResolver();
                values.put(CallLog.Calls.CACHED_NAME, calllogModel.getName());
                values.put(CallLog.Calls.NUMBER, calllogModel.getNumber());
                values.put(CallLog.Calls.DATE, calllogModel.getDatetime());
                values.put(CallLog.Calls.DURATION, calllogModel.getDuration());
                values.put(CallLog.Calls.IS_READ, calllogModel.getIs_read());
                values.put(CallLog.Calls.TYPE, calllogModel.getType());
                contentResolver.insert(CallLog.Calls.CONTENT_URI, values);

还有两点考虑:

1. 通话记录的保存方式:

选择通过文本文件来保存,一行算足一条通话记录。

每个通话记录以字符串的形式保存到文本文件

java中提供BufferReader和BufferWriter两个类可以支持一行一行的读和写

在导入通话记录的时候,读到一行记录,就处理一行:string->json->model->contentvalues->contentResolver.insert

2. 处理效率和OOM异常避免的情况

在处理导出通话记录的时候,通话记录的条数可能成千上万条。

在这样的情况下,需要注意:
a. 那么多记录数不能全部写到内存中,暂据的内存太大,容易报OOM的错误

b. 将那些数据写入到文件中的时候,不能每一次都打开IO流和关闭IO流,耗时耗资源

解决的方法是,维护一个集合Vector<model>,当从系统数据库中读取到一条记录的时候,将其vector,add(model);当每处理完一个model之后,通过vector.remove(0)获取新的Model对象进行处理。

读取记录的过程和处理记录的过程,用两个线程同步执行。

保证多线程下数据的安全考虑,对该集合变量的操作,用同步锁对其进行限定

    /**
     * 需要增加一个对象到集合的时候,type=1;需要获取一个对象的时候,type=2
     * @param index
     * @param calllogModel
     * @param type
     * @return
     */
    private static synchronized CalllogModel modifyVector(int index, CalllogModel calllogModel, int type) {
        switch (type) {
        case 1:
            if (calllogModels.size()>1000) { //确保集合的体积不会过大
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            } 
            calllogModels.add(calllogModel);
            break;
        case 2:
            if (!calllogModels.isEmpty()) {
                return calllogModels.remove(0);
            } else {
                return null;
            }
        default:
            break;
        }
        return null;
    }





  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值