android 手机号
2012-07-23 23:28:13 song_shi_chao 阅读数 22009

最近做一个项目 需要获取到手机的相关信息

一个朋友的看法:

从技术层面而言,手机的SIM卡上并不会存储手机号码信息,只会存储IMSIInternational Mobile Subscriber Identification Number)。手机号码(MSISDN)都是登记在HLRHome Location Register)中的,在HLR中会把IMSIMSISDN关联在一起。

 中国移动的SIM卡里只有IMSI号码而没有存储手机号码,在中国移动的HLR中会有一张映射表,专门用于把用户手机SIM卡的IMSI号映射成为用户的手机号码,这就是移动丢卡不丢号的业务也就是缘于此,也是一卡多号的原理。而电信CDMA(原来联通CDMA)的机卡合一的手机卡里会同时存在IMSI和手机号码。 

客户端获取:在客户端对移动用户而言只能够获取诸如IMSIIMEI号等,并不能直接获得手机号。而对电信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是一个唯一的数字, 标识了GSMUMTS 网络里的唯一一个用户它存储 在手机的SIM卡里,它会通过手机发送到网络上. IMSI 与 SIM唯一对应

IMEI也是一串唯一的数字, 标识了 GSM 和 UMTS网络里的唯一一个手机.它通常被打印在手机里电池下面的那一面,拨 *#06# 也能看到它. IMEI 与 设备唯一对应.

1IMEI不存在于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 可以获取


2016-03-21 16:15:23 u013220682 阅读数 471

转载请注明出处:http://blog.csdn.net/u013220682/article/details/50945019

最近做了一个业务就是短信支付,其中涉及到获取用户手机号并发送短信。下面我们进入正题,看看我是怎么获取到用户手机号的。

很多人都觉得这个问题Android有自带的API来获取,并没什么疑惑的。确实没错,Android的TelephonyManager有一个方法叫getLine1Number(),官网的解释是Returns the phone number string for line 1, for example, the MSISDN for a GSM phone. Return null if it is unavailable.那么我们看看它到底能不能成功获取到呢?我们看代码:

布局文件activity_main.xml如下,就一个Button和一个TextView,Button点击后获取号码并显示在TextView中。

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent" >
    <LinearLayout android:layout_width="match_parent"
        android:layout_height="200dip"
        android:orientation="vertical">
    <TextView
        android:id="@+id/tv"
        android:layout_width="match_parent"
        android:layout_height="0dip"
        android:layout_weight="2"
        android:text="电话号码:" />

    <Button
        android:id="@+id/bt"
        android:layout_width="match_parent"
        android:layout_height="0dip"
        android:layout_weight="1"
        android:text="获取" />
    </LinearLayout>
</RelativeLayout>

看代然后我们创建一个类GetPhoneInfo用来获取手机号,代码如下:

package com.wuping.getphoneinfo;

import android.content.Context;
import android.telephony.TelephonyManager;

public class GetPhoneInfo {

	private TelephonyManager mTelephonyManager;
	private Context mContext;

	public GetPhoneInfo(Context pContext) {
		mContext = pContext;
		mTelephonyManager = (TelephonyManager) pContext.getSystemService(Context.TELEPHONY_SERVICE);
	}
	
	public String getNativePhoneNumber(){
		String nativePhoneNumber = "";
		nativePhoneNumber = mTelephonyManager.getLine1Number();
		if("".equals(nativePhoneNumber) || nativePhoneNumber == null) {
			nativePhoneNumber = "未获取到该号码";
		}
		return nativePhoneNumber;
	}
}
我们看看MainActivity的代码:
public class MainActivity extends ActionBarActivity implements OnClickListener{

	private TextView tv;
	private Button bt;
	private GetPhoneInfo getPhoneInfo;

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);
		tv = (TextView)findViewById(R.id.tv);
		bt = (Button)findViewById(R.id.bt);
		getPhoneInfo = new GetPhoneInfo(this);
		bt.setOnClickListener(this);
	}

	@Override
	public void onClick(View v) {
		// TODO Auto-generated method stub
		switch (v.getId()) {
		case R.id.bt:
			String number = tv.getText().toString() + getPhoneInfo.getNativePhoneNumber();
			tv.setText(number);
			break;

		default:
			break;
		}
	}
}
程序运行结果如下:

我试了好几次都是这样,始终获取不到,这是为什么呢?

其实我查过很多资料发现,这个方法其实获取手机号不一定能获取到。

网上有资料说原因好像是:

