[ACCEPTED]-How to make a phone call in android and come back to my activity when the call is done?-phone-call
use a PhoneStateListener to see when the 10 call is ended. you will most likely need 9 to trigger the listener actions to wait 8 for a the call to start (wait until changed 7 from PHONE_STATE_OFFHOOK to PHONE_STATE_IDLE 6 again) and then write some code to bring 5 your app back up on the IDLE state.
you 4 may need to run the listener in a service 3 to ensure it stays up and your app is restarted. some 2 example code:
EndCallListener callListener = new EndCallListener();
TelephonyManager mTM = (TelephonyManager)this.getSystemService(Context.TELEPHONY_SERVICE);
mTM.listen(callListener, PhoneStateListener.LISTEN_CALL_STATE);
Listener definition:
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");
}
}
}
In your 1 Manifest.xml
file add the following permission:
<uses-permission android:name="android.permission.READ_PHONE_STATE"/>
This is regarding the question asked by 5 Starter.
The problem with your code is that 4 you are not passing the number properly.
The 3 code should be:
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);
}
};
Do not forget to add the 2 permission in manifest file.
<uses-permission android:name="android.permission.CALL_PHONE"></uses-permission>
or
<uses-permission android:name="android.permission.CALL_PRIVILEGED"></uses-permission>
for emergency 1 number in case DIAL
is used.
We had the same problem and managed to solve 4 it by using a PhoneStateListener
to identify when the call 3 ends, but additionally we had to finish()
the original 2 activity before starting it again with startActivity
, otherwise 1 the call log would be in front of it.
I found the EndCallListener the most functional 19 example, to get the behaviour described 18 (finish(), call, restart) I added a few 17 SharedPreferences so the Listener had a 16 reference to manage this behaviour.
My OnClick, initialise 15 and EndCallListener only respond to calls 14 from app. Other calls ignored.
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);
}
}
}
add these 13 to 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>
and something like this in 12 your Manifest if you need to return to the 11 look and feel before the call
<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>
and put these 10 in your '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()
use this to initilaise 9 the behaviour for your onClick in myActivity 8 e.g. after 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();
}
You should find that 7 clicking your list of phone numbers finishes 6 your activty, makes the call to the number 5 and returns to your activty when the call 4 ends.
Making a call from outside your app 3 while it's still around won't restart your 2 activty (unless it's the same as the last 1 BParty number called).
:)
you can use startActivityForResult()
0
This is solution from my point of view:
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);
}
Of 2 course in Activity (class) definition you 1 have to implement View.OnClickListener .
Here is my example, first the user gets 8 to write in the number he/she wants to dial 7 and then presses a call button and gets 6 directed to the phone. After call cancelation 5 the user gets sent back to the application. In 4 order to this the button needs to have a 3 onClick method ('makePhoneCall' in this 2 example) in the xml. You also need to register 1 the permission in the manifest.
Manifest
<uses-permission android:name="android.permission.CALL_PHONE"></uses-permission>
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
Activity
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);
}
0
If you are going to use a listener you will 2 need to add this permission to the manifest 1 as well.
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
To return to your Activity
, you will need to listen 3 to TelephonyStates
. On that listener
you can send an Intent
to re-open 2 your Activity
once the phone is idle.
At least thats 1 how I will do it.
Inside PhoneStateListener after seeing the 6 call is finished better use:
Intent intent = new Intent(CallDispatcherActivity.this, CallDispatcherActivity.class);
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(intent);
Where CallDispatcherActivity 5 is the activity where the user has launched 4 a call (to a taxi service dispatcher, in 3 my case). This just removes Android telephony 2 app from the top, the user gets back instead 1 of ugly code I saw here.
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" />
0
Try using:
finish();
at the end of activity. It will 1 redirect you to your previous activity.
When PhoneStateListener
is used, one need to make sure PHONE_STATE_IDLE
following 5 a PHONE_STATE_OFFHOOK
is used to trigger the action to be done 4 after the call. If the trigger happens upon 3 seeing PHONE_STATE_IDLE
, you will end up doing it before 2 the call. Because you will see the state 1 change PHONE_STATE_IDLE -> PHONE_STATE_OFFHOOK -> PHONE_STATE_IDLE.
// in setonclicklistener put this code:
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);
// give 1 permission for call in manifest:
<uses-permission android:name="android.permission.CALL_PHONE"></uses-permission>
@Dmitri Novikov, FLAG_ACTIVITY_CLEAR_TOP
clears any active instance 2 on top of the new one. So, it may end the 1 old instance before it completes the process.
Add this is your xml: android:autoLink="phone"
0
Steps:
1)Add the required permissions in 4 the Manifest.xml
file.
<!--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)Create a listener for the phone 3 state changes.
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)Initialize the listener 2 in your OnCreate
EndCallListener callListener = new EndCallListener();
TelephonyManager mTM = (TelephonyManager)this.getSystemService(Context.TELEPHONY_SERVICE);
mTM.listen(callListener, PhoneStateListener.LISTEN_CALL_STATE);
but if you want to resume your application last state or to bring it back from the back stack, then replace FLAG_ACTIVITY_CLEAR_TOP
with FLAG_ACTIVITY_SINGLE_TOP
Reference 1 this Answer
Intent callIntent = new Intent(Intent.ACTION_CALL);
callIntent .setData(Uri.parse("tel:+91-XXXXXXXXX"));
startActivity(callIntent );
0
When starting your call, it looks fine.
There 15 is a difference between android 11+ and 14 down in bringing your app to the front though.
Android 13 10 or less you need to start a new intent, android 12 11+ you simply use BringTaskToFront
In the call state 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);
}
I 11 set the MyActivity.MyActivityTaskId
when making the call on my activity 10 like so, it this doesnt work, set this variable 9 on the parent activity page of the page 8 you want to get back to.
MyActivity.MyActivityTaskId = this.getTaskId();
MyActivityTaskId
is a static variable 7 on my activity class
public static int MyActivityTaskId = 0;
I hope this will work 6 for you. I use the above code a bit differently, I 5 open my app as soon as the call is answered 4 sothat the user can see the details of the 3 caller.
I have set some stuff in the AndroidManifest.xml
as 2 well:
/*Dont really know if this makes a difference*/
<activity android:name="MyActivity" android:taskAffinity="" android:launchMode="singleTask" />
and permissions:
<uses-permission android:name="android.permission.GET_TASKS" />
<uses-permission android:name="android.permission.REORDER_TASKS" />
Please ask questions 1 if or when you get stuck.
To call from app use simple intent for call, after 5 that if you want to listen the call status 4 then use below code
1] implement this in 3 your class -
implements AudioManager.OnAudioFocusChangeListener
2] Add 2 below code with overridden method
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; } } }
3]Add this
@Override public 1 void onDestroy() { audioManager.abandonAudioFocus(this); }
More Related questions
We use cookies to improve the performance of the site. By staying on our site, you agree to the terms of use of cookies.