web-dev-qa-db-fra.com

Comment passer un appel téléphonique sous Android et revenir à mon activité une fois l'appel terminé?

Je lance une activité pour passer un appel téléphonique, mais lorsque j'appuie sur le bouton 'mettre fin à l'appel', cela ne revient pas à mon activité. Pouvez-vous s'il vous plaît me dire comment puis-je lancer une activité d'appel qui me revient lorsque le bouton 'Mettre fin à l'appel' est enfoncé? Voici comment je passe l'appel téléphonique:

    String url = "tel:3334444";
    Intent intent = new Intent(Intent.ACTION_CALL, Uri.parse(url));
128
hap497

utilisez PhoneStateListener pour voir quand l'appel est terminé. vous devrez probablement déclencher les actions du programme d'écoute pour attendre le début de l'appel (attendez que PHONE_STATE_OFFHOOK soit à nouveau remplacé par PHONE_STATE_IDLE), puis écrivez du code pour ramener votre application à l'état IDLE.

vous devrez peut-être exécuter le programme d'écoute dans un service pour vous assurer qu'il reste en place et que votre application est redémarrée. un exemple de code:

EndCallListener callListener = new EndCallListener();
TelephonyManager mTM = (TelephonyManager)this.getSystemService(Context.TELEPHONY_SERVICE);
mTM.listen(callListener, PhoneStateListener.LISTEN_CALL_STATE);

Définition de l'auditeur:

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");
        }
    }
}

Dans votre fichier Manifest.xml ajoutez la permission suivante:

<uses-permission Android:name="Android.permission.READ_PHONE_STATE"/>
105
moonlightcheese

Ceci concerne la question posée par Starter.

Le problème avec votre code est que vous ne transmettez pas le numéro correctement.

Le code devrait être:

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);
    }
};

N'oubliez pas d'ajouter l'autorisation dans le fichier manifeste.

<uses-permission Android:name="Android.permission.CALL_PHONE"></uses-permission>

ou

<uses-permission Android:name="Android.permission.CALL_PRIVILEGED"></uses-permission>

pour le numéro d'urgence dans le cas où DIAL est utilisé.

49
Pria

Nous avons eu le même problème et avons réussi à le résoudre en utilisant un PhoneStateListener pour identifier la fin de l'appel, mais nous devions en outre finish() l'activité d'origine avant de le relancer avec startActivity, sinon le journal des appels serait en face de lui.

24
André Lima

J'ai trouvé EndCallListener comme l'exemple le plus fonctionnel. Pour ajouter le comportement décrit (finish (), call, restart), j'ai ajouté quelques SharedPreferences afin que le Listener dispose d'une référence pour gérer ce comportement.

Mon OnClick, initialise et EndCallListener ne répondent qu'aux appels de l'application. Autres appels ignorés.

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);

        }

    }
}

ajoutez-les à 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>

et quelque chose comme ceci dans votre manifeste si vous avez besoin de revenir à l'apparence avant l'appel

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

et mettez-les dans votre '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()

utilisez-le pour initier le comportement de votre onClick dans myActivity, par exemple. après 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();

}

Vous devriez constater que cliquer sur votre liste de numéros de téléphone termine votre activité, appelle le numéro et revient à votre activité à la fin de l'appel.

Passer un appel depuis l'extérieur de votre application lorsqu'il est toujours là ne redémarrera pas votre activité (à moins que ce soit le même que le dernier numéro de BParty appelé).

:)

13
TheSolarSheriff

vous pouvez utiliser startActivityForResult ()

7
yakr

C'est la solution de mon point de vue:

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);

    }

Bien sûr, dans la définition de l'activité (classe), vous devez implémenter View.OnClickListener.

6
cikabole
@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);
}
6
erluxman

Voici mon exemple: l’utilisateur doit d’abord écrire le numéro qu’il souhaite composer, puis appuyer sur un bouton d’appel pour se diriger vers le téléphone. Après l'annulation de l'appel, l'utilisateur est renvoyé à l'application. Pour cela, le bouton doit avoir une méthode onClick ("makePhoneCall" dans cet exemple) dans le xml. Vous devez également enregistrer l'autorisation dans le manifeste.

Manifeste

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

Activité

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

Si vous utilisez un écouteur, vous devez également ajouter cette autorisation au manifeste.

<uses-permission Android:name="Android.permission.READ_PHONE_STATE" />
5
martincm

