如何在机器人打电话,并返回到我的活动时,呼叫完成?

我正在启动一个活动来打电话,但是当我按下“结束通话”按钮时,它不会回到我的活动。你能告诉我如何启动一个呼叫活动,当“结束呼叫”按钮被按下时回到我身边?我就是这么打电话的:

    String url = "tel:3334444";
Intent intent = new Intent(Intent.ACTION_CALL, Uri.parse(url));
224929 次浏览

在我看来,这就是解决方案:

ok.setOnClickListener(this);
@Override
public void onClick(View view) {
if(view == ok){
Intent intent = new Intent(Intent.ACTION_CALL);
intent.setData(Uri.parse("tel:" + num));
activity.startActivity(intent);


}

当然,在 Activity (类)定义中,必须实现 View.OnClickListener。

这是关于 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,请输入紧急电话号码。

要回到你的 Activity,你需要听 TelephonyStates。在这个 listener上,你可以发送一个 Intent重新打开你的 Activity一旦电话是空闲的。

至少我会这么做。

使用 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"/>

可以使用 startActivityForResult ()

尝试使用:

finish();

在活动结束的时候,它会重定向到你之前的活动。

我们也遇到了同样的问题,并且设法通过使用 PhoneStateListener来识别呼叫何时结束来解决这个问题,但是另外,我们必须在使用 startActivity重新开始之前使用 finish()来识别原始活动,否则呼叫日志就会在它的前面。

如果要使用侦听器,还需要将此权限添加到清单中。

<uses-permission android:name="android.permission.READ_PHONE_STATE" />

我发现 EndCallListener 是最实用的例子,为了获得所描述的行为(Finish () ,call,start) ,我添加了一些 SharedPreferences,这样 Listener 就有了一个引用来管理这种行为。

我的 OnClick、初始化和 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>

把这些放在你的“我的活动”里

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 号码是一样的)。

:)

内置 PhoneStateListener 在看到呼叫结束后,最好使用:

Intent intent = new Intent(CallDispatcherActivity.this, CallDispatcherActivity.class);
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(intent);

其中 CallDispatcherActivity 是用户发起呼叫的活动(在我的例子中是呼叫出租车服务调度员)。这只是从顶部删除 Android 电话应用程序,用户得到了回来,而不是我在这里看到的丑陋的代码。

使用 PhoneStateListener时,需要确保使用 PHONE_STATE_OFFHOOK后面的 PHONE_STATE_IDLE来触发调用后要执行的操作。如果触发发生在看到 PHONE_STATE_IDLE之后,那么您将在调用之前完成该操作。因为您将看到状态更改 PHONE_STATE_IDLE -> PHONE_STATE_OFFHOOK -> PHONE_STATE_IDLE.

@ Dmitri Novikov FLAG_ACTIVITY_CLEAR_TOP清除新实例上的所有活动实例。因此,它可能在完成流程之前结束旧实例。

添加这个 xml: android:autoLink="phone"

//在 setonclicklisten 中输入以下代码:

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>
  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" />

开始打电话时,看起来没问题。

不过,android 11 + 和 android 11 + 在将你的应用程序推向市场方面是有区别的。

安卓10或更少你需要开始一个新的意图,安卓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" />

如果你被卡住了,请提出问题。

步骤:

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_SINGLE_TOP代替 FLAG_ACTIVITY_CLEAR_TOP

参考此 回答我

这里是我的例子,首先用户可以写入他/她想要拨打的号码,然后按下一个呼叫按钮,就可以直接拨打电话了。取消调用后,用户将被发送回应用程序。为此,按钮需要在 xml 中有一个 onClick 方法(本例中为‘ makPhoneCall’)。您还需要在清单中注册权限。

旅客名单

<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" />
   Intent callIntent = new Intent(Intent.ACTION_CALL);
callIntent .setData(Uri.parse("tel:+91-XXXXXXXXX"));
startActivity(callIntent );
@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);
}

从应用程序呼叫使用简单的呼叫意图,之后,如果你想监听呼叫状态,然后使用以下代码

在你的类中实现它-

实现 AudioManager.OnAudioFocusChangeListener

用重写的方法添加下面的代码

    AudioManager audioManager = (AudioManager) getSystemService(AUDIO_SERVICE); //public static final String AUDIO_SERVICE = "audio";
audioManager = (AudioManager) getSystemService(Context.AUDIO_SERVICE);
assert audioManager != null;
audioManager.requestAudioFocus(this, AudioManager.STREAM_MUSIC,
AudioManager.AUDIOFOCUS_GAIN);


@Override
public void onAudioFocusChange(int focusChange) {
switch (focusChange) {
case AudioManager.AUDIOFOCUS_LOSS: {
//here you can pause your playing audio
break;
}
case AudioManager.AUDIOFOCUS_LOSS_TRANSIENT: {
//here you can pause your playing audio
break;
}
case AudioManager.AUDIOFOCUS_LOSS_TRANSIENT_CAN_DUCK: {
break;
}
case AudioManager.AUDIOFOCUS_GAIN: {
//here you will return back to the activity when your call is finsihed
//resume your audio here
break;
}
}
}

加上这个

@ 重写 销毁()上的公众空白( 放弃 AudioFocus (this) ; }