Програмно отримати номер телефону телефону Android


443

Як я можу програмно отримати номер телефону пристрою, на якому працює мій додаток для Android?


це неможливо, за винятком випадків, коли ви вводите його самостійно. Номер телефону не знає ні мобільний, ні SIM-
картка

3
@tomsoft Подумайте про це ... Як додатки, такі як Facebook, автоматично магічно підтверджують ваш номер телефону ..?
Едді Харт

1
@tomsoft Ні, більшість випадків він навіть не запитує номер вашого телефону, або якщо це так, то поле заповнено.
Едді Харт

1
@tomsoft Добре, що я зареєструвався у Facebook на днях, і він не запитував мого номера, коли він надсилав мені код. Спробуй це. ;)
Едді Харт

1
@EddieHart Зробіть це також, і мене запитали номер телефону. Це підтверджує, що загалом це не доступно, і деякі оператори можуть додавати цю інформацію про налаштування, але це не стандартна функція GMS
tomsoft

Відповіді:


484

Код:

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

Необхідний дозвіл:

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

Застереження:

Відповідно до висококваліфікованих коментарів, слід знати кілька застережень. Це може повернутися nullабо ""навіть навіть "???????", і він може повернути несвіжий номер телефону, який більше не дійсний. Якщо ви хочете щось, що унікально ідентифікує пристрій, вам слід скористатися getDeviceId()натомість.


150
Насправді, не так ідеально. Востаннє я спробував цей метод, він повідомив про номер телефону, який мій телефон спочатку мав, перш ніж мій старий номер мобільного телефону був перенесений на нього. Це, мабуть, і досі, оскільки додаток "Налаштування" все ще показує, що це число не існує Також є повідомлення про те, що деякі SIM-карти викликають повернення цього методу null. Коли це було сказано, я не знаю кращої відповіді.
CommonsWare

4
Марк прав. Якщо намір використовувати щось, що однозначно ідентифікує телефон, я би скористався getDeviceId (), який поверне IMEA для GSM.
Олексій Воловий

15
(Я думаю, ви маєте на увазі IMEI ...?)
ChaimKut

23
Що ж, я перевірив його на Nexus One з Android OS 2.2, і він повертається нульовим
Омар Рехман,

43
Розробники можуть подумати, що це ідеальна відповідь, враховуючи підрахунок голосів. Слід додати примітку, щоб попередити розробника про те, що цей метод не завжди надаватиме номер телефону.
Habeeb Perwad

151

Немає гарантованого вирішення цієї проблеми, оскільки номер телефону фізично не зберігається на всіх SIM-картах або не передається з мережі в телефон. Особливо це стосується деяких країн, які потребують фізичної перевірки адреси, присвоєння номера відбувається лише після цього. Присвоєння телефонного номера відбувається в мережі - і його можна змінити, не змінюючи SIM-карту чи пристрій (наприклад, так підтримується перенос).

Я знаю, що це біль, але, швидше за все, найкращим рішенням є просто попросити користувача ввести один раз свій номер телефону та зберегти його.


18
Щоб перевірити прийняте число, ви можете надіслати sms (містить код) на номер та керувати відповіддю, поставивши слухача на "android.provider.Telephony.SMS_RECEIVED". таким чином ви можете переконатися, що число правильне та робоче
Hossein Shahdoost

1
Творче рішення, але ви, можливо, захочете повідомити користувачеві, що ви це робите, лише у випадку, якщо за це платять.
Норман Н

3
Чи є якийсь провайдер, який стягує плату за отримання простих текстових повідомлень ?!
ThiefMaster

9
Так, абсолютно. Перш ніж я додав текстові повідомлення до свого плану, мені було нараховано 0,30 долара за отримане текстове повідомлення. Роджерс в Канаді.
Джон Кройч

44

Оновлення: Ця відповідь більше не доступна, оскільки Whatsapp перестав виставляти номер телефону як імені облікового запису, люб’язно не зважайте на цю відповідь.

Насправді є альтернативне рішення, яке ви хочете розглянути, якщо ви не можете його отримати через послугу телефонії.

На сьогоднішній день ви можете розраховувати на інший великий додаток Whatsapp, використовуючи AccountManager. У мільйонах пристроїв встановлено цей додаток, і якщо ви не можете отримати номер телефону TelephonyManager, ви можете зробити це.

Дозвіл:

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

Код:

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

Перевірте actypeрахунок WhatsApp

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

Звичайно, ви можете не отримати його, якщо користувач не встановив WhatsApp, але варто все-таки спробувати. І пам’ятайте, що ви завжди повинні просити користувача підтвердження.


1
Я щойно бачив це сьогодні, коли я возився з рахунками. Дуже погано, що номер виставляється так. Звичайно, вам потрібен дозвіл GET_ACCOUNTS, і в цей момент користувачеві, мабуть, не важливо, які дозволи має додаток.
jargetz

9
Це рішення застаріло, Whatsapp більше не зберігає номер телефону на імені акаунта, чи знаєте ви, де WhatsApp зберігає номер телефону після нового оновлення?
Cohelad

@Cohelad дякую за оновлення, я отримаю перевірку пізніше і перекрестую цю відповідь після підтвердження, тим часом я не знаю, де вони зберігають номер
Чор Вай Чун

3
Але Viber ВИДАЧИ номер! com.viber.voip.account
xnagyg

32

Як було розміщено в моїй попередній відповіді

Використовуйте код нижче:

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

У AndroidManifest.xml надайте такий дозвіл:

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

Але пам’ятайте, що цей код працює не завжди, оскільки номер мобільного телефону залежить від SIM-картки та оператора мережі / оператора стільникового телефону.

Також спробуйте перевірити Телефон -> Установки -> Про -> Ідентифікатор телефону. Якщо ви можете переглянути номер там, то ймовірність отримати номер телефону з вищевказаного коду вище. Якщо ви не в змозі переглянути номер телефону в налаштуваннях, ви не зможете отримати цей код!

Рекомендований спосіб вирішення:

  1. Отримайте номер телефону користувача як ручне введення від користувача.
  2. Надішліть код на мобільний номер користувача через SMS.
  3. Попросіть користувача ввести код, щоб підтвердити номер телефону.
  4. Збережіть номер у спільній налаштуваннях.

Виконайте вищевказані 4 кроки як разову діяльність під час першого запуску програми. Пізніше, коли потрібно вводити номер телефону, використовуйте значення, доступні в спільних налаштуваннях.


Ця відповідь охоплює всі фактори, вона повинна бути прийнятою =)
Слава Фомін II

Як я можу отримати мобільний номер, якщо на телефоні є подвійний сим. з наведеним вище кодом. Для сим-
симу

26

Ось так ви запитуєте номер телефону через API служб Play без дозволу та злому. Джерело та повний приклад .

У своєму build.gradle (потрібна версія 10.2.x і новіша версія):

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

У вашій діяльності (код спрощений):

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

Це створить діалогове вікно, подібне до цього:

введіть тут опис зображення


2
Підказка "Підказка" показує номер телефону з облікового запису електронної пошти, пов'язаного з телефоном, він відображатиметься вниз, навіть якщо в пристрої немає сим-карти.
Арі

як у діалоговому вікні відображаються кілька номерів, поки є лише одна SIM-картка? Для мене це показує 5 чисел. : / :)
cgr

як ми можемо автоматично вибрати перший номер телефону в android?
Noorul

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

Код, взятий з http://www.androidsnippets.com/get-my-phone-number


@JaredBurrows через "s.substring (2)".
Monster Cookie

1
це не працює для мене. Я отримую значення NULL (СІМ-карта сонця, Швейцарія)
e-nature

ваше посилання розірвано.
Ümañg ßürmån

11

Існує нова програма для Android, яка дозволяє користувачеві вибрати номер телефону без необхідності дозволу. Погляньте на сторінку: 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);
} 

Для цього потрібна Firebase
Влад

@Vlad Ні, це не так. Для цього потрібні лише служби Google Play, які постачаються на більшості пристроїв. Цитата з блогу: "Перш ніж почати, вам потрібно буде створити і протестувати це пристрій з номером телефону, який може приймати SMS і запускає служби Google Play 10.2.x і новіші".
Вірлінг

9

Просто хочу трохи додати сюди вищезазначені пояснення у наведених вище відповідях. Що заощадить час і для інших.

У моєму випадку цей метод не повернув жодного мобільного номера, повернувся порожній рядок. Через те, що я переніс свій номер на новому симі. Тож якщо я заходжу в Налаштування> Про телефон> Статус> Мій номер телефону, він відображатиметься "Невідомий".


Моя також, що це за умова? Роумінг? А може бути, на сімкарді просто немає в ній збереженого номера.
Олександр Марконд

8

Іноді під кодом повертається nullчи порожній рядок.

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

З нижчим дозволом

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

Є ще один спосіб, коли ви зможете отримати свій номер телефону, я не перевіряв це на кількох пристроях, але вищевказаний код не працює щоразу.

Спробуйте нижче код:

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

Вам потрібно буде додати ці два дозволи.

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

Сподіваюся, це допомагає, дякую!


Чи можу я запитати: у другому фрагменті, який є номером комірки?
iOSAndroidWindowsMobileAppsDev

1
Значенням String s1буде номер телефону.
activesince93

Цей код для мене не працює. (Ваш останній фрагмент коду). Повертає порожній рядок.
Крісті Валлійська

Будь ласка, поясніть свою відповідь. Де зберігається число і як це число містить? Залежний від чого?
not2qubit

3
@ not2qubit Я думаю, що це доступ до самоконтакту в додатку "Контакти"
Samplasion

4

Це більш спрощена відповідь:

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

3

Перш за все, отримання мобільних номерів користувачів суперечить Етичній політиці, раніше це було можливо, але зараз, згідно з моїми дослідженнями, для цього не існує надійного рішення. За допомогою деякого коду можна отримати мобільний номер, але жодної гарантії може не працювати. лише в декількох пристроях. Після багатьох досліджень я знайшов лише три рішення, але вони працюють не у всіх пристроях.

Є наступна причина, чому ми не отримуємо.

1.Андроїдний пристрій та нова сим-карта не зберігають номер мобільного телефону, якщо номер мобільного телефону не доступний у пристрої та в SIM-коді, то як можна отримати номер, якщо будь-яка стара сим-карта, що має мобільний номер, то за допомогою менеджера телефонії ми можемо отримати номер іншого розумним він поверне "null" або "" або "??????"

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

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

Примітка: - Я перевірив це рішення на наступних пристроях Moto x, Samsung Tab 4, Samsung S4, Nexus 5 та Redmi 2 prime, але воно не працює кожен раз, коли повертає порожню рядок, тому висновок - марний

  1. Цей метод працює лише в Redmi 2 prime, але для цього потрібно додати дозвіл читання контактів у маніфесті.

Примітка: - Це також не гарантоване та ефективне рішення, я протестував це рішення на багатьох пристроях, але він працював лише у Redmi 2 Prime, який є пристроєм з подвійним симом, він дає мені два мобільні номери: перший правильний, але другий - не належать моєму другому симу, він належить до моєї старої сим-карти, яку я не використовую.

 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. У своєму дослідженні я виявив, що раніше можна було отримати мобільний номер за допомогою облікового запису WhatsApp, але тепер нова версія Whatsapp не зберігає мобільний номер користувача.

Висновок : - Android не має жодного гарантованого рішення для програмного отримання мобільного номера користувача.

