android - 如何使用 Oreo 及更高版本上的广播接收器检测 android 中的拨出呼叫状态?
问题描述
谁能提供我在 Android Oreo 及更高版本上检测拨出呼叫状态的示例代码?
我的代码在 android 6 上运行良好,但不适用于 Android 8.1 和 Android 9。几乎所有关于堆栈溢出的答案都包含不推荐使用的代码。
清单具有必要的权限,并且没有根据 Google 的指南注册任何接收者
广播接收器
public class CallReceiver extends BroadcastReceiver{
private static int lastState = TelephonyManager.CALL_STATE_IDLE;
private static Date callStartTime;
private static boolean isIncoming;
private static String savedNumber;
@Override
public void onReceive(Context context, Intent intent) {
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);
}
}
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;
Toast.makeText(context, "Incoming Call Ringing" , Toast.LENGTH_SHORT).show();
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();
Toast.makeText(context, "Outgoing Call Started" , Toast.LENGTH_SHORT).show();
}
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
Toast.makeText(context, "Ringing but no pickup" + savedNumber + " Call time " + callStartTime +" Date " + new Date() , Toast.LENGTH_SHORT).show();
}
else if(isIncoming){
Toast.makeText(context, "Incoming " + savedNumber + " Call time " + callStartTime , Toast.LENGTH_SHORT).show();
}
else{
Toast.makeText(context, "Outgoing "+ savedNumber + " Call time " + callStartTime +" Date " + new Date() , Toast.LENGTH_SHORT).show();
}
break;
}
lastState = state;
}
}
主要活动
public class MainActivity extends AppCompatActivity {
private CallReceiver callReceiver;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
callReceiver = new CallReceiver();
}
@Override
protected void onResume() {
super.onResume();
IntentFilter filter = new IntentFilter();
filter.addAction("android.intent.action.PHONE_STATE");
filter.addAction("android.intent.action.NEW_OUTGOING_CALL");
registerReceiver(callReceiver, filter);
}
@Override
protected void onPause() {
try {
unregisterReceiver(callReceiver);
} catch (Exception e) {
e.getMessage();
}
super.onPause();
}
@Override
protected void onDestroy() {
super.onDestroy();
}
}
解决方案
推荐阅读
- video-streaming - 尝试打开另一个应用程序或单击网站上的其他任何位置时,视频通话会中断
- vue.js - 尝试在 vue 中使用变量时未定义
- reactjs - TailwindCSS Building 不反映配置更改
- java - 为什么 PowerMockito.mockStatic 和 PowerMockito.when 即使用 @RunWith 和 @PrepareForTest 装饰类也不起作用
- python - 如何使用 Python 访问为 AWS lambda 函数启用 MFA 的 SharePoint excel 工作表
- html - CSS动画没有按我的意愿工作
- flutter - 带圆角的文本字段:错误文本行为
- mongoose - Mongoose: aggregate query to return an array of strings instead to array of objects
- multithreading - 并发编程练习
- laravel-5.7 - Laravel 重定向到同一服务器中的另一个应用程序