How to get the mobile number of my device programmatically?

16k Views Asked by At

I have tried using 2 methods for retrieving my phone number but both of them don't work. I used:

  1. TelephonyManager
  2. SubscriptionManager

I do get Network name, Country iso, and IMEI but whenever I try to return Number it returns nothing.

I have also added all the required permissions for these! My manifest looks like:

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

Code using TelephonyManager:

TelephonyManager phoneMgr = (TelephonyManager) getSystemService(Context.TELEPHONY_SERVICE);
phoneMgr.getLine1Number()

Code using SubscriptionManager:

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
        List<SubscriptionInfo> subscription = SubscriptionManager.from(getApplicationContext()).getActiveSubscriptionInfoList();
        for (int i = 0; i < subscription.size(); i++) {
            SubscriptionInfo info = subscription.get(i);
            Log.e("TAG", "number " + info.getNumber());
            Log.e("TAG", "network name : " + info.getCarrierName());
            Log.e("TAG", "country iso " + info.getCountryIso());
        }
    }

In both attempts I get nothing!

Is there any other way to get phone number or I'm doing something wrong?

5

There are 5 best solutions below

9
On BEST ANSWER

Nowadays the TelephonyManager does not help us. Play Services API without permission is good solution for this.

This dependency is useful for this

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

Now inside your Activity.java:

GoogleApiClient  mGoogleApiClient = new GoogleApiClient.Builder(this)
                .addConnectionCallbacks(this)
                .addOnConnectionFailedListener(this)
                .addApi(Auth.CREDENTIALS_API)
                .build();

        if (mGoogleApiClient != null) {
            mGoogleApiClient.connect();
        }

After this do request for Phone Number:

 HintRequest hintRequest = new HintRequest.Builder()
                .setPhoneNumberIdentifierSupported(true)
                .build();

        PendingIntent intent = Auth.CredentialsApi.getHintPickerIntent(mGoogleApiClient, hintRequest);
        try {
            startIntentSenderForResult(intent.getIntentSender(), 1008, null, 0, 0, 0, null);
        } catch (IntentSender.SendIntentException e) {
            Log.e("", "Could not start hint picker Intent", e);
        }

Now you need to handle response in your onActivityResult like this:

    @Override
    public void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
        super.onActivityResult(requestCode, resultCode, data);

        switch (requestCode) {
            case 1008:
                if (resultCode == RESULT_OK) {
                    Credential cred = data.getParcelableExtra(Credential.EXTRA_KEY);
//                    cred.getId====: ====+919*******
                    Log.e("cred.getId", cred.getId());
                    userMob = cred.getId();


                } else {
                    // Sim Card not found!
                    Log.e("cred.getId", "1008 else");

                    return;
                }


                break;
        }
    }
0
On

I found @bhoomika's answer useful but now using GoogleApiClient is deprecated. So you can use CredentialsClient instead.

Below is the method I used to trigger the phone number hint dialog (this method is in a helper class).

public void requestPhoneNumberHint(Activity currentActivity) {
    HintRequest hintRequest = new HintRequest.Builder()
            .setPhoneNumberIdentifierSupported(true)
            .build();
    CredentialsClient credentialsClient = Credentials.getClient(currentActivity);

    PendingIntent intent = credentialsClient.getHintPickerIntent(hintRequest);
    try {
        uiListener.getCurrentActivity().startIntentSenderForResult(intent.getIntentSender(),
                RESOLVE_PHONE_NUMBER_HINT, null, 0, 0, 0);
    } catch (IntentSender.SendIntentException e) {
        e.printStackTrace();
    }
}

Below is my handling for the corresponding onActivityResult (my Activity code is in Kotlin)

override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
    if(requestCode == RESOLVE_PHONE_NUMBER_HINT){
        if (resultCode == RESULT_OK) {
           var credential : Credential?  = data?.getParcelableExtra(Credential.EXTRA_KEY)
            credential?.apply {
                processPhoneNumber(id)
            }
        }
    }

As mentioned in the below documentation, the result codes can be used to identify if there were no hints that were displayed or if the user did not chose any of the options.

public static final int ACTIVITY_RESULT_NO_HINTS_AVAILABLE Activity result code indicating that there were no hints available.

Constant Value: 1002 public static final int ACTIVITY_RESULT_OTHER_ACCOUNT Activity result code indicating that the user wishes to use a different account from what was presented in the credential or hint picker.

Constant Value: 1001

https://developers.google.com/android/reference/com/google/android/gms/auth/api/credentials/CredentialsApi#ACTIVITY_RESULT_NO_HINTS_AVAILABLE

1
On

Have you given access to READ_PHONE_STATE permission?

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

getLine1Number() should do the trick, but depending on the SIM-card this will not always be able to get the phone number

I suggest that if you do not get the number from getLine1Number(), then make the user type it in manually. (This is what iOS users have to do anyway)

EDIT:

Also, you should not use IMEI as of Android 10 you will not have permission to get that information

5
On

By using below code you current device phone number & after selecting phone number onActivity result will be called.

Gradle :

  implementation 'com.google.android.gms:play-services-auth:17.0.0'
  implementation 'com.google.android.gms:play-services-auth-api-phone:17.0.0'

Setup Google API Client :

    //set google api client for hint request
    mGoogleApiClient = new GoogleApiClient.Builder(this)
        .addConnectionCallbacks(this)
        .enableAutoManage(this, this)
        .addApi(Auth.CREDENTIALS_API)
        .build();

Get an available number :

public void getHintPhoneNumber() {
  HintRequest hintRequest =
      new HintRequest.Builder()
          .setPhoneNumberIdentifierSupported(true)
          .build();
  PendingIntent mIntent = Auth.CredentialsApi.getHintPickerIntent(mGoogleApiClient, hintRequest);
  try {
    startIntentSenderForResult(mIntent.getIntentSender(), RESOLVE_HINT, null, 0, 0, 0);
  } catch (IntentSender.SendIntentException e) {
    e.printStackTrace();
  }
}

Get Selected Number in onActivityResult :

@Override
  protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
    super.onActivityResult(requestCode, resultCode, data);
    //Result if we want hint number
    if (requestCode == RESOLVE_HINT) {
      if (resultCode == Activity.RESULT_OK) {

        Credential credential = data.getParcelableExtra(Credential.EXTRA_KEY);
        // credential.getId();  <-- will need to process phone number string
        inputMobileNumber.setText(credential.getId());
      }
    }
  }

Reference : https://androidwave.com/automatic-sms-verification-android/