Android:在呼叫结束后更新呼叫日志后查询呼叫日志
当呼叫结束时,如何确保在将呼叫信息写入数据库后查询呼叫日志 我正在使用Android:在呼叫结束后更新呼叫日志后查询呼叫日志,android,broadcastreceiver,Android,Broadcastreceiver,当呼叫结束时,如何确保在将呼叫信息写入数据库后查询呼叫日志 我正在使用BroadcastReceiver和android.intent.action.PHONE\u STATE上的intent过滤器查找通话结束,查找手机是否空闲 在此方面的任何帮助都将不胜感激 谢谢这是一个非常好的答案 请参阅下面的链接 当您看到上面的示例时,您将了解如何获取调用的结束状态,并且您还将记住,在调用结束后,call\u state\u IDLE将多次调用,因此您必须在某个位置获取一个静态变量,并且在理想状态下工作
BroadcastReceiver
和android.intent.action.PHONE\u STATE
上的intent过滤器查找通话结束,查找手机是否空闲
在此方面的任何帮助都将不胜感激
谢谢这是一个非常好的答案 请参阅下面的链接 当您看到上面的示例时,您将了解如何获取调用的结束状态,并且您还将记住,在调用结束后,
call\u state\u IDLE
将多次调用,因此您必须在某个位置获取一个静态变量,并且在理想状态下工作之前必须检查该变量值
编辑
Android在其内置数据库中存储呼叫日志信息。
因此,更好的解决方案是,当您的代码在OFFHOOK
状态之后调用IDLE
状态时,您可以将所有新的调用日志从内置数据库复制到数据库中,以获取调用日志的信息
您可以使用以下查询从内置数据库检索调用日志信息
Cursor c=context.getContentResolver().query(android.provider.CallLog.Calls.CONTENT_URI,null,null,null)代码>
EDIT2
以下是完整的示例
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
<receiver android:name=".PhoneStateBroadcastReceiver">
<intent-filter>
<action android:name="android.intent.action.PHONE_STATE"/>
</intent-filter>
</receiver>
这是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;
}
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);
}
}
这是广播接收机类
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;
}
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);
}
}
这是从内部数据库获取新呼叫日志的功能
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
<receiver android:name=".PhoneStateBroadcastReceiver">
<intent-filter>
<action android:name="android.intent.action.PHONE_STATE"/>
</intent-filter>
</receiver>
这是清单文件
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
<receiver android:name=".PhoneStateBroadcastReceiver">
<intent-filter>
<action android:name="android.intent.action.PHONE_STATE"/>
</intent-filter>
</receiver>
正确。我遇到的问题是,有时,BroadCastReceiver
会在调用日志更新之前触发,因此当您查询android.provider.CallLog.Calls.CONTENT\u URI
时,您错过了最近的通话。@gnub当您的手机状态变为“理想”至“挂断”,再变为“理想”状态时,意味着您的通话现在结束,此时您可以查询内部数据库以检索新的通话日志。您可以通过存储与内部数据库中完全相同的行id来保持通话记录,以便您可以查询数据库以获取新的通话记录调用日志大于最后一行id@gnub:您是否找到了处理此竞赛条件的解决方案。我也面临同样的问题。谢谢lot@gnub当前位置你说得对,我在寻找你提到的问题的解决方案时,终于想到了这个问题。作为一个临时且非常难看的修复,我用创建和调用一个新线程的start()
替换了您对fetchNewCallLogs()的调用,该线程只需休眠500毫秒,然后调用fetchNewCallLogs()
。UDF是什么??有人能解释一下吗?