现在的位置: 首页 > 综合 > 正文

android取手机号的问题

2013年10月10日 ⁄ 综合 ⁄ 共 2275字 ⁄ 字号 评论关闭

以下结论,只是本人亲手测试的结果,可能并不全面:

最近做一个项目,需要取用户手机号,用代码取获取移动神州行的,返回null,但是取另外一个同事的联通WCDMA,可以获取到。很是纠结,想弄明白手机号码到底存放在什么地方,后来就去google了一下,很多热心网友都给出了一个相同的回答:能取到手机号的是因为运营商将手机号写入了SIM中,不能取到号码的是需要通过SIM卡的串号IMSI上行到运营商,然后通过映射表中查找对应的手机号。当时这么一听,觉得挺有道理,就信了。

后来和ios开发的同事聊起这事儿,他说iphone手机只要一插入卡,过几秒钟就能读出来手机号。亲自给我演示了一下,果然如此,原来iphone也是上行imsi到运营商,然后去拿到手机号的。

回到android这边,我想啊,android原本可以取到手机号的卡,如果不让android手机IMSI上行,不知道能不能取到手机号。如果能,说明手机号真的存在sim卡中,如果不能,说明即使能取到号码的sim卡,里面也并没有存储手机号,只是运营商能返回这个sim卡对应的手机号,而那些取不到手机号的sim卡,也将imsi上行给了运营商,而运营商不返回给终端手机号码。后来我就把手机调成飞行模式,再运行代码,果然不出所料,所有手机都取不到号码了。。看来SIM卡里并没有存放手机号,起码我上面测试过的2种卡没有存,其他的大家一起测测吧。

那新的疑问就出来了,我们打电话的时候,被叫是怎么知道主叫的手机号的呢。

其实是终端将自己的IMSI串号和被叫手机号一起上行到运营商,运营商通过主叫的IMSI查找到手机号,通过被叫到手机号查找到IMSI串号(找不到的话会提示主叫,拨打的是空号)。然后通过被叫到串号IMSI查找到对应的被叫手机,并将主叫的手机号下行给了被叫,这也就是为什么我们可以截取到来电号码原因了。

 

相关代码供参考

1获取手机号(不是每个SIM卡都可以获取到。再次更正很多网友的一个观点。其实手机号并没有存储在SIM中,即使能拿到手机号的SIM卡也没有储存手机号)

String telephoneNumber = (TelephonyManager)this.getSystemService(Context.TELEPHONY_SERVICE).getLine1Number();
<uses-permission android:name="android.permission.READ_PHONE_STATE" />

2获取来电号码(每个SIM都可以,因为运营商将主叫的IMSI查找到对应手机号码后,一起下行给了被叫。否则我们就不知道是谁的来电了)
在配置文件中注册广播

<receiver android:name=".broadcast.PhoneStatReceiver">
   <intent-filter>
    <action android:name="android.intent.action.PHONE_STATE" />
    <action android:name="android.intent.action.NEW_OUTGOING_CALL" />
   </intent-filter>
  </receiver>

加几个权限

 <uses-permission android:name="android.permission.CALL_PHONE" />
 <uses-permission android:name="android.permission.CALL_PRIVILEGED" />
 <uses-permission android:name="android.permission.READ_PHONE_STATE" />
<uses-permission android:name="android.permission.PROCESS_OUTGOING_CALLS" />

然后在java代码广播类中的onReceive()方法中如下:

@Override
 public void onReceive(Context context, Intent intent) {

String out_phoneNum = intent.getStringExtra(Intent.EXTRA_PHONE_NUMBER);
  String in_phoneNum = intent.getExtras().getString("incoming_number");
  Logger.out(1, "拨出去的号码-->" + out_phoneNum + "---来电号码-->" + in_phoneNum);

} 

 如果项目中非要用到用户的真实手机号,有一个很麻烦的办法可以做到:

首先尝试着取client手机号,取不到时由client后台将当前系统时间发一条短信到“phoneService”,同时由http或者udp发送到“pcService”,"phoneService"提取出短信的发件人手机号和短信内容(System.currentTimeMillis())后发送给pcService,pcService将2个渠道的内容比较,相同时,把对应手机号码返回给clients。

(这个流程中,很多不靠谱的情况大家可想而知了,不止是客户端,服务器也要做短信超时和请求超时判断,还有要用个专门的手机一直运行着)

我观察了很多类似软件,都是先尝试去获取手机号,取不到就提示用户手动输入,或者提示用户发短信一键注册。。没有非得一次性成功的。。再说了,偷偷发短信很多电子市场是会扫源代码的,这样的话软件就没法上线了

抱歉!评论已关闭.