以编程方式获取Android手机的电话号码

Programmatically obtain the phone number of the Android phone

如何以编程方式获取运行我的Android应用程序的设备的电话号码?


码:

1
2
TelephonyManager tMgr = (TelephonyManager)mAppContext.getSystemService(Context.TELEPHONY_SERVICE);
String mPhoneNumber = tMgr.getLine1Number();

要求的许可:

1
<uses-permission android:name="android.permission.READ_PHONE_STATE"/>

注意事项:

根据高度评价的评论,有一些需要注意的注意事项。这可以返回null""甚至"???????",并且可以返回不再有效的陈旧电话号码。如果您想要唯一标识设备的内容,则应使用getDeviceId()


此问题无法保证解决方案,因为电话号码不是物理存储在所有SIM卡上,也不是从网络广播到手机。在一些需要物理地址验证的国家尤其如此,数字分配仅在事后发生。电话号码分配在网络上进行 - 并且可以在不更改SIM卡或设备的情况下进行更改(例如,这是支持移植的方式)。

我知道这很痛苦,但最有可能最好的解决方案就是要求用户输入他/她的电话号码并保存。


更新:由于Whatsapp已停止将电话号码作为帐户名称公开,因此不再提供此答案,请忽略此答案。

如果您无法通过电话服务获得它,实际上您可能需要考虑另一种解决方案。

截至今天,你可以依赖另一个大应用程序Whatsapp,使用AccountManager。数百万台设备已安装此应用程序,如果您无法通过TelephonyManager获取电话号码,您可以试一试。

允许:

1
<uses-permission android:name="android.permission.GET_ACCOUNTS" />

码:

1
2
3
4
5
6
7
8
9
AccountManager am = AccountManager.get(this);
Account[] accounts = am.getAccounts();

for (Account ac : accounts) {
    String acname = ac.name;
    String actype = ac.type;
    // Take your time to look at all available accounts
    System.out.println("Accounts :" + acname +"," + actype);
}

检查actype以查看WhatsApp帐户

1
2
3
if(actype.equals("com.whatsapp")){
    String phoneNumber = ac.name;
}

当然,如果用户没有安装WhatsApp,你可能无法得到它,但无论如何都值得尝试。
并记住你应该总是要求用户确认。


正如我之前的回答中所述

使用以下代码:

1
2
TelephonyManager tMgr = (TelephonyManager)mAppContext.getSystemService(Context.TELEPHONY_SERVICE);
String mPhoneNumber = tMgr.getLine1Number();

在AndroidManifest.xml中,授予以下权限:

1
 <uses-permission android:name="android.permission.READ_PHONE_STATE"/>

但请记住,此代码并不总是有效,因为手机号码取决于SIM卡和网络运营商/手机运营商。

此外,尝试检查电话 - >设置 - >关于 - >电话身份,如果您能够在那里查看号码,从上面的代码获取电话号码的概率更高。如果您无法在设置中查看电话号码,那么您将无法通过此代码获取!

