有的手机获取不到手机号码的原因:
手机号码不是所有的都能获取。只是有一部分可以拿到。这个是由于移动运营商没有把手机号码的数据写入到sim卡中.SIM卡只有唯一的编号,供网络与设备识别那就是IMSI号码,手机的信号也可以说是通过这个号码在网络中传递的,并不是手机号码。试想,你的SIM丢失后,补办一张新的会换号码吗?是不会的.就是因为在你的手机号码对应的IMSI号 在移动运营商中被修改成新SIM卡的IMSI号码。
那么手机号为什么有的就能显示呢?
这个就像是一个变量,当移动运营商为它赋值了,它自然就会有值。不赋值自然为空。
对于移动的用户,手机号码(MDN)保存在运营商的服务器中,而不是保存在SIM卡里。SIM卡只保留了IMSI和一些验证信息。手机每次入网注册的时候,都会以短信的形式将IMSI及验证信息上传到运营商的服务器,服务器在完成注册动作之后,会以短信的形式将注册的结果下发到手机里。下发的内容会因条件不同而不同。
如果服务器在下发的短信中,不包含手机的号码,手机是无法取得电话号码。如果短信中包含了号码,手机才会将其缓存,以备他用.此外,对于其他运行商的SIM卡或者UIM卡,MDN有可能保存在UIM卡中。100%能够取得本机号码不太可能。
移动神州行,联通的卡是可以取到的.动感地带的取不到.别的卡还没有试过.
能够读取SIM卡号的话应该有前提.那就是SIM卡已经写入了本机号码,不然是无法读取的。
ICCID
ICCID:Integrate circuit card identity 集成电路卡识别码(固化在手机SIM卡中) ICCID为IC卡的唯一识别号码,共有20位数字组成,其编码格式为:XXXXXX 0MFSS YYGXX XXXXX。在SIM卡的背面。
前六位运营商代码:中国移动的为:898600;898602 ,中国联通的为:898601,中国电信898603
获取手机信息的工具类
public class PhoneInfoUtils {
private static String TAG = "PhoneInfoUtils";
private TelephonyManager telephonyManager;
//移动运营商编号
private String NetworkOperator;
private Context context;
public PhoneInfoUtils(Context context) {
this.context = context;
telephonyManager = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);
}
/**
* 获取sim卡Iccid
*/
public String getIccid() {
return telephonyManager.getSimSerialNumber();
}
/**
* 获取电话号码
*
* @return
*/
public String getNativePhoneNumber() {
return telephonyManager.getLine1Number();
}
/**
* 获取手机服务商信息
*
* @return
*/
public String getProvidersName() {
String providersName = "N/A";
NetworkOperator = telephonyManager.getNetworkOperator();
// IMSI号前面3位460是国家,紧接着后面2位00 02是中国移动,01是中国联通,03是中国电信。
if (NetworkOperator.equals("46000") || NetworkOperator.equals("46002")) {
providersName = "中国移动";//中国移动
} else if (NetworkOperator.equals("46001")) {
providersName = "中国联通";//中国联通
} else if (NetworkOperator.equals("46003")) {
providersName = "中国电信";//中国电信
}
return providersName;
}
/**
* 获取手机IMEI
*
* @return
*/
public String getIMEI() {
return telephonyManager.getDeviceId();
}
/**
* 获取手机IMSI
*/
public String getIMSI(Context context) {
return telephonyManager.getSubscriberId();
}
public String getPhoneInfo() {
TelephonyManager tm = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);
StringBuffer sb = new StringBuffer();
sb.append("\nLine1Number = " + tm.getLine1Number());
sb.append("\nNetworkOperator = " + tm.getNetworkOperator());//移动运营商编号
sb.append("\nNetworkOperatorName = " + tm.getNetworkOperatorName());//移动运营商名称
sb.append("\nSimCountryIso = " + tm.getSimCountryIso());
sb.append("\nSimOperator = " + tm.getSimOperator());
sb.append("\nSimOperatorName = " + tm.getSimOperatorName());
sb.append("\nSimSerialNumber = " + tm.getSimSerialNumber());
sb.append("\nSubscriberId(IMSI) = " + tm.getSubscriberId());
return sb.toString();
}
//获取本机真实的物理地址
public String getLocalMacAddress() {
String macAddress = Settings.Secure.getString(context.getContentResolver(), "bluetooth_address");
return macAddress;
}
}
如果通过phoneInfoUtils.getNativePhoneNumber()获取不到本地号码,就要使用迂回的方式获取
下面提供了一种解决方案:通过发送短信到服务商,在返回的信息中提取本机号码
以移动卡为例,发送BJ到10086,返回的信息中就包含本机的号码
发送短信的工具类:
public class SMSUtils {
// 正则提取手机号码
public static String GetPhoneNumberFromSMSText(String sms) {
String phoneNumberRegex = "\\d*";
Pattern p = Pattern.compile(phoneNumberRegex);
Matcher m = p.matcher(sms);
while (m.find()) {
String msg = m.group();
if (!TextUtils.isEmpty(msg) && msg.length() == 11) {
return msg;
}
}
return "";
}
// 发送短信
public void SendSMS(Context context, String number, String text) {
PendingIntent pi = PendingIntent.getActivity(context, 0,
new Intent(context, context.getClass()), 0);
SmsManager sms = SmsManager.getDefault();
sms.sendTextMessage(number, null, text, pi, null);
}
// 发送短信
public void SendSMS2(Context context, String number, String text) {
String SENT = "sms_sent";
String DELIVERED = "sms_delivered";
PendingIntent sentPI = PendingIntent.getActivity(context, 0, new Intent(SENT), 0);
PendingIntent deliveredPI = PendingIntent.getActivity(context, 0, new Intent(DELIVERED), 0);
SmsManager smsm = SmsManager.getDefault();
smsm.sendTextMessage(number, null, text, sentPI, deliveredPI);
}
}
写一个短信广播监听:
public class SMSReceiver extends BroadcastReceiver {
public static final String GetNumberAddress = "10086";// 短信来源
public static final String SMS_RECEIVED = "android.provider.Telephony.SMS_RECEIVED";
public static String phoneNumber = "";
private Handler handler;
public SMSReceiver(Handler handler){
this.handler = handler;
}
@Override
public void onReceive(Context context, Intent intent) {
if (SMS_RECEIVED.equals(intent.getAction())) {
Object[] pdus = (Object[]) intent.getExtras().get("pdus");
SmsMessage[] message = new SmsMessage[pdus.length];
StringBuilder sb = new StringBuilder();
String address = "";
for (int i = 0; i < pdus.length; i++) { // 拼接信息字符串
//虽然是循环,其实pdus长度一般都是1
message[i] = SmsMessage.createFromPdu((byte[]) pdus[i]);
sb.append("接收到短信来自:\n");
address = message[i].getDisplayOriginatingAddress();
sb.append(address + "\n");
sb.append("内容:" + message[i].getDisplayMessageBody());
}
if (address.equals(GetNumberAddress)) { // 将phoneNumber加入消息队列,让主Activity处理
phoneNumber = SMSUtils.GetPhoneNumberFromSMSText(sb.toString());
Message messagel = handler.obtainMessage();
messagel.what = MainActivity.HANDLER_REV_MSG;
messagel.obj = phoneNumber;
handler.handleMessage(messagel);
}
}
}
}
然后在需要发送短信的地方调用:
//发送短信
SMSUtils smscore = new SMSUtils();
smscore.SendSMS2(this, "10086", "BJ");
在广播监听中处理接收到的短信信息。
注册广播接收者记得在onDestory的时候销毁。
@Override
protected void onDestroy() {
super.onDestroy();
if (smsReceiver != null) {
unregisterReceiver(smsReceiver);
}
... ...
}
手机号码不是所有的都能获取。只是有一部分可以拿到。这个是由于移动运营商没有把手机号码的数据写入到sim卡中.SIM卡只有唯一的编号,供网络与设备识别那就是IMSI号码,手机的信号也可以说是通过这个号码在网络中传递的,并不是手机号码。试想,你的SIM丢失后,补办一张新的会换号码吗?是不会的.就是因为在你的手机号码对应的IMSI号 在移动运营商中被修改成新SIM卡的IMSI号码。
那么手机号为什么有的就能显示呢?
这个就像是一个变量,当移动运营商为它赋值了,它自然就会有值。不赋值自然为空。
对于移动的用户,手机号码(MDN)保存在运营商的服务器中,而不是保存在SIM卡里。SIM卡只保留了IMSI和一些验证信息。手机每次入网注册的时候,都会以短信的形式将IMSI及验证信息上传到运营商的服务器,服务器在完成注册动作之后,会以短信的形式将注册的结果下发到手机里。下发的内容会因条件不同而不同。
如果服务器在下发的短信中,不包含手机的号码,手机是无法取得电话号码。如果短信中包含了号码,手机才会将其缓存,以备他用.此外,对于其他运行商的SIM卡或者UIM卡,MDN有可能保存在UIM卡中。100%能够取得本机号码不太可能。
移动神州行,联通的卡是可以取到的.动感地带的取不到.别的卡还没有试过.
能够读取SIM卡号的话应该有前提.那就是SIM卡已经写入了本机号码,不然是无法读取的。
ICCID
ICCID:Integrate circuit card identity 集成电路卡识别码(固化在手机SIM卡中) ICCID为IC卡的唯一识别号码,共有20位数字组成,其编码格式为:XXXXXX 0MFSS YYGXX XXXXX。在SIM卡的背面。
前六位运营商代码:中国移动的为:898600;898602 ,中国联通的为:898601,中国电信898603
获取手机信息的工具类
public class PhoneInfoUtils {
private static String TAG = "PhoneInfoUtils";
private TelephonyManager telephonyManager;
//移动运营商编号
private String NetworkOperator;
private Context context;
public PhoneInfoUtils(Context context) {
this.context = context;
telephonyManager = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);
}
/**
* 获取sim卡Iccid
*/
public String getIccid() {
return telephonyManager.getSimSerialNumber();
}
/**
* 获取电话号码
*
* @return
*/
public String getNativePhoneNumber() {
return telephonyManager.getLine1Number();
}
/**
* 获取手机服务商信息
*
* @return
*/
public String getProvidersName() {
String providersName = "N/A";
NetworkOperator = telephonyManager.getNetworkOperator();
// IMSI号前面3位460是国家,紧接着后面2位00 02是中国移动,01是中国联通,03是中国电信。
if (NetworkOperator.equals("46000") || NetworkOperator.equals("46002")) {
providersName = "中国移动";//中国移动
} else if (NetworkOperator.equals("46001")) {
providersName = "中国联通";//中国联通
} else if (NetworkOperator.equals("46003")) {
providersName = "中国电信";//中国电信
}
return providersName;
}
/**
* 获取手机IMEI
*
* @return
*/
public String getIMEI() {
return telephonyManager.getDeviceId();
}
/**
* 获取手机IMSI
*/
public String getIMSI(Context context) {
return telephonyManager.getSubscriberId();
}
public String getPhoneInfo() {
TelephonyManager tm = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);
StringBuffer sb = new StringBuffer();
sb.append("\nLine1Number = " + tm.getLine1Number());
sb.append("\nNetworkOperator = " + tm.getNetworkOperator());//移动运营商编号
sb.append("\nNetworkOperatorName = " + tm.getNetworkOperatorName());//移动运营商名称
sb.append("\nSimCountryIso = " + tm.getSimCountryIso());
sb.append("\nSimOperator = " + tm.getSimOperator());
sb.append("\nSimOperatorName = " + tm.getSimOperatorName());
sb.append("\nSimSerialNumber = " + tm.getSimSerialNumber());
sb.append("\nSubscriberId(IMSI) = " + tm.getSubscriberId());
return sb.toString();
}
//获取本机真实的物理地址
public String getLocalMacAddress() {
String macAddress = Settings.Secure.getString(context.getContentResolver(), "bluetooth_address");
return macAddress;
}
}
如果通过phoneInfoUtils.getNativePhoneNumber()获取不到本地号码,就要使用迂回的方式获取
下面提供了一种解决方案:通过发送短信到服务商,在返回的信息中提取本机号码
以移动卡为例,发送BJ到10086,返回的信息中就包含本机的号码
发送短信的工具类:
public class SMSUtils {
// 正则提取手机号码
public static String GetPhoneNumberFromSMSText(String sms) {
String phoneNumberRegex = "\\d*";
Pattern p = Pattern.compile(phoneNumberRegex);
Matcher m = p.matcher(sms);
while (m.find()) {
String msg = m.group();
if (!TextUtils.isEmpty(msg) && msg.length() == 11) {
return msg;
}
}
return "";
}
// 发送短信
public void SendSMS(Context context, String number, String text) {
PendingIntent pi = PendingIntent.getActivity(context, 0,
new Intent(context, context.getClass()), 0);
SmsManager sms = SmsManager.getDefault();
sms.sendTextMessage(number, null, text, pi, null);
}
// 发送短信
public void SendSMS2(Context context, String number, String text) {
String SENT = "sms_sent";
String DELIVERED = "sms_delivered";
PendingIntent sentPI = PendingIntent.getActivity(context, 0, new Intent(SENT), 0);
PendingIntent deliveredPI = PendingIntent.getActivity(context, 0, new Intent(DELIVERED), 0);
SmsManager smsm = SmsManager.getDefault();
smsm.sendTextMessage(number, null, text, sentPI, deliveredPI);
}
}
写一个短信广播监听:
public class SMSReceiver extends BroadcastReceiver {
public static final String GetNumberAddress = "10086";// 短信来源
public static final String SMS_RECEIVED = "android.provider.Telephony.SMS_RECEIVED";
public static String phoneNumber = "";
private Handler handler;
public SMSReceiver(Handler handler){
this.handler = handler;
}
@Override
public void onReceive(Context context, Intent intent) {
if (SMS_RECEIVED.equals(intent.getAction())) {
Object[] pdus = (Object[]) intent.getExtras().get("pdus");
SmsMessage[] message = new SmsMessage[pdus.length];
StringBuilder sb = new StringBuilder();
String address = "";
for (int i = 0; i < pdus.length; i++) { // 拼接信息字符串
//虽然是循环,其实pdus长度一般都是1
message[i] = SmsMessage.createFromPdu((byte[]) pdus[i]);
sb.append("接收到短信来自:\n");
address = message[i].getDisplayOriginatingAddress();
sb.append(address + "\n");
sb.append("内容:" + message[i].getDisplayMessageBody());
}
if (address.equals(GetNumberAddress)) { // 将phoneNumber加入消息队列,让主Activity处理
phoneNumber = SMSUtils.GetPhoneNumberFromSMSText(sb.toString());
Message messagel = handler.obtainMessage();
messagel.what = MainActivity.HANDLER_REV_MSG;
messagel.obj = phoneNumber;
handler.handleMessage(messagel);
}
}
}
}
然后在需要发送短信的地方调用:
//发送短信
SMSUtils smscore = new SMSUtils();
smscore.SendSMS2(this, "10086", "BJ");
在广播监听中处理接收到的短信信息。
注册广播接收者记得在onDestory的时候销毁。
@Override
protected void onDestroy() {
super.onDestroy();
if (smsReceiver != null) {
unregisterReceiver(smsReceiver);
}
... ...
}