我如何通过编程方式获得正在运行我的android应用程序的设备的电话号码?
当前回答
正如我之前回答的那样
使用以下代码:
TelephonyManager tMgr = (TelephonyManager)mAppContext.getSystemService(Context.TELEPHONY_SERVICE);
String mPhoneNumber = tMgr.getLine1Number();
在AndroidManifest.xml中,赋予以下权限:
<uses-permission android:name="android.permission.READ_PHONE_STATE"/>
但请记住,这个代码并不总是有效,因为手机号码取决于SIM卡和网络运营商/手机运营商。
另外,试着在电话->设置->关于->电话身份,如果你能在那里看到号码,从上面的代码获得电话号码的概率更高。如果您不能在设置中查看电话号码,那么您将无法通过此代码获得!
建议解决方案:
获取用户的电话号码作为用户的手动输入。 通过短信将代码发送到用户的手机号码。 请用户输入确认电话号码的代码。 保存在sharedpreference中。
在应用首次发布时一次性执行上述4个步骤。稍后,当需要电话号码时,使用共享首选项中可用的值。
其他回答
添加这个依赖: 实现“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)
}
}
}
这个问题没有保证的解决方案,因为电话号码不是物理地存储在所有sim卡上,也不是从网络广播到电话上。在一些需要物理地址验证的国家尤其如此,只有在验证之后才会分配号码。电话号码分配是在网络上进行的,并且可以在不改变SIM卡或设备的情况下进行更改(例如,这就是支持移植的方式)。
我知道这很痛苦,但最有可能的最好的解决方案是让用户输入一次他/她的电话号码并存储它。
所以这就是你如何通过Play服务API请求一个电话号码,而没有许可和黑客。源代码和完整的示例。
在你的构建中。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;
}
}
这会生成一个这样的对话框:
对于android版本>= LOLLIPOP_MR1:
增加权限:
叫它:
val subscriptionManager =
getSystemService(Context.TELEPHONY_SUBSCRIPTION_SERVICE) as SubscriptionManager
if (ActivityCompat.checkSelfPermission(this, Manifest.permission.READ_PHONE_STATE) == PackageManager.PERMISSION_GRANTED) {
val list = subscriptionManager.activeSubscriptionInfoList
for (info in list) {
Log.d(TAG, "number " + info.number)
Log.d(TAG, "network name : " + info.carrierName)
Log.d(TAG, "country iso " + info.countryIso)
}
}
只是想在以上回答中对以上解释做一点补充。这也会为其他人节省时间。
在我的情况下,这个方法没有返回任何手机号码,返回一个空字符串。这是由于我把我的号码移植到新的sim卡上的情况。所以如果我进入设置>关于电话>状态>我的电话号码,它显示我“未知”。
推荐文章
- 警告:API ' variable . getjavacompile()'已过时,已被' variable . getjavacompileprovider()'取代
- 安装APK时出现错误
- 碎片中的onCreateOptionsMenu
- TextView粗体通过XML文件?
- 如何使线性布局的孩子之间的空间?
- DSL元素android.dataBinding。enabled'已过时,已被'android.buildFeatures.dataBinding'取代
- ConstraintLayout:以编程方式更改约束
- PANIC: AVD系统路径损坏。检查ANDROID_SDK_ROOT值
- 如何生成字符串类型的buildConfigField
- Recyclerview不调用onCreateViewHolder
- Android API 21工具栏填充
- Android L中不支持操作栏导航模式
- 如何在TextView中添加一个子弹符号?
- PreferenceManager getDefaultSharedPreferences在Android Q中已弃用
- 在Android Studio中创建aar文件