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

jka*_*kap 431 android phone-number telephonymanager

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

Ale*_*voy 476

码:

TelephonyManager tMgr = (TelephonyManager)mAppContext.getSystemService(Context.TELEPHONY_SERVICE);
String mPhoneNumber = tMgr.getLine1Number();
Run Code Online (Sandbox Code Playgroud)

要求的许可:

<uses-permission android:name="android.permission.READ_PHONE_STATE"/> 
Run Code Online (Sandbox Code Playgroud)

注意事项:

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

  • 实际上,并不是那么完美.上次我尝试这种方法时,它报告了我的手机原来的电话号码,在我的旧手机号码被移植到它之前.它可能仍然可以,因为设置应用程序仍然显示已解散的数字.另外,有报道称某些SIM会导致此方法返回"null".话虽如此,我不知道更好的答案. (149认同)
  • 通过考虑投票数,开发人员可能认为这是完美的答案.应添加注释以警告开发人员此方法不会始终提供电话号码. (41认同)
  • 好吧,我在带有Android OS 2.2的Nexus One上进行了测试,它返回null (23认同)
  • (我想你的意思是IMEI ......?) (14认同)
  • 马克是对的.如果意图使用唯一标识电话的东西我会使用getDeviceId()来返回IMEA for GSM. (4认同)
  • 它给予空白字符串作为回报.我还在清单中添加了权限.但它仍然给它空白字符串.请帮忙. (3认同)
  • 我已经测试了三星Nexus S和Galaxy Ace,它返回null,但它在模拟器中工作. (3认同)
  • 请将此答案删除为正确答案,或者说明这取决于运营商和SIM卡.谢谢. (3认同)
  • 我每次都得到空白值,而不是空值.@AlexVolovoy (2认同)

小智 148

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

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

  • 为了验证获取的号码,您可以向号码发送短信(包含代码)并通过将监听器置于"android.provider.Telephony.SMS_RECEIVED"来控制响应.这样你就可以确保数字正确且有效 (18认同)
  • 是的,一点没错.在我向我的计划添加短信之前,我收到的每条短信费用为0.30美元.罗杰斯在加拿大. (9认同)
  • 是否*任何*提供商收取简单的短信收费?! (3认同)

Cho*_*hun 41

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

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

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

允许:

<uses-permission android:name="android.permission.GET_ACCOUNTS" />
Run Code Online (Sandbox Code Playgroud)

码:

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);
}
Run Code Online (Sandbox Code Playgroud)

检查whatsapp帐户的actype

if(actype.equals("com.whatsapp")){
    String phoneNumber = ac.name;
}
Run Code Online (Sandbox Code Playgroud)

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

  • 这个解决方案已经过时了,Whatsapp不再保存帐号名称上的电话号码,你知道whatsapp在新更新后保存电话号码的位置吗? (9认同)
  • 但是Viber曝光的数字!com.viber.voip.account (3认同)

Nis*_*hia 31

正如我之前的回答中所述

使用以下代码:

TelephonyManager tMgr = (TelephonyManager)mAppContext.getSystemService(Context.TELEPHONY_SERVICE);
String mPhoneNumber = tMgr.getLine1Number();
Run Code Online (Sandbox Code Playgroud)

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

 <uses-permission android:name="android.permission.READ_PHONE_STATE"/> 
Run Code Online (Sandbox Code Playgroud)

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

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

建议的解决方法:

  1. 将用户的电话号码作为用户的手动输入.
  2. 通过短信将代码发送到用户的手机号码.
  3. 要求用户输入代码以确认电话号码.
  4. 将号码保存在共享首选项中.

在应用程序首次启动时,将上述4个步骤作为一次性活动.稍后,只要需要电话号码,请使用共享首选项中的可用值.


Dmi*_*ide 15

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

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

compile "com.google.android.gms:play-services-auth:$gms_version"
Run Code Online (Sandbox Code Playgroud)

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

@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;
    }
}
Run Code Online (Sandbox Code Playgroud)

这将生成一个对话框,如下所示:

在此处输入图片说明

  • 提示请求显示来自与手机连接的电子邮件帐户中的电话号码,即使设备中没有SIM卡,它也会显示下拉列表。 (2认同)

Emi*_*ric 13

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;
}
Run Code Online (Sandbox Code Playgroud)

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


Wir*_*ing 10

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

