Obter programaticamente o número de telefone do telefone Android


443

Como posso obter programaticamente o número de telefone do dispositivo que está executando meu aplicativo Android?


isso não é possível, exceto se você o inserir sozinho. O número de telefone não é conhecido pelo celular ou do SIM, apenas pela rede ....
TomSoft

3
@tomsoft Pense bem ... Como aplicativos como o Facebook verificam automaticamente automaticamente seu número de telefone ..?
Eddie Hart

1
@tomsoft Não, na maioria das vezes nem pede o seu número de telefone ou, se o fizer, a caixa é pré-preenchida.
Eddie Hart

1
@tomsoft Bem, eu me inscrevi no Facebook outro dia, e ele não pediu meu número quando me enviou um código. Tente. ;)
Eddie Hart

1
@ EddieHart Faça isso também, e me perguntaram meu número de telefone. Portanto, este é confirmar que de um modo geral, isso não é acessível e alguns operadores poderia acrescentar esta informação sobre configuração, mas isso não é uma característica padrão GMS
TomSoft

Respostas:


484

Código:

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

Permissão necessária:

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

Ressalvas:

De acordo com os comentários altamente votados, há algumas ressalvas a serem observadas. Isso pode retornar nullou ""até mesmo "???????", e pode retornar um número de telefone obsoleto que não é mais válido. Se você deseja algo que identifique exclusivamente o dispositivo, use-o getDeviceId().


150
Na verdade, não é tão perfeito. Na última vez em que tentei esse método, ele relatou o número de telefone que meu telefone tinha originalmente, antes que meu antigo número de celular fosse portado para ele. Provavelmente ainda o faz, pois o aplicativo Configurações ainda mostra esse número extinto. Além disso, há relatos de que alguns SIMs fazem com que esse método retorne null. Dito isto, não estou ciente de uma resposta melhor.
CommonsWare

4
Mark está certo. Se a intenção de usar algo que identifique exclusivamente o telefone, eu usaria getDeviceId (), que retornará o IMEA para GSM.
Alex Volovoy

15
(Eu acho que você quer dizer IMEI ...?)
ChaimKut

23
Bem, eu testei no Nexus One com Android OS 2.2 e retorna null
Omar Rehman

43
Os desenvolvedores podem pensar que é a resposta perfeita considerando a contagem de votos. Uma nota deve ser adicionada para avisar o desenvolvedor que esse método não fornecerá o número de telefone sempre.
precisa saber é o seguinte

151

Não há solução garantida para esse problema porque o número de telefone não está fisicamente armazenado em todos os cartões SIM ou transmitido da rede para o telefone. Isso é especialmente verdadeiro em alguns países que exigem verificação de endereço físico, com a atribuição de números somente depois. A atribuição do número de telefone acontece na rede - e pode ser alterada sem a alteração do cartão ou dispositivo SIM (por exemplo, é assim que a porta é suportada).

Sei que é doloroso, mas provavelmente a melhor solução é pedir ao usuário para digitar seu número de telefone uma vez e armazená-lo.


18
Para verificar o número obtido, você pode enviar um sms (contendo um código) para o número e controlar a resposta colocando um ouvinte em "android.provider.Telephony.SMS_RECEIVED". dessa forma você pode ter certeza de que o número está correto e funcionando
Hossein Shahdoost

1
Solução criativa, mas convém que o usuário saiba que está fazendo isso, caso seja cobrado por isso.
Norman H

3
Existe algum provedor que cobra pelo recebimento de mensagens de texto simples ?!
ThiefMaster 29/03

9
Sim absolutamente. Antes de adicionar mensagens de texto ao meu plano, cobravam $ 0,30 por mensagem de texto recebida. Rogers no Canadá.
precisa saber é o seguinte

44

Atualização: esta resposta não está mais disponível, pois o Whatsapp parou de expor o número de telefone como nome da conta, desconsidere esta resposta.

Na verdade, você pode considerar uma solução alternativa, se não conseguir obtê-la através do serviço de telefonia.

A partir de hoje, você pode confiar em outro grande aplicativo WhatsApp, usando AccountManager. Milhões de dispositivos têm esse aplicativo instalado e, se você não conseguir obter o número de telefone TelephonyManager, poderá tentar.

Permissão:

<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 actypea conta do WhatsApp

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

Claro que você pode não conseguir se o usuário não instalou o WhatsApp, mas vale a pena tentar de qualquer maneira. E lembre-se de que você deve sempre pedir confirmação ao usuário.


1
Acabei de ver isso hoje, quando estava mexendo com contas. É muito ruim que o número seja exposto assim. Obviamente, você precisa da permissão GET_ACCOUNTS e, nesse ponto, o usuário provavelmente não se importa com as permissões que o aplicativo possui.
jargetz

9
Esta solução está desatualizada, o Whatsapp não salva mais o número de telefone no nome da conta, você sabe onde o WhatsApp salvou o número de telefone após a nova atualização?
Cohelad

@Cohelad obrigado por me atualizar, eu vou ter uma verificação mais tarde e atravessar esta resposta após a confirmação, enquanto isso eu não tenho nenhuma idéia de onde eles guardar o número
Chor Wai Chun

