简介
应用层通话状监听仅三种,由TelephonyManager.java注释知三状含义:
- CALL_STATE_IDLE
空闲态(无通话活动) - CALL_STATE_RINGING
响铃、第三方来电等 - CALL_STATE_OFFHOOK
dialing拨号中、active接通、hold挂起等
资料
实现
权限
<uses-permission android:name="android.permission.CALL_PHONE" />
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
服务
package com.zsp.library.telephony;
import android.app.Service;
import android.content.Intent;
import android.os.IBinder;
import android.telephony.PhoneStateListener;
import android.telephony.TelephonyManager;
import com.zsp.utilone.log.LogManager;
/**
* Created on 2019/6/11.
*
* @author 郑少鹏
* @desc 电话服务
*/
public class TelephonyService extends Service {
private static final String TAG = "TelephonyService";
/**
* 电话管理器
*/
private TelephonyManager telephonyManager;
/**
* 电话状监听
*/
private MyPhoneStateListener myPhoneStateListener;
/**
* 电话服务监听
*/
private static TelephonyServiceListener telephonyServiceListener;
/**
* 记录上电话状
*/
private int lastCallState = TelephonyManager.CALL_STATE_IDLE;
/**
* 时长
*/
private long duration;
@Override
public IBinder onBind(Intent intent) {
return null;
}
@Override
public void onCreate() {
super.onCreate();
LogManager.e(TAG, "开启电话服务");
// 监听通话状
listenCallState();
}
@Override
public void onDestroy() {
super.onDestroy();
LogManager.e(TAG, "关闭电话服务");
// 不监听
listenNone();
}
/**
* 监听通话状
*/
private void listenCallState() {
telephonyManager = (TelephonyManager) getSystemService(TELEPHONY_SERVICE);
myPhoneStateListener = new MyPhoneStateListener();
telephonyManager.listen(myPhoneStateListener, PhoneStateListener.LISTEN_CALL_STATE);
}
/**
* 不监听
*/
private void listenNone() {
telephonyManager.listen(myPhoneStateListener, PhoneStateListener.LISTEN_NONE);
}
/**
* 电话状监听
*/
class MyPhoneStateListener extends PhoneStateListener {
@Override
public void onCallStateChanged(int state, String incomingNumber) {
super.onCallStateChanged(state, incomingNumber);
LogManager.e(TAG, incomingNumber);
switch (state) {
/*
响铃
*/
case TelephonyManager.CALL_STATE_RINGING:
lastCallState = TelephonyManager.CALL_STATE_RINGING;
LogManager.e(TAG, "响铃");
duration = System.currentTimeMillis();
telephonyServiceListener.callStateRinging(duration);
break;
/*
通话
*/
case TelephonyManager.CALL_STATE_OFFHOOK:
if (lastCallState == TelephonyManager.CALL_STATE_RINGING) {
// 呼入
LogManager.e(TAG, "呼入");
telephonyServiceListener.incomingCall();
} else {
// 呼出
LogManager.e(TAG, "呼出");
duration = System.currentTimeMillis();
telephonyServiceListener.callOut(duration);
}
lastCallState = TelephonyManager.CALL_STATE_OFFHOOK;
break;
/*
空闲
*/
case TelephonyManager.CALL_STATE_IDLE:
if (lastCallState == TelephonyManager.CALL_STATE_IDLE) {
// 无通话
LogManager.e(TAG, "无通话");
if (telephonyServiceListener != null) {
telephonyServiceListener.noCalls();
}
} else {
// 挂断通话
LogManager.e(TAG, "挂断通话");
lastCallState = TelephonyManager.CALL_STATE_IDLE;
long endTime = System.currentTimeMillis();
telephonyServiceListener.hangUpTheCall(endTime, endTime - duration);
}
break;
default:
break;
}
}
}
/**
* 设电话服务监听
*
* @param telephonyServiceListener 电话服务监听
*/
public static void setTelephonyServiceListener(TelephonyServiceListener telephonyServiceListener) {
TelephonyService.telephonyServiceListener = telephonyServiceListener;
}
/**
* 电话服务监听
*/
public interface TelephonyServiceListener {
/**
* 响铃
* <p>
* 呼入调,不调{@link #incomingCall()}。
*
* @param startTime 开始时间
*/
void callStateRinging(long startTime);
/**
* 呼入
* <p>
* 呼入不调,调{@link #callStateRinging(long)}。
*/
void incomingCall();
/**
* 呼出
*
* @param startTime 开始时间
*/
void callOut(long startTime);
/**
* 无通话
*/
void noCalls();
/**
* 挂断通话
*
* @param endTime 结束时间
* @param duration 时长
*/
void hangUpTheCall(long endTime, long duration);
}
}
<service android:name="widget.telephony.TelephonyService" />
主代码
public class MemberDetailFragment implements TelephonyService.TelephonyServiceListener {
/**
* 意图
*/
private Intent intent;
@Override
public void onDestroyView() {
super.onDestroyView();
baseFragmentActivity.stopService(intent);
}
/**
* Fragment对用户可见时调
*/
@Override
protected void visibleToUser() {
if (null == intent) {
intent = new Intent(baseFragmentActivity, TelephonyService.class);
}
if (!ServiceUtils.isServiceRunning(baseFragmentActivity, Magic.STRING_SERVICE_NAME, Magic.INT_TWENTY_THIRTY)) {
baseFragmentActivity.startService(intent);
}
}
private void setListener() {
TelephonyService.setTelephonyServiceListener(this);
}
/**
* 响铃
* <p>
* 呼入调,不调{@link #incomingCall()}。
*
* @param startTime 开始时间
*/
@Override
public void callStateRinging(long startTime) {
}
/**
* 呼入
* <p>
* 呼入不调,调{@link #callStateRinging(long)}。
*/
@Override
public void incomingCall() {
}
/**
* 呼出
*
* @param startTime 开始时间
*/
@Override
public void callOut(long startTime) {
}
/**
* 无通话
*/
@Override
public void noCalls() {
}
/**
* 挂断通话
*
* @param endTime 结束时间
* @param duration 时长
*/
@Override
public void hangUpTheCall(long endTime, long duration) {
}
}
不足
目前所获时长为呼出(或响铃)至挂断通话时长,并非真正意义上开始通话至挂断通话时长。
引申
active接通状没单独给出,无法得知电话接通否。需其它手段获更多精确通话状。
系统API监听
源码如下。该回调API于android.jar被hide,可通反射或没被hide之android.jar解决。
/**
* Callback invoked when precise device call state changes.
*
* @hide
*/
public void onPreciseCallStateChanged(PreciseCallState callState) {
// default implementation empty
}
读Logcat通信日志
- android4.1+需root权限,android 4.1-仅添日志权限android.permission.READ_LOGS。
- root状下执行
logcat -v time -b radio
读通信状。