Android笔记系列--获取手机号码

有的手机获取不到手机号码的原因:
    手机号码不是所有的都能获取。只是有一部分可以拿到。这个是由于移动运营商没有把手机号码的数据写入到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);
    }
    ... ...
}

猜你喜欢

转载自blog.csdn.net/u012861467/article/details/80060088