CSipSimple 原有的分組功能只能針對連續相同被叫號碼,如果中間有間隔,相同的號碼就不會被分成一組。這個實現很弱,也失去了分組的意義。下面針對這塊功能的設計實現做下簡單記錄。
1. 自己封裝一個CursorLoader
這裏取名爲CalllogCursorLoader,在CallLogListFragment -> OnCreateLoader中:
~.java
// Loader
public Loader 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 {
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
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;
~~~