最近做一个项目 需要获取到手机的相关信息
【点击下载 科学上网软件(能上youtube、facebook,享受google服务)】
一个朋友的看法:
从技术层面而言,手机的SIM卡上并不会存储手机号码信息,只会存储IMSI(International Mobile Subscriber Identification Number)。手机号码(MSISDN)都是登记在HLR(Home Location Register)中的,在HLR中会把IMSI和MSISDN关联在一起。
中国移动的SIM卡里只有IMSI号码而没有存储手机号码,在中国移动的HLR中会有一张映射表,专门用于把用户手机SIM卡的IMSI号映射成为用户的手机号码,这就是移动丢卡不丢号的业务也就是缘于此,也是一卡多号的原理。而电信CDMA(原来联通CDMA)的机卡合一的手机卡里会同时存在IMSI和手机号码。
•客户端获取:在客户端对移动用户而言只能够获取诸如IMSI、IMEI号等,并不能直接获得手机号。而对电信CDMA机卡合一用户可以获取手机号码。
•服务器端获取:在早期的移动白名单中是能够获得明文的手机号的,最近移动策略变了,手机号变成了天书般的唯一串号。因此目前从服务器端直接获取手机号也不行了。
目前能够想到的能够相对可靠地自动获取用户手机号的方法只有通过短信方式。
•通过短信方式:让用户上行一条短信,通过短信网关获取用户手机号,从而将用户id与手机号绑定
另一个朋友的看法:
android 获取手机号码的方法 这里就不说了,太简单了。
手机号码不是所有的都能获取。只是有一部分可以拿到。这个是由于移动运营商没有把手机号码的数据写入到sim卡中.SIM卡只有唯一的编号,供网络与设备识别那就是IMSI号码,手机的信号也可以说是通过这个号码在网络中传递的,并不是手机号码。试想,你的SIM丢失后,补办一张新的会换号码吗?是不会的.就是因为在你的手机号码对应的IMSI号 在移动运营商中被修改成新SIM卡的IMSI号码。
那么手机号为什么有的就能显示呢?
这个就像是一个变量,当移动运营商为它赋值了,它自然就会有值。不赋值自然为空。
对于移动的用户,手机号码(MDN)保存在运营商的服务器中,而不是保存在SIM卡里。SIM卡只保留了IMSI和一些验证信息。手机每次入网注册的时候,都会以短信的形式将IMSI及验证信息上传到运营商的服务器,服务器在完成注册动作之后,会以短信的形式将注册的结果下发到手机里。下发的内容会因条件不同而不同。
如果服务器在下发的短信中,不包含手机的号码,手机是无法取得电话号码。如果短信中包含了号码,手机才会将其缓存,以备他用.此外,对于其他运行商的SIM卡或者UIM卡,MDN有可能保存在UIM卡中。100%能够取得本机号码不太可能。
移动神州行,联通的卡是可以取到的.动感地带的取不到.别的卡还没有试过.
能够读取SIM卡号的话应该有前提.那就是SIM卡已经写入了本机号码,不然是无法读取的
Android开发平台中,可通过TelephonyManager 获取本机号码。
TelephonyManager phoneMgr=(TelephonyManager)this.getSystemService(Context.TELEPHONY_SERVICE);
txtPhoneNumber.setText(phoneMgr.getLine1Number()); //txtPhoneNumber是一个EditText 用于显示手机号
注:
根据Android的安全机制,在使用TelephonyManager时,必须在AndroidManifest.xml中添加<uses-permission android:name="READ_PHONE_STATE" /> 否则无法获得系统的许可。
手机型号 Build.MODEL
String |
MODEL |
The end-user-visible name for the end product. |
sdk版本 Build.VERSION.SDK
String |
SDK |
This constant is deprecated. Use SDK_INT to easily get this as an integer. |
及frimware版本号(系统版本号) Build.VERSION.RELEASE
String |
RELEASE |
The user-visible version string. |
private void loadPhoneStatus(){ TelephonyManager phoneMgr=(TelephonyManager)this.getSystemService(Context.TELEPHONY_SERVICE); txtPhoneModel.setText(Build.MODEL); //手机型号 txtPhoneNumber.setText(phoneMgr.getLine1Number());//本机电话号码 txtSdkVersion.setText(Build.VERSION.SDK);//SDK版本号 txtOsVersion.setText(Build.VERSION.RELEASE);//Firmware/OS 版本号}
事实上,Build能向我们提供包括 硬件厂商,硬件编号,序列号等很多信息 调用方法也都同上,很简单。
String |
BOARD |
The name of the underlying board, like "goldfish". |
|
String |
BOOTLOADER |
The system bootloader version number. |
|
String |
BRAND |
The brand (e.g., carrier) the software is customized for, if any. |
|
String |
CPU_ABI |
The name of the instruction set (CPU type + ABI convention) of native code. |
|
String |
CPU_ABI2 |
The name of the second instruction set (CPU type + ABI convention) of native code. |
|
String |
DEVICE |
The name of the industrial design. |
|
String |
DISPLAY |
A build ID string meant for displaying to the user |
|
String |
FINGERPRINT |
A string that uniquely identifies this build. |
|
String |
HARDWARE |
The name of the hardware (from the kernel command line or /proc). |
|
String |
HOST |
||
String |
ID |
Either a changelist number, or a label like "M4-rc20". |
|
String |
MANUFACTURER |
The manufacturer of the product/hardware. |
|
String |
MODEL |
The end-user-visible name for the end product. |
|
String |
PRODUCT |
The name of the overall product. |
|
String |
RADIO |
The radio firmware version number. |
|
String |
SERIAL |
A hardware serial number, if available. |
|
String |
TAGS |
Comma-separated tags describing the build, like "unsigned,debug". |
|
long |
TIME |
||
String |
TYPE |
The type of build, like "user" or "eng". |
|
String |
UNKNOWN |
Value used for when a build property is unknown. |
|
String |
USER |
=================================================
首先我们来明确几个概念:
SIM卡存储的数据可分为四类:
第一类是固定存放的数据。这类数据在移动电话机被出售之前由SIM卡中心写入,包括国际移动用户识别号(IMSI)、鉴权密钥(KI)、鉴权和加密算法等等。
第二类是暂时存放的有关网络的数据。如位置区域识别码(LAI)、移动用户暂时识别码(TMSI)、禁止接入的公共电话网代码等。
第三类是相关的业务代码,如个人识别码(PIN)、解锁码(PUK)、计费费率等。
第四类是电话号码簿,是手机用户随时输入的电话号码。用户全部资料几乎都存储在SIM卡内,因此SIM卡又称为用户资料识别卡。
IMSI是一个唯一的数字, 标识了GSM和UMTS 网络里的唯一一个用户. 它存储 在手机的SIM卡里,它会通过手机发送到网络上. IMSI 与 SIM唯一对应
IMEI也是一串唯一的数字, 标识了 GSM 和 UMTS网络里的唯一一个手机.它通常被打印在手机里电池下面的那一面,拨 *#06# 也能看到它. IMEI 与 设备唯一对应.
1。IMEI不存在于SIM卡中,它是手机本身的串号。
2。通常我们所说的手机号也不存在于SIM卡中,虽然SIM卡中有一个专门存储SIM卡本身号码的地方,但是此号码是通过手工设定的,而且是可以更改的。 SIM卡的识别通常使用IMSI号,这个对于SIM卡是唯一的。
3。使用SimGetRecordInfo之类的函数获得SIM卡的IMSI号码能否成功依赖于设备制造商是否实现了此函数,据我所知在DOPOD的机器上是可以获得,但是在联想的机器上却不行,其他机器没有。
4。获得IMEI以及IMSI可以通过RIL或者TAPI中的LINE操作的函数获得。
下面给出获取手机本机号码的代码:
TelephonyManager tm = (TelephonyManager) this.getSystemService(Context.TELEPHONY_SERVICE);
String deviceid = tm.getDeviceId();
String tel = tm.getLine1Number();
String imei = tm.getSimSerialNumber();
String imsi = tm.getSubscriberId();
添加权限:
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
注意,手机号码不是所有的都能获取。只是有一部分可以拿到。这个是由于移动运营商没有把手机号码的数据写入到sim卡中。这个就像是一个变量,当移动运营商为它赋值了,它自然就会有值。不赋值自然为空。这就是为什么很多人得不到本机号码的原因。
这里才是我写的,上面都是开发过程中,转自别的朋友们的有用的资料,在此谢过。这个是我们的测试结果,不同手机,不同卡会得到不同的结果,下面的测试数据也不是绝对的。
运营商 卡类型 结果
中国移动 动感地带:3.0 获取不到
中国移动 神州行卡 可以获取
中国移动 全球通 可以获取
中国电信 全球漫游天翼国际卡 获取不到
中国联通 世界风 64K OTA 获取不到
中国联通 沃 128K USIM 可以获取
代码:
TelephonyManager tm = (TelephonyManager)
this
.getSystemService(TELEPHONY_SERVICE);
/*
* 电话状态:
* 1.tm.CALL_STATE_IDLE=0 无活动
* 2.tm.CALL_STATE_RINGING=1 响铃
* 3.tm.CALL_STATE_OFFHOOK=2 摘机
*/
tm.getCallState();//int
/*
* 电话方位:
*
*/
tm.getCellLocation();//CellLocation
/*
* 唯一的设备ID:
* GSM手机的 IMEI 和 CDMA手机的 MEID.
* Return null if device ID is not available.
*/
tm.getDeviceId();//String
/*
* 设备的软件版本号:
* 例如:the IMEI/SV(software version) for GSM phones.
* Return null if the software version is not available.
*/
tm.getDeviceSoftwareVersion();//String
/*
* 手机号:
* GSM手机的 MSISDN.
* Return null if it is unavailable.
*/
tm.getLine1Number();//String
/*
* 附近的电话的信息:
* 类型:List<NeighboringCellInfo>
* 需要权限:android.Manifest.permission#ACCESS_COARSE_UPDATES
*/
tm.getNeighboringCellInfo();//List<NeighboringCellInfo>
/*
* 获取ISO标准的国家码,即国际长途区号。
* 注意:仅当用户已在网络注册后有效。
* 在CDMA网络中结果也许不可靠。
*/
tm.getNetworkCountryIso();//String
/*
* MCC+MNC(mobile country code + mobile network code)
* 注意:仅当用户已在网络注册时有效。
* 在CDMA网络中结果也许不可靠。
*/
tm.getNetworkOperator();//String
/*
* 按照字母次序的current registered operator(当前已注册的用户)的名字
* 注意:仅当用户已在网络注册时有效。
* 在CDMA网络中结果也许不可靠。
*/
tm.getNetworkOperatorName();//String
/*
* 当前使用的网络类型:
* 例如: NETWORK_TYPE_UNKNOWN 网络类型未知 0
NETWORK_TYPE_GPRS GPRS网络 1
NETWORK_TYPE_EDGE EDGE网络 2
NETWORK_TYPE_UMTS UMTS网络 3
NETWORK_TYPE_HSDPA HSDPA网络 8
NETWORK_TYPE_HSUPA HSUPA网络 9
NETWORK_TYPE_HSPA HSPA网络 10
NETWORK_TYPE_CDMA CDMA网络,IS95A 或 IS95B. 4
NETWORK_TYPE_EVDO_0 EVDO网络, revision 0. 5
NETWORK_TYPE_EVDO_A EVDO网络, revision A. 6
NETWORK_TYPE_1xRTT 1xRTT网络 7
*/
tm.getNetworkType();//int
/*
* 手机类型:
* 例如: PHONE_TYPE_NONE 无信号
PHONE_TYPE_GSM GSM信号
PHONE_TYPE_CDMA CDMA信号
*/
tm.getPhoneType();//int
/*
* Returns the ISO country code equivalent for the SIM provider's country code.
* 获取ISO国家码,相当于提供SIM卡的国家码。
*
*/
tm.getSimCountryIso();//String
/*
* Returns the MCC+MNC (mobile country code + mobile network code) of the provider of the SIM. 5 or 6 decimal digits.
* 获取SIM卡提供的移动国家码和移动网络码.5或6位的十进制数字.
* SIM卡的状态必须是 SIM_STATE_READY(使用getSimState()判断).
*/
tm.getSimOperator();//String
/*
* 服务商名称:
* 例如:中国移动、联通
* SIM卡的状态必须是 SIM_STATE_READY(使用getSimState()判断).
*/
tm.getSimOperatorName();//String
/*
* SIM卡的序列号:
* 需要权限:READ_PHONE_STATE
*/
tm.getSimSerialNumber();//String
/*
* SIM的状态信息:
* SIM_STATE_UNKNOWN 未知状态 0
SIM_STATE_ABSENT 没插卡 1
SIM_STATE_PIN_REQUIRED 锁定状态,需要用户的PIN码解锁 2
SIM_STATE_PUK_REQUIRED 锁定状态,需要用户的PUK码解锁 3
SIM_STATE_NETWORK_LOCKED 锁定状态,需要网络的PIN码解锁 4
SIM_STATE_READY 就绪状态 5
*/
tm.getSimState();//int
/*
* 唯一的用户ID:
* 例如:IMSI(国际移动用户识别码) for a GSM phone.
* 需要权限:READ_PHONE_STATE
*/
tm.getSubscriberId();//String
/*
* 取得和语音邮件相关的标签,即为识别符
* 需要权限:READ_PHONE_STATE
*/
tm.getVoiceMailAlphaTag();//String
/*
* 获取语音邮件号码:
* 需要权限:READ_PHONE_STATE
*/
tm.getVoiceMailNumber();//String
/*
* ICC卡是否存在
*/
tm.hasIccCard();//boolean
/*
* 是否漫游:
* (在GSM用途下)
*/
tm.isNetworkRoaming();
//