我正在android中构建一个应用程序,当我的手机中有任何电话时,它将执行一个动作。我用广播接收器和电话状态监听器试过这个。但它没有用。如果我使用活动,那么手机状态监听器工作得很好,但它不适用于广播接收器。我做错了什么?请任何身体帮助......
谢谢&问候
答案 0 :(得分:3)
<receiver android:name="ClassName">
<intent-filter>
<action android:name="android.intent.action.PHONE_STATE">/action>
</intent-filter>
</receiver>
它的工作!!
答案 1 :(得分:3)
以下是a Chinese BBS的示例。
public class PhoneStatReceiver extends BroadcastReceiver{
private static final String TAG = "PhoneStatReceiver";
private static boolean incomingFlag = false;
private static String incoming_number = null;
@Override
public void onReceive(Context context, Intent intent) {
//如果是拨打电话
if(intent.getAction().equals(Intent.ACTION_NEW_OUTGOING_CALL)){
incomingFlag = false;
String phoneNumber = intent.getStringExtra(Intent.EXTRA_PHONE_NUMBER);
Log.i(TAG, "call OUT:"+phoneNumber);
}else{
//如果是来电
TelephonyManager tm =
(TelephonyManager)context.getSystemService(Service.TELEPHONY_SERVICE);
switch (tm.getCallState()) {
case TelephonyManager.CALL_STATE_RINGING:
incomingFlag = true;//标识当前是来电
incoming_number = intent.getStringExtra("incoming_number");
Log.i(TAG, "RINGING :"+ incoming_number);
break;
case TelephonyManager.CALL_STATE_OFFHOOK:
if(incomingFlag){
Log.i(TAG, "incoming ACCEPT :"+ incoming_number);
}
break;
case TelephonyManager.CALL_STATE_IDLE:
if(incomingFlag){
Log.i(TAG, "incoming IDLE");
}
break;
}
}
}
}
在AndroidManifest.xml
。
<receiver android:name=".filter.PhoneStatReceiver">
<intent-filter>
<action android:name="android.intent.action.PHONE_STATE"/>
<action android:name="android.intent.action.NEW_OUTGOING_CALL" />
</intent-filter>
</receiver>
<uses-permission android:name="android.permission.READ_PHONE_STATE"></uses-permission>
<uses-permission android:name="android.permission.PROCESS_OUTGOING_CALLS"></uses-permission>
答案 2 :(得分:2)
您可以在这篇文章中找到一些基本代码:
答案 3 :(得分:1)
我在这里读过 https://gist.github.com/ftvs/e61ccb039f511eb288ee
对我来说很好。 Android版本5.0。
接下来是我的任务。
我的应用程序必须观察所有调用事件。并区分呼入,呼出电话。来电完成后,必须随时创建新的来电。设置号码中指定的电话号码。此电话号码是门禁控制器的号码。 (https://www.pal-es.com/3g-eng) 它为为用户打开自动门而不是在白名单中作弊。此应用程序可在独立的智能手机中使用,仅用于完成此任务。
一些功能也可以在这里找到。
例如:
MainActivity.java
package com.example.root.test02;
import android.content.Intent;
import android.net.Uri;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.widget.TextView;
import java.text.SimpleDateFormat;
import java.util.Date;
/*
https://androidexample.com/Introduction_To_Broadcast_Receiver_Basics/index.php?view=article_discription&aid=60&aaid=85
https://androidexample.com/Incomming_Phone_Call_Broadcast_Receiver__-_Android_Example/index.php?view=article_discription&aid=61
https://stackoverflow.com/questions/5990590/how-to-detect-phone-call-broadcast-receiver-in-android
https://stackoverflow.com/questions/1083527/how-to-block-calls-in-android
https://stackoverflow.com/questions/5571249/how-do-i-retrieve-the-incoming-phone-calls-number-while-ringing-and-store-it-in
https://gist.github.com/ftvs/e61ccb039f511eb288ee
*/
public class MainActivity extends AppCompatActivity {
public TextView textView;
public String MetallurgTelNumber = "+79091112233"; // need redirect calls to this phone number
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
PhonecallReceiver rv = new PhonecallReceiver();
Thread myThread = new Thread(myRunnable);
myThread.start();
textView = (TextView) findViewById(R.id.incoming_calls_log);
textView.setText("Журнал входящих звонков:");
TextView version = (TextView) findViewById(R.id.tvVersion);
version.setText("v3.0");
}
public void CallToMetallurgGates()
{
Intent callIntent = new Intent(Intent.ACTION_CALL);
callIntent.setData(Uri.parse("tel:" + MetallurgTelNumber));
startActivity(callIntent);
}
Runnable myRunnable = new Runnable() {
@Override
public void run()
{
while (true)
{
try
{
Thread.sleep(50); // Waits for 1 second (1000 milliseconds)
if (MyProperties.getInstance().NewIncomingCall)
{
CallToMetallurgGates();
MyProperties.getInstance().NewIncomingCall = false;
MyProperties.getInstance().CallId++;
String dbg_str = Integer.toString(MyProperties.getInstance().CallId) + " " + MyProperties.getInstance().PhoneNumber;
textView.post(new Runnable() {
public void run() {
SimpleDateFormat sdf = new SimpleDateFormat("dd.MM.yyyy HH:mm:ss");
String currentDateandTime = sdf.format(new Date());
textView.append("\n" + currentDateandTime);
textView.append("\n(" + Integer.toString(MyProperties.getInstance().CallId) + "): " + MyProperties.getInstance().PhoneNumber);
textView.append("\nЗвоню на ворота: " + MetallurgTelNumber);
}
});
Thread.sleep(5000); // Waits for 1 second (1000 milliseconds)
}
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
};
}
PhonecallReceiver.java
package com.example.root.test02;
import java.util.Date;
import android.app.Application;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.net.Uri;
import android.telephony.PhoneStateListener;
import android.telephony.TelephonyManager;
import android.util.Log;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import java.util.Date;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.telephony.TelephonyManager;
import com.example.root.test02.MainActivity;
public class PhonecallReceiver extends BroadcastReceiver {
// как только происходит входящий звонок
protected void onIncomingCallStarted(Context ctx, String number, Date start) {
Log.d("onIncomingCallStarted",number);
}
// как только снимается (hook off) трубка и делается исходящий
protected void onOutgoingCallStarted(Context ctx, String number, Date start) {
Log.d("onOutgoingCallStarted",number);
}
// когда нажимается кнопка Завершить на входящем звонке
protected void onIncomingCallEnded(Context ctx, String number, Date start, Date end) {
Log.d("onIncomingCallEnded",number);
MyProperties.getInstance().NewIncomingCall = true;
MyProperties.getInstance().PhoneNumber = number + " завершенный";
}
// когда нажимается кнопка Завершить на исходящем звонке
protected void onOutgoingCallEnded(Context ctx, String number, Date start, Date end) {
Log.d("onOutgoingCallEnded",number);
}
// когда не сняли трубку при входящем звонке (пропуск звонка)
protected void onMissedCall(Context ctx, String number, Date start) {
MyProperties.getInstance().NewIncomingCall = true;
MyProperties.getInstance().PhoneNumber = number + " пропущенный";
}
//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;
onIncomingCallStarted(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);
}
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;
}
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
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);
}
}
}
AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.root.test02">
**<uses-permission android:name="android.permission.READ_PHONE_STATE" />
<uses-permission android:name="android.permission.PROCESS_OUTGOING_CALLS"/>
<uses-permission android:name="android.permission.CALL_PHONE" />**
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/Theme.AppCompat.Light">
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
**<receiver android:name="com.example.root.test02.PhonecallReceiver">
<intent-filter>
<action android:name="android.intent.action.PHONE_STATE" />
</intent-filter>
</receiver>**
</application>
</manifest>
MyProperties.java
package com.example.root.test02;
public class MyProperties {
private static MyProperties mInstance= null;
public boolean NewIncomingCall = false;
public int CallId = 0;
public String PhoneNumber = "";
protected MyProperties(){}
public static synchronized MyProperties getInstance() {
if(null == mInstance){
mInstance = new MyProperties();
}
return mInstance;
}
}
答案 4 :(得分:0)
希望这符合您的目的,
请检查一下。
<receiver android:name="ClassName">
<intent-filter>
<action android:name="android.intent.action.ANSWER">/action>
</intent-filter>
</receiver>
答案 5 :(得分:0)
我最初经历了同样的事情但后来我将以下权限添加到我的清单。
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
当然,在我的代码中,当我接到电话时,我正在显示一个祝酒词。
因此,您可能需要添加与您的要求相对应的其他权限。