Come posso ottenere a livello di codice il numero di telefono del dispositivo che esegue la mia app Android?
Come posso ottenere a livello di codice il numero di telefono del dispositivo che esegue la mia app Android?
Risposte:
Codice:
TelephonyManager tMgr = (TelephonyManager)mAppContext.getSystemService(Context.TELEPHONY_SERVICE);
String mPhoneNumber = tMgr.getLine1Number();
Autorizzazione richiesta:
<uses-permission android:name="android.permission.READ_PHONE_STATE"/>
Secondo i commenti altamente votati, ci sono alcuni avvertimenti di cui essere consapevoli. Questo può restituire null
o ""
o anche "???????"
e può restituire un numero di telefono non aggiornato che non è più valido. Se vuoi qualcosa che identifichi in modo univoco il dispositivo, dovresti getDeviceId()
invece utilizzare .
null
. Detto questo, non sono a conoscenza di una risposta migliore.
Non esiste una soluzione garantita a questo problema perché il numero di telefono non viene archiviato fisicamente su tutte le schede SIM o trasmesso dalla rete al telefono. Ciò è particolarmente vero in alcuni paesi che richiedono la verifica dell'indirizzo fisico, con l'assegnazione dei numeri solo dopo. L'assegnazione del numero di telefono avviene sulla rete e può essere modificata senza cambiare la scheda SIM o il dispositivo (ad esempio, in questo modo è supportato il porting).
So che è un dolore, ma molto probabilmente la soluzione migliore è semplicemente chiedere all'utente di inserire il proprio numero di telefono una volta e memorizzarlo.
Esiste in realtà una soluzione alternativa che potresti prendere in considerazione, se non riesci a ottenerla tramite il servizio di telefonia.
Ad oggi, puoi fare affidamento su un'altra grande applicazione Whatsapp, utilizzando AccountManager
. Milioni di dispositivi hanno installato questa applicazione e se non riesci a ottenere il numero di telefono tramite TelephonyManager
, puoi provarlo.
Autorizzazione:
<uses-permission android:name="android.permission.GET_ACCOUNTS" />
Codice:
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);
}
Controlla l' actype
account WhatsApp
if(actype.equals("com.whatsapp")){
String phoneNumber = ac.name;
}
Ovviamente potresti non ottenerlo se l'utente non ha installato WhatsApp, ma vale comunque la pena provare. E ricorda che dovresti sempre chiedere conferma all'utente.
Come pubblicato nella mia precedente risposta
Usa sotto il codice:
TelephonyManager tMgr = (TelephonyManager)mAppContext.getSystemService(Context.TELEPHONY_SERVICE);
String mPhoneNumber = tMgr.getLine1Number();
In AndroidManifest.xml, concedere le seguenti autorizzazioni:
<uses-permission android:name="android.permission.READ_PHONE_STATE"/>
Ma ricorda, questo codice non funziona sempre, poiché il numero di cellulare dipende dalla carta SIM e dall'operatore di rete / gestore di telefonia cellulare.
Inoltre, prova a controllare in Telefono -> Impostazioni -> Informazioni -> Identità telefono , se riesci a visualizzare il numero lì, la probabilità di ottenere il numero di telefono dal codice sopra è più alta. Se non riesci a visualizzare il numero di telefono nelle impostazioni, non sarai in grado di ottenere tramite questo codice!
Soluzione suggerita:
Esegui i 4 passaggi precedenti come attività unica durante il primo avvio dell'app. Successivamente, ogni volta che è richiesto il numero di telefono, utilizzare il valore disponibile nelle preferenze condivise.
Quindi è così che richiedi un numero di telefono tramite l'API di Play Services senza l'autorizzazione e gli hack. Fonte e esempio completo .
Nel tuo build.gradle (versione 10.2.x e successive necessarie):
compile "com.google.android.gms:play-services-auth:$gms_version"
Nella tua attività (il codice è semplificato):
@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;
}
}
Questo genererà una finestra di dialogo come questa:
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;
}
Codice tratto da http://www.androidsnippets.com/get-my-phone-number
C'è una nuova API Android che consente all'utente di selezionare il proprio numero di telefono senza la necessità di un'autorizzazione. Dai un'occhiata 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);
}
Voglio solo aggiungere un po 'qui alle spiegazioni sopra nelle risposte sopra. Ciò farà risparmiare tempo anche agli altri.
Nel mio caso questo metodo non ha restituito alcun numero di cellulare, è stata restituita una stringa vuota. È stato a causa del caso che avevo portato il mio numero sulla nuova sim. Quindi, se vado in Impostazioni> Informazioni sul telefono> Stato> Il mio numero di telefono mi mostra "Sconosciuto".
A volte, sotto il codice restituisce null
o stringa vuota.
TelephonyManager tMgr = (TelephonyManager)mAppContext.getSystemService(Context.TELEPHONY_SERVICE);
String mPhoneNumber = tMgr.getLine1Number();
Con il permesso seguente
<uses-permission android:name="android.permission.READ_PHONE_STATE"/>
C'è un altro modo in cui sarai in grado di ottenere il tuo numero di telefono, non l'ho testato su più dispositivi ma il codice sopra non funziona ogni volta.
Prova sotto il codice:
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();
}
Dovrai aggiungere queste due autorizzazioni.
<uses-permission android:name="android.permission.READ_CONTACTS" />
<uses-permission android:name="android.permission.READ_PROFILE" />
Spero che questo ti aiuti, grazie!
String s1
sarà il numero di telefono.
Innanzitutto ottenere il numero di cellulare degli utenti è contro la politica etica, prima era possibile, ma ora secondo la mia ricerca non esiste una soluzione solida disponibile per questo, Usando un po 'di codice è possibile ottenere il numero di cellulare ma nessuna garanzia potrebbe essere che funzionerà solo in pochi dispositivi. Dopo molte ricerche ho trovato solo tre soluzioni ma non funzionano su tutti i dispositivi.
C'è il seguente motivo per cui non stiamo ottenendo.
1.Il dispositivo Android e la nuova scheda SIM non memorizzano il numero di cellulare se il numero di cellulare non è disponibile nel dispositivo e nella sim, quindi come è possibile ottenere il numero, se qualsiasi vecchia scheda SIM con numero di cellulare quindi utilizza il gestore della telefonia, possiamo ottenere il numero altro saggio restituirà il "null" o "" o "??????"
<uses-permission android:name="android.permission.READ_PHONE_STATE"/>
TelephonyManager tel= (TelephonyManager)this.getSystemService(Context.
TELEPHONY_SERVICE);
String PhoneNumber = tel.getLine1Number();
Nota: - Ho testato questa soluzione nel seguente dispositivo Moto x, Samsung Tab 4, Samsung S4, Nexus 5 e Redmi 2 prime ma non funziona ogni volta che restituisce una stringa vuota, quindi la conclusione è inutile
Nota: - Questa non è anche la soluzione garantita ed efficiente, ho testato questa soluzione su molti dispositivi ma ha funzionato solo in Redmi 2 prime che è un dispositivo dual sim che mi dà due numeri di cellulare il primo è corretto ma il secondo no appartiene alla mia seconda sim appartiene alla mia vecchia sim card che non sto 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();
}
Conclusione : - Android non ha alcuna soluzione garantita per ottenere il numero di cellulare dell'utente a livello di codice.
Suggerimento : - 1. Se desideri verificare il numero di cellulare dell'utente, chiedi all'utente di fornire il suo numero, utilizzando otp puoi verificarlo.
- Se si desidera identificare il dispositivo dell'utente, è possibile ottenere facilmente il numero IMEI del dispositivo.
TelephonyManager
non è la soluzione giusta, perché in alcuni casi il numero non è memorizzato nella SIM. Ti suggerisco di usare la preferenza condivisa per memorizzare il numero di telefono dell'utente per la prima volta che l'applicazione è aperta e il numero verrà utilizzato ogni volta che ti serve.
Ecco una combinazione delle soluzioni che ho trovato (esempio di progetto qui , se si desidera controllare anche il riempimento automatico):
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 ""
}
}
}
Un piccolo contributo. Nel mio caso, il codice ha lanciato un'eccezione di errore. Ho dovuto mettere un'annotazione che per l'esecuzione del codice e risolvere il problema. Qui ho lasciato questo codice.
public static String getLineNumberPhone(Context scenario) {
TelephonyManager tMgr = (TelephonyManager) scenario.getSystemService(Context.TELEPHONY_SERVICE);
@SuppressLint("MissingPermission") String mPhoneNumber = tMgr.getLine1Number();
return mPhoneNumber;
}
Sebbene sia possibile avere più account Voicemail, quando si chiama dal proprio numero, i gestori indirizzano l'utente alla Voicemail. Quindi, TelephonyManager.getVoiceMailNumber()
oTelephonyManager.getCompleteVoiceMailNumber()
, a seconda del sapore di cui hai bisogno.
Spero che sia di aiuto.
Aggiungi questa dipendenza:
implementation 'com.google.android.gms:play-services-auth:18.0.0'
Per recuperare l'elenco dei numeri di telefono, utilizzare questo:
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
)
Dopo aver toccato la finestra di dialogo dei servizi di riproduzione:
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)
}
}
}
mentre lavoravo su un'app di sicurezza che aveva bisogno di ottenere il numero di telefono di chi mai il mio telefono potesse avere nelle loro mani, ho dovuto farlo; 1. ricevere l'avvio completato e quindi provare a ottenere Line1_Number da telephonyManager che restituisce un risultato stringa. 2. confronta il risultato della stringa con il mio numero di telefono e se non corrispondono o la stringa restituisce null allora, 3. invia segretamente un SMS contenente il risultato della stringa più un segno speciale al mio numero di ufficio. 4. se l'invio del messaggio fallisce, avviare un servizio e continuare a provare dopo ogni ora fino a quando l'SMS in attesa non restituisce l'intento con successo. Con questi passaggi ho potuto ottenere il numero della persona che utilizza il mio telefono perso. non importa se la persona è accusata.