Как программно получить номер телефона устройства, на котором запущено мое приложение для Android?
Как программно получить номер телефона устройства, на котором запущено мое приложение для Android?
Ответы:
Код:
TelephonyManager tMgr = (TelephonyManager)mAppContext.getSystemService(Context.TELEPHONY_SERVICE);
String mPhoneNumber = tMgr.getLine1Number();
Требуемое разрешение:
<uses-permission android:name="android.permission.READ_PHONE_STATE"/>
Согласно высоко голосуемым комментариям, есть несколько предостережений, о которых нужно знать. Это может вернуть null
или ""
даже "???????"
, и это может вернуть устаревший номер телефона, который больше не действителен. Если вы хотите что-то, что однозначно идентифицирует устройство, вы должны использовать getDeviceId()
вместо этого.
null
. При этом, я не знаю лучшего ответа.
Гарантированного решения этой проблемы не существует, поскольку номер телефона физически не хранится на всех SIM-картах и не транслируется из сети на телефон. Это особенно верно в некоторых странах, где требуется проверка физического адреса, причем назначение номера происходит только после этого. Назначение номера телефона происходит в сети и может быть изменено без замены SIM-карты или устройства (например, поддерживается портирование).
Я знаю, что это боль, но, скорее всего, лучшее решение - просто попросить пользователя ввести свой номер телефона и сохранить его.
На самом деле есть альтернативное решение, которое вы можете рассмотреть, если вы не можете получить его через службу телефонии.
На сегодняшний день вы можете положиться на другое большое приложение, которое использует 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, но в любом случае стоит попробовать. И помните, что вы всегда должны спрашивать у пользователя подтверждение.
Как написано в моем предыдущем ответе
Используйте код ниже:
TelephonyManager tMgr = (TelephonyManager)mAppContext.getSystemService(Context.TELEPHONY_SERVICE);
String mPhoneNumber = tMgr.getLine1Number();
В AndroidManifest.xml дайте следующее разрешение:
<uses-permission android:name="android.permission.READ_PHONE_STATE"/>
Но помните, этот код не всегда работает, так как номер мобильного телефона зависит от SIM-карты и оператора сети / оператора сотовой связи.
Также попробуйте проверить в « Телефон» -> «Настройки» -> «О программе» -> «Идентификация телефона». Если вы можете просмотреть номер там, вероятность получения номера телефона по указанному выше коду выше. Если вы не можете просмотреть номер телефона в настройках, вы не сможете получить через этот код!
Предлагаемое решение:
Выполните вышеуказанные 4 шага как одноразовое действие во время первого запуска приложения. Позже, когда требуется номер телефона, используйте значение, доступное в общих настройках.
Так вот, как вы запрашиваете номер телефона через API сервисов Play Services без разрешения и взломов. Источник и полный пример .
В вашем 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;
}
}
Это создаст диалог, подобный этому:
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
Существует новый Android API, который позволяет пользователю выбирать свой номер телефона без необходимости разрешения. Взгляните на: 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);
}
Просто хочу добавить немного здесь к объяснениям выше в ответах выше. Что сэкономит время и другим.
В моем случае этот метод не вернул номер мобильного телефона, была возвращена пустая строка. Это было связано с тем, что я перенес свой номер на новую симку. Поэтому, если я захожу в «Настройки»> «О телефоне»> «Состояние»> «Мой номер телефона», отображается сообщение «Неизвестно».
Иногда ниже кода возвращается 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" />
Надеюсь, это поможет, спасибо!
String s1
будет номер телефона.
Во-первых, получение мобильного номера пользователя противоречит этической политике, раньше это было возможно, но теперь, согласно моим исследованиям, для этого нет надежного решения. Используя некоторый код, можно получить номер мобильного телефона, но нет никаких гарантий, что он будет работать. только в нескольких устройствах. После долгих исследований я нашел только три решения, но они работают не на всех устройствах.
Есть следующая причина, почему мы не получаем.
1. Android-устройство и новая SIM-карта не хранят номер мобильного телефона, если мобильный номер недоступен в устройстве и в симе, то как можно получить номер, если любая старая SIM-карта, имеющая номер мобильного телефона, то с помощью диспетчера телефонии мы можем получить номер другого мудро, он вернет «ноль» или «» или «??????»
<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, но он не работает каждый раз, когда возвращает пустую строку, поэтому вывод бесполезен
Примечание: - Это также не гарантированное и эффективное решение, я тестировал это решение на многих устройствах, но оно работало только в 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();
}
Вывод : - Android не имеет какого-либо гарантированного решения для получения номера мобильного телефона программно.
Предложение : - 1. Если вы хотите подтвердить номер мобильного телефона пользователя, попросите пользователя указать его номер, используя otp, вы можете это проверить.
- Если вы хотите идентифицировать устройство пользователя, для этого вы можете легко получить номер IMEI устройства.
TelephonyManager
не является правильным решением, потому что в некоторых случаях номер не сохраняется на SIM-карте. Я предлагаю вам использовать общие предпочтения, чтобы сохранить номер телефона пользователя при первом открытии приложения, и этот номер будет использоваться всякий раз, когда вам нужно.
Вот комбинация решений, которые я нашел (пример проекта здесь , если вы также хотите проверить автозаполнение):
манифест
<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 ""
}
}
}
Небольшой вклад. В моем случае код запускает исключение ошибки. Мне нужно было поместить аннотацию для запуска кода и решить эту проблему. Здесь я позволю этот код.
public static String getLineNumberPhone(Context scenario) {
TelephonyManager tMgr = (TelephonyManager) scenario.getSystemService(Context.TELEPHONY_SERVICE);
@SuppressLint("MissingPermission") String mPhoneNumber = tMgr.getLine1Number();
return mPhoneNumber;
}
Несмотря на то, что возможно иметь несколько учетных записей голосовой почты, при звонке со своего собственного номера операторы направляют вас на голосовую почту. Так TelephonyManager.getVoiceMailNumber()
или TelephonyManager.getCompleteVoiceMailNumber()
, в зависимости от вкуса, который вам нужен.
Надеюсь это поможет.
Добавьте эту зависимость:
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)
}
}
}
во время работы над приложением безопасности, которое должно было получить номер телефона того, кому мой телефон мог попасть в их руки, я должен был это сделать; 1. Получите Boot complete и затем попробуйте получить Line1_Number из telephonyManager, который возвращает строковый результат. 2. сравните результат «Строка» с моим собственным номером телефона, и если они не совпадают или строка вернет значение «ноль», 3. тайно отправьте SMS-сообщение с результатом строки и специальным знаком на номер моего офиса. 4. если отправка сообщения не удалась, запустите службу и продолжайте попытки после каждого часа, пока не будет успешно отправлено ожидающее отправленное SMS-сообщение. С помощью этих шагов я мог получить номер человека, использующего мой потерянный телефон. не имеет значения, если человек обвинен.