private class EndCallListener extends PhoneStateListener {
@Override
public void onCallStateChanged(int state, String incomingNumber) {
if(TelephonyManager.CALL_STATE_RINGING == state) {
Log.i(LOG_TAG, "RINGING, number: " + incomingNumber);
}
if(TelephonyManager.CALL_STATE_OFFHOOK == state) {
//wait for phone to go offhook (probably set a boolean flag) so you know your app initiated the call.
Log.i(LOG_TAG, "OFFHOOK");
}
if(TelephonyManager.CALL_STATE_IDLE == state) {
//when this state occurs, and your flag is set, restart your app
Log.i(LOG_TAG, "IDLE");
}
}
}
public static Activity mApp=null; //Before onCreate()
...
onCreate( ... ) {
...
if (mApp == null) mApp = this; //Links your resources to other classes
...
//Test if we've been called to show phone call list
Intent _outcome = getIntent();
String _phoneCallAction = mApp.getResources().getString(R.string.main_show_phone_call_list);
String _reqAction = _outcome.getAction();//Can be null when no intent involved
//Decide if we return to the Phone Call List view
if (_reqAction != null &&_reqAction.equals(_phoneCallAction) == true) {
//DO something to return to look and feel
}
...
myListView.setOnItemClickListener(new OnItemClickListener() { //Act on item when selected
@Override
public void onItemClick(AdapterView<?> a, View v, int position, long id) {
myListView.moveToPosition(position);
String _bPartyNumber = "tel:"+myListView.getString(myListView.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER));
//Provide an initial state for the listener to access.
initialiseCallStatePreferences(_bPartyNumber);
//Setup the listener so we can restart myActivity
EndCallListener _callListener = new EndCallListener();
TelephonyManager _TM = (TelephonyManager)mApp.getSystemService(Context.TELEPHONY_SERVICE);
_TM.listen(_callListener, PhoneStateListener.LISTEN_CALL_STATE);
Intent _makeCall = new Intent(Intent.ACTION_CALL, Uri.parse(_bPartyNumber));
_makeCall.setComponent(new ComponentName("com.android.phone","com.android.phone.OutgoingCallBroadcaster"));
startActivity(_makeCall);
finish();
//Wait for call to enter the IDLE state and then we will be recalled by _callListener
}
});
}//end of onCreate()
使用它来启动myActivity中onClick的行为,例如在onCreate()之后
private void initialiseCallStatePreferences(String _BParty) {
final int LAUNCHED = -1;
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(
mApp.getBaseContext());
SharedPreferences.Editor _ed = prefs.edit();
String _prefKey = mApp.getString(R.string.last_phone_call_state_key),
_bPartyKey = mApp.getString(R.string.last_phone_call_bparty_key);
//Save default call state before next call
_ed.putInt(_prefKey,LAUNCHED);
_ed.putString(_bPartyKey,_BParty);
_ed.commit();
}
<!--For using the phone calls -->
<uses-permission android:name="android.permission.CALL_PHONE" />
<!--For reading phone call state-->
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
2)为手机状态更改创建一个监听器 .
public class EndCallListener extends PhoneStateListener {
@Override
public void onCallStateChanged(int state, String incomingNumber) {
if(TelephonyManager.CALL_STATE_RINGING == state) {
}
if(TelephonyManager.CALL_STATE_OFFHOOK == state) {
//wait for phone to go offhook (probably set a boolean flag) so you know your app initiated the call.
}
if(TelephonyManager.CALL_STATE_IDLE == state) {
//when this state occurs, and your flag is set, restart your app
Intent i = context.getPackageManager().getLaunchIntentForPackage(
context.getPackageName());
//For resuming the application from the previous state
i.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);
//Uncomment the following if you want to restart the application instead of bring to front.
//i.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
context.startActivity(i);
}
}
}
21 回答
从我的观点来看,这是解决方案:
当然,在Activity(类)定义中,您必须实现View.OnClickListener .
使用PhoneStateListener查看呼叫何时结束 . 您很可能需要触发侦听器操作以等待调用启动(等待直到从PHONE_STATE_OFFHOOK再次更改为PHONE_STATE_IDLE)然后编写一些代码以使您的应用程序重新处于IDLE状态 .
您可能需要在服务中运行侦听器以确保其保持运行状态并重新启动应用程序 . 一些示例代码:
听众定义:
在
Manifest.xml
文件中添加以下权限:这是关于Starter提出的问题 .
代码的问题在于您没有正确传递数字 .
代码应该是:
不要忘记在清单文件中添加权限 .
要么
如果使用
DIAL
,则为紧急号码 .我们遇到了同样的问题,并设法通过使用
PhoneStateListener
来确定呼叫何时结束,但另外我们必须finish()
原始活动再次使用startActivity
启动它,否则呼叫日志将在它前面 .我发现EndCallListener是最实用的示例,用于获取描述的行为(finish(),call,restart)我添加了一些SharedPreferences,因此Listener有一个引用来管理这种行为 .
我的OnClick,initialise和EndCallListener只响应来自app的调用 . 其他通话被忽略 .
将这些添加到strings.xml
如果您需要在通话前回到外观和感觉,那么在您的清单中会出现类似的情况
把它们放在你的'myActivity'中
使用它来启动myActivity中onClick的行为,例如在onCreate()之后
您应该会发现单击您的电话号码列表会完成您的激活,拨打号码并在呼叫结束时返回您的电话号码 .
在应用程序外部拨打电话时仍然无法重启您的活动(除非它与上次调用的BParty号码相同) .
:)
你可以使用startActivityForResult()
这是我的例子,首先用户可以写下他/她想要拨打的号码然后按下呼叫按钮并转到电话 . 呼叫取消后,用户将被发送回应用程序 . 为此,按钮需要在xml中具有onClick方法(在此示例中为'makePhoneCall') . 您还需要在清单中注册权限 .
表现
活动
XML
如果您要使用侦听器,则还需要将此权限添加到清单中 .
在看到调用完成后,在PhoneStateListener内部更好用:
CallDispatcherActivity是用户发起呼叫的活动(在我的情况下是出租车服务调度员) . 这只是从顶部删除Android电话应用程序,用户返回而不是我在这里看到的丑陋代码 .
要返回
Activity
,您需要收听TelephonyStates
. 在listener
上,您可以发送Intent
以在手机空闲时重新打开Activity
.至少那就是我将如何做到这一点 .
完美教程here!请务必查看此博客,因为它有许多优秀的教程!
尝试使用:
在活动结束时 . 它会将您重定向到之前的活动 .
当使用
PhoneStateListener
时,需要确保PHONE_STATE_OFFHOOK
后面的PHONE_STATE_IDLE
用于触发调用后要执行的操作 . 如果在看到PHONE_STATE_IDLE
时发生触发,您将在通话前结束 . 因为你会看到状态变化PHONE_STATE_IDLE -> PHONE_STATE_OFFHOOK -> PHONE_STATE_IDLE.
//在setonclicklistener中输入以下代码:
//给出清单中的呼叫权限:
@Dmitri Novikov,
FLAG_ACTIVITY_CLEAR_TOP
清除新的活动实例 . 所以,它可能会结束在完成该过程之前的旧实例 .添加这是你的xml:
android:autoLink="phone"
如需更多参考,请点击此处http://androiddhina.blogspot.in/2015/10/how-to-make-phone-call-from-android.html
开始通话时,它看起来很好 .
虽然Android将你的应用程序带到了前面,但是在android 11和down之间存在差异 .
Android 10或更少你需要启动一个新的意图,android 11你只需使用
BringTaskToFront
在通话状态IDLE:
我在调用我的活动时设置了
MyActivity.MyActivityTaskId
,这不起作用,将此变量设置在您想要返回的页面的父活动页面上 .MyActivityTaskId
是我的activity类的静态变量我希望这对你有用 . 我使用上面的代码有点不同,我在应答呼叫后立即打开我的应用程序,用户可以看到呼叫者的详细信息 .
我也在_1464736中设置了一些东西:
和权限:
如果您遇到困难,请提出问题 .
脚步:
1)在
Manifest.xml
文件中添加所需的权限 .2)为手机状态更改创建一个监听器 .
3)在
OnCreate
中初始化监听器但 if you want to resume your application last state or to bring it back from the back stack ,然后用
FLAG_ACTIVITY_SINGLE_TOP
替换FLAG_ACTIVITY_CLEAR_TOP
参考这个Answer