Obtenga programáticamente el número de teléfono del teléfono Android


443

¿Cómo puedo obtener programáticamente el número de teléfono del dispositivo que ejecuta mi aplicación de Android?


esto no es posible, excepto si lo ingresa usted mismo. El número de teléfono no se conoce por el móvil o la SIM, solo por la red ...
tomsoft

3
@tomsoft Piénselo ... ¿Cómo verifican automáticamente su número de teléfono aplicaciones como Facebook?
Eddie Hart

1
@tomsoft No, la mayoría de las veces ni siquiera pide su número de teléfono, o si lo hace, la casilla está precargada.
Eddie Hart

1
@tomsoft Bueno, me inscribí en Facebook el otro día, y no me pidió mi número cuando me envió un código de texto. Intentalo. ;)
Eddie Hart

1
@EddieHart Hazlo también, y me han preguntado mi número de teléfono. Así que esto es confirmar que, en general, esto no es accesible y algunos operadores podría agregar esta información sobre la configuración, pero esto no es una característica estándar GMS
tomsoft

Respuestas:


484

Código:

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

Permiso requerido:

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

Advertencias:

De acuerdo con los comentarios altamente votados, hay algunas advertencias a tener en cuenta. Esto puede devolver nullo ""incluso "???????", y puede devolver un número de teléfono obsoleto que ya no es válido. Si desea algo que identifique de forma exclusiva el dispositivo, debe usarlo getDeviceId()en su lugar.


150
En realidad, no tan perfecto. La última vez que probé este método, informó el número de teléfono que tenía originalmente mi teléfono, antes de que mi antiguo número de teléfono móvil fuera transferido a él. Probablemente todavía lo haga, ya que la aplicación Configuración todavía muestra ese número desaparecido. Además, hay informes de que algunas SIM hacen que este método regrese null. Dicho esto, no estoy al tanto de una mejor respuesta.
CommonsWare

44
Mark tiene razón. Si la intención de usar algo que identifique de manera única el teléfono, usaría getDeviceId () que devolverá IMEA para GSM.
Alex Volovoy

15
(Creo que te refieres a IMEI ...?)
ChaimKut

23
Bueno, lo probé en Nexus One con Android OS 2.2 y devuelve nulo
Omar Rehman

43
Los desarrolladores pueden pensar que es la respuesta perfecta al considerar el recuento de votos. Se debe agregar una nota para advertir al desarrollador que este método no siempre dará un número de teléfono.
Habeeb Perwad

151

No hay una solución garantizada para este problema porque el número de teléfono no se almacena físicamente en todas las tarjetas SIM, ni se transmite desde la red al teléfono. Esto es especialmente cierto en algunos países que requieren la verificación de la dirección física, con la asignación de números solo después. La asignación del número de teléfono ocurre en la red, y se puede cambiar sin cambiar la tarjeta SIM o el dispositivo (por ejemplo, así es como se admite la transferencia).

Sé que es doloroso, pero lo más probable es que la mejor solución sea pedirle al usuario que ingrese su número de teléfono una vez y lo almacene.


18
Para verificar el número tomado, puede enviar un sms (que contiene un código) al número y controlar la respuesta poniendo un oyente en "android.provider.Telephony.SMS_RECEIVED". de esa manera puedes asegurarte de que el número sea correcto y que funcione
Hossein Shahdoost

1
Solución creativa, pero es posible que desee informar al usuario que lo está haciendo en caso de que se le cobre por ello.
Norman H

3
¿Hay algún proveedor que cobre por recibir mensajes de texto simples?
ThiefMaster

99
Si, absolutamente. Antes de agregar mensajes de texto a mi plan, me cobraron $ 0.30 por mensaje de texto recibido. Rogers en Canadá.
John Kroetch

44

Actualización: esta respuesta ya no está disponible ya que Whatsapp dejó de exponer el número de teléfono como nombre de cuenta, ignore esta respuesta.