3
Mas o Viber EXPOSE o número! com.viber.voip.account
xnagyg 12/01

32

Conforme publicado na minha resposta anterior

Use o código abaixo:

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

No AndroidManifest.xml, dê a seguinte permissão:

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

Mas lembre-se, esse código nem sempre funciona, pois o número do celular depende do cartão SIM e da operadora de rede / operadora de celular.

Além disso, tente verificar Telefone -> Configurações -> Sobre -> Identidade do telefone . Se você conseguir visualizar o número lá, a probabilidade de obter o número de telefone do código acima é maior. Se você não conseguir visualizar o número de telefone nas configurações, não poderá obter esse código!

Solução sugerida:

  1. Obtenha o número de telefone do usuário como entrada manual do usuário.
  2. Envie um código para o número de celular do usuário via SMS.
  3. Peça ao usuário para digitar o código para confirmar o número de telefone.
  4. Salve o número na preferência compartilhada.

Execute as 4 etapas acima como uma atividade única durante o primeiro lançamento do aplicativo. Posteriormente, sempre que for necessário um número de telefone, use o valor disponível na preferência compartilhada.


Esta resposta abrange todos os fatores, ele deve ser o único aceite =)
Slava Fomin II

Como posso obter o número de celular se houver um dual sim disponível no telefone. com o código acima. Para único sim seu bom trabalho
Amrit Chakradhari

26

É assim que você solicita um número de telefone por meio da API do Play Services sem a permissão e os hacks. Fonte e exemplo completo .

No seu build.gradle (versão 10.2.xe superior):

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

Na sua atividade (o código é 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;
    }
}

Isso irá gerar um diálogo como este:

insira a descrição da imagem aqui


2
Solicitação de dica mostra o número de telefone da conta de e-mail conectada ao telefone, ele exibirá a lista suspensa mesmo se não houver um sim no dispositivo.
Ari

como a caixa de diálogo mostra vários números enquanto existe apenas um SIM? Para mim, mostra 5 números. : / :)
cgr 23/08/19

como podemos selecionar o primeiro número de telefone automaticamente no android?
Noorul 11/02

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 extraído de http://www.androidsnippets.com/get-my-phone-number


@JaredBurrows por causa de "s.substring (2)".
Cookie Monster

1
Não está funcionando para mim. Recebo um valor NULL (nascer do sol, cartão SIM, Suíça)
e-nature

seu link está quebrado.
Umang ßürmån

11

Existe uma nova API do Android que permite ao usuário selecionar seu número de telefone sem a necessidade de permissão. Dê uma olhada em: 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);
} 

Isso requer Firebase
Vlad

@ Vlad Não, não. Isso requer apenas o Google Play Services, que é fornecido com a maioria dos dispositivos. Cite no blog: 'Antes de começar, você precisará criar e testar este é um dispositivo com um número de telefone que pode receber SMS e executar os serviços do Google Play 10.2.xe superior.'
Wirling

9

Só quero adicionar um pouco aqui às explicações acima nas respostas acima. O que economizará tempo para os outros também.

No meu caso, esse método não retornou nenhum número de celular, uma string vazia foi retornada. Foi devido ao caso que eu tinha portado meu número no novo sim. Portanto, se eu entrar em Configurações> Sobre o telefone> Status> Meu número de telefone, ele me mostrará "Desconhecido".


A minha também, qual é essa condição? Roaming? Ou talvez o simcard simplesmente não tenha o número armazenado nele.
Alexandre Marcondes

8

Às vezes, o código abaixo retorna nullou string em branco.

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

Com permissão abaixo

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

Existe outra maneira de obter seu número de telefone. Eu não testei isso em vários dispositivos, mas o código acima não funciona sempre.

Experimente o código abaixo:

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

Você precisará adicionar essas duas permissões.

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

Espero que isso ajude, obrigado!


Eu poderia, por favor, perguntar: no segundo trecho, qual é o número da célula?
iOSAndroidWindowsMobileAppsDev

1
O valor de String s1será o número de telefone.
activesince93

Este código não está funcionando para mim. (Seu último trecho de código). Retorna uma string vazia.
perfil completo de Kristy Welsh

Por favor, explique sua resposta. Onde o número está armazenado e como ele contém o número? Depende do que?
not2qubit

3
@ not2qubit Eu acho que está acessando o auto contato no aplicativo Contatos
Samplasion

4

Esta é uma resposta mais simplificada:

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

3

Em primeiro lugar, obter o número de celular dos usuários é contra a política ética, antes era possível, mas agora, de acordo com minha pesquisa, não há uma solução sólida disponível para isso. Ao usar algum código, é possível obter o número de celular, mas não há garantia de que funcione. apenas em alguns dispositivos. Após muita pesquisa, encontrei apenas três soluções, mas elas não estão funcionando em todos os dispositivos.

Existe a seguinte razão pela qual não estamos recebendo.

1.O dispositivo Android e o novo cartão SIM não armazenam número de celular se o número do celular não estiver disponível no dispositivo e no sim, como é possível obter o número, se algum cartão SIM antigo tiver número de celular e usar o gerenciador de telefonia, podemos obter o número outro sábio, ele retornará o "nulo" ou "" ou "??????"

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

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

