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

时间:2010-03-19 20:09:38

标签: android phone-number telephonymanager

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

19 个答案:

答案 0 :(得分:468)

代码:

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

必需许可:

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

注意事项:

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

答案 1 :(得分:145)

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

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

答案 2 :(得分:40)

更新:由于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);
}

检查actype WhatsApp帐户

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

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

答案 3 :(得分:30)

发布在我的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卡和网络运营商/手机运营商。

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

建议的解决方法:

  1. 将用户的电话号码作为用户的手动输入。
  2. 通过短信将代码发送到用户的手机号码。
  3. 要求用户输入密码以确认电话号码。
  4. 将号码保存在共享偏好中。
  5. 在应用首次发布期间,将上述4个步骤作为一次性活动。稍后,只要需要电话号码,请使用共享首选项中的可用值。

答案 4 :(得分: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;
}

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

答案 5 :(得分:8)

有时,下面的代码返回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" />

希望这有帮助, 谢谢!

答案 6 :(得分: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);
} 

答案 7 :(得分:8)

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

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

答案 8 :(得分: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

答案 9 :(得分:4)

这是一个更简化的答案:

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

答案 10 :(得分:3)

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

答案 11 :(得分:3)

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

我们没有得到以下原因。

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中测试了这个解决方案,但它并不是每个都有效   时间它返回空字符串所以结论是没用的

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

    注意: - 这也不是有保证和有效的解决方案,我已经在许多设备中测试了这个解决方案,但它只适用于Redmi 2 prime   这是双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();
        }
    
    1. 在我之前发现的研究中,我可以使用WhatsApp帐户获取手机号码,但现在新的Whatsapp版本不会存储用户的手机号码。
    2.   

      结论: - Android没有任何有保障的解决方案   用户的手机号码。

           

      建议: - 1.如果您想验证用户的手机号码,请询问   用户提供他的号码,使用otp即可验证。

           
          
      1. 如果您想识别用户的设备,可以轻松获取设备IMEI号。
      2.   

答案 12 :(得分:3)

以下是我找到的解决方案的组合(示例项目here,如果您还想检查自动填充):

清单

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

build.gradle

    implementation "com.google.android.gms:play-services-auth:17.0.0"

MainActivity.kt

class MainActivity : AppCompatActivity() {
    private lateinit var googleApiClient: GoogleApiClient

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        tryGetCurrentUserPhoneNumber(this)
        googleApiClient = GoogleApiClient.Builder(this).addApi(Auth.CREDENTIALS_API).build()
        if (phoneNumber.isEmpty()) {
            val hintRequest = HintRequest.Builder().setPhoneNumberIdentifierSupported(true).build()
            val intent = Auth.CredentialsApi.getHintPickerIntent(googleApiClient, hintRequest)
            try {
                startIntentSenderForResult(intent.intentSender, REQUEST_PHONE_NUMBER, null, 0, 0, 0);
            } catch (e: IntentSender.SendIntentException) {
                Toast.makeText(this, "failed to show phone picker", Toast.LENGTH_SHORT).show()
            }
        } else
            onGotPhoneNumberToSendTo()

    }

    override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
        super.onActivityResult(requestCode, resultCode, data)
        if (requestCode == REQUEST_PHONE_NUMBER) {
            if (resultCode == Activity.RESULT_OK) {
                val cred: Credential? = data?.getParcelableExtra(Credential.EXTRA_KEY)
                phoneNumber = cred?.id ?: ""
                if (phoneNumber.isEmpty())
                    Toast.makeText(this, "failed to get phone number", Toast.LENGTH_SHORT).show()
                else
                    onGotPhoneNumberToSendTo()
            }
        }
    }

    private fun onGotPhoneNumberToSendTo() {
        Toast.makeText(this, "got number:$phoneNumber", Toast.LENGTH_SHORT).show()
    }


    companion object {
        private const val REQUEST_PHONE_NUMBER = 1
        private var phoneNumber = ""

        @SuppressLint("MissingPermission", "HardwareIds")
        private fun tryGetCurrentUserPhoneNumber(context: Context): String {
            if (phoneNumber.isNotEmpty())
                return phoneNumber
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
                val subscriptionManager = context.getSystemService(Context.TELEPHONY_SUBSCRIPTION_SERVICE) as SubscriptionManager
                try {
                    subscriptionManager.activeSubscriptionInfoList?.forEach {
                        val number: String? = it.number
                        if (!number.isNullOrBlank()) {
                            phoneNumber = number
                            return number
                        }
                    }
                } catch (ignored: Exception) {
                }
            }
            try {
                val telephonyManager = context.getSystemService(Context.TELEPHONY_SERVICE) as TelephonyManager
                val number = telephonyManager.line1Number ?: ""
                if (!number.isBlank()) {
                    phoneNumber = number
                    return number
                }
            } catch (e: Exception) {
            }
            return ""
        }
    }
}