Inside PhoneStateListener après avoir vu l'appel terminé est une meilleure utilisation:

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

Où CallDispatcherActivity est l'activité dans laquelle l'utilisateur a lancé un appel (à un répartiteur de service de taxi, dans mon cas). Cela supprime simplement Android l'application de téléphonie du haut, l'utilisateur récupère le code au lieu du code laid que j'ai vu ici.

3
Dmitri Novikov

Tutoriel parfait ici ! Consultez toujours ce blog car il contient de nombreux excellents tutoriels!

3
Raphael Oliveira
  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" />          
3
ritesh4326

Pour revenir à votre Activity, vous devrez écouter TelephonyStates. Sur ce listener, vous pouvez envoyer un Intent pour rouvrir votre Activity une fois le téléphone inactif.

Au moins c'est comment je vais le faire.

3
Aimeric

// dans setonclicklistener mettez ce 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);

// donne la permission d'appeler dans le manifeste:

<uses-permission Android:name="Android.permission.CALL_PHONE"></uses-permission>
2
Hiren Patel

Essayez d'utiliser:

finish();

en fin d'activité. Cela vous redirigera vers votre activité précédente.

2
Ankit Kedia

Lorsque PhoneStateListener est utilisé, vous devez vous assurer que PHONE_STATE_IDLE après un PHONE_STATE_OFFHOOK est utilisé pour déclencher l'action à effectuer après l'appel. Si le déclenchement se produit à la vue de PHONE_STATE_IDLE, vous finirez par le faire avant l'appel. Parce que vous verrez l'état changer PHONE_STATE_IDLE -> PHONE_STATE_OFFHOOK -> PHONE_STATE_IDLE.

2
PonMaran
   Intent callIntent = new Intent(Intent.ACTION_CALL);
   callIntent .setData(Uri.parse("tel:+91-XXXXXXXXX"));
   startActivity(callIntent );

pour plus de références, cliquez ici http://androiddhina.blogspot.in/2015/10/how-to-make-phone-call-from-Android.html

1
Dhina k

@Dmitri Novikov, FLAG_ACTIVITY_CLEAR_TOP efface toute instance active par-dessus la nouvelle. Ainsi, il peut mettre fin à l'ancienne instance avant la fin du processus.

1
PonMaran

Pas:

1) Ajoutez les autorisations requises dans le fichier 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) Créez un écouteur pour les changements d'état du téléphone.

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) Initialisez l’auditeur dans votre OnCreate

EndCallListener callListener = new EndCallListener();
TelephonyManager mTM = (TelephonyManager)this.getSystemService(Context.TELEPHONY_SERVICE);
mTM.listen(callListener, PhoneStateListener.LISTEN_CALL_STATE);

mais si vous souhaitez reprendre le dernier état de votre application ou le ramener de la pile arrière , remplacez FLAG_ACTIVITY_CLEAR_TOP par FLAG_ACTIVITY_SINGLE_TOP

Référence cette réponse

1
Sami Eltamawy

Ajoutez ceci est votre xml: Android:autoLink="phone"

1
Roman Marius

Au début de votre appel, ça a l'air bien.

Cependant, il y a une différence entre Android 11+ et les versions antérieures pour amener votre application au premier plan.

Android 10 ou moins, vous devez créer une nouvelle intention, Android 11+, vous utilisez simplement BringTaskToFront

Dans l'état d'appel 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);
}

Je règle le MyActivity.MyActivityTaskId lors de l'appel de mon activité, cela ne fonctionne pas, définissez cette variable sur la page d'activité parente de la page vers laquelle vous souhaitez revenir.

MyActivity.MyActivityTaskId = this.getTaskId();

MyActivityTaskId est une variable statique dans ma classe d'activité

public static int MyActivityTaskId = 0;

J'espère que cela fonctionnera pour vous. J'utilise le code ci-dessus un peu différemment, j'ouvre mon application dès que l'appel est pris afin que l'utilisateur puisse voir les détails de l'appelant.

J'ai mis quelques trucs dans le AndroidManifest.xml aussi:

/*Dont really know if this makes a difference*/
<activity Android:name="MyActivity" Android:taskAffinity="" Android:launchMode="singleTask" />

et autorisations:

<uses-permission Android:name="Android.permission.GET_TASKS" />
<uses-permission Android:name="Android.permission.REORDER_TASKS" />

S'il vous plaît poser des questions si ou quand vous êtes bloqué.

0
Pierre