我如何通过编程方式获得正在运行我的android应用程序的设备的电话号码?
当前回答
不建议使用TelephonyManager,因为它要求应用程序在运行时需要READ_PHONE_STATE权限。
<uses-permission android:name="android.permission.READ_PHONE_STATE"/>
应该使用谷歌的播放服务进行身份验证,它将能够允许用户选择使用哪个phoneNumber,并处理多个SIM卡,而不是我们试图猜测哪一个是主SIM卡。
implementation "com.google.android.gms:play-services-auth:$play_service_auth_version"
fun main() {
val googleApiClient = GoogleApiClient.Builder(context)
.addApi(Auth.CREDENTIALS_API).build()
val hintRequest = HintRequest.Builder()
.setPhoneNumberIdentifierSupported(true)
.build()
val hintPickerIntent = Auth.CredentialsApi.getHintPickerIntent(
googleApiClient, hintRequest
)
startIntentSenderForResult(
hintPickerIntent.intentSender, REQUEST_PHONE_NUMBER, null, 0, 0, 0
)
}
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
super.onActivityResult(requestCode, resultCode, data)
when (requestCode) {
REQUEST_PHONE_NUMBER -> {
if (requestCode == Activity.RESULT_OK) {
val credential = data?.getParcelableExtra<Credential>(Credential.EXTRA_KEY)
val selectedPhoneNumber = credential?.id
}
}
}
}
其他回答
以下是我找到的解决方案的组合(这里是示例项目,如果你也想检查自动填充):
清单
<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 ""
}
}
}
虽然你可以有多个语音信箱帐号,但当你用自己的号码打电话时,运营商会把你转到语音信箱。因此,telephonymanager。getvoicemailnumber()或telephonymanager。getcompletevoicemailnumber(),这取决于你需要的风格。
希望这能有所帮助。
TelephonyManager不是正确的解决方案,因为在某些情况下,号码没有存储在SIM卡中。我建议您在应用程序第一次打开时使用共享首选项存储用户的电话号码,并且在需要时使用该号码。
不建议使用TelephonyManager,因为它要求应用程序在运行时需要READ_PHONE_STATE权限。
<uses-permission android:name="android.permission.READ_PHONE_STATE"/>
应该使用谷歌的播放服务进行身份验证,它将能够允许用户选择使用哪个phoneNumber,并处理多个SIM卡,而不是我们试图猜测哪一个是主SIM卡。
implementation "com.google.android.gms:play-services-auth:$play_service_auth_version"
fun main() {
val googleApiClient = GoogleApiClient.Builder(context)
.addApi(Auth.CREDENTIALS_API).build()
val hintRequest = HintRequest.Builder()
.setPhoneNumberIdentifierSupported(true)
.build()
val hintPickerIntent = Auth.CredentialsApi.getHintPickerIntent(
googleApiClient, hintRequest
)
startIntentSenderForResult(
hintPickerIntent.intentSender, REQUEST_PHONE_NUMBER, null, 0, 0, 0
)
}
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
super.onActivityResult(requestCode, resultCode, data)
when (requestCode) {
REQUEST_PHONE_NUMBER -> {
if (requestCode == Activity.RESULT_OK) {
val credential = data?.getParcelableExtra<Credential>(Credential.EXTRA_KEY)
val selectedPhoneNumber = credential?.id
}
}
}
}
更新:这个答案不再可用,因为Whatsapp已经停止将电话号码作为帐户名,请忽略这个答案。
实际上,如果你不能通过电话服务获得它,你可以考虑另一种解决方案。
到今天为止,你可以依靠另一个大型应用程序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);
}
检查WhatsApp帐户的actype
if(actype.equals("com.whatsapp")){
String phoneNumber = ac.name;
}
当然,如果用户没有安装WhatsApp,你可能不会得到它,但无论如何都值得一试。 记住,你应该总是询问用户的确认。
推荐文章
- 如何隐藏动作栏之前的活动被创建,然后再显示它?
- 是否有一种方法以编程方式滚动滚动视图到特定的编辑文本?
- 在Android中将字符串转换为Uri
- 如何在NestedScrollView内使用RecyclerView ?
- 移动到另一个EditText时,软键盘下一步点击Android
- Android应用中的GridView VS GridLayout
- Activity和FragmentActivity的区别
- 右对齐文本在android TextView
- 权限拒绝:start前台需要android.permission.FOREGROUND_SERVICE
- 如何更改android操作栏的标题和图标
- Android Split字符串
- 让一个链接在安卓浏览器启动我的应用程序?
- 如何在Android工作室的外部库中添加一个jar ?
- GridLayout(不是GridView)如何均匀地拉伸所有子元素
- 如何让一个片段删除自己,即它的等效完成()?