android 获取手机号

原文出处 http://blog.csdn.net/r8hzgemq/article/details/7941274#comments

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

最近做一个项目,需要取用户手机号,用代码取获取移动神州行的,返回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卡也没有储存手机号)

[java]  view plain copy
  1. String telephoneNumber = (TelephonyManager)this.getSystemService(Context.TELEPHONY_SERVICE).getLine1Number();  
[html]  view plain copy
  1. <uses-permission android:name="android.permission.READ_PHONE_STATE" />  


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

[html]  view plain copy
  1. <receiver android:name=".broadcast.PhoneStatReceiver">  
  2.    <intent-filter>  
  3.     <action android:name="android.intent.action.PHONE_STATE" />  
  4.     <action android:name="android.intent.action.NEW_OUTGOING_CALL" />  
  5.    intent-filter>  
  6.   receiver>  


加几个权限

[html]  view plain copy
  1. <uses-permission android:name="android.permission.CALL_PHONE" />  
  2. <uses-permission android:name="android.permission.CALL_PRIVILEGED" />  
  3. <uses-permission android:name="android.permission.READ_PHONE_STATE" />  
  4. lt;uses-permission android:name="android.permission.PROCESS_OUTGOING_CALLS" />  


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

[java]  view plain copy
  1. @Override  
  2.  public void onReceive(Context context, Intent intent) {  
  3.   
  4. String out_phoneNum = intent.getStringExtra(Intent.EXTRA_PHONE_NUMBER);  
  5.   String in_phoneNum = intent.getExtras().getString("incoming_number");  
  6.   Logger.out(1"拨出去的号码-->" + out_phoneNum + "---来电号码-->" + in_phoneNum);  
  7.   
  8. }   


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

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

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

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


你可能感兴趣的:(android,android,获取手机号)