如何检测来电,在Android设备? [英] How to detect incoming calls, in an android device?
问题描述
我是新来的Android开发。我试图让一个应用程序一样,当有电话打进来,以我要检测的号码的电话,我试过了,下面是我的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屋!