android实现接通和挂断电话

时间:2022-10-22 21:05:48

本文实例为大家分享了android实现接通和挂断电话的具体代码,供大家参考,具体内容如下

关键代码:【PhoneUtils类】

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
package com.ebupt.phonerecorddemo.server;
 
import java.lang.reflect.Method;
import android.content.Context;
import android.content.Intent;
import android.telephony.TelephonyManager;
import android.util.Log;
import android.view.KeyEvent;
 
import com.android.internal.telephony.ITelephony;
 
public class PhoneUtils {
 static String TAG = "PhoneUtils";
 /**
  * 从TelephonyManager中实例化ITelephony,并返回
  */
 static public ITelephony getITelephony(TelephonyManager telMgr)
   throws Exception {
  Method getITelephonyMethod = telMgr.getClass().getDeclaredMethod(
    "getITelephony");
  getITelephonyMethod.setAccessible(true);// 私有化函数也能使用
  return (ITelephony) getITelephonyMethod.invoke(telMgr);
 }
  
 //自动接听
 public static void autoAnswerPhone(Context c,TelephonyManager tm) {
  try {
   Log.i(TAG, "autoAnswerPhone");
   ITelephony itelephony = getITelephony(tm);
   // itelephony.silenceRinger();
   itelephony.answerRingingCall();
  } catch (Exception e) {
   e.printStackTrace();
   try {
    Log.e(TAG, "用于Android2.3及2.3以上的版本上");
    Intent intent = new Intent("android.intent.action.MEDIA_BUTTON");
    KeyEvent keyEvent = new KeyEvent(KeyEvent.ACTION_DOWN,
      KeyEvent.KEYCODE_HEADSETHOOK);
    intent.putExtra("android.intent.extra.KEY_EVENT", keyEvent);
    c.sendOrderedBroadcast(intent,
      "android.permission.CALL_PRIVILEGED");
    intent = new Intent("android.intent.action.MEDIA_BUTTON");
    keyEvent = new KeyEvent(KeyEvent.ACTION_UP,
      KeyEvent.KEYCODE_HEADSETHOOK);
    intent.putExtra("android.intent.extra.KEY_EVENT", keyEvent);
    c.sendOrderedBroadcast(intent,
      "android.permission.CALL_PRIVILEGED");
    Intent localIntent1 = new Intent(Intent.ACTION_HEADSET_PLUG);
    localIntent1.addFlags(Intent.FLAG_ACTIVITY_NO_HISTORY);
    localIntent1.putExtra("state", 1);
    localIntent1.putExtra("microphone", 1);
    localIntent1.putExtra("name", "Headset");
    c.sendOrderedBroadcast(localIntent1,
      "android.permission.CALL_PRIVILEGED");
    Intent localIntent2 = new Intent(Intent.ACTION_MEDIA_BUTTON);
    KeyEvent localKeyEvent1 = new KeyEvent(KeyEvent.ACTION_DOWN,
      KeyEvent.KEYCODE_HEADSETHOOK);
    localIntent2.putExtra("android.intent.extra.KEY_EVENT",
      localKeyEvent1);
    c.sendOrderedBroadcast(localIntent2,
      "android.permission.CALL_PRIVILEGED");
    Intent localIntent3 = new Intent(Intent.ACTION_MEDIA_BUTTON);
    KeyEvent localKeyEvent2 = new KeyEvent(KeyEvent.ACTION_UP,
      KeyEvent.KEYCODE_HEADSETHOOK);
    localIntent3.putExtra("android.intent.extra.KEY_EVENT",
      localKeyEvent2);
    c.sendOrderedBroadcast(localIntent3,
      "android.permission.CALL_PRIVILEGED");
    Intent localIntent4 = new Intent(Intent.ACTION_HEADSET_PLUG);
    localIntent4.addFlags(Intent.FLAG_ACTIVITY_NO_HISTORY);
    localIntent4.putExtra("state", 0);
    localIntent4.putExtra("microphone", 1);
    localIntent4.putExtra("name", "Headset");
    c.sendOrderedBroadcast(localIntent4,
      "android.permission.CALL_PRIVILEGED");
   } catch (Exception e2) {
    e2.printStackTrace();
    Intent meidaButtonIntent = new Intent(
      Intent.ACTION_MEDIA_BUTTON);
    KeyEvent keyEvent = new KeyEvent(KeyEvent.ACTION_UP,
      KeyEvent.KEYCODE_HEADSETHOOK);
    meidaButtonIntent.putExtra(Intent.EXTRA_KEY_EVENT, keyEvent);
    c.sendOrderedBroadcast(meidaButtonIntent, null);
   }
  }
 }
  
