电话 API

简介

应用层通话状监听仅三种,由TelephonyManager.java注释知三状含义:

  • CALL_STATE_IDLE
    空闲态(无通话活动)
  • CALL_STATE_RINGING
    响铃、第三方来电等
  • CALL_STATE_OFFHOOK
    dialing拨号中、active接通、hold挂起等

资料

Android-9种通话状态(精确)

实现

权限

<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读通信状。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

snpmyn

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值