免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 1713 | 回复: 0
打印 上一主题 下一主题

[Android] 重新设计实现CSipSimple呼叫记录分组功能 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2016-09-10 11:32 |只看该作者 |倒序浏览
CSipSimple 原有的分组功能只能针对连续相同被叫号码,如果中间有间隔,相同的号码就不会被分成一组。这个实现很弱,也失去了分组的意义。下面针对这块功能的设计实现做下简单记录。

#### 1. 自己封装一个CursorLoader

这里取名为CalllogCursorLoader,在CallLogListFragment -> OnCreateLoader中:

~~~.java
    // Loader
    public Loader<Cursor> onCreateLoader(int id, Bundle args) {
            return new CalllogCursorLoader(getActivity());
    }
~~~

#### 2. CalllogCursorLoader.java 代码:

~~~.java
package org.phoneos.db;

import org.phoneos.api.SipManager;

import android.content.Context;
import android.database.Cursor;
import android.net.Uri;
import android.provider.CallLog;
import android.support.v4.content.AsyncTaskLoader;

public class CalllogCursorLoader extends AsyncTaskLoader<Cursor> {
        final ForceLoadContentObserver mObserver;
        private FastCursor fastCursor = null;
        private Cursor mObserverCursor = null;

        /**
         * Creates an empty unspecified CursorLoader. You must follow this with
         * calls to {@link #setUri(Uri)}, {@link #setSelection(String)}, etc to
         * specify the query to perform.
         */
        public CalllogCursorLoader(Context context) {
                super(context);
                mObserver = new ForceLoadContentObserver();
        }

