Android:在呼叫结束后更新呼叫日志后查询呼叫日志

gnu*_*nub 8 android broadcastreceiver

当呼叫结束时,如何在将呼叫信息写入数据库后查询呼叫记录?

我正在寻找呼叫的结束,使用一个BroadcastReceiver带有intent-filter android.intent.action.PHONE_STATE,寻找电话闲置.

任何有关这方面的帮助将不胜感激.

谢谢

Dha*_*dra 8

这是非常好的答案.

见下面的链接

点击这里

当您看到上面的示例时,您将学习如何获取调用的结束状态,并且您还要记住,在调用结束CALL_STATE_IDLE 后将调用多次,因此您必须在某些地方获取一个静态变量,并且您必须检查该变量值在你处于理想状态之前.

编辑

Android将呼叫日志信息存储在其内置数据库中.因此,更好的解决方案是,当您的代码调用IDLE状态后,OFFHOOK您可以将所有新调用的日志从内置数据库复制到您的数据库,以获取调用日志的信息

您可以使用以下查询从内置数据库中检索调用日志信息

Cursor c = context.getContentResolver().query(android.provider.CallLog.Calls.CONTENT_URI, null, null, null, null);

EDIT2

这是完整的例子

这是PhoneStateListener类

public class CustomPhoneStateListener extends PhoneStateListener {

Context context;
public CustomPhoneStateListener(Context context) {
super();
this.context = context;
}

@Override
public void onCallStateChanged(int state, String incomingNumber) {
super.onCallStateChanged(state, incomingNumber);

switch (state) {
    case TelephonyManager.CALL_STATE_IDLE:
        // Toast.makeText(context, "CALL_STATE_IDLE", Toast.LENGTH_LONG).show();
        if(UDF.phoneState != TelephonyManager.CALL_STATE_IDLE) {
            UDF.fetchNewCallLogs(context);
        } 
        break;
    case TelephonyManager.CALL_STATE_OFFHOOK:
         //Toast.makeText(context, "CALL_STATE_OFFHOOK", Toast.LENGTH_LONG).show();
        break;
    case TelephonyManager.CALL_STATE_RINGING:
         //Toast.makeText(context, "CALL_STATE_RINGING", Toast.LENGTH_LONG).show();
        endCallIfBlocked(incomingNumber);
        break;

    default:
        break;
}
UDF.phoneState = state;
}
Run Code Online (Sandbox Code Playgroud)

这是广播接收器类

public class PhoneStateBroadcastReceiver extends BroadcastReceiver{

    @Override
    public void onReceive(Context context, Intent intent) {
        //UDF.createTablesIfNotExists(context);
        TelephonyManager telephonyManager = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);
        telephonyManager.listen(new CustomPhoneStateListener(context), PhoneStateListener.LISTEN_CALL_STATE);
    }
}
Run Code Online (Sandbox Code Playgroud)

这是从内部数据库获取新呼叫日志的功能

public static void fetchNewCallLogs(Context context) {

        CallLogHelper callLogHelper = new CallLogHelper(context);
        callLogHelper.open();
        Long maxId = callLogHelper.getMaxId();

        Cursor c = context.getContentResolver().query(android.provider.CallLog.Calls.CONTENT_URI, null, "_id > ?", new String[]{String.valueOf(maxId)}, null);
        if(c != null && c.moveToFirst()) {
            while (c.isAfterLast() == false) {
                int _ID = c.getColumnIndex(android.provider.CallLog.Calls._ID);
                int _NUMBER = c.getColumnIndex(android.provider.CallLog.Calls.NUMBER);
                int _DATE =  c.getColumnIndex(android.provider.CallLog.Calls.DATE);
                int _DURATION =  c.getColumnIndex(android.provider.CallLog.Calls.DURATION);
                int _CALLTYPE =  c.getColumnIndex(android.provider.CallLog.Calls.TYPE);
                int _NAME =  c.getColumnIndex(android.provider.CallLog.Calls.CACHED_NAME);
                int _NUMBERTYPE =  c.getColumnIndex(android.provider.CallLog.Calls.CACHED_NUMBER_TYPE);
                int _NEW = c.getColumnIndex(android.provider.CallLog.Calls.NEW);

                String id = c.getString(_ID);
                String number = c.getString(_NUMBER);
                String date = c.getString(_DATE);
                String duration = c.getString(_DURATION);
                String callType = c.getString(_CALLTYPE);
                String name = c.getString(_NAME);
                String numberType = c.getString(_NUMBERTYPE);
                String _new = c.getString(_NEW);

                callLogHelper.createLog(id, number, date, duration, callType, name, numberType, _new, "N");

                c.moveToNext();
            }
        }
        callLogHelper.close();
    }


**Where** 


 => CallLogHelper is a helper class to communicate with my local database
    => callLogHelper.getMaxId(); will returns the maximum id of call logs in my local database and I am keeping the id in local database and internal database will be same
    => callLogHelper.createLog() is my function to insert call log in my local database
Run Code Online (Sandbox Code Playgroud)

这是清单文件

<receiver android:name=".PhoneStateBroadcastReceiver">
<intent-filter>
    <action android:name="android.intent.action.PHONE_STATE"/>     
</intent-filter>
</receiver>
Run Code Online (Sandbox Code Playgroud)

  • 正确.我遇到的问题是,有时在更新CallLog之前会触发`BroadCastReceiver`,因此当您查询`android.provider.CallLog.Calls.CONTENT_URI`时,您错过了最近的调用. (4认同)
  • @gnub:你是对的,我在寻找你提到的问题的解决方案时最终得到了这个问题.作为一个临时的,非常丑陋的修复,我用你的调用替换了你对`fetchNewCallLogs()`的调用,并调用了一个新线程的`start()`,它只是睡了500ms,然后调用`fetchNewCallLogs()` . (4认同)
  • @gnub:你找到了解决这种竞争条件的解决方案.我面临同样的问题.非常感谢 (2认同)