我如何通过编程方式获得正在运行我的android应用程序的设备的电话号码?


当前回答

我注意到有几个回复都发了同样的东西。首先,从2021年开始,onActivityResult已弃用。下面是不弃用的解决方案。

private fun requestHint() {

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

    val intent = Credentials.getClient(this).getHintPickerIntent(hintRequest)
    val intentSender = IntentSenderRequest.Builder(intent.intentSender).build()

    val resultLauncher = registerForActivityResult(
        ActivityResultContracts.StartIntentSenderForResult()
    ) { result ->
        if (result.resultCode == Activity.RESULT_OK) {
            val credential: Credential? = result.data?.getParcelableExtra(Credential.EXTRA_KEY)
            // Phone number with country code
            Log.i("mTag", "Selected phone No: ${credential?.id}")
        }
    }
    resultLauncher.launch(intentSender)
}

注意:虽然很多人认为这可以让你检索用户的手机号码。通常情况并非如此。谷歌播放服务缓存了几个电话号码,有时对话框显示电话号码,其中不属于用户。

一个重要的导入。com.google.android.gms.auth.api.credentials.Credential

参考文档提供了详细信息,但代码有些不推荐。

其他回答

添加这个依赖: 实现“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
)

点击播放服务对话框后:

override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent? { 
    super.onActivityResult(requestCode, resultCode, data)

    if (requestCode == PHONE_NUMBER_FETCH_REQUEST_CODE) {
        data?.getParcelableExtra<Credential>(Credential.EXTRA_KEY)?.id?.let { 
            useFetchedPhoneNumber(it)
        }
    }
}

这是一个更简单的答案:

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

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

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

应该使用谷歌的播放服务进行身份验证,它将能够允许用户选择使用哪个phoneNumber,并处理多个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
            }
        }
    }
}

一点小小的贡献。在我的例子中,代码启动了一个错误异常。我需要把一个注释,为代码运行和修复这个问题。这里我让这段代码。

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

只是想在以上回答中对以上解释做一点补充。这也会为其他人节省时间。

在我的情况下,这个方法没有返回任何手机号码,返回一个空字符串。这是由于我把我的号码移植到新的sim卡上的情况。所以如果我进入设置>关于电话>状态>我的电话号码,它显示我“未知”。