【发布时间】:2019-04-22 11:55:25
【问题描述】:
我正在尝试让应用程序监听呼叫(传入和传出),我现在所做的只是在清单中注册接收器,这在 9.0 以下的 Android 中完美运行。 但是,当我在 Android oreo 上测试该应用程序时出现了问题,我知道某些广播已被禁用。 我尝试制作一个前台服务来注册接收器并收听此广播,但它再次适用于 oreo 以下版本。
我不知道还能做什么,我必须让它工作,我不在乎它是否会以一种不优雅的方式,我不发布这个应用程序我只需要它供私人使用。
总结:即使应用当前未激活,我也需要在 Android pie 中收听电话
清单
<receiver android:name=".MyReceiver">
<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>
我的接收者
public class MyReceiver extends BroadcastReceiver {
private static Date callStartTime;
private static boolean isIncoming;
private static int lastState;
private static String savedNumber;
private static String savedOutgoingNumber;
private TelephonyManager tm;
@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);
}
}
'
问题是它甚至没有在 android oreo 上被调用 编辑:我让它在 android oreo 上工作,但它在 android pie 中有问题
另一个编辑:
@Override
public void onCreate() {
super.onCreate();
createNotificationChannel();
IntentFilter filter = new IntentFilter();
filter.addAction("android.intent.action.PHONE_STATE");
filter.addAction("android.intent.action.NEW_OUTGOING_CALL");
BroadcastReceiver receiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
CallListenerService.this.onReceive(intent);
}
};
registerReceiver(receiver, filter);
}
public void onReceive(Intent i){
if (i.getAction().equals("android.intent.action.NEW_OUTGOING_CALL")) {
savedNumber = i.getExtras().getString("android.intent.extra.PHONE_NUMBER");
}
else{
String stateStr = i.getExtras().getString(TelephonyManager.EXTRA_STATE);
String number = i.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(this, state, number);
}
}
其余的没关系,它只是在通话结束时启动一个活动来测试它是否工作
我添加了一个注册接收者的fourground服务,这适用于android oreo,但在android pie上仍然存在问题。
编辑:解决方案是混合一堆答案,直到它适用于每台设备。 我这样写了声明清单:
<receiver
android:name=".MyReceiver"
android:enabled="true">
<intent-filter android:priority="1000">
<action android:name="android.intent.action.PHONE_STATE" />
</intent-filter>
<intent-filter android:priority="1000">
<action android:name="android.intent.action.NEW_OUTGOING_CALL"
/>
</intent-filter>
</receiver>
真的不知道那是不是它做了什么。 此外,我使用的是普通广播接收器而不是服务,我也不知道发生了什么,但突然它在某些设备上工作了。
现在到了最后,我发现我可以通过阅读通话记录来获取电话号码,所以我所做的就是添加这段代码:
protected void onMissedCall(final Context ctx, String number, Date start) {
if (PreferenceManager.getDefaultSharedPreferences(ctx).getBoolean("missed_calls", false)) {
if (number == null) {
new Handler().postDelayed(new Runnable() {
@Override
public void run() {
final String phoneNumber = getLastCallNumber(ctx);
if (phoneNumber != null) {
Intent intent = new Intent(ctx, Dialog.class);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
intent.putExtra("number", phoneNumber);
intent.putExtra("missed_call", true);
ctx.startActivity(intent);
} else {
Toast.makeText(ctx, "cannot get phone number", Toast.LENGTH_SHORT).show();
}
}
}, 2000);
} else {
Intent intent = new Intent(ctx, Dialog.class);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
intent.putExtra("number", number);
intent.putExtra("missed_call", true);
ctx.startActivity(intent);
}
}
}
private String getLastCallNumber(Context context) {
Uri contacts = CallLog.Calls.CONTENT_URI;
if (ActivityCompat.checkSelfPermission(context, android.Manifest.permission.READ_CALL_LOG) != PackageManager.PERMISSION_GRANTED) {
Toast.makeText(context, "Permission denied can not get phone number", Toast.LENGTH_SHORT).show();
}
Cursor managedCursor = context.getContentResolver().query(
contacts, null, null, null, null);
int number = managedCursor.getColumnIndex( CallLog.Calls.NUMBER );
String phoneNumber = null;
if( managedCursor.moveToLast() == true ) {
phoneNumber = managedCursor.getString( number );
}
managedCursor.close();
return phoneNumber;
}
我添加了 if 行,它检查数字是否为空,如果是,它启动一个处理程序以运行 2 秒后,当处理程序启动时,我从调用日志中读取最后一个数字。 2 秒的延迟是为了让号码进入通话记录,如果您尝试立即读取它,它不起作用。
【问题讨论】:
-
请发布您的代码尝试,否则有人会标记为“太板问题”。
-
我会发布我的尝试,但是它在 android oero 中不起作用,所以它并不重要
-
不计其数,其他人只有看到长相才能提供帮助!这个社区也没有按照某人的意愿工作。错误代码示例是这里的主要人员。从别人的错误中学习。
-
我会发布,我再次告诉你广播接收器在 android oreo 上不起作用,所以我要求解决它。几分钟后我会回家并发布代码
-
@erantsalach 尝试注册动态接收器,而不是在清单文件中进行静态注册,即在运行时在 java 文件中注册此接收器。