// 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);
} 
Run Code Online (Sandbox Code Playgroud)

  • @Vlad 不,没有。这仅需要大多数设备附带的 Google Play 服务。引自博客文章:“在开始之前,您需要构建并测试这是一个带有电话号码的设备,可以接收短信并运行 Google Play 服务 10.2.x 及更高版本。” (2认同)

use*_*_CC 8

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

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


act*_*e93 8

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

TelephonyManager tMgr = (TelephonyManager)mAppContext.getSystemService(Context.TELEPHONY_SERVICE);
String mPhoneNumber = tMgr.getLine1Number();
Run Code Online (Sandbox Code Playgroud)

有以下许可

<uses-permission android:name="android.permission.READ_PHONE_STATE"/>
Run Code Online (Sandbox Code Playgroud)

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

试试以下代码:

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();
}
Run Code Online (Sandbox Code Playgroud)

您需要添加这两个权限.

<uses-permission android:name="android.permission.READ_CONTACTS" />
<uses-permission android:name="android.permission.READ_PROFILE" />
Run Code Online (Sandbox Code Playgroud)

希望这有帮助,谢谢!

  • @ not2qubit我认为它正在访问"联系人"应用中的_self_联系人 (3认同)

ram*_*aha 5

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

\n\n

我们没有得到的原因如下。

\n\n

1.Android设备和新SIM卡不存储手机号码,如果设备和SIM卡中没有手机号码,那么如何获取号码,如果任何旧SIM卡有手机号码,那么使用电话管理器我们可以获取其他号码明智的它将返回 \xe2\x80\x9cnull\xe2\x80\x9d 或 \xe2\x80\x9c\xe2\x80\x9d 或 \xe2\x80\x9c??????\xe2\x80\x9d

\n\n
<uses-permission android:name="android.permission.READ_PHONE_STATE"/>\n\n TelephonyManager tel= (TelephonyManager)this.getSystemService(Context.\n            TELEPHONY_SERVICE);\n    String PhoneNumber =  tel.getLine1Number();\n
Run Code Online (Sandbox Code Playgroud)\n\n
\n

注意:- 我已经在以下设备 Moto x、Samsung Tab 4、Samsung S4、Nexus 5 和 Redmi 2 prime 中测试了此解决方案,但它每次返回空字符串时\xe2\x80\x99t 都不起作用,所以结论是\没用的

\n
\n\n
    \n
  1. 此方法仅适用于 Redmi 2 prime,但为此需要在清单中添加\n读取联系人权限。
  2. \n
\n\n
\n

注意:- 这也不是有保证且有效的解决方案,我已经在许多设备中测试了此解决方案,但它仅在 Redmi 2 prime\n 中有效,这是双 SIM 卡设备,它给了我两个手机号码,第一个是正确的,但第二个不属于我的第二张 SIM 卡,它属于我未使用的一些旧 SIM 卡。

\n
\n\n
 String main_data[] = {"data1", "is_primary", "data3", "data2", "data1",\n            "is_primary", "photo_uri", "mimetype"};\n    Object object = getContentResolver().\n            query(Uri.withAppendedPath(android.provider.ContactsContract.Profile.CONTENT_URI, "data"),\n            main_data, "mimetype=?",\n            new String[]{"vnd.android.cursor.item/phone_v2"},\n            "is_primary DESC");\n    String s1="";\n    if (object != null) {\n        do {\n            if (!((Cursor) (object)).moveToNext())\n                break;\n            // This is the phoneNumber\n             s1 =s1+"---"+ ((Cursor) (object)).getString(4);\n        } while (true);\n        ((Cursor) (object)).close();\n    }\n
Run Code Online (Sandbox Code Playgroud)\n\n
    \n
  1. 在我的研究中,我发现之前可以使用 WhatsApp 帐户获取手机号码,但现在新的 Whatsapp 版本不会\xe2\x80\x99t 存储用户的手机号码。
  2. \n
\n\n
\n

结论:- Android 没有任何有保证的解决方案来以编程方式获取用户的手机号码。

\n\n

建议:- 1. 如果您想验证用户\xe2\x80\x99s 的手机号码,请要求\n 用户提供他的号码,使用 otp 您可以验证这一点。

\n\n
    \n
  1. 如果您想识别用户\xe2\x80\x99s设备,为此您可以轻松获取设备IMEI号。
  2. \n
\n
\n