Programmatically obtain the phone number of the Android phone

后端 未结 18 1726
南笙
南笙 2020-11-21 06:17

How can I programmatically get the phone number of the device that is running my android app?

相关标签:
18条回答
  • 2020-11-21 06:54

    TelephonyManager is not the right solution, because in some cases the number is not stored in the SIM. I suggest that you should use the shared preference to store the user's phone number for the first time the application is open and the number will used whenever you need.

    0 讨论(0)
  • 2020-11-21 06:55

    This is a more simplified answer:

    public String getMyPhoneNumber()
    {
        return ((TelephonyManager) getSystemService(TELEPHONY_SERVICE))
                .getLine1Number();
    }
    
    0 讨论(0)
  • 2020-11-21 06:55

    So that's how you request a phone number through the Play Services API without the permission and hacks. Source and Full example.

    In your build.gradle (version 10.2.x and higher required):

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

    In your activity (the code is simplified):

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

    This will generate a dialog like this:

    0 讨论(0)
  • 2020-11-21 06:57

    Code:

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

    Required Permission:

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

    Caveats:

    According to the highly upvoted comments, there are a few caveats to be aware of. This can return null or "" or even "???????", and it can return a stale phone number that is no longer valid. If you want something that uniquely identifies the device, you should use getDeviceId() instead.

    0 讨论(0)
  • 2020-11-21 06:58

    Here's a combination of the solutions I've found (sample project here, if you want to also check auto-fill):

    manifest

        <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 ""
            }
        }
    }
    
    0 讨论(0)
  • 2020-11-21 06:59

    Wouldn't be recommending to use TelephonyManager as it requires the app to require READ_PHONE_STATE permission during runtime.

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

    Should be using Google's Play Service for Authentication, and it will able to allow User to select which phoneNumber to use, and handles multiple SIM cards, rather than us trying to guess which one is the primary SIM Card.

    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
                }
            }
        }
    }
    
    0 讨论(0)
提交回复
热议问题