这是一篇关于phone的杂文,主要涉及了和phone相关的一些周边功能,内容比较琐碎,所以也就不像之前文章有明确的主线(比如前
面关于phone的来电,去电流程)可依循,估计看起来会比较凌乱,请见谅,我会尽量区分不同的小节内容。
1. 关于来电防火墙或黑名单
这个功能好像需求还挺大的,至于实现原理无非是根据号码在数据库中查找有无匹配的号码,如果是黑名单中的号码,则挂断该号码的来电或删除该号码的当前消息。我们要做的就是获取号码、查找和后续处理(比如挂断电话),能否获取号码是拦截的关键,如果你是做整机系统的,有相应的工程源码,那么拿到号码是一件很简单的事情,直接修改phone或mms源码的处理逻辑,不管是在RIL,Framework,packages哪一层处理都可以实现,根据实现需要处理即可。如果是第三方应用apk,想用上面的方法就不行了,这时就要借助phone开放的接口来监听phone的状态和获取来电号码,phone对外部应用开放的状态只有三种IDLE、OFFHOOK和 RINGING,phone内部使用的9个状态外面是看不到的,也就是说只有当电话状态变化的,第三方的apk才可能知道是否有电话来了,这样就可以解释为什么类似360来电拒接功能要先响铃一声然后再挂断,它没法提前拿到号码才是根本原因。关于短信的拦截主要是接收相应的广播消息,之后是删除原系统消息还是保留,就要看应用怎么做了。
电话状态监听方法核心代码如下,
来电话能看到电话是哪里打来的,具体到省市。现在大部分手机尤其是智能机都有这个功能,实现起来也不复杂。通常的做法弄个号码归属地的数据库在手机上,来电的时候根据号码去数据库查询一下就OK了,至于查询是通过provider还是利用JNI就看个人的实现方式了。这里面的问题是你的数据库可能不是最新,当然也是没法实时更新的,所以有些号码可能查不到,最近联通准备为Iphone开放185号段,这个我相信现在大多数手机是查不到归属地的,不过如果运营商告诉你来电归属地,事情就简单多了,运营商总是知道电话是从哪来的,但是通常运营商是不会告诉你的归属地,出于安全隐私和利益的考虑。
3.PIN,PUK,PIN2,PUK2
PIN码-Personal Identification Number,SIM卡的个人识别密码,也就是通常所指的PIN1,android手机开启PIN码在设置 -->位置与安全-->SIM卡锁定, 那个屏幕锁定里的PIN码锁定和 sim卡PIN码一点关系没有,不知道为什么弄个同样的名字混淆视听。设置PIN后,开机时要输入正确PIN(4- 8位数字,通常是4位)才可以使用,3次机会,输错就要用PUK码解锁,PUK有10次机会,puk再输错SIM卡就被锁定了,那只能去营业厅补卡了。PIN2码是开启某项功能时比如计费和固定拨号,和PIN码一样,PIN2也是3次机会,PUK2是对应解锁PIN2的,如果PUK2锁了,只是和PIN2 PUK2相关的功能不能使用了,其它的功能还是可以用的,后果没有PIN那么严重。最后提下PUK是买卡的时候在卡片上就会有写,而PUK2一般是要在移动网站上查询才能得到,不过还不是每个卡都能查到。
4.本机号码
android里获取本机号码的代码是这样的
1. 关于来电防火墙或黑名单
这个功能好像需求还挺大的,至于实现原理无非是根据号码在数据库中查找有无匹配的号码,如果是黑名单中的号码,则挂断该号码的来电或删除该号码的当前消息。我们要做的就是获取号码、查找和后续处理(比如挂断电话),能否获取号码是拦截的关键,如果你是做整机系统的,有相应的工程源码,那么拿到号码是一件很简单的事情,直接修改phone或mms源码的处理逻辑,不管是在RIL,Framework,packages哪一层处理都可以实现,根据实现需要处理即可。如果是第三方应用apk,想用上面的方法就不行了,这时就要借助phone开放的接口来监听phone的状态和获取来电号码,phone对外部应用开放的状态只有三种IDLE、OFFHOOK和 RINGING,phone内部使用的9个状态外面是看不到的,也就是说只有当电话状态变化的,第三方的apk才可能知道是否有电话来了,这样就可以解释为什么类似360来电拒接功能要先响铃一声然后再挂断,它没法提前拿到号码才是根本原因。关于短信的拦截主要是接收相应的广播消息,之后是删除原系统消息还是保留,就要看应用怎么做了。
电话状态监听方法核心代码如下,
TelephonyManager tm = ( TelephonyManager )this.getSystemService(this.TELEPHONY_SERVICE);
listener = new MyPhoneSateListener(PhoneStateActivity.this);
tm.listen(listener, PhoneStateListener.LISTEN_CALL_STATE);
class MyPhoneSateListener extends PhoneStateListener{
public void onCallStateChanged(int state, String incomingNumber) {
super.onCallStateChanged(state, incomingNumber);
switch(state){
case TelephonyManager.CALL_STATE_IDLE:
break;
case TelephonyManager.CALL_STATE_OFFHOOK:
break;
case TelephonyManager.CALL_STATE_RINGING:
break;
}
}
}
2. 来电归属地来电话能看到电话是哪里打来的,具体到省市。现在大部分手机尤其是智能机都有这个功能,实现起来也不复杂。通常的做法弄个号码归属地的数据库在手机上,来电的时候根据号码去数据库查询一下就OK了,至于查询是通过provider还是利用JNI就看个人的实现方式了。这里面的问题是你的数据库可能不是最新,当然也是没法实时更新的,所以有些号码可能查不到,最近联通准备为Iphone开放185号段,这个我相信现在大多数手机是查不到归属地的,不过如果运营商告诉你来电归属地,事情就简单多了,运营商总是知道电话是从哪来的,但是通常运营商是不会告诉你的归属地,出于安全隐私和利益的考虑。
3.PIN,PUK,PIN2,PUK2
PIN码-Personal Identification Number,SIM卡的个人识别密码,也就是通常所指的PIN1,android手机开启PIN码在设置 -->位置与安全-->SIM卡锁定, 那个屏幕锁定里的PIN码锁定和 sim卡PIN码一点关系没有,不知道为什么弄个同样的名字混淆视听。设置PIN后,开机时要输入正确PIN(4- 8位数字,通常是4位)才可以使用,3次机会,输错就要用PUK码解锁,PUK有10次机会,puk再输错SIM卡就被锁定了,那只能去营业厅补卡了。PIN2码是开启某项功能时比如计费和固定拨号,和PIN码一样,PIN2也是3次机会,PUK2是对应解锁PIN2的,如果PUK2锁了,只是和PIN2 PUK2相关的功能不能使用了,其它的功能还是可以用的,后果没有PIN那么严重。最后提下PUK是买卡的时候在卡片上就会有写,而PUK2一般是要在移动网站上查询才能得到,不过还不是每个卡都能查到。
4.本机号码
android里获取本机号码的代码是这样的
TelephonyManager tm = (TelephonyManager) this.getSystemService(Context.TELEPHONY_SERVICE);
String tel = tm.getLine1Number();
不保证你每次都能拿到,这个本机号码是要先写在sim卡上才可能拿到,如果事先没有写是取不到,运营商可以写,做手机系统的也可用指定的命令写进去,这就是说如果我写一个错误的号码,那么后面你拿到本机号码就是错误的,并非你真正的号码,如果用错误的号码去匹配联系人,一些略显诡异的事情就发生了。
5.号码匹配
通常情况我们怎么判断两个号码是否相同呢,很简单是吧,一个个字符比较下就行,可是在android源码里从后向前比较只比较了后7位,老外认为用后7位就可能区别出来了,我们手机号码多少位呢 11位,这种判断方法有问题了,类似这样的13011111111,13511111111的号码源码是有可能识别不出来是到底是哪个,虽然后续android的代码加了判断是否要完全匹配的,不过默认的号码匹配规则仍然是后7位,现实中后7位号码相同的情况其实也是比较少见的,当初google的短信门bug不知道是不是这个原因,猜测而已。暂时就写到这里吧,还有一些琐碎的功能就不写了。