如何检测来电,在Android设备? [英] How to detect incoming calls, in an android device?

查看:363
本文介绍了如何检测来电,在Android设备?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我是新来的Andr​​oid开发。我试图让一个应用程序一样,当有电话打进来,以我要检测的号码的电话,我试过了,下面是我的code.But它不是检测来电。我想在后台运行我的 MainActivity 。请帮帮我。如何让它在后台运行?
我给在清单文件的权限。

<使用许可权的android:NAME =android.permission.READ_PHONE_STATE />

还有什么我应该在清单提供?请帮我!

 公共类MainActivity延伸活动{
    @覆盖
    保护无效的onCreate(捆绑savedInstanceState){
        super.onCreate(savedInstanceState);
        的setContentView(R.layout.test_layout);
   }   公共类myPhoneStateChangeListener扩展PhoneStateListener {
       @覆盖
       公共无效onCallStateChanged(INT状态,弦乐incomingNumber){
           super.onCallStateChanged(州,incomingNumber);
           如果(状态== TelephonyManager.CALL_STATE_RINGING){
               字符串phoneNumber的= incomingNumber;
           }
       }
   }
}


解决方案

下面是我用它来做到这一点:

清单:

 <使用许可权的android:NAME =android.permission.READ_PHONE_STATE/>
<使用许可权的android:NAME =android.permission.PROCESS_OUTGOING_CALLS/><! - 这一部分是应用程序内部 - >
    <接收机器人:名字=。CallReceiver>
        &所述;意图滤光器>
            <作用机器人:名字=android.intent.action.PHONE_STATE/>
        &所述; /意图滤光器>
        &所述;意图滤光器>
            <作用机器人:名字=android.intent.action.NEW_OUTGOING_CALL/>
        &所述; /意图滤光器>
    < /接收器>

我的基本可重复使用的呼叫检测

 包com.gabesechan.android.reusable.receivers;进口java.util.Date;进口android.content.BroadcastReceiver;
进口android.content.Context;
进口android.content.Intent;
进口android.telephony.TelephonyManager;公共抽象类PhonecallReceiver扩展广播接收器{    //每当Android的感觉就像是,接收器将被重新创建。我们需要一个静态变量来记住实例之间的数据    私有静态诠释lastState = TelephonyManager.CALL_STATE_IDLE;
    私有静态日期callStartTime;
    私有静态布尔isIncoming;
    私人静态字符串savedNumber; //因为传递进来的是只有在有效振铃
    @覆盖
    公共无效的onReceive(上下文的背景下,意图意图){        //我们听两个目的。新的呼出只告诉我们一个呼出。我们用它来获得的数目。
        如果(intent.getAction()。等于(android.intent.action.NEW_OUTGOING_CALL)){
            savedNumber = intent.getExtras()的getString(android.intent.extra.PHONE_NUMBER);
        }
        其他{
            字符串stateStr = intent.getExtras()的getString(TelephonyManager.EXTRA_STATE)。
            。弦数= intent.getExtras()的getString(TelephonyManager.EXTRA_INCOMING_NUMBER);
            INT状态= 0;
            如果(stateStr.equals(TelephonyManager.EXTRA_STATE_IDLE)){
                状态= TelephonyManager.CALL_STATE_IDLE;
            }
            否则如果(stateStr.equals(TelephonyManager.EXTRA_STATE_OFFHOOK)){
                状态= TelephonyManager.CALL_STATE_OFFHOOK;
            }
            否则如果(stateStr.equals(TelephonyManager.EXTRA_STATE_RINGING)){
                状态= TelephonyManager.CALL_STATE_RINGING;
            }
            onCallStateChanged(上下文,状态,数量);
        }
    }    //派生类应覆盖这些对感兴趣的特定事件作出回应
    受保护的抽象无效onIncomingCallReceived(上下文CTX,串号,日期开始);
    受保护的抽象无效onIncomingCallAnswered(上下文CTX,串号,日期开始);
    受保护的抽象无效onIncomingCallEnded(上下文CTX,串号,开始日期,结束日期);    受保护的抽象无效onOutgoingCallStarted(上下文CTX,串号,日期开始);
    受保护的抽象无效onOutgoingCallEnded(上下文CTX,串号,开始日期,结束日期);    受保护的抽象无效onMissedCall(上下文CTX,串号,日期开始);    //实际的活动优惠    //传入call-从IDLE进入响起时,振铃,摘机来时,它的回答,当其吊起来IDLE
    //传出call-从IDLE变为摘机时,拨出,当吊起来IDLE
    公共无效onCallStateChanged(上下文的背景下,INT状态,串号){
        如果(lastState ==州){
            //没有变化,反跳演员
            返回;
        }
        开关(州){
            案例TelephonyManager.CALL_STATE_RINGING:
                isIncoming = TRUE;
                callStartTime =新的日期();
                savedNumber =号;
                onIncomingCallReceived(上下文,号码,callStartTime);
                打破;
            案例TelephonyManager.CALL_STATE_OFFHOOK:
                的ringing-&GT //过渡;摘机是来电的皮卡。没有对他们做
                如果(lastState!= TelephonyManager.CALL_STATE_RINGING){
                    isIncoming = FALSE;
                    callStartTime =新的日期();
                    onOutgoingCallStarted(背景下,savedNumber,callStartTime);
                }
                其他
                {
                    isIncoming = TRUE;
                    callStartTime =新的日期();
                    onIncomingCallAnswered(背景下,savedNumber,callStartTime);
                }                打破;
            案例TelephonyManager.CALL_STATE_IDLE:
                //走到idle-这是一个呼叫的结束。什么类型取决于previous状态(S)
                如果(lastState == TelephonyManager.CALL_STATE_RINGING){
                    //戒指,但没有接听 - 思念
                    onMissedCall(背景下,savedNumber,callStartTime);
                }
                否则,如果(isIncoming){
                    onIncomingCallEnded(背景下,savedNumber,callStartTime,新的Date());
                }
                其他{
                    onOutgoingCallEnded(背景下,savedNumber,callStartTime,新的Date());
                }
                打破;
        }
        lastState =状态;
    }
}