En realidad, es posible que desee considerar una solución alternativa si no puede obtenerla a través del servicio de telefonía.

A partir de hoy, puede confiar en otra gran aplicación Whatsapp, utilizando AccountManager. Millones de dispositivos tienen instalada esta aplicación y, si no puede obtener el número de teléfono, puede intentarlo TelephonyManager.

Permiso:

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

Código:

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

Verifique la actypecuenta de WhatsApp

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

Por supuesto, es posible que no lo obtenga si el usuario no instaló WhatsApp, pero vale la pena intentarlo de todos modos. Y recuerde que siempre debe pedirle confirmación al usuario.


1
Acabo de ver esto hoy cuando estaba jugando con las cuentas. Es bastante malo que el número se exponga así. Por supuesto, necesita el permiso GET_ACCOUNTS y ​​en ese momento al usuario probablemente no le importa qué permisos tiene la aplicación.
jargetz

99
Esta solución está desactualizada, Whatsapp ya no guarda el número de teléfono en el nombre de la cuenta, ¿sabe dónde guardar Whatsapp después de la nueva actualización?
Cohelad

@Cohelad, gracias por actualizarme, revisaré más tarde y tacharé esta respuesta después de la confirmación, mientras tanto, no tengo idea de dónde guardan el número
Chor Wai Chun

3
¡Pero Viber EXPONE el número! com.viber.voip.account
xnagyg

32

Como publicado en mi respuesta anterior

Use el siguiente código:

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

En AndroidManifest.xml, otorgue el siguiente permiso:

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

Pero recuerde, este código no siempre funciona, ya que el número de teléfono celular depende de la tarjeta SIM y del operador de red / operador de telefonía celular.

Además, intente verificar en Teléfono -> Configuración -> Acerca de -> Identidad del teléfono , si puede ver el Número allí, la probabilidad de obtener el número de teléfono del código anterior es mayor. Si no puede ver el número de teléfono en la configuración, ¡no podrá obtenerlo a través de este código!

Solución sugerida:

  1. Obtenga el número de teléfono del usuario como entrada manual del usuario.
  2. Envíe un código al número móvil del usuario por SMS.
  3. Solicite al usuario que ingrese el código para confirmar el número de teléfono.
  4. Guarde el número en preferencia compartida.

Realice los 4 pasos anteriores como actividad única durante el primer inicio de la aplicación. Más adelante, cuando se requiera un número de teléfono, use el valor disponible en preferencia compartida.


Esta respuesta cubre todos los factores, debería ser la aceptada =)
Slava Fomin II

¿Cómo puedo obtener el número de teléfono móvil si hay un doble sim disponible en el teléfono? con el código anterior Para un solo sim funciona bien
Amrit Chakradhari

26

Así es como solicitas un número de teléfono a través de la API de Play Services sin el permiso y los hacks. Fuente y ejemplo completo .

En su build.gradle (se requiere la versión 10.2.xy superior):

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

En su actividad (el código está simplificado):

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

Esto generará un diálogo como este:

ingrese la descripción de la imagen aquí


2
Sugerencia de solicitud muestra el número de teléfono de la cuenta de correo electrónico conectada con el teléfono, aparecerá el menú desplegable incluso si no hay sim en el dispositivo.
Ari

¿Cómo muestra el diálogo varios números mientras solo hay una SIM? Para mí, muestra 5 números. : / :)
cgr

¿Cómo podemos seleccionar el primer número de teléfono automáticamente en 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;
}

Código tomado de http://www.androidsnippets.com/get-my-phone-number


@JaredBurrows debido a "s.substring (2)".
Cookie Monster

1
No está funcionando para mi. Obtengo un valor NULO (tarjeta SIM Sunrise, Suiza)
e-nature

Tu enlace está roto.
Ümañg ßürmån

11

Hay una nueva API de Android que permite al usuario seleccionar su número de teléfono sin la necesidad de un permiso. Echa un vistazo a: 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);
} 

