阅读更多 原文地址: https://stackoverflow.com/a/15564021

实测可用。
测试手机:
MeiZu MX4 Android 5.1
HuaWei Mate 8 Android 7.0

-----------------------------------------------------------
Here's what I use to do this:

AndroidManifest:

                                

My base reusable call detector
package com.gabesechan.android.reusable.receivers;import java.util.Date;import android.content.BroadcastReceiver;import android.content.Context;import android.content.Intent;import android.telephony.TelephonyManager;public abstract class PhonecallReceiver extends BroadcastReceiver {    //The receiver will be recreated whenever android feels like it.  We need a static variable to remember data between instantiations    private static int lastState = TelephonyManager.CALL_STATE_IDLE;    private static Date callStartTime;    private static boolean isIncoming;    private static String savedNumber;  //because the passed incoming is only valid in ringing    @Override    public void onReceive(Context context, Intent intent) {        //We listen to two intents.  The new outgoing call only tells us of an outgoing call.  We use it to get the number.        if (intent.getAction().equals("android.intent.action.NEW_OUTGOING_CALL")) {            savedNumber = intent.getExtras().getString("android.intent.extra.PHONE_NUMBER");        }        else{            String stateStr = intent.getExtras().getString(TelephonyManager.EXTRA_STATE);            String number = intent.getExtras().getString(TelephonyManager.EXTRA_INCOMING_NUMBER);            int state = 0;            if(stateStr.equals(TelephonyManager.EXTRA_STATE_IDLE)){                state = TelephonyManager.CALL_STATE_IDLE;            }            else if(stateStr.equals(TelephonyManager.EXTRA_STATE_OFFHOOK)){                state = TelephonyManager.CALL_STATE_OFFHOOK;            }            else if(stateStr.equals(TelephonyManager.EXTRA_STATE_RINGING)){                state = TelephonyManager.CALL_STATE_RINGING;            }            onCallStateChanged(context, state, number);        }    }    //Derived classes should override these to respond to specific events of interest    protected abstract void onIncomingCallReceived(Context ctx, String number, Date start);    protected abstract void onIncomingCallAnswered(Context ctx, String number, Date start);    protected abstract void onIncomingCallEnded(Context ctx, String number, Date start, Date end);    protected abstract void onOutgoingCallStarted(Context ctx, String number, Date start);          protected abstract void onOutgoingCallEnded(Context ctx, String number, Date start, Date end);    protected abstract void onMissedCall(Context ctx, String number, Date start);    //Deals with actual events    //Incoming call-  goes from IDLE to RINGING when it rings, to OFFHOOK when it's answered, to IDLE when its hung up    //Outgoing call-  goes from IDLE to OFFHOOK when it dials out, to IDLE when hung up    public void onCallStateChanged(Context context, int state, String number) {        if(lastState == state){            //No change, debounce extras            return;        }        switch (state) {            case TelephonyManager.CALL_STATE_RINGING:                isIncoming = true;                callStartTime = new Date();                savedNumber = number;                onIncomingCallReceived(context, number, callStartTime);                break;            case TelephonyManager.CALL_STATE_OFFHOOK:                //Transition of ringing->offhook are pickups of incoming calls.  Nothing done on them                if(lastState != TelephonyManager.CALL_STATE_RINGING){                    isIncoming = false;                    callStartTime = new Date();                    onOutgoingCallStarted(context, savedNumber, callStartTime);                                     }                else                {                    isIncoming = true;                    callStartTime = new Date();                    onIncomingCallAnswered(context, savedNumber, callStartTime);                 }                break;            case TelephonyManager.CALL_STATE_IDLE:                //Went to idle-  this is the end of a call.  What type depends on previous state(s)                if(lastState == TelephonyManager.CALL_STATE_RINGING){                    //Ring but no pickup-  a miss                    onMissedCall(context, savedNumber, callStartTime);                }                else if(isIncoming){                    onIncomingCallEnded(context, savedNumber, callStartTime, new Date());                                       }                else{                    onOutgoingCallEnded(context, savedNumber, callStartTime, new Date());                                                               }                break;        }        lastState = state;    }}

Then to use it, simply derive a class from it and implement a few easy functions, whichever call types you care about:

public class CallReceiver extends PhonecallReceiver {    @Override    protected void onIncomingCallReceived(Context ctx, String number, Date start)    {        //    }    @Override    protected void onIncomingCallAnswered(Context ctx, String number, Date start)    {        //    }    @Override    protected void onIncomingCallEnded(Context ctx, String number, Date start, Date end)    {        //    }    @Override    protected void onOutgoingCallStarted(Context ctx, String number, Date start)    {        //    }     @Override     protected void onOutgoingCallEnded(Context ctx, String number, Date start, Date end)    {        //    }    @Override    protected void onMissedCall(Context ctx, String number, Date start)    {        //    }}

In addition you can see a writeup I did on why the code is like it is on my blog. Gist link: https://gist.github.com/ftvs/e61ccb039f511eb288ee

EDIT: Updated to simpler code, as I've reworked the class for my own use

更多相关文章

  1. android 获取ip地址,获取2,3,4g,wifi状态等
  2. 博客地址
  3. Android 获取Gmail邮箱地址方法
  4. android ip地址,手机号码,邮箱格式验证
  5. Android 4权威专家撰写,经典作品最新升级版(内附部分章节试读下载
  6. Android获取设备IP地址代码与分析
  7. Android的默认虚拟机地址
  8. Android 定位地址,获取经纬度,并转换为中文地址

随机推荐

  1. Android禁用返回键
  2. Android(安卓)浮点型当小数点后为0时自动
  3. android异步加载图片
  4. Android的SensorEventListener例子(摇晃手
  5. 对话框android
  6. Android修改system只读权限:remount
  7. Android之文件存储
  8. android Fragment + FragmentStatePagerA
  9. android 自动更新apk版本
  10. Android图片圆角处理