 //自动挂断
 public static void endPhone(Context c,TelephonyManager tm) {
  try {
   Log.i(TAG, "endPhone");
   ITelephony iTelephony;
   Method getITelephonyMethod = TelephonyManager.class
     .getDeclaredMethod("getITelephony", (Class[]) null);
   getITelephonyMethod.setAccessible(true);
   iTelephony = (ITelephony) getITelephonyMethod.invoke(tm,
     (Object[]) null);
   // 挂断电话
   iTelephony.endCall();
  } catch (Exception e) {
   e.printStackTrace();
  }
 }
 
}

需要用到的ITelephony.aidl:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
package com.android.internal.telephony;
 /**
 * Interface used to interact with the phone. Mostly this is used by the
 * TelephonyManager class. A few places are still using this directly.
 * Please clean them up if possible and use TelephonyManager instead.
 * {@hide}
 */
 
interface ITelephony { 
 /** 
 * End call or go to the Home screen
 * @return whether it hung up 
 */
 boolean endCall(); 
  
 /** 
 * Answer the currently-ringing call. 
 
 * If there's already a current active call, that call will be 
 * automatically put on hold. If both lines are currently in use, the 
 * current active call will be ended. 
 
 * TODO: provide a flag to let the caller specify what policy to use 
 * if both lines are in use. (The current behavior is hardwired to 
 * "answer incoming, end ongoing", which is how the CALL button 
 * is specced to behave.) 
 
 * TODO: this should be a oneway call (especially since it's called 
 * directly from the key queue thread). 
 */
 void answerRingingCall();
  
 /**
  * Silence the ringer if an incoming call is currently ringing.
  * (If vibrating, stop the vibrator also.)
  *
  * It's safe to call this if the ringer has already been silenced, or
  * even if there's no incoming call. (If so, this method will do nothing.)
  *
  * TODO: this should be a oneway call too (see above).
  *  (Actually *all* the methods here that return void can
  *  probably be oneway.)
  */
 void silenceRinger();
  
 /**
  * Allow mobile data connections.
  */
 boolean enableDataConnectivity();
 
 /**
  * Disallow mobile data connections.
  */
 boolean disableDataConnectivity();
 
 /**
  * Report whether data connectivity is possible.
  */
 boolean isDataConnectivityPossible();
}

监听通话广播【PhoneReceiver.java】:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
package com.ebupt.phonerecorddemo.server;
 
import android.app.Service;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.telephony.TelephonyManager;
import android.util.Log;
 
public class PhoneReceiver extends BroadcastReceiver {
 String TAG = "PhoneReceiver";
 @Override
 public void onReceive(Context context, Intent intent) {
  TelephonyManager tm = (TelephonyManager) context
    .getSystemService(Service.TELEPHONY_SERVICE);
  switch (tm.getCallState()) {
  case TelephonyManager.CALL_STATE_OFFHOOK:// 电话打进来接通状态;电话打出时首先监听到的状态。
   Log.i("onCallStateChanged", "CALL_STATE_OFFHOOK");
   break;
  case TelephonyManager.CALL_STATE_RINGING:// 电话打进来状态
   Log.i("onCallStateChanged", "CALL_STATE_RINGING");
   PhoneUtils.autoAnswerPhone(context,tm);
   break;
  case TelephonyManager.CALL_STATE_IDLE:// 不管是电话打出去还是电话打进来都会监听到的状态。
   Log.i("onCallStateChanged", "CALL_STATE_IDLE");
   break;
  }
 }
 
  
}

在上面类适当的地方加上挂断或接通电话的代码即可。

最后别忘记在AndroidManifest.xml里声明和注册权限。

?
1
2
3
4
5
6
<uses-permission android:name="android.permission.READ_PHONE_STATE" >
</uses-permission>
<uses-permission android:name="android.permission.PROCESS_OUTGOING_CALLS" >
</uses-permission>
<uses-permission android:name="android.permission.MODIFY_PHONE_STATE" />
<uses-permission android:name="android.permission.CALL_PHONE" />
?
1
2
3
4
5
6
<receiver android:name="com.ebupt.phonerecorddemo.server.PhoneReceiver" >
 <intent-filter android:priority="2147483647" >
 <action android:name="android.intent.action.PHONE_STATE" >
 </action>
 </intent-filter>
</receiver>

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持服务器之家。

原文链接:https://blog.csdn.net/viviwen123/article/details/9299503