手机号码不是所有的都能获取。只是有一部分可以拿到(目前我是没有拿到过)。这个是由于移动运营商没有把手机号码的数据写入到sim卡中.SIM卡只有唯一的编号,供网络与设备识别那就是IMSI号码,手机的信号也可以说是通过这个号码在网络中传递的,并不是手机号码。试想,你的SIM卡丢失后,补办一张新的会换号码吗?是不会的.就是因为在你的手机号码对应的IMSI号 在移动运营商中被修改成新SIM卡的IMSI号码。

那么我们怎么解决这个问题呢?

我是这样处理的,我们公司跟移动有合作,所以我们有移动分配的号码。我们手机发送短信到这个号码,那么移动就会通知我们某某手机号给我们发送某信息了。于是我们能够从短信下行内容就知道该用户的手机号了。然后通过后台储存并告诉前端,这样我们就间接的拿到了手机号。

此次内容供大家讨论,欢迎大家分享出更好的获取手机号的方法,谢谢。

2013-01-19 15:37:27 waterseason 阅读数 22
从技术层面而言,手机的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
[table]
|String|MODEL|The end-user-visible name for the end product.|
[/table]

sdk版本 Build.VERSION.SDK
[table]
|String|SDK|This constant is deprecated. Use SDK_INT to easily get this as an integer.|
[/table]

及frimware版本号(系统版本号) Build.VERSION.RELEASE
[table]
|String|RELEASE|The user-visible version string.|
[/table]

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能向我们提供包括 硬件厂商,硬件编号,序列号等很多信息 调用方法也都同上,很简单。
[table]
|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||
[/table]

=================================================

首先我们来明确几个概念:

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 可以获取
2017-08-18 19:11:01 m0_37177456 阅读数 577
public class PhoneNumberTextWatcher implements TextWatcher {
    private EditText editText;
    private boolean mDelte;

    public PhoneNumberTextWatcher(EditText editText) {
        this.editText = editText;
        editText.setOnKeyListener(new View.OnKeyListener() {
            @Override
            public boolean onKey(View v, int keyCode, KeyEvent event) {
                /**
                 * 加外层判断可以屏蔽调用两次
                 */
                if (event.getAction() == KeyEvent.ACTION_DOWN) {
                    if (keyCode == KeyEvent.KEYCODE_DEL) {
                        mDelte = true;
                    }
                }

                return false;
            }
        });
    }


    @Override
    public void beforeTextChanged(CharSequence s, int start, int count, int after) {


    }

    @Override
    public void onTextChanged(CharSequence s, int start, int before, int count) {

    }

    @Override
    public void afterTextChanged(Editable s) {
        /**
         * 如果按下删除键则不进行字符串判断,这样可以屏蔽删除>重新排列>删除>重新排列..导致类似删除无效的情况发生。
         */
        if (mDelte) {
            mDelte = false;
            return;
        }
        String inputNumber = s.toString().replace(" ", "");
        String a = "";//存储第一段的三位数
        String b = "";//存储第二段的四位数
        String c = "";//存储第三段的四位数
        if (inputNumber.length() >= 3) {
            a = inputNumber.substring(0, 3);
        } else if (inputNumber.length() < 3) {
            a = inputNumber.substring(0, inputNumber.length());
        }
        if (inputNumber.length() >= 7) {
            b = inputNumber.substring(3, 7);
            c = inputNumber.substring(7, inputNumber.length());
        } else if (inputNumber.length() > 3 && inputNumber.length() < 7) {
            b = inputNumber.substring(3, inputNumber.length());
        }
        StringBuilder sb = new StringBuilder();
        if (a.length() > 0) {
            sb.append(a);
            if (a.length() == 3) {
                sb.append(" ");
            }
        }
        if (b.length() > 0) {
            sb.append(b);
            if (b.length() == 4) {
                sb.append(" ");
            }
        }
        if (c.length() > 0) {
            sb.append(c);
        }
        /**
         * 下面先去除改变监听是为了避免editText.setText(sb.toString())导致的无限递归
         */
        editText.removeTextChangedListener(this);
        editText.setText(sb.toString());
        editText.setSelection(editText.getText().toString().length());
        editText.addTextChangedListener(this);
    }
}

使用:
username.addTextChangedListener(new PhoneNumberTextWatcher(username));
2016-01-20 11:19:22 lazyer_dog 阅读数 4980

原文出处 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 plaincopy
  1. String telephoneNumber = (TelephonyManager)this.getSystemService(Context.TELEPHONY_SERVICE).getLine1Number();  
[html] view plaincopy
  1. <uses-permission android:name="android.permission.READ_PHONE_STATE" />  


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

[html] view plaincopy
  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 plaincopy
  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 plaincopy
  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。

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

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


博文 来自: waterseason

android手机号正则

阅读数 257

android获取手机号

阅读数 12

博文 来自: waterseason
没有更多推荐了,返回首页