如何以编程方式获取我的设备的手机号码?
How to get the mobile number of my device programmatically?
我尝试过使用 2 种方法来检索我的 phone 号码,但它们都不起作用。我用过:
- 电话管理器
- 订阅管理器
我确实得到了网络名称、国家 iso 和 IMEI,但每当我尝试 return 给它编号时 return 什么都没有。
我还为这些添加了所有必需的权限!我的清单看起来像:
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
<uses-permission android:name="android.permission.READ_PHONE_NUMBERS" />
<uses-permission android:name="android.permission.GET_ACCOUNTS" />
代码使用 TelephonyManager:
TelephonyManager phoneMgr = (TelephonyManager) getSystemService(Context.TELEPHONY_SERVICE);
phoneMgr.getLine1Number()
代码使用 SubscriptionManager:
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
List<SubscriptionInfo> subscription = SubscriptionManager.from(getApplicationContext()).getActiveSubscriptionInfoList();
for (int i = 0; i < subscription.size(); i++) {
SubscriptionInfo info = subscription.get(i);
Log.e("TAG", "number " + info.getNumber());
Log.e("TAG", "network name : " + info.getCarrierName());
Log.e("TAG", "country iso " + info.getCountryIso());
}
}
两次尝试我都一无所获!
有没有其他方法可以获取 phone 号码或者我做错了什么?
您是否已授予 READ_PHONE_STATE 权限?
<uses-permission android:name="android.permission.READ_PHONE_STATE"/>
现在 TelephonyManager
对我们没有帮助。未经许可播放服务 API 是解决此问题的好方法。
此依赖项对此很有用
implementation 'com.google.android.gms:play-services-auth:16.0.1'
现在在你的 Activity.java 中:
GoogleApiClient mGoogleApiClient = new GoogleApiClient.Builder(this)
.addConnectionCallbacks(this)
.addOnConnectionFailedListener(this)
.addApi(Auth.CREDENTIALS_API)
.build();
if (mGoogleApiClient != null) {
mGoogleApiClient.connect();
}
在此之后请求 Phone 号码:
HintRequest hintRequest = new HintRequest.Builder()
.setPhoneNumberIdentifierSupported(true)
.build();
PendingIntent intent = Auth.CredentialsApi.getHintPickerIntent(mGoogleApiClient, hintRequest);
try {
startIntentSenderForResult(intent.getIntentSender(), 1008, null, 0, 0, 0, null);
} catch (IntentSender.SendIntentException e) {
Log.e("", "Could not start hint picker Intent", e);
}
现在您需要像这样处理 onActivityResult
中的响应:
@Override
public void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
super.onActivityResult(requestCode, resultCode, data);
switch (requestCode) {
case 1008:
if (resultCode == RESULT_OK) {
Credential cred = data.getParcelableExtra(Credential.EXTRA_KEY);
// cred.getId====: ====+919*******
Log.e("cred.getId", cred.getId());
userMob = cred.getId();
} else {
// Sim Card not found!
Log.e("cred.getId", "1008 else");
return;
}
break;
}
}
getLine1Number() 应该可以解决问题,但是根据 SIM 卡,这并不总是能够获得 phone 号码
我建议,如果您没有从 getLine1Number() 中获取号码,则让用户手动输入。 (这是 iOS 用户无论如何都必须做的)
编辑:
此外,从 Android10 开始,您不应该使用 IMEI,您将无权获取该信息
通过使用下面的代码,您当前的设备 phone 号码 & 选择 phone 号码后将调用 onActivity 结果。
Gradle :
implementation 'com.google.android.gms:play-services-auth:17.0.0'
implementation 'com.google.android.gms:play-services-auth-api-phone:17.0.0'
设置 Google API 客户端:
//set google api client for hint request
mGoogleApiClient = new GoogleApiClient.Builder(this)
.addConnectionCallbacks(this)
.enableAutoManage(this, this)
.addApi(Auth.CREDENTIALS_API)
.build();
获取可用号码:
public void getHintPhoneNumber() {
HintRequest hintRequest =
new HintRequest.Builder()
.setPhoneNumberIdentifierSupported(true)
.build();
PendingIntent mIntent = Auth.CredentialsApi.getHintPickerIntent(mGoogleApiClient, hintRequest);
try {
startIntentSenderForResult(mIntent.getIntentSender(), RESOLVE_HINT, null, 0, 0, 0);
} catch (IntentSender.SendIntentException e) {
e.printStackTrace();
}
}
在onActivityResult中获取选中的数字:
@Override
protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
super.onActivityResult(requestCode, resultCode, data);
//Result if we want hint number
if (requestCode == RESOLVE_HINT) {
if (resultCode == Activity.RESULT_OK) {
Credential credential = data.getParcelableExtra(Credential.EXTRA_KEY);
// credential.getId(); <-- will need to process phone number string
inputMobileNumber.setText(credential.getId());
}
}
}
参考: https://androidwave.com/automatic-sms-verification-android/
我发现@bhoomika 的回答很有用,但现在使用 GoogleApiClient 已被弃用。因此,您可以 改用 CredentialsClient。
下面是我用来触发 phone 数字提示对话框的方法(此方法在帮助程序 class 中)。
public void requestPhoneNumberHint(Activity currentActivity) {
HintRequest hintRequest = new HintRequest.Builder()
.setPhoneNumberIdentifierSupported(true)
.build();
CredentialsClient credentialsClient = Credentials.getClient(currentActivity);
PendingIntent intent = credentialsClient.getHintPickerIntent(hintRequest);
try {
uiListener.getCurrentActivity().startIntentSenderForResult(intent.getIntentSender(),
RESOLVE_PHONE_NUMBER_HINT, null, 0, 0, 0);
} catch (IntentSender.SendIntentException e) {
e.printStackTrace();
}
}
下面是我对相应的onActivityResult的处理(我的Activity代码是Kotlin的)
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
if(requestCode == RESOLVE_PHONE_NUMBER_HINT){
if (resultCode == RESULT_OK) {
var credential : Credential? = data?.getParcelableExtra(Credential.EXTRA_KEY)
credential?.apply {
processPhoneNumber(id)
}
}
}
如以下文档中所述,结果代码可用于确定是否没有显示提示或用户是否未选择任何选项。
public static final int ACTIVITY_RESULT_NO_HINTS_AVAILABLE
Activity 结果代码表明没有可用的提示。
常数值:1002
public 静态最终整数 ACTIVITY_RESULT_OTHER_ACCOUNT
Activity 结果代码表明用户希望使用与凭据或提示选择器中提供的帐户不同的帐户。
常数值:1001
我尝试过使用 2 种方法来检索我的 phone 号码,但它们都不起作用。我用过:
- 电话管理器
- 订阅管理器
我确实得到了网络名称、国家 iso 和 IMEI,但每当我尝试 return 给它编号时 return 什么都没有。
我还为这些添加了所有必需的权限!我的清单看起来像:
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
<uses-permission android:name="android.permission.READ_PHONE_NUMBERS" />
<uses-permission android:name="android.permission.GET_ACCOUNTS" />
代码使用 TelephonyManager:
TelephonyManager phoneMgr = (TelephonyManager) getSystemService(Context.TELEPHONY_SERVICE);
phoneMgr.getLine1Number()
代码使用 SubscriptionManager:
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
List<SubscriptionInfo> subscription = SubscriptionManager.from(getApplicationContext()).getActiveSubscriptionInfoList();
for (int i = 0; i < subscription.size(); i++) {
SubscriptionInfo info = subscription.get(i);
Log.e("TAG", "number " + info.getNumber());
Log.e("TAG", "network name : " + info.getCarrierName());
Log.e("TAG", "country iso " + info.getCountryIso());
}
}
两次尝试我都一无所获!
有没有其他方法可以获取 phone 号码或者我做错了什么?
您是否已授予 READ_PHONE_STATE 权限?
<uses-permission android:name="android.permission.READ_PHONE_STATE"/>
现在 TelephonyManager
对我们没有帮助。未经许可播放服务 API 是解决此问题的好方法。
此依赖项对此很有用
implementation 'com.google.android.gms:play-services-auth:16.0.1'
现在在你的 Activity.java 中:
GoogleApiClient mGoogleApiClient = new GoogleApiClient.Builder(this)
.addConnectionCallbacks(this)
.addOnConnectionFailedListener(this)
.addApi(Auth.CREDENTIALS_API)
.build();
if (mGoogleApiClient != null) {
mGoogleApiClient.connect();
}
在此之后请求 Phone 号码:
HintRequest hintRequest = new HintRequest.Builder()
.setPhoneNumberIdentifierSupported(true)
.build();
PendingIntent intent = Auth.CredentialsApi.getHintPickerIntent(mGoogleApiClient, hintRequest);
try {
startIntentSenderForResult(intent.getIntentSender(), 1008, null, 0, 0, 0, null);
} catch (IntentSender.SendIntentException e) {
Log.e("", "Could not start hint picker Intent", e);
}
现在您需要像这样处理 onActivityResult
中的响应:
@Override
public void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
super.onActivityResult(requestCode, resultCode, data);
switch (requestCode) {
case 1008:
if (resultCode == RESULT_OK) {
Credential cred = data.getParcelableExtra(Credential.EXTRA_KEY);
// cred.getId====: ====+919*******
Log.e("cred.getId", cred.getId());
userMob = cred.getId();
} else {
// Sim Card not found!
Log.e("cred.getId", "1008 else");
return;
}
break;
}
}
getLine1Number() 应该可以解决问题,但是根据 SIM 卡,这并不总是能够获得 phone 号码
我建议,如果您没有从 getLine1Number() 中获取号码,则让用户手动输入。 (这是 iOS 用户无论如何都必须做的)
编辑:
此外,从 Android10 开始,您不应该使用 IMEI,您将无权获取该信息
通过使用下面的代码,您当前的设备 phone 号码 & 选择 phone 号码后将调用 onActivity 结果。
Gradle :
implementation 'com.google.android.gms:play-services-auth:17.0.0'
implementation 'com.google.android.gms:play-services-auth-api-phone:17.0.0'
设置 Google API 客户端:
//set google api client for hint request
mGoogleApiClient = new GoogleApiClient.Builder(this)
.addConnectionCallbacks(this)
.enableAutoManage(this, this)
.addApi(Auth.CREDENTIALS_API)
.build();
获取可用号码:
public void getHintPhoneNumber() {
HintRequest hintRequest =
new HintRequest.Builder()
.setPhoneNumberIdentifierSupported(true)
.build();
PendingIntent mIntent = Auth.CredentialsApi.getHintPickerIntent(mGoogleApiClient, hintRequest);
try {
startIntentSenderForResult(mIntent.getIntentSender(), RESOLVE_HINT, null, 0, 0, 0);
} catch (IntentSender.SendIntentException e) {
e.printStackTrace();
}
}
在onActivityResult中获取选中的数字:
@Override
protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
super.onActivityResult(requestCode, resultCode, data);
//Result if we want hint number
if (requestCode == RESOLVE_HINT) {
if (resultCode == Activity.RESULT_OK) {
Credential credential = data.getParcelableExtra(Credential.EXTRA_KEY);
// credential.getId(); <-- will need to process phone number string
inputMobileNumber.setText(credential.getId());
}
}
}
参考: https://androidwave.com/automatic-sms-verification-android/
我发现@bhoomika 的回答很有用,但现在使用 GoogleApiClient 已被弃用。因此,您可以 改用 CredentialsClient。
下面是我用来触发 phone 数字提示对话框的方法(此方法在帮助程序 class 中)。
public void requestPhoneNumberHint(Activity currentActivity) {
HintRequest hintRequest = new HintRequest.Builder()
.setPhoneNumberIdentifierSupported(true)
.build();
CredentialsClient credentialsClient = Credentials.getClient(currentActivity);
PendingIntent intent = credentialsClient.getHintPickerIntent(hintRequest);
try {
uiListener.getCurrentActivity().startIntentSenderForResult(intent.getIntentSender(),
RESOLVE_PHONE_NUMBER_HINT, null, 0, 0, 0);
} catch (IntentSender.SendIntentException e) {
e.printStackTrace();
}
}
下面是我对相应的onActivityResult的处理(我的Activity代码是Kotlin的)
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
if(requestCode == RESOLVE_PHONE_NUMBER_HINT){
if (resultCode == RESULT_OK) {
var credential : Credential? = data?.getParcelableExtra(Credential.EXTRA_KEY)
credential?.apply {
processPhoneNumber(id)
}
}
}
如以下文档中所述,结果代码可用于确定是否没有显示提示或用户是否未选择任何选项。
public static final int ACTIVITY_RESULT_NO_HINTS_AVAILABLE Activity 结果代码表明没有可用的提示。
常数值:1002 public 静态最终整数 ACTIVITY_RESULT_OTHER_ACCOUNT Activity 结果代码表明用户希望使用与凭据或提示选择器中提供的帐户不同的帐户。
常数值:1001