答案 13 :(得分:2)

添加此依赖项: <form id="Myform"> <select name="myoption" id="MyOptions" multiple="multiple"> <option value="1" selected=""> Value 1 </option> <option value="2" selected=""> Value 2</option> <option value="3"> Value 3 </option> </select> </form> var Mydata = $('#Myform').serialize(); OR var Mydata = $('#MyOptions').serialize(); So it gets from all the selected values $.ajax({ type: "post", url: "http://URL" , dataType: "text", data: Mydata, success: function(request) { result.innerHTML = request ; } });

要获取电话号码列表,请使用此:

implementation 'com.google.android.gms:play-services-auth:18.0.0'

点击“播放服务”对话框后:

val hintRequest = HintRequest.Builder()
    .setPhoneNumberIdentifierSupported(true)
    .build()

val intent = Credentials.getClient(context).getHintPickerIntent(hintRequest)

startIntentSenderForResult(
    intent.intentSender,
    PHONE_NUMBER_FETCH_REQUEST_CODE,
    null,
    0,
    0,
    0,
    null
)

答案 14 :(得分:1)

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

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

答案 15 :(得分:1)

对于安卓版本>= LOLLIPOP_MR1 :

添加权限:

并称之为:

 val subscriptionManager =
        getSystemService(Context.TELEPHONY_SUBSCRIPTION_SERVICE) as SubscriptionManager
    
if (ActivityCompat.checkSelfPermission(this, Manifest.permission.READ_PHONE_STATE) == PackageManager.PERMISSION_GRANTED) {
        
val list = subscriptionManager.activeSubscriptionInfoList
        for (info in list) {
            Log.d(TAG, "number " + info.number)
            Log.d(TAG, "network name : " + info.carrierName)
            Log.d(TAG, "country iso " + info.countryIso)
        }
    }

答案 16 :(得分:0)

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

希望这有帮助。

答案 17 :(得分:0)

不建议使用TelephonyManager,因为它要求应用在运行时需要READ_PHONE_STATE权限。

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

应该使用Google的Play服务进行身份验证,它将允许用户选择要使用的电话号码并处理多个SIM卡,而不是我们试图猜测哪个是主要的SIM卡。

implementation "com.google.android.gms:play-services-auth:$play_service_auth_version"
fun main() {
    val googleApiClient = GoogleApiClient.Builder(context)
        .addApi(Auth.CREDENTIALS_API).build()

    val hintRequest = HintRequest.Builder()
        .setPhoneNumberIdentifierSupported(true)
        .build()

    val hintPickerIntent = Auth.CredentialsApi.getHintPickerIntent(
        googleApiClient, hintRequest
    )

    startIntentSenderForResult(
        hintPickerIntent.intentSender, REQUEST_PHONE_NUMBER, null, 0, 0, 0
    )
}

override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
    super.onActivityResult(requestCode, resultCode, data)
    when (requestCode) {
        REQUEST_PHONE_NUMBER -> {
            if (requestCode == Activity.RESULT_OK) {
                val credential = data?.getParcelableExtra<Credential>(Credential.EXTRA_KEY)
                val selectedPhoneNumber = credential?.id
            }
        }
    }
}

答案 18 :(得分:-5)

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