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


当前回答

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

清单

    <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 ""
        }
    }
}

其他回答

while working on a security app which needed to get the phone number of who so ever my phone might get into their hands, I had to do this; 1. receive Boot completed and then try getting Line1_Number from telephonyManager which returns a string result. 2. compare the String result with my own phone number and if they don't match or string returns null then, 3. secretly send an SMS containing the string result plus a special sign to my office number. 4. if message sending fails, start a service and keep trying after each hour until sent SMS pending intent returns successful. With this steps I could get the number of the person using my lost phone. it doesn't matter if the person is charged.

有一个新的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);
} 

首先在Intent中初始化你的符号

private val signInIntent = registerForActivityResult(ActivityResultContracts.StartIntentSenderForResult()) { result ->
        try {
            val phoneNumber = Identity.getSignInClient(requireContext()).getPhoneNumberFromIntent(result.data)
            // Note phone number will be in country code + phone number format           
        } catch (e: Exception) {
        }
    }

要打开谷歌播放意图,并显示与谷歌帐户相关联的电话号码,请使用此

val phoneNumberHintIntentRequest = GetPhoneNumberHintIntentRequest.builder()
            .build()
        Identity.getSignInClient(requireContext())
            .getPhoneNumberHintIntent(phoneNumberHintIntentRequest)
            .addOnSuccessListener { pendingIntent ->
                signInIntent.launch(IntentSenderRequest.Builder(pendingIntent).build())
            }.addOnFailureListener {
                it.printStackTrace()
            }

注意:

如果用户禁用电话号码共享,此操作将失败。如果是这样,用户必须从设置->谷歌->自动填充->电话号码共享 如果您正在使用播放服务不可用的模拟设备,这将不起作用

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

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

虽然你可以有多个语音信箱帐号,但当你用自己的号码打电话时,运营商会把你转到语音信箱。因此,telephonymanager。getvoicemailnumber()或telephonymanager。getcompletevoicemailnumber(),这取决于你需要的风格。

希望这能有所帮助。