我正在尝试为应用开发一个功能,其中包含一个"代码列表"你输入并逐个拨打。我已经查看了TelephonyManager并跟随tutorial开发了一个带有响应侦听器的广播接收器,但它并不总能正常工作。 一个想法是存储SharedPref中所需的所有数字。如果 Activity (仅针对dialer的意图创建)进入onStop()(意思是上面,拨号器屏幕打开)然后进入onResume()(调用结束并恢复活动),I将删除最后从SharedPref拨打的号码,然后,如果仍然存在,再次打开拨号器。广播确保TelephonyManager的状态流不是一次" OFFHOOK => IDLE",它会将用户返回到 Activity 。简短的故事,它并不总是如此表现。
我该如何解决这个问题?
修改
我的解决方案是
创建一个doPhoneCall()函数,用于处理意图创建和部署本身。
@Override
protected void doPhoneCall(){
super.onResume();
wentIntoCall = false;
/** More code here for dialing */
}
将此函数放入onResume()。即使onResume被多次调用,goIntoCall布尔值也会确保函数不会被多次调用。
@Override
protected void onResume() {
super.onResume();
if(wentIntoCall)
doPhoneCall();
}
请记住,在通话后,手机应该返回到之前的状态,因此它将返回我们正在进行的Activity调用,我们将向活动添加一个CallListener,并在IDLE的情况,基于上面链接的教程,我们使goIntoCall成为现实。 (该活动将进入onResume(),并且在看到布尔值为true时,它将初始化下一个调用。)
case TelephonyManager.CALL_STATE_IDLE:
Log.e(TAG, "CALL_STATE_IDLE==>"+incoming_number);
if((prev_state == TelephonyManager.CALL_STATE_OFFHOOK)){
prev_state=state;
wentIntoCall = true;
//Answered Call which is ended
}
if((prev_state == TelephonyManager.CALL_STATE_RINGING)){
prev_state=state;
wentIntoCall = true;
//Rejected or Missed call
}
我的最后一个问题:这是处理此功能的正确方法,还是我应该尝试另外实现它?
编辑2
看起来像我的#34;代码",是USSD代码,不像普通电话那样。所以对于普通电话,上面的代码似乎有效,但对于拨号代码,不是那么多。我已降级"降级"我对一个简单的for循环的解决方案。现在似乎工作正常。
答案 0 :(得分:1)
我不知道对于Android O,但是对于android 6.0>你无法直接找到答案。调用不存在的数字,并查看PhoneStateListener在一个案例中将触发什么并跟踪成功的调用。
制作公共静态数组,添加所有数字intro数组。 我提供服务。在清单中插入权限也可以自己动作(例如NEXT_CALL)。
比startServices更容易制作意图:
SharedPreferences settings;
SharedPreferences.Editor SAVES;
Intent serviceIntent = new Intent(MainActivity.this, ServiceForCalls.class);
serviceIntent.setAction("xxx.xxx.NEXT_CALL");
startService(serviceIntent);
isCalling = true;
SAVES.putBoolean( "isCalling" , isCalling );
SAVES.commit();
SAVES.apply();
您必须在下次通话时使用大约10秒的超时间隔。
Heres little help func - end call和phoneState handler :
void END_CALL () throws InvocationTargetException, IllegalAccessException, ClassNotFoundException, NoSuchMethodException {
tm = (TelephonyManager) getSystemService(Context.TELEPHONY_SERVICE);
Class c = null;
try {
c = Class.forName(tm.getClass().getName());
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
Method m = null;
try {
m = c.getDeclaredMethod("getITelephony");
} catch (NoSuchMethodException e) {
e.printStackTrace();
}
m.setAccessible(true);
Object telephonyService = m.invoke(tm); // Get the internal ITelephony object
c = Class.forName(telephonyService.getClass().getName()); // Get its class
m = c.getDeclaredMethod("endCall"); // Get the "endCall()" method
m.setAccessible(true); // Make it accessible
m.invoke(telephonyService); // invoke endCall()
if ( SIGNAL_STOP == false ) {
timerHandlerServicesStartNewNumber.postDelayed(timerRunnableServicesStartNewNumber, 1000);
}
}
private class PhoneStateChangeListener extends PhoneStateListener {
@Override
public void onCallStateChanged(int state, String incomingNumber) {
switch(state){
case TelephonyManager.CALL_STATE_RINGING:
Log.println( Log.INFO , "RINGING" , "SERVICES%%%%%%%%%%%%%%%%RINGING%%%%%%%%%%%%%%%%%%");
wasRinging = true;
break;
case TelephonyManager.CALL_STATE_OFFHOOK:
Log.println( Log.INFO , "OFFHOOK BROADCAST" , "SERVICES%%%%%%%%%%%%%%%%%%%%%%%%");
if (!wasRinging) {
// Start your new activity
Log.println( Log.INFO , "OFFHOOK BROADCAST" , "SERVICES%%%%%%%%%%%%%%%%%%%%%%%");
if (SIGNAL_STOP == false) {
timerHandlerServices.postDelayed(timerRunnableServices, 10000);
}
} else {
// Cancel your old activity
Log.println( Log.INFO , "OFFHOOK BROADCAST" , "SERVICES%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%");
}
// this should be the last piece of code before the break
wasRinging = true;
break;
case TelephonyManager.CALL_STATE_IDLE:
Log.println( Log.INFO , "IDLE BROADCAST" , "SERVICES%%%%%%%%%%%%%%%%%IDLE%%%%%%%%%%%%%%%%%%%");
// this should be the last piece of code before the break
wasRinging = false;
break;
}
}
}
感谢:“意思就是上面,拨号器屏幕上有”很好的捕捉。
答案 1 :(得分:0)
作为旁注,在Android O开发者预览版中,有一个新的API允许您send a USSD request并注册回调以接收其结果。对于较新版本的Android,这可能会更好地满足您的需求。