浏览 866 次
精华帖 (0) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (0)
|
|
---|---|
作者 | 正文 |
发表时间:2016-09-08
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(8); 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; ~~~ 转自:http://www.yinqisen.cn/blog-510.html 声明:ITeye文章版权属于作者,受法律保护。没有作者书面许可不得转载。
推荐链接
|
|
返回顶楼 | |