我如何通过编程方式获得正在运行我的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个步骤。稍后,当需要电话号码时,使用共享首选项中可用的值。

其他回答

所以这就是你如何通过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;
    }
}

这会生成一个这样的对话框:

这是一个更简单的答案:

public String getMyPhoneNumber()
{
    return ((TelephonyManager) getSystemService(TELEPHONY_SERVICE))
            .getLine1Number();
}

这个问题没有保证的解决方案,因为电话号码不是物理地存储在所有sim卡上,也不是从网络广播到电话上。在一些需要物理地址验证的国家尤其如此,只有在验证之后才会分配号码。电话号码分配是在网络上进行的,并且可以在不改变SIM卡或设备的情况下进行更改(例如,这就是支持移植的方式)。

我知道这很痛苦,但最有可能的最好的解决方案是让用户输入一次他/她的电话号码并存储它。

添加这个依赖: 实现“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)
        }
    }
}

不建议使用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
            }
        }
    }
}