重新设计实现CSipSimple呼叫记录分组功能

本文介绍了一种改进CSipSimple中电话记录分组功能的方法,通过自定义CursorLoader和FastCursor,使得即使被叫号码间有间隔也能正确分组,增强了功能性和实用性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

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;
    ~~~

转自:http://www.yinqisen.cn/blog-510.html

内容概要:该研究通过在黑龙江省某示范村进行24小时实地测试,比较了燃煤炉具与自动/手动进料生物质炉具的污染物排放特征。结果显示,生物质炉具相比燃煤炉具显著降低了PM2.5、CO和SO2的排放(自动进料分别降低41.2%、54.3%、40.0%;手动进料降低35.3%、22.1%、20.0%),但NOx排放未降低甚至有所增加。研究还发现,经济性和便利性是影响生物质炉具推广的重要因素。该研究不仅提供了实际排放数据支持,还通过Python代码详细复现了排放特征比较、减排效果计算和结果可视化,进一步探讨了燃料性质、动态排放特征、碳平衡计算以及政策建议。 适合人群:从事环境科学研究的学者、政府环保部门工作人员、能源政策制定者、关注农村能源转型的社会人士。 使用场景及目标:①评估生物质炉具在农村地区的推广潜力;②为政策制定者提供科学依据,优化补贴政策;③帮助研究人员深入了解生物质炉具的排放特征和技术改进方向;④为企业研发更高效的生物质炉具提供参考。 其他说明:该研究通过大量数据分析和模拟,揭示了生物质炉具在实际应用中的优点和挑战,特别是NOx排放增加的问题。研究还提出了多项具体的技术改进方向和政策建议,如优化进料方式、提高热效率、建设本地颗粒厂等,为生物质炉具的广泛推广提供了可行路径。此外,研究还开发了一个智能政策建议生成系统,可以根据不同地区的特征定制化生成政策建议,为农村能源转型提供了有力支持。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值