Nota: - Testei esta solução nos seguintes dispositivos Moto x, Samsung Tab 4, Samsung S4, Nexus 5 e Redmi 2 prime, mas não funciona toda vez que retorna uma string vazia, portanto, a conclusão é inútil

  1. Esse método está funcionando apenas no Redmi 2 prime, mas para isso é necessário adicionar a permissão de contato de leitura no manifesto.

Nota: - Esta também não é a solução garantida e eficiente; testei esta solução em muitos dispositivos, mas funcionou apenas no Redmi 2 prime, que é um dispositivo dual sim, me dá dois números de celular, o primeiro está correto, mas o segundo não. pertencem ao meu segundo sim, pertencem ao meu cartão sim antigo, que não estou 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. Na minha pesquisa, descobri anteriormente que era possível obter o número de celular usando a conta do WhatsApp, mas agora a nova versão do WhatsApp não armazena o número de celular do usuário.

Conclusão : - O Android não possui solução garantida para obter o número de celular do usuário programaticamente.

Sugestão : - 1. Se você deseja verificar o número de celular do usuário, peça ao usuário que forneça o número dele, usando otp, você pode verificar isso.

  1. Se você deseja identificar o dispositivo do usuário, para isso, pode obter facilmente o número IMEI do dispositivo.

2

TelephonyManagernão é a solução certa, porque em alguns casos o número não é armazenado no SIM. Sugiro que você use a preferência compartilhada para armazenar o número de telefone do usuário pela primeira vez que o aplicativo estiver aberto e o número será usado sempre que você precisar.


1
Mas esse método é propenso a erros. O usuário pode digitar o número errado.
precisa

3
Sim assim para esta finalidade eu usei uma mensagem de texto, quando o usuário digite um número, então a partir SMSManager a própria mensagem aplicativo, e através deste podemos usar smsReciever obter o número original
Naveed Ahmad

1
Tenho mais uma pergunta .. com esse método, haverá uma cobrança de SMS fornecida pelo usuário (se não for um número gratuito) .. Existe algum outro método que eu possa obter pelo telefone do usuário?
precisa

Sim, é claro que haverá alguma cobrança nesse SMS se o número não for gratuito.
Naveed Ahmad

Acho que não existe esse método sem o TelephonyManager até agora. e aponto o problema do TelephoneManager na minha resposta.
Naveed Ahmad

2

Aqui está uma combinação das soluções que encontrei (exemplo de projeto aqui , se você também quiser verificar o preenchimento automático):

manifesto

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

pl veja os comentários nesta resposta stackoverflow.com/a/48210130/5457916 , antes de implementar esse método
humble_wolf

O link que você forneceu é apenas uma parte do que eu fiz aqui. Aqui, tentei primeiro preenchê-lo sozinho. E tenha um substituto para isso.
desenvolvedor android

Eu sei, senhor, sua resposta é ótima e não está incorreta em nenhum sentido, eu só queria que os leitores estivessem cientes das condições que acompanham esse caminho. Por exemplo, isso pode preencher o número associado à sua conta do Google, etc. mencionado nos comentários.
humble_wolf 20/04

Eu ainda prefiro o que escrevi. Desculpe
desenvolvedor android

1

Uma pequena contribuição. No meu caso, o código lançou uma exceção de erro. Eu precisava colocar uma anotação para que o código fosse executado e corrija esse problema. Aqui deixo esse 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

Embora seja possível ter várias contas de correio de voz, ao ligar a partir do seu próprio número, as operadoras o encaminham para o correio de voz. Então, TelephonyManager.getVoiceMailNumber()ou TelephonyManager.getCompleteVoiceMailNumber(), dependendo do sabor que você precisa.

Espero que isto ajude.


5
não há função "getCompleteVoiceMailNumber", além de getVoiceMailNumber () retorna um número diferente do número real do telefone.
desenvolvedor android

Esse é um truque que funciona apenas com algumas operadoras de celular do mundo. Mas tecnicamente pode ser uma solução alternativa.
Technik

0

Adicione esta dependência: implementation 'com.google.android.gms:play-services-auth:18.0.0'

Para buscar a lista de números de telefone, use este:

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
)

Depois de tocar na caixa de diálogo "play services":

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

enquanto trabalhava em um aplicativo de segurança que precisava obter o número de telefone de quem quer que meu telefone estivesse em suas mãos, eu tive que fazer isso; 1. receba a inicialização concluída e tente obter o Line1_Number do telephonyManager, que retorna um resultado de sequência. 2. compare o resultado da String com o meu próprio número de telefone e, se eles não corresponderem ou retornarem nulos, 3. envie secretamente um SMS contendo o resultado da string, além de um sinal especial para o número do meu escritório. 4. Se o envio da mensagem falhar, inicie um serviço e continue tentando após cada hora até que a intenção pendente do SMS enviado retorne com êxito. Com essas etapas, eu poderia obter o número da pessoa usando meu telefone perdido. não importa se a pessoa é cobrada.


por que votos negativos?
humble_wolf 20/04
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.