        /* Runs on a worker thread */
        @Override
        public Cursor loadInBackground() {

                String[] fields = new String[] { CallLog.Calls._ID,
                                CallLog.Calls.CACHED_NAME, CallLog.Calls.CACHED_NUMBER_LABEL,
                                CallLog.Calls.CACHED_NUMBER_TYPE, CallLog.Calls.DURATION,
                                CallLog.Calls.DATE, CallLog.Calls.NEW, CallLog.Calls.NUMBER,
                                CallLog.Calls.TYPE, SipManager.CALLLOG_PROFILE_ID_FIELD };

                try {
                        if (mObserverCursor != null) {
                                mObserverCursor.close();
                                mObserverCursor = null;
                        }
                       
                        // get last inserted, a trick for observer data
                        mObserverCursor = getContext().getContentResolver().query(
                                        SipManager.CALLLOG_URI, fields, null, null,
                                        "date desc limit 1";

                        if (mObserverCursor != null) {
                                mObserverCursor.registerContentObserver(mObserver);
                        }

//                        if (fastCursor == null) {
                        Cursor cursor = getContext().getContentResolver().query(
                                        SipManager.CALLLOG_URI, fields, null, null, "date asc";

                        fastCursor = new FastCursor(cursor);

                        cursor.close();
                        cursor = null;

//                        } else {
//                                fastCursor.addCursor(mObserverCursor);
//                        }

//                        int min = fastCursor.getCount();
//                        if (min > 100)
//                                min = 100;
//                        for (int i = 0; i < min; i++) {
//                                fastCursor.moveToPosition(i);
//                                Log.d("LOADER", i + ", " + fastCursor.getString(fastCursor.getColumnIndex(CallLog.Calls.NUMBER)));
//                        }

                        return fastCursor;
                } finally {
                }
        }

        /* Runs on the UI thread */
        @Override
        public void deliverResult(Cursor cursor) {
                if (isReset()) {
                        if (fastCursor != null) {
                                fastCursor.close();
                        }
                }
               
                Cursor oldCursor = fastCursor;
                fastCursor = (FastCursor)cursor;
               
                if (isStarted()) {
                        super.deliverResult(cursor);
                }

                if (oldCursor != null && oldCursor != cursor && !oldCursor.isClosed()) {
                        oldCursor.close();
                }
        }

        /**
         * Starts an asynchronous load of the contacts list data. When the result is
         * ready the callbacks will be called on the UI thread. If a previous load
         * has been completed and is still valid the result may be passed to the
         * callbacks immediately.
         *
         * Must be called from the UI thread
         */
        @Override
        protected void onStartLoading() {
                if (fastCursor != null) {
                        deliverResult(fastCursor);
                }

                if (takeContentChanged() || fastCursor == null) {
                        forceLoad();
                }
        }

        /**
         * Must be called from the UI thread
         */
        @Override
        protected void onStopLoading() {
                // Attempt to cancel the current load task if possible.
                cancelLoad();
        }
       
        @Override
        public void onCanceled(Cursor data) {
                if (fastCursor != null && !fastCursor.isClosed()) {
                        fastCursor.close();
                }
        }

        @Override
        protected void onReset() {
                super.onReset();
                // Ensure the loader is stopped
                onStopLoading();

                if (fastCursor != null && !fastCursor.isClosed()) {
                        fastCursor.close();
                }

                fastCursor = null;
        }
       
}
~~~

#### 3. FastCursor.java 代码:

~~~.java
package org.phoneos.db;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;

import android.database.AbstractCursor;
import android.database.Cursor;
import android.database.MatrixCursor;
import android.provider.CallLog;
import android.util.Log;

// Custom a cursor, better group call logs, better performace
public class FastCursor extends AbstractCursor {
        private HashMap<String, ArrayList<Integer>> groupHashMap = new HashMap<String, ArrayList<Integer>>();
        private ArrayList<ArrayList<Integer>> groupList;
        private MatrixCursor mCursor;

        public FastCursor(Cursor cursor) {
                mCursor = new MatrixCursor(cursor.getColumnNames());

                int capacity = cursor.getCount() >> 3;
                if (capacity < 10)
                        capacity = 10;
                groupList = new ArrayList<ArrayList<Integer>>(capacity);

                addCursor(cursor);
        }

        // Cursor order by date asc
        public void addCursor(Cursor cursor) {
       
                for (int index = 0; index < cursor.getCount(); index++) {
                        cursor.moveToPosition(index);

                        Object[] columnValues = new Object[cursor.getColumnCount()];
                        columnValues[0] = cursor.getInt(0);
                        columnValues[1] = cursor.getString(1);
                        columnValues[2] = cursor.getString(2);
                        columnValues[3] = cursor.getInt(3);
                        columnValues[4] = cursor.getInt(4);
                        columnValues[5] = cursor.getLong(5);
                        columnValues[6] = cursor.getInt(6);
                        columnValues[7] = cursor.getString(7);
                        columnValues[8] = cursor.getInt(;
                        columnValues[9] = cursor.getInt(9);

                        mCursor.addRow(columnValues);

                        String number = cursor.getString(cursor.getColumnIndex(CallLog.Calls.NUMBER));
                        ArrayList<Integer> list = groupHashMap.get(number);
                        if (list == null) {
                                list = new ArrayList<Integer>(4);
                                groupHashMap.put(number, list);
                        }
                        else {
                                groupList.remove(list);
                        }

                        list.add(mCursor.getCount() - 1);
                        groupList.add(list);
                }

                // MUST reset mPos, workaroud for AbstractCursor.moveToPosition issue
                mPos = -1;

                Log.d("LOADER", groupHashMap.toString());
                Log.d("LOADER", groupList.toString());
        }

        @Override
        public boolean onMove(int oldPosition, int newPosition) {
                int cursorStartPos = 0;
                int length = groupList.size();
                ArrayList<Integer> list = null;
                for (int i = length - 1; i >= 0; i--) {
                        if (newPosition < (cursorStartPos + groupList.get(i).size())) {
                                list = groupList.get(i);
                                break;
                        }

                        cursorStartPos += groupList.get(i).size();
                }

                /* Move it to the right position */
                if (list != null) {
                        int index = list.size() - (newPosition - cursorStartPos) - 1;
                        Boolean ret = mCursor.moveToPosition(list.get(index));
                        return ret;
                }
                return false;
        }

        // AbstractCursor implementation.

        @Override
        public void close() {
                super.close();
               
                mCursor.close();
                groupHashMap.clear();
                groupList.clear();
               
                mCursor = null;
                groupHashMap = null;
                groupList = null;
        }

        @Override
        public int getCount() {
                return mCursor.getCount();
        }

        @Override
        public String[] getColumnNames() {
                return mCursor.getColumnNames();
        }

        @Override
        public String getString(int column) {
                return mCursor.getString(column);
        }

        @Override
        public short getShort(int column) {
                return mCursor.getShort(column);
        }

        @Override
        public int getInt(int column) {
                return mCursor.getInt(column);
        }

        @Override
        public long getLong(int column) {
                return mCursor.getLong(column);
        }

        @Override
        public float getFloat(int column) {
                return mCursor.getFloat(column);
        }

        @Override
        public double getDouble(int column) {
                return mCursor.getDouble(column);
        }

        @Override
        public byte[] getBlob(int column) {
                return mCursor.getBlob(column);
        }

        @Override
        public int getType(int column) {
                return mCursor.getType(column);
        }

        @Override
        public boolean isNull(int column) {
                return mCursor.isNull(column);
        }

}
~~~

#### 4. 修改CallLogGroupBuilder.java

~~~.diff
+++ b/src/org/phoneos/ui/calllog/CallLogGroupBuilder.java
@@ -81,16 +81,17 @@ public class CallLogGroupBuilder {
             final boolean sameNumber = equalNumbers(firstNumber, currentNumber);
             final boolean shouldGroup;

-            if (!sameNumber) {
-                // Should only group with calls from the same number.
-                shouldGroup = false;
-            } else if ( firstCallType == Calls.MISSED_TYPE) {
-                // Voicemail and missed calls should only be grouped with subsequent missed calls.
-                shouldGroup = callType == Calls.MISSED_TYPE;
-            } else {
-                // Incoming and outgoing calls group together.
-                shouldGroup = callType == Calls.INCOMING_TYPE || callType == Calls.OUTGOING_TYPE;
-            }
+            shouldGroup = sameNumber;
~~~

您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP