Answers:
使用PhoneStateListener查看呼叫何时结束。您很可能需要触发侦听器操作以等待调用开始(等待直到再次从PHONE_STATE_OFFHOOK更改为PHONE_STATE_IDLE),然后编写一些代码以使您的应用恢复到IDLE状态。
您可能需要在服务中运行侦听器,以确保侦听器保持运行状态并重新启动您的应用。一些示例代码:
EndCallListener callListener = new EndCallListener();
TelephonyManager mTM = (TelephonyManager)this.getSystemService(Context.TELEPHONY_SERVICE);
mTM.listen(callListener, PhoneStateListener.LISTEN_CALL_STATE);
侦听器定义:
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");
}
}
}
在Manifest.xml
文件中添加以下权限:
<uses-permission android:name="android.permission.READ_PHONE_STATE"/>
这是关于Starter提出的问题。
您的代码的问题是您没有正确传递数字。
代码应为:
private OnClickListener next = new OnClickListener() {
public void onClick(View v) {
EditText num=(EditText)findViewById(R.id.EditText01);
String number = "tel:" + num.getText().toString().trim();
Intent callIntent = new Intent(Intent.ACTION_CALL, Uri.parse(number));
startActivity(callIntent);
}
};
不要忘记在清单文件中添加权限。
<uses-permission android:name="android.permission.CALL_PHONE"></uses-permission>
要么
<uses-permission android:name="android.permission.CALL_PRIVILEGED"></uses-permission>
如果DIAL
使用紧急电话号码。
我们遇到了同样的问题,并设法通过使用a PhoneStateListener
来识别呼叫结束的时间来解决该问题,但是此外,finish()
在再次使用再次开始之前,我们不得不进行原始活动startActivity
,否则,呼叫日志将位于它的前面。
我发现EndCallListener是功能最强大的示例,为了获得所描述的行为(finish(),调用,重新启动),我添加了一些SharedPreferences,因此Listener具有管理此行为的引用。
我的OnClick,initialize和EndCallListener仅响应来自应用程序的呼叫。其他呼叫被忽略。
import android.content.Intent;
import android.content.SharedPreferences;
import android.preference.PreferenceManager;
import android.telephony.PhoneStateListener;
import android.telephony.TelephonyManager;
import android.util.Log;
public class EndCallListener extends PhoneStateListener {
private String TAG ="EndCallListener";
private int LAUNCHED = -1;
SharedPreferences prefs = PreferenceManager
.getDefaultSharedPreferences(
myActivity.mApp.getBaseContext());
SharedPreferences.Editor _ed = prefs.edit();
@Override
public void onCallStateChanged(int state, String incomingNumber) {
String _prefKey = myActivity.mApp
.getResources().getString(R.string.last_phone_call_state_key),
_bPartyNumber = myActivity.mApp
.getResources().getString(R.string.last_phone_call_bparty_key);
int mLastCallState = prefs.getInt(_prefKey, LAUNCHED);
//Save current call sate for next call
_ed.putInt(_prefKey,state);
_ed.commit();
if(TelephonyManager.CALL_STATE_RINGING == state) {
Log.i(TAG, " >> RINGING, number: " + incomingNumber);
}
if(TelephonyManager.CALL_STATE_IDLE == state && mLastCallState != LAUNCHED ) {
//when this state occurs, and your flag is set, restart your app
if (incomingNumber.equals(_bPartyNumber) == true) {
//Call relates to last app initiated call
Intent _startMyActivity =
myActivity.mApp
.getPackageManager()
.getLaunchIntentForPackage(
myActivity.mApp.getResources()
.getString(R.string.figjam_package_path));
_startMyActivity.setAction(
myActivity.mApp.getResources()
.getString(R.string.main_show_phone_call_list));
myActivity.mApp
.startActivity(_startMyActivity);
Log.i(TAG, "IDLE >> Starting MyActivity with intent");
}
else
Log.i(TAG, "IDLE after calling "+incomingNumber);
}
}
}
将它们添加到strings.xml
<string name="main_show_phone_call_list">android.intent.action.SHOW_PHONE_CALL_LIST</string>
<string name="last_phone_call_state_key">activityLpcsKey</string>
<string name="last_phone_call_bparty_key">activityLpbpKey</string>
如果您需要在通话之前恢复外观,则在清单中可以看到类似的内容
<activity android:label="@string/app_name" android:name="com.myPackage.myActivity"
android:windowSoftInputMode="stateHidden"
android:configChanges="keyboardHidden" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<action android:name="android.intent.action.SHOW_PHONE_CALL_LIST" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
并将它们放在您的“ myActivity”中
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();
}
您应该发现单击电话号码列表可以完成您的活动,可以拨打该电话,并在通话结束时返回到您的活动。
在应用仍在运行时从应用外部拨打电话不会重启您的活动(除非它与最后一个调用的BParty号码相同)。
:)
这是我的示例,首先,用户输入他/她想要拨打的号码,然后按下呼叫按钮,然后将其定向到电话。取消通话后,用户将被发送回应用程序。为此,按钮需要在xml中具有onClick方法(在此示例中为“ makePhoneCall”)。您还需要在清单中注册许可。
表现
<uses-permission android:name="android.permission.CALL_PHONE"></uses-permission>
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
活动
import android.net.Uri;
import android.os.Bundle;
import android.app.Activity;
import android.content.Intent;
import android.view.View;
import android.widget.EditText;
import android.widget.Toast;
public class PhoneCall extends Activity {
EditText phoneTo;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_phone_call);
phoneTo = (EditText) findViewById(R.id.phoneNumber);
}
public void makePhoneCall(View view) {
try {
String number = phoneTo.getText().toString();
Intent phoneIntent = new Intent(Intent.ACTION_CALL);
phoneIntent.setData(Uri.parse("tel:"+ number));
startActivity(phoneIntent);
} catch (android.content.ActivityNotFoundException ex) {
Toast.makeText(PhoneCall.this,
"Call failed, please try again later!", Toast.LENGTH_SHORT).show();
}
}
}
XML格式
<EditText
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:inputType="phone"
android:ems="10"
android:id="@+id/phoneNumber"
android:layout_marginTop="67dp"
android:layout_below="@+id/textView"
android:layout_centerHorizontal="true" />
<Button
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="Call"
android:id="@+id/makePhoneCall"
android:onClick="makePhoneCall"
android:layout_alignParentBottom="true"
android:layout_centerHorizontal="true" />
@Override
public void onClick(View view) {
Intent phoneIntent = new Intent(Intent.ACTION_CALL);
phoneIntent.setData(Uri.parse("tel:91-000-000-0000"));
if (ActivityCompat.checkSelfPermission(mContext, Manifest.permission.CALL_PHONE) != PackageManager.PERMISSION_GRANTED) {
return;
}
startActivity(phoneIntent);
}
看到呼叫完成后,在PhoneStateListener内部可以更好地使用:
Intent intent = new Intent(CallDispatcherActivity.this, CallDispatcherActivity.class);
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(intent);
其中CallDispatcherActivity是用户发起呼叫的活动(在我的情况下,是呼叫出租车服务调度员的活动)。这只是从顶部删除了Android电话应用程序,用户回来了,而不是我在这里看到的难看的代码。
((TelephonyManager)getSystemService(Context.TELEPHONY_SERVICE)).listen(this, LISTEN_NONE);
Intent intentRestart = new Intent(ControlPanel.this, ControlPanel.class);
。我应该指出,PhoneStateListener也在ControlPanel中。即,我的目标是将UI恢复到发起电话之前的状态。有什么建议?
Intent callIntent = new Intent(Intent.ACTION_CALL);
callIntent.setData(Uri.parse("tel:"+number));
startActivity(callIntent);
**Add permission :**
<uses-permission android:name="android.permission.CALL_PHONE" />
尝试使用:
finish();
在活动结束时。它会将您重定向到上一个活动。
当PhoneStateListener
使用时,一个需要确认PHONE_STATE_IDLE
以下一个PHONE_STATE_OFFHOOK
用来触发调用后要做的动作。如果触发是在看到时发生的PHONE_STATE_IDLE
,那么您将在通话之前结束触发。因为你会看到状态的变化PHONE_STATE_IDLE -> PHONE_STATE_OFFHOOK -> PHONE_STATE_IDLE.
((TelephonyManager)getSystemService(Context.TELEPHONY_SERVICE)).listen(new PhoneStateListener(), PhoneStateListener.LISTEN_CALL_STATE)
它将继续侦听电话状态并一直处于活动状态,直到使用((TelephonyManager)getSystemService(Context.TELEPHONY_SERVICE)).listen(this, LISTEN_NONE)
//在setonclicklistener中放入以下代码:
EditText et_number=(EditText)findViewById(R.id.id_of_edittext);
String my_number = et_number.getText().toString().trim();
Intent callIntent = new Intent(Intent.ACTION_CALL, Uri.parse(my_number));
startActivity(callIntent);
//在清单中授予调用权限:
<uses-permission android:name="android.permission.CALL_PHONE"></uses-permission>
脚步:
1)在Manifest.xml
文件中添加所需的权限。
<!--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);
}
}
}
3)初始化您的听众 OnCreate
EndCallListener callListener = new EndCallListener();
TelephonyManager mTM = (TelephonyManager)this.getSystemService(Context.TELEPHONY_SERVICE);
mTM.listen(callListener, PhoneStateListener.LISTEN_CALL_STATE);
但是,如果您想恢复应用程序的上一状态或将其从后台堆栈中恢复过来,请替换FLAG_ACTIVITY_CLEAR_TOP
为FLAG_ACTIVITY_SINGLE_TOP
参考这个答案
Intent callIntent = new Intent(Intent.ACTION_CALL);
callIntent .setData(Uri.parse("tel:+91-XXXXXXXXX"));
startActivity(callIntent );
有关更多参考,请单击此处http://androiddhina.blogspot.in/2015/10/how-to-make-phone-call-from-android.html
开始通话时,看起来不错。
android 11+和更低版本之间的区别在于将您的应用程序置于最前面。
您需要启动新的意图的Android 10或更低版本,您只需使用android 11+ BringTaskToFront
在通话状态IDLE中:
if (Build.VERSION.SDK_INT >= 11) {
ActivityManager am = (ActivityManager) activity.getSystemService(Activity.ACTIVITY_SERVICE);
am.moveTaskToFront(MyActivity.MyActivityTaskId, ActivityManager.MOVE_TASK_WITH_HOME);
} else {
Intent intent = new Intent(activity, MyActivity.class);
activity.startActivity(intent);
}
我MyActivity.MyActivityTaskId
像这样在我的活动上进行调用时设置了它,它不起作用,请在要返回的页面的父活动页面上设置此变量。
MyActivity.MyActivityTaskId = this.getTaskId();
MyActivityTaskId
是我的活动课上的静态变量
public static int MyActivityTaskId = 0;
希望这对您有用。我对上面的代码使用了一些不同的方式,只要应答了呼叫,我就会打开我的应用程序,以便用户可以看到呼叫者的详细信息。
我也设置了一些东西AndroidManifest.xml
:
/*Dont really know if this makes a difference*/
<activity android:name="MyActivity" android:taskAffinity="" android:launchMode="singleTask" />
和权限:
<uses-permission android:name="android.permission.GET_TASKS" />
<uses-permission android:name="android.permission.REORDER_TASKS" />
请问是否或何时卡住。