Пропозиція : - 1. Якщо ви хочете підтвердити мобільний номер користувача, тоді попросіть користувача надати його номер, використовуючи otp, ви можете це підтвердити.

  1. Якщо ви хочете ідентифікувати пристрій користувача, для цього ви можете легко отримати номер IMEI пристрою.

2

TelephonyManagerне є правильним рішенням, оскільки в деяких випадках число не зберігається в SIM-картці. Я пропоную вам скористатися спільним уподобанням, щоб зберігати номер телефону користувача вперше, коли програма відкрита, і номер буде використовуватися, коли вам потрібно.


1
Але цей метод схильний до помилок. Користувач може ввести неправильне число.
Зохра Хан

3
так, для цієї мети я використовував текстове повідомлення, коли користувач вводить номер, отже SmsManager повідомляє додаток, і через це ми можемо використовувати smsReciever, щоб отримати оригінальний номер
Naveed Ahmad

1
У мене є ще одне запитання .. з цим методом буде плата за SMS, яку надає користувач (якщо це не безкоштовний номер) .. Чи є інший метод, за допомогою якого я можу отримати телефон, не користувач?
Зохра Хан

Так, звичайно, за це SMS буде стягуватися плата, якщо номер не є безкоштовним номером.
Naveed Ahmad

Ні, я думаю, що досі не існує такого методу без TelephonyManager. і я вказую на проблему TelephoneManager у своїй відповіді.
Naveed Ahmad

2

Ось комбінація знайдених нами рішень (зразок проекту тут , якщо ви хочете також перевірити автоматичне заповнення):

маніфест

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

Подивіться коментарі до цієї відповіді stackoverflow.com/a/48210130/5457916 , перш ніж застосовувати цей метод
humble_wolf

Надане вами посилання - це лише частина того, що я тут зробив. Тут я вперше спробував її автоматично заповнити. І є резервні для цього.
андроїд розробник

Я знаю, сер, ваша відповідь є чудовою і не має жодної помилки в будь-якому сенсі, я просто хотів, щоб читачі усвідомлювали умови, що виникають таким чином, наприклад, це може заповнити число, пов’язане з вашим обліковим записом google тощо, згадане в коментарях.
humble_wolf

Я все ще віддаю перевагу тому, що написав. Вибачте
андроїд розробник

1

Невеликий внесок. У моєму випадку код запустив виняток з помилками. Мені потрібно поставити анотацію, що для запуску коду, і виправити цю проблему. Ось я пустив цей код.

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

0

Хоча можливо мати кілька облікових записів голосової пошти, коли дзвоните з власного номера, оператори направляють вас на голосову пошту. Отже, TelephonyManager.getVoiceMailNumber()або TelephonyManager.getCompleteVoiceMailNumber(), залежно від потрібного вам аромату.

Сподіваюсь, це допомагає.


5
немає функції "getCompleteVoiceMailNumber", плюс getVoiceMailNumber () повертає число, яке відрізняється від реального номера телефону.
андроїд розробник

Це хитрість, яка працює лише з парою мобільних операторів у світі. Але технічно це може бути вирішено.
технік

0

Додайте цю залежність: implementation '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)
        }
    }
}

-6

працюючи над додатком безпеки, який потребував отримання номера телефону того, хто міг би мій телефон потрапити до їхніх рук, мені довелося це зробити; 1. отримайте завантаження завершеним, а потім спробуйте отримати Line1_Number від telephonyManager, який повертає рядковий результат. 2. порівняйте результат String з моїм власним номером телефону, і якщо вони не збігаються або рядок не повертається до нуля, 3. таємно надішліть SMS, що містить результат рядка плюс спеціальний знак, на мій номер офісу. 4. якщо надсилання повідомлення не вдається, запустіть послугу та продовжуйте пробувати кожну годину, поки відправлений SMS у очікуванні наміру не буде успішним. Цими кроками я міг отримати номер людини, яка використовує мій загублений телефон. не має значення, якщо особа стягується.


чому низовики?
humble_wolf
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.