Как сделать телефонный звонок в android и вернуться к моей активности, когда вызов будет выполнен?
Я запускаю операцию для совершения телефонного звонка, но когда я нажимаю кнопку "end call", она не возвращается к моей активности. Не могли бы вы рассказать мне, как я могу запустить функцию вызова, которая возвращается мне, когда нажата кнопка "Конец вызова"? Вот как я делаю телефонный звонок:
String url = "tel:3334444";
Intent intent = new Intent(Intent.ACTION_CALL, Uri.parse(url));
Ответы
Ответ 1
используйте 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"/>
Ответ 2
Это касается вопроса, заданного стартером.
Проблема с вашим кодом заключается в том, что вы не правильно передаете номер.
Код должен быть:
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
.
Ответ 3
У нас была та же проблема, и нам удалось решить ее с помощью PhoneStateListener
, чтобы определить, когда заканчивается вызов, но дополнительно мы должны были finish()
выполнить первоначальную операцию перед ее повторным запуском с помощью startActivity
, иначе журнал вызовов будет перед ним.
Ответ 4
Я нашел EndCallListener наиболее функциональный пример, чтобы описать поведение (finish(), call, restart). Я добавил несколько SharedPreferences, чтобы у Listener была ссылка для управления этим поведением.
My OnClick, initialise и 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()
используйте это, чтобы инициализировать поведение для вашего onClick в myActivity, например. после 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).
:)
Ответ 5
вы можете использовать startActivityForResult()
Ответ 6
Это решение с моей точки зрения:
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 (class) вам необходимо реализовать View.OnClickListener.
Ответ 7
Вот мой пример: сначала пользователь набирает номер, который он хочет набрать, а затем нажимает кнопку вызова и направляется на телефон. После отмены вызова пользователь отправляется обратно в приложение. Для этого кнопка должна иметь метод onClick ( "makePhoneCall" в этом примере) в xml. Вам также необходимо зарегистрировать разрешение в манифесте.
манифеста
<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" />
Ответ 8
@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);
}
Ответ 9
Если вы собираетесь использовать прослушиватель, вам также нужно будет добавить это разрешение в манифест.
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
Ответ 10
Чтобы вернуться к Activity
, вам нужно будет прослушать TelephonyStates
. На этом listener
вы можете отправить Intent
, чтобы повторно открыть свой Activity
, когда телефон находится в режиме ожидания.
По крайней мере, как я это сделаю.
Ответ 11
Внутри PhoneStateListener после того, как вызов завершен, лучше использовать:
Intent intent = new Intent(CallDispatcherActivity.this, CallDispatcherActivity.class);
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(intent);
Если CallDispatcherActivity - это активность, когда пользователь запустил вызов (диспетчеру обслуживания такси, в моем случае). Это просто удаляет приложение Android телефонии сверху, пользователь возвращается вместо уродливого кода, который я видел здесь.
Ответ 12
Идеальный учебник здесь! Всегда проверяйте этот блог, потому что у него много отличных уроков!
Ответ 13
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" />
Ответ 14
Попробуйте использовать:
finish();
в конце действия. Он перенаправит вас на предыдущую работу.
Ответ 15
Когда используется PhoneStateListener
, необходимо убедиться, что PHONE_STATE_IDLE
после PHONE_STATE_OFFHOOK
используется для запуска действия, которое должно быть выполнено после вызова. Если срабатывание триггера происходит при просмотре PHONE_STATE_IDLE
, вы получите его до вызова. Поскольку вы увидите изменение состояния PHONE_STATE_IDLE -> PHONE_STATE_OFFHOOK -> PHONE_STATE_IDLE.
Ответ 16
//в 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>
Ответ 17
@Dmitri Novikov, FLAG_ACTIVITY_CLEAR_TOP
очищает любой активный экземпляр поверх нового. Таким образом, он может завершить старый экземпляр до завершения процесса.
Ответ 18
Добавьте это ваш xml: android:autoLink="phone"
Ответ 19
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
Ответ 20
При запуске вашего вызова это выглядит нормально.
Существует разница между 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" />
Пожалуйста, задавайте вопросы, если или когда вы застряли.
Ответ 21
Шаги:
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
Ссылка на этот Ответ