首页 文章

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

提问于
浏览
389

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

15 回答

  • 28

    码:

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

    要求的许可:

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

    警告:

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

  • 13

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

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

  • 0

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

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

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

    允许:

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

    码:

    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);
    }
    

    检查whatsapp帐户的actype

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

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

  • 2

    发布在我的earlier answer

    使用以下代码:

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

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

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

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

    此外,尝试检入 Phone--> Settings --> About --> Phone Identity ,如果您能够查看其中的号码,从上面的代码获取电话号码的概率更高 . 如果您无法在设置中查看电话号码,那么您将无法通过此代码获取!

    Suggested Workaround:

    • 将用户的电话号码作为用户的手动输入 .

    • 通过短信将代码发送到用户的手机号码 .

    • 要求用户输入密码以确认电话号码 .

    • 将号码保存在共享首选项中 .

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

  • 7
    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

  • 456

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

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

    有以下许可

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

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

    试试以下代码:

    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();
    }
    

    您需要添加这两个权限 .

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

    希望这有帮助,谢谢!

  • 3

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

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

  • 8

    有一个新的Android API,允许用户选择他们的电话号码,而无需许可 . 看看: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);
    }
    
  • 40

    这是一个更简化的答案:

    public String getMyPhoneNumber()
    {
        return ((TelephonyManager) getSystemService(TELEPHONY_SERVICE))
                .getLine1Number();
    }
    
  • 3

    TelephonyManager不是正确的解决方案,因为在某些情况下,该号码不存储在SIM中,由于我的建议,您应该在应用程序打开时使用共享首选项来存储用户的电话号码,之后每次都会使用该号码你需要在申请中 .

  • 0

    首先获取用户的移动电话号码是违反道德政策的,早些时候它是可能的,但现在根据我的研究,没有可用的固定解决方案,通过使用一些代码可以获得手机号码,但不保证可能会工作只有少数设备 . 经过大量研究后,我发现只有三种解决方案,但它们并不适用于所有设备 .

    我们没有得到以下原因 .

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

    <uses-permission android:name="android.permission.READ_PHONE_STATE"/>
    
     TelephonyManager tel= (TelephonyManager)this.getSystemService(Context.
                TELEPHONY_SERVICE);
        String PhoneNumber =  tel.getLine1Number();
    

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

    • 此方法仅适用于Redmi 2 prime,但是需要在manifest中添加读取联系人权限 .

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

    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版本不存储用户的手机号码 .

    结论: - Android没有任何保证的解决方案来以编程方式获取用户的手机号码 . 建议: - 1.如果您想验证用户的手机号码,请要求用户提供他的号码,使用otp您可以验证 . 如果要识别用户的设备,可以轻松获取设备IMEI号 .

  • -5

    这就是您未经许可和黑客通过Play Services API请求电话号码的方式 . SourceFull example .

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

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

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

    @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

  • 141

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

    希望这可以帮助 .

  • 7

    一点贡献 . 在我的例子中,代码启动了一个错误异常 . 我需要添加一个注释,以便运行代码并修复该问题 . 在这里,我让这段代码 .

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

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

相关问题