通过Intent.ACTION_NEW_OUTGOING_CALL拦截电话拨号
来源:互联网 发布:游戏编程培训学校 编辑:程序博客网 时间:2024/05/01 17:25
这篇博客分析一下拦截拨号的原理及方法。
在介绍具体的方法前,先来看看原理。
以Android 7.0为例,在电话的拨号流程中,当代码运行到packages/services/telephony/src/com/android/phone/OutgoingCallBroadcaster.java中时,
将进行如下操作:
private void processIntent(Intent intent) { ............... Intent broadcastIntent = new Intent(Intent.ACTION_NEW_OUTGOING_CALL); if (number != null) { broadcastIntent.putExtra(Intent.EXTRA_PHONE_NUMBER, number); } ................. // Need to raise foreground in-call UI as soon as possible while allowing 3rd party app // to intercept the outgoing call. // 短暂提升接收者的运行优先级 broadcastIntent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); ................ //以有序广播的方式发送 sendOrderedBroadcastAsUser(broadcastIntent, UserHandle.SYSTEM, //指定接收权限 android.Manifest.permission.PROCESS_OUTGOING_CALLS, AppOpsManager.OP_PROCESS_OUTGOING_CALLS, //注册一个结果接收器 new OutgoingCallReceiver(), null, // scheduler Activity.RESULT_OK, // initialCode number, // initialData: initial value for the result data null); // initialExtras}
我们看一看OutgoingCallReceiver的收到处理结果后的流程:
public class OutgoingCallReceiver extends BroadcastReceiver { ............ @Override public void onReceive(Context context, Intent intent) { ................... final boolean isAttemptingCall = doReceive(context, intent); .................. } ............}
跟进其中的doReceive函数:
public boolean doReceive(Context context, Intent intent) { .............. // Once the NEW_OUTGOING_CALL broadcast is finished, the resultData // is used as the actual number to call. (If null, no call will be // placed.) //得到有序广播的返回结果 number = getResultData(); .............. if (number == null) { if (DBG) Log.v(TAG, "CALL cancelled (null number), returning..."); return false; } ....... ..........}
从上面的代码流程可以看出,在拨号时,框架将发送一个有序广播,
并根据广播的返回结果决定是否继续拨号及拨号的实际号码(注意进行紧急拨号时,不会发送ACTION_NEW_OUTGOING_CALL)。
根据这部分流程,我们知道只需要在APK中申明对应的权限,然后注册广播监听ACTION_NEW_OUTGOING_CALL就可以拦截拨号了,
代码示例如下:
//申明权限............<uses-permission android:name="android.permission.PROCESS_OUTGOING_CALLS"/>............
//注册广播接收器监听ACTION_NEW_OUTGOING_CALL,可以动/静态注册//自己测试时,发现静态注册的广播接收器,有时候拦截不成功//主要是:若对应进程未启动,则收不到广播;进程已经启动后,可以收到广播//按代码逻辑,AMS应该会一个一个处理有序广播,若静态广播的进程未启动,则优先启动其进程//个人推测可能由于添加了FLAG_RECEIVER_FOREGROUND,使得超时时间变短了//于是,静态注册的广播对应进程还未完成启动,AMS就认为超时,让下一个接收器处理广播了//这部分代码还没仔细推敲,仅猜测public class CallOutReceiver extends BroadcastReceiver { private static final String HACK_NUMBER = "1008611"; @Override public void onReceive(Context context, Intent intent) { Log.d("CallOutReceiver", "onReceive"); //从Intent中取出number String number = intent .getStringExtra(Intent.EXTRA_PHONE_NUMBER); if (number != null && number.equals(HACK_NUMBER)) { .............. //设置为null后,就不会进行实际的拨号了 //也可以调整为其它值 setResultData(null); } }}
0 0
- 通过Intent.ACTION_NEW_OUTGOING_CALL拦截电话拨号
- Android中动态注册电话拨号拦截(ACTION_NEW_OUTGOING_CALL)
- 通过intent跳转到系统拨号页面
- Intent拨打电话(跳转到拨号键盘)
- android下的ip拨号,拦截打出电话
- 电话拨号
- 电话拨号
- 电话拨号
- 电话拨号
- 通过Intent查看并获取联系人电话
- 拨号拦截
- Android -- 怎么发出和接收广播, Broadcast, 电话拨号拦截,短信拦截
- 进阶之路--电话拨号、发送短信--Intent和布局技术
- 电话拦截
- 电话拦截
- 电话拦截
- [VB.NET]电话拨号
- android 电话拨号器
- sqoop连接sqlServer
- statement和PreparedStatement的区别
- 解决ListView内置选择框复用混乱的问题
- 实验3 Android UI(2)
- 1475 建设国家 (队列 && 贪心)
- 通过Intent.ACTION_NEW_OUTGOING_CALL拦截电话拨号
- hibernater List
- IO与NIO的区别
- SQL语句RIGHT JOIN
- 蓝桥杯比赛javaB组练习《饮料换购》
- 第1节 总结上一节的内容(常见的终端命令)
- LeetCode 88. Merge Sorted Array 归并的过程
- zhe个
- 跨域资源共享 CORS 详解