首页 文章

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

提问于
浏览
126

我正在启动一个打电话的活动,但当我按下“结束通话”按钮时,它不会返回我的活动 . 您能否告诉我如何在按下“结束通话”按钮时启动回复给我的通话活动?这就是我拨打电话的方式:

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

21 回答

  • 2

    从我的观点来看,这是解决方案:

    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 .

  • 3

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

    这是关于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 ,则为紧急号码 .

  • 1

    我们遇到了同样的问题,并设法通过使用 PhoneStateListener 来确定呼叫何时结束,但另外我们必须 finish() 原始活动再次使用 startActivity 启动它,否则呼叫日志将在它前面 .

  • 1

    我发现EndCallListener是最实用的示例,用于获取描述的行为(finish(),call,restart)我添加了一些SharedPreferences,因此Listener有一个引用来管理这种行为 .

    我的OnClick,initialise和EndCallListener只响应来自app的调用 . 其他通话被忽略 .

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

    使用它来启动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号码相同) .

    :)

  • 3

    你可以使用startActivityForResult()

  • 6

    这是我的例子,首先用户可以写下他/她想要拨打的号码然后按下呼叫按钮并转到电话 . 呼叫取消后,用户将被发送回应用程序 . 为此,按钮需要在xml中具有onClick方法(在此示例中为'makePhoneCall') . 您还需要在清单中注册权限 .

    表现

    <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" />
    
  • 3
    @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

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

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

    在看到调用完成后,在PhoneStateListener内部更好用:

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

    CallDispatcherActivity是用户发起呼叫的活动(在我的情况下是出租车服务调度员) . 这只是从顶部删除Android电话应用程序,用户返回而不是我在这里看到的丑陋代码 .

  • 0

    要返回 Activity ,您需要收听 TelephonyStates . 在 listener 上,您可以发送 Intent 以在手机空闲时重新打开 Activity .

    至少那就是我将如何做到这一点 .

  • 6

    完美教程here!请务必查看此博客,因为它有许多优秀的教程!

  • 1
    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" />
    
  • 6

    尝试使用:

    finish();
    

    在活动结束时 . 它会将您重定向到之前的活动 .

  • 3

    当使用 PhoneStateListener 时,需要确保 PHONE_STATE_OFFHOOK 后面的 PHONE_STATE_IDLE 用于触发调用后要执行的操作 . 如果在看到 PHONE_STATE_IDLE 时发生触发,您将在通话前结束 . 因为你会看到状态变化 PHONE_STATE_IDLE -> PHONE_STATE_OFFHOOK -> PHONE_STATE_IDLE.

  • 105

    //在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>
    
  • 7

    @Dmitri Novikov, FLAG_ACTIVITY_CLEAR_TOP 清除新的活动实例 . 所以,它可能会结束在完成该过程之前的旧实例 .

  • 2

    添加这是你的xml: android:autoLink="phone"

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

  • 5

    开始通话时,它看起来很好 .

    虽然Android将你的应用程序带到了前面,但是在android 11和down之间存在差异 .

    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 是我的activity类的静态变量

    public static int MyActivityTaskId = 0;
    

    我希望这对你有用 . 我使用上面的代码有点不同,我在应答呼叫后立即打开我的应用程序,用户可以看到呼叫者的详细信息 .

    我也在_1464736中设置了一些东西:

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

    如果您遇到困难,请提出问题 .

  • 13

    脚步:

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

    if you want to resume your application last state or to bring it back from the back stack ,然后用 FLAG_ACTIVITY_SINGLE_TOP 替换 FLAG_ACTIVITY_CLEAR_TOP

    参考这个Answer

相关问题