如何以编程方式获取运行我的android应用的设备的电话号码?
如何以编程方式获取运行我的android应用的设备的电话号码?
Answers:
码:
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个步骤作为一次活动进行。以后,每当需要电话号码时,请使用共享首选项中的可用值。
因此,这就是您未经许可和黑客就通过Play Services API请求电话号码的方式。源代码和完整示例。
在您的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;
}
有一个新的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);
}
只是想在以上答案的以上说明中添加一些内容。这也将为他人节省时间。
在我的情况下,此方法未返回任何手机号码,返回了一个空字符串。由于这种情况,我将自己的号码移植到了新的SIM卡上。因此,如果我进入“设置”>“关于电话”>“状态”>“我的电话号码”,则会显示“未知”。
有时,下面的代码返回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卡中没有手机号,那么如何获取号码,如果有旧的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,但是每次返回空字符串时它都不起作用,因此得出结论,它是无用的
注意:-这也不是保证有效的解决方案,我已经在很多设备上测试了该解决方案,但是它只能在Redmi 2 prime(这是双SIM卡设备)中工作,它给我两个手机号码第一个是正确的,但是第二个不是属于我的第二张SIM卡,属于我未使用的一些旧SIM卡。
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.接收启动完成,然后尝试从telephonyManager获取Line1_Number,它返回字符串结果。2.将字符串结果与我自己的电话号码进行比较,如果不匹配或字符串返回null,则3.将包含字符串结果和特殊符号的SMS秘密发送到我的办公室号码。4.如果消息发送失败,请启动服务,并在每个小时后继续尝试,直到发送的SMS挂起意图返回成功为止。通过此步骤,我可以使用丢失的电话获得该人员的号码。收费是否无关紧要。