jkap
jkap

Reputation: 5222

Programmatically obtain the phone number of the Android phone

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

Upvotes: 502

Views: 543291

Answers (26)

Ahamadullah Saikat
Ahamadullah Saikat

Reputation: 4644

// print phone numbers    
getPhoneNumbers().forEach {
    val phoneNumber = it
    Log.d("DREG_PHONE", "phone number: $phoneNumber")
}

// Required Permissions: READ_PHONE_STATE, READ_PHONE_NUMBERS
fun Context.getPhoneNumbers(): ArrayList<String> {
    val phoneNumbers = arrayListOf<String>()
    if (isFromAPI(23)) {
        val subscriptionManager = getSystemService(SubscriptionManager::class.java)
        val subsInfoList = subscriptionManager.activeSubscriptionInfoList
        for (subscriptionInfo in subsInfoList) {
            val phoneNumber =
                if (isFromAPI(33))
                    subscriptionManager.getPhoneNumber(subscriptionInfo.subscriptionId)
                else subscriptionInfo.number    
            if (phoneNumber.isNullOrBlank().not()) phoneNumbers.add(phoneNumber)
        }
    }
    return phoneNumbers
}
    
fun isFromAPI(apiLevel: Int) = Build.VERSION.SDK_INT >= apiLevel

Note: To Avoid Policy Violation in PlayConsole: In AppIntro Screen, you need to have a PrivacyPolicy Screen. And in PrivacyPolicy section you need to explain why you get phone numbers from users.

Upvotes: 2

David Crawford
David Crawford

Reputation: 305

On newer versions of Android, the only way to listen to incoming SMS is by making your app the default SMS app. This restriction was added in recent Android versions to prevent apps from spying on users' SMS communications without permission.

In my current project, I am building an SMS sending app that works by downloading messages from a remote web server and sending them via an Android phone. The goal is to avoid paying $$$ for every 160-character text block when using SMS gateway companies. While working on this, I discovered the challenges of obtaining the device’s phone number.

In modern Android, the phone number is normally not stored on the device, and if it is, it's likely a remnant from when the phone was running an older Android OS before the restrictions were introduced. To overcome this, you can try the following:

Set up a second device with another custom app you build, and set that app as the default SMS app so it can listen to incoming SMS messages. Send an SMS from the user's device via your app to the second device, including a unique code in the message. The second device's app extracts the phone number and the code from the SMS and uploads this data to your web server. Your app on the user’s phone then downloads the number and code from your web server. This process might involve a delay of a few seconds, but it ensures that the number is accurate because it is provided by the carrier network as part of the outgoing SMS. This method eliminates issues with users mistyping their number or providing a false one.

It's worth noting that Facebook and similar companies might use a variation of this principle. Instead of rows of old Android phones, they likely rely on server infrastructure to achieve the same goal. However, the concept is essentially the same.

This method requires infrastructure but avoids ongoing costs to SMS gateway companies. It ensures the user's phone number is reliable and eliminates the need to request it directly. While you can use SMS gateway companies instead of a second Android device, you'd still need a web server to listen for webhooks from the gateway company. Additionally, you'd incur charges for every message sent and received through those gateways. For businesses dealing with thousands of messages, these costs can become prohibitive.

In my case, the primary purpose of the user's app is to send unlimited SMS messages from our server on behalf of an employee, such as sending promotional information to customers of a specific salesperson (e.g., in real estate). By leveraging this method, the system achieves its goal of cost-effectiveness while maintaining reliability and user trust. As well as this, in our case, customers who receive these messages can reply directly to the employee rather than receiving a message from a gateway system using a word or number that cant receive replies. It intergrates the messages sent by the system into the message streams of the staff member for each customer they are sent to so when a reply comes in, the staff can see the context for the reply as they see the message sent by the app to the customer.

Upvotes: 0

Mohammed Shahbaz
Mohammed Shahbaz

Reputation: 109

steps:

  1. Add the play service dependency
implementation 'com.google.android.gms:play-services-auth:21.2.0'
  1. Define a launcher to get the result of selected phone number.
val request: GetPhoneNumberHintIntentRequest = GetPhoneNumberHintIntentRequest.builder().build()

private val phoneNumberHintIntentResultLauncher =
        registerForActivityResult(ActivityResultContracts.StartIntentSenderForResult()) { result ->
            if (result.resultCode == RESULT_OK && result.data != null) {
                try {
                    val phoneNumber =
                        Identity.getSignInClient(this).getPhoneNumberFromIntent(result.data)

                    binding.phoneNumberEt.setText(phoneNumber )
                } catch (e: Exception) {
                    Timber.d("Phone Number Hint failed to launch:: ${e.message}")
                }
            }
        }
  1. Write code to trigger phone number hint dialog. You can call the below method inside of onCreate if you want to show the phone hint at the start of activity.
private fun requestPhoneNumberHint() {
        Identity.getSignInClient(this)
            .getPhoneNumberHintIntent(request)
            .addOnSuccessListener { result: PendingIntent ->
                try {
                    phoneNumberHintIntentResultLauncher.launch(
                        IntentSenderRequest.Builder(result).build()
                    )
                } catch (e: Exception) {
                    Timber.d("Launching the PendingIntent failed")
                }
            }
            .addOnFailureListener { exception ->
                Timber.d("Phone Number Hint failed : ${exception.message}")
            }
    }
  1. Your phone hint dialog is ready, and all set!!

Reference link: https://developers.google.com/identity/phone-number-hint/android

List item

Upvotes: 0

Mirwise Khan
Mirwise Khan

Reputation: 1410

I noticed several answers posting the same thing. First of all things changed, onActivityResult is deprecated followed by HintRequest which also got deprecated. Here is the non-deprecated solution from 2023.

 private fun requestHint() {

    val signInClient = SignIn.getClient(this)
    val hintRequest = HintRequest.Builder()
        .setPhoneNumberIdentifierSupported(true)
        .build()

    val intentTask = signInClient.getSignInIntentBuilder()
        .setHintPickerConfig(hintRequest)
        .build()

    intentTask.addOnSuccessListener { intent ->
        val intentSenderRequest = 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(intentSenderRequest)
    }

    intentTask.addOnFailureListener { e ->
        // Handle the error
        Log.e("mTag", "Error retrieving hint picker intent: $e")
    }
}

Note: While many of you think this allows you to retrieve user's mobile phone number. That is usually not the case. Google Play Services has cached few phone numbers and sometimes the dialog shows phone numbers in which none belongs to user.

Documentation

Upvotes: 1

Amit Yadav
Amit Yadav

Reputation: 35044

This will work on SDK 33

private void processSubscriptionManager() {
        SubscriptionManager subscriptionManager = (SubscriptionManager) getSystemService(TELEPHONY_SUBSCRIPTION_SERVICE);
        if (ActivityCompat.checkSelfPermission(this, Manifest.permission.READ_PHONE_NUMBERS) != PackageManager.PERMISSION_GRANTED ||
                ActivityCompat.checkSelfPermission(this, Manifest.permission.READ_PHONE_STATE) != PackageManager.PERMISSION_GRANTED) {
            ActivityCompat.requestPermissions(MainActivity.this, new String[]{Manifest.permission.READ_PHONE_NUMBERS,
                    Manifest.permission.READ_PHONE_STATE}, 0);
            return;
        }
        List<SubscriptionInfo> subsInfoList = (List<SubscriptionInfo>) subscriptionManager.getActiveSubscriptionInfoList();
        StringBuilder number = new StringBuilder();
        for (SubscriptionInfo subscriptionInfo : subsInfoList) {
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
                number.append(subscriptionManager.getPhoneNumber(subscriptionInfo.getSubscriptionId())).append("\n");
            } else {
                number.append(subscriptionInfo.getCarrierName()).append("\n");
            }

        }

        Log.d(TAG, number.toString());
        tvMobileNumber.setText("Mobile Number = " + number.toString());
    }

AndroidManifest.xml

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

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

Upvotes: 0

Reyaz Ahmad
Reyaz Ahmad

Reputation: 136

Firstly Initalize your sign in Intent like this

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) {
        }
    }

To open google play intent and show phone number associated with google account use this

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

Note:

  1. This will fail if user is disabled phone number sharing. If is it so user have to enable that from Settings -> Google -> Auto-fill -> Phone Number sharing
  2. This will not working if you are using emulated device where play services is not available

Upvotes: 0

If I'm getting number from voiceMailNumer then it is working good -

val telephonyManager = getSystemService(TELEPHONY_SERVICE) as TelephonyManager
    if (ActivityCompat.checkSelfPermission(this,
                    Manifest.permission.READ_PHONE_STATE) == PackageManager.PERMISSION_GRANTED
    ) {
        Log.d("number", telephonyManager.voiceMailNumber.toString())
    }

Upvotes: 0

ROHIT LIEN
ROHIT LIEN

Reputation: 497

For android version >= LOLLIPOP_MR1 :

Add permission :

And call this :

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

Upvotes: 0

Morgan Koh
Morgan Koh

Reputation: 2465

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

Upvotes: 0

Reyaz Ahmad
Reyaz Ahmad

Reputation: 136

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

To fetch phone number list use this:

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
)

After tap on play services dialog:

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

Upvotes: 3

android developer
android developer

Reputation: 116362

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

Upvotes: 4

Naveed Ahmad
Naveed Ahmad

Reputation: 6737

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.

Upvotes: 4

Chor Wai Chun
Chor Wai Chun

Reputation: 3236

Update: This answer is no longer available as Whatsapp had stopped exposing the phone number as account name, kindly disregard this answer.

There is actually an alternative solution you might want to consider, if you can't get it through telephony service.

As of today, you can rely on another big application Whatsapp, using AccountManager. Millions of devices have this application installed and if you can't get the phone number via TelephonyManager, you may give this a shot.

Permission:

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

Code:

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

Check actype for WhatsApp account

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

Of course you may not get it if user did not install WhatsApp, but its worth to try anyway. And remember you should always ask user for confirmation.

Upvotes: 45

A little contribution. In my case, the code launched an error exception. I have needed put an annotation that for the code be run and fix that problem. Here I let this code.

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

Upvotes: 1

Dmide
Dmide

Reputation: 6462

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:

enter image description here

Upvotes: 44

Wirling
Wirling

Reputation: 5375

There is a new Android api that allows the user to select their phonenumber without the need for a permission. Take a look at: 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);
} 

Upvotes: 17

ramkrishna kushwaha
ramkrishna kushwaha

Reputation: 390

First of all getting users mobile number is against the Ethical policy, earlier it was possible but now as per my research there no solid solution available for this, By using some code it is possible to get mobile number but no guarantee may be it will work only in few device. After lot of research i found only three solution but they are not working in all device.

There is the following reason why we are not getting.

1.Android device and new Sim Card not storing mobile number if mobile number is not available in device and in sim then how it is possible to get number, if any old sim card having mobile number then using Telephony manager we can get the number other wise it will return the “null” or “” or “??????”

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

 TelephonyManager tel= (TelephonyManager)this.getSystemService(Context.
            TELEPHONY_SERVICE);
    String PhoneNumber =  tel.getLine1Number();

Note:- I have tested this solution in following device Moto x, Samsung Tab 4, Samsung S4, Nexus 5 and Redmi 2 prime but it doesn’t work every time it return empty string so conclusion is it's useless

  1. This method is working only in Redmi 2 prime, but for this need to add read contact permission in manifest.

Note:- This is also not the guaranteed and efficient solution, I have tested this solution in many device but it worked only in Redmi 2 prime which is dual sim device it gives me two mobile number first one is correct but the second one is not belong to my second sim it belong to my some old sim card which i am not using.

 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. In my research i have found earlier it was possible to get mobile number using WhatsApp account but now new Whatsapp version doesn’t storing user's mobile number.

Conclusion:- Android doesn’t have any guaranteed solution to get user's mobile number programmatically.

Suggestion:- 1. If you want to verify user’s mobile number then ask to user to provide his number, using otp you can can verify that.

  1. If you want to identify the user’s device, for this you can easily get device IMEI number.

Upvotes: 5

activesince93
activesince93

Reputation: 1736

Sometimes, below code returns null or blank string.

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

With below permission

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

There is another way you will be able to get your phone number, I haven't tested this on multiple devices but above code is not working every time.

Try below code:

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();
}

You will need to add these two permissions.

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

Hope this helps, Thanks!

Upvotes: 9

Ray
Ray

Reputation: 17

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.

Upvotes: -8

Alex Volovoy
Alex Volovoy

Reputation: 68444

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.

Upvotes: 511

Emil Hajric
Emil Hajric

Reputation: 720

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

Code taken from http://www.androidsnippets.com/get-my-phone-number

Upvotes: 14

ngrashia
ngrashia

Reputation: 9904

As posted in my earlier answer

Use below code :

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

In AndroidManifest.xml, give the following permission:

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

But remember, this code does not always work, since Cell phone number is dependent on the SIM Card and the Network operator / Cell phone carrier.

Also, try checking in Phone--> Settings --> About --> Phone Identity, If you are able to view the Number there, the probability of getting the phone number from above code is higher. If you are not able to view the phone number in the settings, then you won't be able to get via this code!

Suggested Workaround:

  1. Get the user's phone number as manual input from the user.
  2. Send a code to the user's mobile number via SMS.
  3. Ask user to enter the code to confirm the phone number.
  4. Save the number in sharedpreference.

Do the above 4 steps as one time activity during the app's first launch. Later on, whenever phone number is required, use the value available in shared preference.

Upvotes: 36

user_CC
user_CC

Reputation: 4776

Just want to add a bit here to above explanations in the above answers. Which will save time for others as well.

In my case this method didn't returned any mobile number, an empty string was returned. It was due to the case that I had ported my number on the new sim. So if I go into the Settings>About Phone>Status>My Phone Number it shows me "Unknown".

Upvotes: 9

E P Lewis
E P Lewis

Reputation: 63

This is a more simplified answer:

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

Upvotes: 3

Johan
Johan

Reputation: 1579

There is no guaranteed solution to this problem because the phone number is not physically stored on all SIM-cards, or broadcasted from the network to the phone. This is especially true in some countries which requires physical address verification, with number assignment only happening afterwards. Phone number assignment happens on the network - and can be changed without changing the SIM card or device (e.g. this is how porting is supported).

I know it is pain, but most likely the best solution is just to ask the user to enter his/her phone number once and store it.

Upvotes: 157

Jim
Jim

Reputation: 10278

Although it's possible to have multiple voicemail accounts, when calling from your own number, carriers route you to voicemail. So, TelephonyManager.getVoiceMailNumber() or TelephonyManager.getCompleteVoiceMailNumber(), depending on the flavor you need.

Hope this helps.

Upvotes: 0

Related Questions