Esto requiere Firebase
Vlad

@Vlad No, no lo hace. Esto solo requiere los servicios de Google Play que vienen con la mayoría de los dispositivos. Cita de la publicación del blog: "Antes de comenzar, deberá construir y probar este es un dispositivo con un número de teléfono que puede recibir SMS y ejecuta los servicios de Google Play 10.2.xy superior".
Wirling

9

Solo quiero agregar un poco aquí a las explicaciones anteriores en las respuestas anteriores. Lo que también ahorrará tiempo para los demás.

En mi caso, este método no devolvió ningún número de móvil, se devolvió una cadena vacía. Fue debido al caso de que había portado mi número en el nuevo sim. Entonces, si entro en Configuración> Acerca del teléfono> Estado> Mi número de teléfono, me muestra "Desconocido".


La mía también, ¿cuál es esta condición? ¿Itinerancia? O tal vez la tarjeta SIM simplemente no tiene el número almacenado en ella.
Alexandre Marcondes

8

A veces, debajo del código devuelve nullo cadena en blanco.

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

Con el siguiente permiso

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

Hay otra manera de que pueda obtener su número de teléfono, no lo he probado en varios dispositivos, pero el código anterior no funciona todo el tiempo.

Pruebe el siguiente código:

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

Deberá agregar estos dos permisos.

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

Espero que esto ayude, ¡Gracias!


¿Podría preguntar: en el segundo fragmento, cuál es el número de celda?
iOSAndroidWindowsMobileAppsDev

1
El valor de String s1será el número de teléfono.
activesin9393

Este código no me funciona. (Su último fragmento de código). Devuelve una cadena vacía.
Kristy Welsh

Por favor explique su respuesta. ¿Dónde se almacena el número y cómo contiene este número? Depende de qué?
not2qubit

3
@ not2qubit Creo que está accediendo al autocontacto en la aplicación Contactos
Samplasion

4

Esta es una respuesta más simplificada:

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

3

En primer lugar, obtener el número de teléfono móvil de los usuarios va en contra de la política ética, antes era posible, pero ahora, según mi investigación, no hay una solución sólida disponible para esto. Al usar algún código, es posible obtener el número de teléfono móvil, pero no hay garantía de que funcione. solo en pocos dispositivos. Después de mucha investigación, encontré solo tres soluciones, pero no funcionan en todos los dispositivos.

Hay la siguiente razón por la que no estamos recibiendo.

1.El dispositivo Android y la nueva tarjeta Sim no almacenan el número de teléfono móvil si el número de teléfono móvil no está disponible en el dispositivo y en la tarjeta SIM, entonces, ¿cómo es posible obtener el número? sabio devolverá el "nulo" o "" o "??????"

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

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

Nota: He probado esta solución en el siguiente dispositivo Moto x, Samsung Tab 4, Samsung S4, Nexus 5 y Redmi 2 prime, pero no funciona cada vez que devuelve una cadena vacía, por lo que la conclusión es inútil.

  1. Este método solo funciona en Redmi 2 prime, pero para esto es necesario agregar permiso de contacto de lectura en el manifiesto.

Nota: - Esta tampoco es la solución garantizada y eficiente, he probado esta solución en muchos dispositivos, pero funcionó solo en Redmi 2 prime, que es un dispositivo dual sim, me da dos números móviles, el primero es correcto pero el segundo no. pertenece a mi segundo sim, pertenece a mi antigua tarjeta sim que no estoy usando.

 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. En mi investigación, descubrí que antes era posible obtener un número de teléfono móvil usando la cuenta de WhatsApp, pero ahora la nueva versión de Whatsapp no ​​almacena el número de teléfono móvil del usuario.

Conclusión : - Android no tiene ninguna solución garantizada para obtener el número de teléfono móvil del usuario mediante programación.

Sugerencia : - 1. Si desea verificar el número de teléfono móvil del usuario, solicite al usuario que proporcione su número, utilizando otp puede verificarlo.

  1. Si desea identificar el dispositivo del usuario, para esto puede obtener fácilmente el número IMEI del dispositivo.

2

TelephonyManagerno es la solución correcta, porque en algunos casos el número no se almacena en la SIM. Le sugiero que use la preferencia compartida para almacenar el número de teléfono del usuario por primera vez que la aplicación esté abierta y el número se usará cuando lo necesite.


1
Pero este método es propenso a errores. El usuario puede ingresar un número incorrecto.
Zohra Khan

3
sí, para este propósito utilicé un mensaje de texto, cuando el usuario ingresó un número, de SmsManager, el mensaje de la aplicación en sí, y a través de esto podemos usar smsReciever para obtener el número original
Naveed Ahmad

1
Tengo una pregunta más ... con este método habrá un cargo por SMS dado por el usuario (si no es un número gratuito) ... ¿Hay algún otro método que pueda obtener el teléfono del usuario?
Zohra Khan

Sí, por supuesto, habrá algún cargo en ese SMS si el número no es un número gratuito.
Naveed Ahmad

No, creo que no hay tal método sin TelephonyManager hasta ahora. y señalo el problema de TelephoneManager en mi respuesta.
Naveed Ahmad

2

Aquí hay una combinación de las soluciones que he encontrado (proyecto de muestra aquí , si desea verificar también el autocompletado):

manifiesto

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

por favor vea los comentarios sobre esta respuesta stackoverflow.com/a/48210130/5457916 , antes de implementar este método
humble_wolf

El enlace que ha proporcionado es solo una parte de lo que hice aquí. Aquí, primero intenté rellenarlo yo mismo. Y tener respaldo para esto.
Desarrollador de Android

Lo sé señor, su respuesta es excelente y no es incorrecta en ningún sentido, solo quería que los lectores conocieran las condiciones que se presentan de esta manera, por ejemplo, esto puede completar el número asociado con su cuenta de Google, etc. mencionado en los comentarios allí.
humble_wolf

Todavía prefiero lo que escribí. Lo sentimos
desarrollador de Android

1

Un pequeño aporte. En mi caso, el código lanzó una excepción de error. Necesito poner una anotación para que se ejecute el código y solucionar ese problema. Aquí dejo este código.

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

0

Aunque es posible tener varias cuentas de correo de voz, cuando llama desde su propio número, los operadores lo enrutan al correo de voz. Entonces, TelephonyManager.getVoiceMailNumber()o TelephonyManager.getCompleteVoiceMailNumber(), dependiendo del sabor que necesites.

Espero que esto ayude.


55
no existe la función "getCompleteVoiceMailNumber", además de getVoiceMailNumber () devuelve un número que es diferente del número real del teléfono.
Desarrollador de Android el

Este es un truco que solo funciona con un par de operadores móviles en el mundo. Pero técnicamente podría ser una solución alternativa.
technik

0

Agregue esta dependencia: implementation 'com.google.android.gms:play-services-auth:18.0.0'

Para buscar la lista de números de teléfono, use esto:

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
)

Después de tocar en el cuadro de diálogo de servicios de reproducción:

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

mientras trabajaba en una aplicación de seguridad que necesitaba obtener el número de teléfono de quién podría tener mi teléfono en mis manos, tuve que hacer esto; 1. reciba el inicio completado y luego intente obtener Line1_Number de telephonyManager que devuelve un resultado de cadena. 2. comparar el resultado de la Cadena con mi propio número de teléfono y si no coinciden o si la cadena devuelve un valor nulo, 3. enviar secretamente un SMS que contenga el resultado de la cadena más un signo especial al número de mi oficina. 4. si falla el envío del mensaje, inicie un servicio y siga intentándolo después de cada hora hasta que el intento de envío de SMS pendiente vuelva con éxito. Con estos pasos podría obtener el número de la persona que usa mi teléfono perdido. No importa si la persona está acusada.


¿Por qué votos negativos?
humble_wolf
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.