如何在android中拨打电话并在通话结束后返回我的活动?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/1556987/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-20 03:15:41  来源:igfitidea点击:

How to make a phone call in android and come back to my activity when the call is done?

androidphone-call

提问by hap497

I am launching an activity to make a phone call, but when I pressed the 'end call' button, it does not go back to my activity. Can you please tell me how can I launch a call activity which comes back to me when 'End call' button is pressed? This is how I'm making the phone call:

我正在启动一个活动来打电话,但是当我按下“结束通话”按钮时,它不会回到我的活动中。你能告诉我如何启动一个在按下“结束通话”按钮时返回给我的通话活动吗?这是我打电话的方式:

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

回答by moonlightcheese

use a PhoneStateListener to see when the call is ended. you will most likely need to trigger the listener actions to wait for a the call to start (wait until changed from PHONE_STATE_OFFHOOK to PHONE_STATE_IDLE again) and then write some code to bring your app back up on the IDLE state.

使用 PhoneStateListener 查看呼叫何时结束。您很可能需要触发侦听器操作以等待调用开始(等到再次从 PHONE_STATE_OFFHOOK 更改为 PHONE_STATE_IDLE),然后编写一些代码使您的应用程序恢复到空闲状态。

you may need to run the listener in a service to ensure it stays up and your app is restarted. some 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 Manifest.xmlfile add the following permission:

在您的Manifest.xml文件中添加以下权限:

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

回答by Pria

This is regarding the question asked by Starter.

这是关于Starter提出的问题。

The problem with your code is that you are not passing the number properly.

您的代码的问题在于您没有正确传递数字。

The 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 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 number in case DIALis used.

用于紧急号码以防万一DIAL

回答by André Lima

We had the same problem and managed to solve it by using a PhoneStateListenerto identify when the call ends, but additionally we had to finish()the original activity before starting it again with startActivity, otherwise the call log would be in front of it.

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

回答by TheSolarSheriff

I found the EndCallListener the most functional example, to get the behaviour described (finish(), call, restart) I added a few SharedPreferences so the Listener had a reference to manage this behaviour.

我发现 EndCallListener 是功能最强大的示例,为了获得所描述的行为(完成()、调用、重新启动),我添加了一些 SharedPreferences,因此监听器有一个参考来管理此行为。

My OnClick, initialise and EndCallListener only respond to calls from app. Other calls ignored.

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

        }

    }
}

add these to strings.xml

将这些添加到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 your Manifest if you need to return to the 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 in your 'myActivity'

并将这些放在您的“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 the behaviour for your onClick in myActivity e.g. after 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();

}

You should find that clicking your list of phone numbers finishes your activty, makes the call to the number and returns to your activty when the call ends.

您应该会发现单击您的电话号码列表会完成您的活动,拨打该号码并在通话结束时返回您的活动。

Making a call from outside your app while it's still around won't restart your activty (unless it's the same as the last BParty number called).

在应用程序仍在运行时从应用程序外部拨打电话不会重新启动您的活动(除非它与上次呼叫的 BParty 号码相同)。

:)

:)

回答by yakr

you can use startActivityForResult()

你可以使用 startActivityForResult()

回答by cikabole

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 course in Activity (class) definition you have to implement View.OnClickListener .

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

回答by Oyee

Here is my example, first the user gets to write in the number he/she wants to dial and then presses a call button and gets directed to the phone. After call cancelation the user gets sent back to the application. In order to this the button needs to have a onClick method ('makePhoneCall' in this example) in the xml. You also need to register the permission in the manifest.

这是我的示例,首先用户输入他/她想要拨打的号码,然后按下呼叫按钮并被定向到电话。呼叫取消后,用户将被发送回应用程序。为此,按钮需要在 xml 中有一个 onClick 方法(在本例中为“makePhoneCall”)。您还需要在清单中注册权限。

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

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

回答by erluxman

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

回答by martincm

If you are going to use a listener you will need to add this permission to the manifest as well.

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

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

回答by Aimeric

To return to your Activity, you will need to listen to TelephonyStates. On that listeneryou can send an Intentto re-open your Activityonce the phone is idle.

要回到你的Activity身边,你需要倾听TelephonyStates。一旦手机空闲,listener您可以发送一个Intent重新打开您Activity的电话。

At least thats how I will do it.

至少我会这样做。