您的位置:首页 > 大数据 > 人工智能

AlDl跨进程服务之电话拦截

2016-09-18 23:31 405 查看
出于系统安全的考虑,Android系统中的进程之间是不允许共享内存的,进而难以进行不同进程之间的数据通信。谷歌为了其他应用程序也可以访问本应用程序提供的除,Android使用了一种接口定义语言IDL来公开服务的接口,使Service能过跟其他三大组件(Activity,BroadcastReceiver,ContentProvider)一样,能过实现跨进程访问。而这种可以跨进程访问的服务被称为AIDL(Android Interface Definition Language)服务。

以下例子为利用AIDI服务进行来电监听并将其来电拦截

在main目录中,创建一个aidl的目录文件,并创建AIDL文件(需要创建对应的包,这里引用第三方的.aidl文件。如需文件,请点击连接 链接:http://pan.baidu.com/s/1nuYXZy5 密码:o2wn



将写好的ITelephony.aidl以及NeighboringCellInfo.aidl手动编译一下(系统不会自动将编译)



相关权限设置

<!--允许应用监听程序,控制,取消呼出电话选项-->
<uses-permission android:name="android.permission.PROCESS_OUTGOING_CALLS" />
<!--读取状态权限-->
<uses-permission android:name="android.permission.READ_PHONE_STATE" />


4.具体实现代码以及相关注释

public class MainActivity extends AppCompatActivity {

//声明变量
//获取收取手机电话管理
TelephonyManager manager;
//状态监听
PhoneStateListener listener;

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//初始化数据
manager = (TelephonyManager) getSystemService(TELEPHONY_SERVICE);
listener = new PhoneStateListener() {
@Override
public void onCallStateChanged(int state, String incomingNumber) {
super.onCallStateChanged(state, incomingNumber);

switch (state) {
//空闲状态
case TelephonyManager.CALL_STATE_IDLE: {
Log.d("msg", "onCallStateChanged:空闲状态 ");
}
break;
//占线状态
case TelephonyManager.CALL_STATE_OFFHOOK: {
Log.d("msg", "onCallStateChanged: 占线状态");
}
break;
//响铃状态
case TelephonyManager.CALL_STATE_RINGING: {
Log.d("msg", "onCallStateChanged: 响铃状态");
//当电话响起时,拦截并挂断
catComeCall();
}
break;
}
}
};
//设置监听
manager.listen(listener,PhoneStateListener.LISTEN_CALL_STATE);

}
//Activity摧毁时取消监听
protected void onDestroy() {
// TODO Auto-generated method stub
super.onDestroy();
manager.listen(listener, PhoneStateListener.LISTEN_NONE);
}
//电话拦截方法,跟两个aidl文件匹配
protected void catComeCall() {
// 拦截来电
try {
Method method=Class.forName("android.os.ServiceManager")
.getMethod("getService", String.class);
//获取远程TELEPHONY_SERVICE的IBinder对象的代理
IBinder iBinder=(IBinder) method.invoke(null,new Object[]{TELEPHONY_SERVICE});
//将IBinder对象的代理转换为ITelephony对象
ITelephony telephony=ITelephony.Stub.asInterface(iBinder);
//挂断电话
telephony.endCall();
Log.i("msg", "catComeCall: 已经挂断电话");

} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}

}


温馨提示

1.由于在Android studio环境中,当进行模拟来电时,AS容易跟模拟器断开,即使使用dos命令(其他文章有介绍具体方法)也容易断开,导致不容易看到log,所以最好用真机调试;当然,Eclipse环境可以直接使用模拟来电。

2.建议使用sdk自带模拟器来实验,因为其他模拟器大多不提供这个服务,或者需要收费。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息