建议的解决方法:

  • 将用户的电话号码作为用户的手动输入。
  • 通过短信将代码发送到用户的手机号码。
  • 要求用户输入代码以确认电话号码。
  • 将号码保存在共享首选项中。
  • 在应用程序首次启动时,将上述4个步骤作为一次性活动。稍后,只要需要电话号码,请使用共享首选项中的可用值。


    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    private String getMyPhoneNumber(){
        TelephonyManager mTelephonyMgr;
        mTelephonyMgr = (TelephonyManager)
            getSystemService(Context.TELEPHONY_SERVICE);
        return mTelephonyMgr.getLine1Number();
    }

    private String getMy10DigitPhoneNumber(){
        String s = getMyPhoneNumber();
        return s != null && s.length() > 2 ? s.substring(2) : null;
    }

    代码取自http://www.androidsnippets.com/get-my-phone-number


    有一个新的Android api允许用户选择他们的phonenumber而无需许可。看一眼:
    https://android-developers.googleblog.com/2017/10/effective-phone-number-verification.html

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    // Construct a request for phone numbers and show the picker
    private void requestHint() {
        HintRequest hintRequest = new HintRequest.Builder()
           .setPhoneNumberIdentifierSupported(true)
           .build();

        PendingIntent intent = Auth.CredentialsApi.getHintPickerIntent(
            apiClient, hintRequest);
        startIntentSenderForResult(intent.getIntentSender(),
            RESOLVE_HINT, null, 0, 0, 0);
    }


    这就是您未经许可和黑客通过Play Services API请求电话号码的方式。来源和完整的例子。

    在build.gradle中(需要10.2.x及更高版本):

    1
    compile"com.google.android.gms:play-services-auth:$gms_version"

    在您的活动中(代码简化):

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        // ...
        googleApiClient = new GoogleApiClient.Builder(this)
                .addApi(Auth.CREDENTIALS_API)
                .build();
        requestPhoneNumber(result -> {
            phoneET.setText(result);
        });
    }

    public void requestPhoneNumber(SimpleCallback<String> callback) {
        phoneNumberCallback = callback;
        HintRequest hintRequest = new HintRequest.Builder()
                .setPhoneNumberIdentifierSupported(true)
                .build();

        PendingIntent intent = Auth.CredentialsApi.getHintPickerIntent(googleApiClient, hintRequest);
        try {
            startIntentSenderForResult(intent.getIntentSender(), PHONE_NUMBER_RC, null, 0, 0, 0);
        } catch (IntentSender.SendIntentException e) {
            Logs.e(TAG,"Could not start hint picker Intent", e);
        }
    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        if (requestCode == PHONE_NUMBER_RC) {
            if (resultCode == RESULT_OK) {
                Credential cred = data.getParcelableExtra(Credential.EXTRA_KEY);
                if (phoneNumberCallback != null){
                    phoneNumberCallback.onSuccess(cred.getId());
                }
            }
            phoneNumberCallback = null;
        }
    }

    这将生成如下对话框:

    enter image description here


    有时,下面的代码返回null或空字符串。

    1
    2
    TelephonyManager tMgr = (TelephonyManager)mAppContext.getSystemService(Context.TELEPHONY_SERVICE);
    String mPhoneNumber = tMgr.getLine1Number();

    有以下许可

    1
    <uses-permission android:name="android.permission.READ_PHONE_STATE"/>

    还有另一种方法可以获取您的电话号码,我没有在多台设备上测试过,但上面的代码每次都无法正常工作。

    试试以下代码:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    String main_data[] = {"data1","is_primary","data3","data2","data1","is_primary","photo_uri","mimetype"};
    Object object = getContentResolver().query(Uri.withAppendedPath(android.provider.ContactsContract.Profile.CONTENT_URI,"data"),
            main_data,"mimetype=?",
            new String[]{"vnd.android.cursor.item/phone_v2"},
           "is_primary DESC");
    if (object != null) {
        do {
            if (!((Cursor) (object)).moveToNext())
                break;
            // This is the phoneNumber
            String s1 = ((Cursor) (object)).getString(4);
        } while (true);
        ((Cursor) (object)).close();
    }

    您需要添加这两个权限。

    1
    2
    <uses-permission android:name="android.permission.READ_CONTACTS" />
    <uses-permission android:name="android.permission.READ_PROFILE" />

    希望这可以帮助,
    谢谢!


    只是想在上面的答案中添加一些上述解释。这也将为其他人节省时间。

    在我的情况下,此方法未返回任何移动号码,返回空字符串。这是因为我在新的SIM卡上移植了我的号码。因此,如果我进入设置>关于手机>状态>我的电话号码,它会显示"未知"。


    这是一个更简化的答案:

    1
    2
    3
    4
    5
    public String getMyPhoneNumber()
    {
        return ((TelephonyManager) getSystemService(TELEPHONY_SERVICE))
                .getLine1Number();
    }


    首先获取用户手机号码是违反道德政策的,之前有可能,但现在根据我的研究,没有可靠的解决方案,通过使用一些代码可以获得手机号码,但不保证可能会有效只有少数设备。经过大量的研究,我发现只有三种解决方案,但它们并不适用于所有设备。

    我们没有得到以下原因。

    1.Android设备和新的SIM卡没有存储手机号码,如果手机号码在设备和SIM卡中不可用,那么如何获得号码,如果任何旧的SIM卡有手机号码然后使用电话管理器,我们可以得到其他号码明智的是它将返回"null"或""或"??????"

    1
    2
    3
    4
    5
    <uses-permission android:name="android.permission.READ_PHONE_STATE"/>

     TelephonyManager tel= (TelephonyManager)this.getSystemService(Context.
                TELEPHONY_SERVICE);
        String PhoneNumber =  tel.getLine1Number();

    Note:- I have tested this solution in following device Moto x, Samsung Tab 4, Samsung S4, Nexus 5 and Redmi 2 prime but it doesn’t work every
    time it return empty string so conclusion is it's useless

  • 此方法仅适用于Redmi 2 prime,但需要添加
    读取清单中的联系人权限。
  • Note:- This is also not the guaranteed and efficient solution, I have tested this solution in many device but it worked only in Redmi 2 prime
    which is dual sim device it gives me two mobile number first one is
    correct but the second one is not belong to my second sim it belong to
    my some old sim card which i am not using.

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
     String main_data[] = {"data1","is_primary","data3","data2","data1",
               "is_primary","photo_uri","mimetype"};
        Object object = getContentResolver().
                query(Uri.withAppendedPath(android.provider.ContactsContract.Profile.CONTENT_URI,"data"),
                main_data,"mimetype=?",
                new String[]{"vnd.android.cursor.item/phone_v2"},
               "is_primary DESC");
        String s1="";
        if (object != null) {
            do {
                if (!((Cursor) (object)).moveToNext())
                    break;
                // This is the phoneNumber
                 s1 =s1+"---"+ ((Cursor) (object)).getString(4);
            } while (true);
            ((Cursor) (object)).close();
        }
  • 在我之前发现的研究中,我可以使用WhatsApp帐户获取手机号码,但现在新的Whatsapp版本不存储用户的手机号码。
  • Conclusion:- Android doesn’t have any guaranteed solution to get
    user's mobile number programmatically.

    Suggestion:- 1. If you want to verify user’s mobile number then ask to
    user to provide his number, using otp you can can verify that.

  • If you want to identify the user’s device, for this you can easily get device IMEI number.

  • TelephonyManager不是正确的解决方案,因为在某些情况下,数字不会存储在SIM中。我建议您应该首次使用共享首选项来存储用户的电话号码,并在应用程序打开时随时使用该号码。


    一点贡献。就我而言,代码启动了一个错误异常。我需要添加一个注释,以便运行代码并修复该问题。在这里,我让这个代码。

    1
    2
    3
    4
    5
    public static String getLineNumberPhone(Context scenario) {
        TelephonyManager tMgr = (TelephonyManager) scenario.getSystemService(Context.TELEPHONY_SERVICE);
        @SuppressLint("MissingPermission") String mPhoneNumber = tMgr.getLine1Number();
        return mPhoneNumber;
    }

    虽然可以拥有多个语音邮件帐户,但是当您使用自己的号码拨打电话时,运营商会将您转到语音邮件。所以,TelephonyManager.getVoiceMailNumber()TelephonyManager.getCompleteVoiceMailNumber(),取决于你需要的味道。

    希望这可以帮助。


    在开发一个安全应用程序的时候,我需要知道手机的电话号码是什么,我必须这样做;
    1.接收Boot completed,然后尝试从telephonyManager获取Line1_Number,返回字符串结果。
    2.将字符串结果与我自己的电话号码进行比较,如果它们不匹配或字符串返回null,则,
    3.秘密向我的办公室号码发送包含字符串结果和特殊标志的短信。
    4.如果消息发送失败,则启动服务并在每小时后继续尝试,直到发送短信待定意图返回成功为止。
    通过这些步骤,我可以获得使用丢失手机的人数。
    这个人是否被起诉并不重要。