`
yhz61010
  • 浏览: 561432 次
  • 来自: -
博客专栏
63c13ecc-ef01-31cf-984e-de461c7dfde8
libgdx 游戏开发
浏览量:12245
社区版块
存档分类
最新评论

[转] How to detect incoming calls in an Android

阅读更多
原文地址: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:
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
<uses-permission android:name="android.permission.PROCESS_OUTGOING_CALLS"/>

<!--This part is inside the application-->
<receiver android:name=".CallReceiver" >
    <intent-filter>
        <action android:name="android.intent.action.PHONE_STATE" />
    </intent-filter>
    <intent-filter>
        <action android:name="android.intent.action.NEW_OUTGOING_CALL" />
    </intent-filter>
</receiver>

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
分享到:
评论

相关推荐

    opencvsharp-20个例子

    Sample10: How to calculate the histogram of an image. Sample11: How use k-means method of OpenCV. Sample12: How to use watershed transform. Sample13: How to use SURF. Sample14: How to use ...

    OpenCVSharp 最新4.0 的19个例子

    Sample10: How to calculate the histogram of an image. Sample11: How use k-means method of OpenCV. Sample12: How to use watershed transform. Sample13: How to use SURF. Sample14: How to use ...

    OpenCVSharp-DEMO.zip

    Sample10: How to calculate the histogram of an image. Sample11: How use k-means method of OpenCV. Sample12: How to use watershed transform. Sample13: How to use SURF. Sample14: How to use ...

    How to Cheat at Securing a Wireless Network

    He has contributed to several other Syngress publications, including Penetration Tester's Open Source Toolkit (ISBN: 1-5974490210), Stealing the Network: How to Own an Identity (ISBN: 1597490067), ...

    HOW TO DETECT OPEN PORTS, PROTOCOLS AND SERVICES.docx

    【如何检测开放端口、协议和服务】 在信息技术领域,服务依赖于特定的端口来接收和传输信息。因此,组织必须了解其IT环境中哪些端口是开放的,这些端口的功能以及它们关联的服务是什么,这一点至关重要。...

    OpenCV 3.x with Python By Example, 2nd Edition-Packt Publishing(2018).pdf

    Chapter 4, Detecting and Tracking Different Body Parts, shows how to detect and track faces in a live video stream. We will discuss the face detection pipeline and see how we can use it to detect and...

    'Learning to Detect Video Saliency With HEVC Features'.pdf

    Learning to Detect Video SaliencyWith HEVC Features 中文引用格式 英文引用格式 Xu M , Jiang L , Sun X , et al. Learning to Detect Video Saliency With HEVC Features[J]. Image Processing, IEEE ...

    learning to detect a salient object

    ### 学习检测显著物体:图像显著性检测的深度解析 #### 摘要与背景 本文探讨了视觉注意力在图像处理中的应用,通过检测图像中的显著物体来模拟人类视觉系统对特定区域的关注机制。作者将显著物体检测视为一种图像...

    Unsupervised Learning From Video to Detect Foreground Objects in

    视频无监督学习检测单图像前景对象 无监督学习是计算机视觉和机器学习中最具挑战性和趣味的问题之一。它对于理解视觉识别的工作机理非常重要。此外,无监督学习还具有实际应用价值,因为可以在低成本下收集大量未...

    gec.zip_GA_gec

    How to detect an image in matlab

    Android Design Patterns and Best Practices

    You will then develop an application that will help you grasp Activities, Services and Broadcasts and their roles in Android development. Moving on, you will add user detecting classes ansd APIs such...

    An Advanced Hybrid Peer-to-Peer Botnet

    To be well prepared for future attacks, it is not enough to study how to detect and defend against the botnets that have appeared in the past. More importantly, we should study advanced botnet ...

    精通Android增强现实源码

    How to detect movement and orientation of the device How to program against the accelerometer and compass How to use the AndAR library in marker recognition How to create an artificial horizon for ...

    SetupMDSolids40.zip_how to research_object detect_object track

    在“SetupMDSolids40.zip_how to research_object detect_object track”这个压缩包中,我们可以找到关于对象检测和跟踪的研究论文。这篇论文详细阐述了如何在IT领域,特别是计算机视觉方面,进行有效的物体识别与...

    CVPR2007_Learning_to_detect_a_salient_object

    CVPR2007_Learning_to_detect_a_salient_object论文源代码

    kbejjjbd(www.greenxf.com).rar

    Unable to detect adb version, exit value: 0xc0000135. ADB depends on the Windows Universal C Runtime, which is usually installed by default via Windows Update. You may need to manually fetch and ...

    Intelligent-IoT-Projects-in-7-Days.pdf

    Learn how to detect a car plate and to count the car parking duration. Various pattern recognition algorithms will be introduced to detect a car plate. Chapter 3 , Making Your Own Vending Machine, ...

    Code to detect ellipses in 2D images mainly for CMCs

    THe FiberToolbox is a plugin for DREAM.3D that allows the user to extract ellipses from a 2D image. The plugin was primarily developed to extract fibers from a micrograph cross section of a Composite ...

Global site tag (gtag.js) - Google Analytics