我如何通过编程方式获得正在运行我的android应用程序的设备的电话号码?
当前回答
虽然你可以有多个语音信箱帐号,但当你用自己的号码打电话时,运营商会把你转到语音信箱。因此,telephonymanager。getvoicemailnumber()或telephonymanager。getcompletevoicemailnumber(),这取决于你需要的风格。
希望这能有所帮助。
其他回答
以下是我找到的解决方案的组合(这里是示例项目,如果你也想检查自动填充):
清单
<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 ""
}
}
}
首先,获取用户的手机号码是违反道德政策的,以前是可能的,但现在根据我的研究,没有可靠的解决方案,通过使用一些代码,有可能获得手机号码,但不能保证可能只在少数设备上工作。经过大量的研究,我发现只有三个解决方案,但他们不是在所有设备工作。
有以下原因,为什么我们没有得到。
1.Android设备和新的Sim卡没有存储手机号码,如果手机号码在设备和Sim卡中都不可用,那么如何获得号码,如果任何旧的Sim卡有手机号码,那么使用Telephony manager我们可以获得号码,否则它将返回“null”或“”或“??????”
<uses-permission android:name="android.permission.READ_PHONE_STATE"/>
TelephonyManager tel= (TelephonyManager)this.getSystemService(Context.
TELEPHONY_SERVICE);
String PhoneNumber = tel.getLine1Number();
注:-我已经在以下设备Moto x,三星Tab 4,三星S4, Nexus 5和红米2 prime上测试了这个解决方案,但它并不是每一个都有效 Time返回空字符串,所以结论是没有用的
此方法仅适用于红米2 ',但为此需要添加 读取清单中的联系人权限。
注意:-这也不是保证和有效的解决方案,我已经在许多设备上测试了这个解决方案,但它只在红米2撇中工作 哪个是双卡设备它给了我两个手机号码第一个是 正确,但第二个不属于我的第二个模拟,它属于 我的一些旧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();
}
在我的研究中,我发现之前使用WhatsApp账户可以获得手机号码,但现在新的WhatsApp版本不存储用户的手机号码。
结论:Android没有任何可靠的解决方案 用户的手机号码。 建议:- 1。如果你想验证用户的手机号码,请问 用户提供他的号码,使用otp可以验证。 如果你想识别用户的设备,你可以很容易地获得设备IMEI号。
首先在Intent中初始化你的符号
private val signInIntent = registerForActivityResult(ActivityResultContracts.StartIntentSenderForResult()) { result ->
try {
val phoneNumber = Identity.getSignInClient(requireContext()).getPhoneNumberFromIntent(result.data)
// Note phone number will be in country code + phone number format
} catch (e: Exception) {
}
}
要打开谷歌播放意图,并显示与谷歌帐户相关联的电话号码,请使用此
val phoneNumberHintIntentRequest = GetPhoneNumberHintIntentRequest.builder()
.build()
Identity.getSignInClient(requireContext())
.getPhoneNumberHintIntent(phoneNumberHintIntentRequest)
.addOnSuccessListener { pendingIntent ->
signInIntent.launch(IntentSenderRequest.Builder(pendingIntent).build())
}.addOnFailureListener {
it.printStackTrace()
}
注意:
如果用户禁用电话号码共享,此操作将失败。如果是这样,用户必须从设置->谷歌->自动填充->电话号码共享 如果您正在使用播放服务不可用的模拟设备,这将不起作用
对于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文件