case TelephonyManager.CALL_STATE_OFFHOOK: // 来电接通 或者 去电 但是没法区分
break;
}
}
}
三种状态源码解释
/** Device call state: No activity. */
public static final int CALL_STATE_IDLE = 0; // 电话挂断
/** Device call state: Ringing. A new call arrived and is
-
ringing or waiting. In the latter case, another call is
-
already active. */
public static final int CALL_STATE_RINGING = 1; // 来电响铃
/** Device call state: Off-hook. At least one call exists
-
that is dialing, active, or on hold, and no calls are ringing
-
or waiting. */
public static final int CALL_STATE_OFFHOOK = 2; // 来电接通 或者 去电拨号 但是没法区分出来
2.2 来去电监听方式二(广播监听,但是时机比上面的 PhoneStateListener 方式要晚一点)
<receiver android:name=“.PhoneStateReceiver”
android:enabled=“true”
android:process=“:PhoneListenService”>
public class PhoneStateReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
if (intent.getAction().equals(Intent.ACTION_NEW_OUTGOING_CALL)) {
// 去电,可以用定时挂断
} else {
//来电
String state = intent.getStringExtra(TelephonyManager.EXTRA_STATE);
Log.d(PhoneListenService.TAG, "PhoneStateReceiver onReceive state: " + state);
if (state.equalsIgnoreCase(TelephonyManager.EXTRA_STATE_RINGING)) {
Log.d(PhoneListenService.TAG, “PhoneStateReceiver onReceive endCall”);
HangUpTelephonyUtil.endCall(context);
}
}
}
}
三. 实战,有什么需要特别注意地方
3.1 双卡双待的手机怎么获取
对于双卡手机,每张卡都对应一个 Service 和一个 PhoneStateListener,需要给每个服务注册自己的 PhoneStateListener,服务的名称还会有点变化,厂商可能会修改
public ArrayList getMultSimCardInfo() {
// 获取双卡的信息,这个也是经验尝试出来的,不知道其他厂商有什么坑
ArrayList phoneServerList = new ArrayList();
for(int i = 1; i < 3; i++) {
try {
String phoneServiceName;
if (MiuiUtils.isMiuiV6()) {
phoneServiceName = “phone.” + String.valueOf(i-1);
} else {
phoneServiceName = “phone” + String.valueOf(i);
}
// 尝试获取服务看是否能获取到
IBinder iBinder = ServiceManager.getService(phoneServiceName);
if(iBinder == null) continue;
ITelephony iTelephony = ITelephony.Stub.asInterface(iBinder);
if(iTelephony == null) continue;
phoneServerList.add(phoneServiceName);
} catch(Exception e) {
e.printStackTrace();
}
}
// 这个是默认的
phoneServerList.add(Context.TELEPHONY_SERVICE);
return phoneServerList;
}
3.2 挂断电话
挂断电话使用系统服务提供的接口去挂断,但是挂断电话是个并不能保证成功的方法,所以会有多种方式挂断同时使用,下面提供
package com.phone.listen;
import android.content.Context;
import android.os.RemoteException;
import android.telephony.TelephonyManager;
import com.android.internal.telephony.ITelephony;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.concurrent.Executor;
import java.util.concurrent.Executors;
/**
- 封装挂断电话接口
*/
public class HangUpTelephonyUtil {
public static boolean endCall(Context context) {
boolean callSuccess = false;
ITelephony telephonyService = getTelephonyService(context);
try {
if (telephonyService != null) {
callSuccess = telephonyService.endCall();
}
} catch (RemoteException e) {
e.printStackTrace();
} catch (Exception e){
e.printStackTrace();
}
if (callSuccess == false) {
Executor eS = Executors.newSingleThreadExecutor();
eS.execute(new Runnable() {
@Override
public void run() {
disconnectCall();
}
});
callSuccess = true;
}
return callSuccess;
}
private static ITelephony getTelephonyService(Context context) {
TelephonyManager telephonyManager = (TelephonyManager)
context.getSystemService(Context.TELEPHONY_SERVICE);
Class clazz;
try {
clazz = Class.forName(telephonyManager.getClass().getName());
Method method = clazz.getDeclaredMethod(“getITelephony”);
method.setAccessible(true);
return (ITelephony) method.invoke(telephonyManager);
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (NoSuchMethodException e) {
e.printStackTrace();
} catch (IllegalArgumentException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}
return null;
}
private static boolean disconnectCall() {
Runtime runtime = Runtime.getRuntime();
try {
runtime.exec(“service call phone 5 \n”);
} catch (Exception exc) {
exc.printStackTrace();
return false;
}
return true;
}
// 使用 endCall 挂断不了,再使用 killCall 反射调用再挂一次
public static boolean killCall(Context context) {
try {
// Get the boring old TelephonyManager
TelephonyManager telephonyManager = (TelephonyManager)
context.getSystemService(Context.TELEPHONY_SERVICE);
// Get the getITelephony() method
Class classTelephony = Class.forName(telephonyManager.getClass().getName());
Method methodGetITelephony = classTelephony.getDeclaredMethod(“getITelephony”);
// Ignore that the method is supposed to be private
methodGetITelephony.setAccessible(true);
// Invoke getITelephony() to get the ITelephony interface
Object telephonyInterface = methodGetITelephony.invoke(telephonyManager);
// Get the endCall method from ITelephony
Class telephonyInterfaceClass = Class.forName(telephonyInterface.getClass().getName());
Method methodEndCall = telephonyInterfaceClass.getDeclaredMethod(“endCall”);
// Invoke endCall()
methodEndCall.invoke(telephonyInterface);
} catch (Exception ex) { // Many things can go wrong with reflection calls
return false;
}
return true;
}
}
自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。
深知大多数初中级安卓工程师,想要提升技能,往往是自己摸索成长,但自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!
因此收集整理了一份《2024年最新Android移动开发全套学习资料》送给大家,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。
由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频
如果你觉得这些内容对你有帮助,可以添加下面V无偿领取!(备注Android)
极易碰到天花板技术停滞不前!**
因此收集整理了一份《2024年最新Android移动开发全套学习资料》送给大家,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。
[外链图片转存中…(img-Bed4ApRt-1711298442337)]
[外链图片转存中…(img-T3vi9AKc-1711298442338)]
[外链图片转存中…(img-FhNNs8Lf-1711298442338)]
[外链图片转存中…(img-fkUw7aHu-1711298442338)]
由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频
如果你觉得这些内容对你有帮助,可以添加下面V无偿领取!(备注Android)
[外链图片转存中…(img-9159IUMD-1711298442339)]