然后使用它,只要能从中得到一类并实现一些简单的功能,你所关心的任何呼叫类型:

 公共类CallReceiver扩展PhonecallReceiver {    @覆盖
    受保护的抽象无效onIncomingCallReceived(上下文CTX,串号,日期开始)
    {
        //
    }    @覆盖
    受保护的抽象无效onIncomingCallAnswered(上下文CTX,串号,日期开始)
    {
        //
    }    @覆盖
    受保护的抽象无效onIncomingCallEnded(上下文CTX,串号,开始日期,结束日期)
    {
        //
    }    @覆盖
    受保护的抽象无效onOutgoingCallStarted(上下文CTX,串号,日期开始)
    {
        //
    }    @覆盖
    受保护的抽象无效onOutgoingCallEnded(上下文CTX,串号,开始日期,结束日期)
    {
        //
    }    @覆盖
    受保护的抽象无效onMissedCall(上下文CTX,串号,日期开始)
    {
        //
    }}

此外,你可以看到一个书面记录我为什么在code是喜欢它是我的博客。吉斯特链接:<一个href=\"https://gist.github.com/ftvs/e61ccb039f511eb288ee\">https://gist.github.com/ftvs/e61ccb039f511eb288ee

编辑:更新后简单code,因为我已经修改了类为我所用。

I m new to Android Development. I'm trying to make an app like, when a call comes to the phone i want to detect the number,and i tried,and below is my code.But its not detecting incoming calls. I want to run my MainActivity in background. Please, help me. how to make it runs in background? i had given the permission in manifest file.

<uses-permission android:name="android.permission.READ_PHONE_STATE/>

Is there anything else should i provide in manifest? please help me out!

public class MainActivity extends Activity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.test_layout);
   }

   public class myPhoneStateChangeListener extends PhoneStateListener {
       @Override
       public void onCallStateChanged(int state, String incomingNumber) {
           super.onCallStateChanged(state, incomingNumber);
           if (state == TelephonyManager.CALL_STATE_RINGING) {
               String phoneNumber =   incomingNumber;
           }
       }
   }
}

解决方案

Here's what I use to do this:

Manifest:

<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 abstract void onIncomingCallReceived(Context ctx, String number, Date start)
    {
        //
    }

    @Override
    protected abstract void onIncomingCallAnswered(Context ctx, String number, Date start)
    {
        //
    }

    @Override
    protected abstract void onIncomingCallEnded(Context ctx, String number, Date start, Date end)
    {
        //
    }

    @Override
    protected abstract void onOutgoingCallStarted(Context ctx, String number, Date start)
    {
        //
    } 

    @Override 
    protected abstract void onOutgoingCallEnded(Context ctx, String number, Date start, Date end)
    {
        //
    }

    @Override
    protected abstract 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

这篇关于如何检测来电,在Android设备?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