プログラム的にAndroidフォンの電話番号を取得する


443

Androidアプリを実行しているデバイスの電話番号をプログラムで取得するにはどうすればよいですか?


自分で入力する場合を除いて、これは不可能です。電話番号は携帯電話やSIMでは認識されず、ネットワークでしか認識されません...
tomsoft

3
@tomsoft考えてみてください... Facebookのようなアプリはどのようにして電話番号を自動的に魔法のように検証しますか?
Eddie Hart

1
@tomsoftいいえ、ほとんどの場合、それはあなたの電話番号を要求することすらありません。要求する場合、ボックスは事前に入力されています。
Eddie Hart

1
@tomsoftさて、私は先日Facebookにサインアップしましたが、コードがテキストメッセージで送られてきても、電話番号を尋ねられませんでした。それを試してみてください。;)
Eddie Hart、

1
@EddieHartそれもやってください、そして私は私の電話番号を尋ねられました。したがって、これは一般的に言えば、これにはアクセスできず、一部のオペレーターはセットアップ時にこの情報を追加する可能性があることを確認していますが、これはGMSの標準機能ではありません
tomsoft

回答:


484

コード:

TelephonyManager tMgr = (TelephonyManager)mAppContext.getSystemService(Context.TELEPHONY_SERVICE);
String mPhoneNumber = tMgr.getLine1Number();

必要な許可:

<uses-permission android:name="android.permission.READ_PHONE_STATE"/> 

警告:

非常に賛成のコメントによると、いくつかの注意点があります。これはnull""またはを返す可能性があり"???????"、無効になった古い電話番号を返す可能性があります。デバイスを一意に識別するものが必要な場合は、getDeviceId()代わりに使用する必要があります。


150
実際には、完璧ではありません。私がこの方法を最後に試したとき、私の古い携帯電話番号がそれに移植される前に、私の電話が最初に持っていた電話番号を報告しました。設定アプリにはまだその無効な番号が表示されているため、おそらくまだ機能します。また、一部のSIMによってこのメソッドが返されるという報告もありますnull。そうは言っても、私はもっと良い答えを知りません。
CommonsWare 2010年

4
マークは正しいです。電話を一意に識別するものを使用する場合は、GSMに対してIMEAを返すgetDeviceId()を使用します。
Alex Volovoy 2010年

15
(私はIMEIを意味すると思いますか...?)
ChaimKut

23
そうですね、Android OS 2.2を搭載したNexus Oneでテストしたところ、nullが返されました
Omar Rehman、

43
開発者は、投票数を考慮すると、これが完全な答えであると考えるかもしれません。このメソッドは電話番号を常に提供するわけではないことを開発者に警告するメモを追加する必要があります。
Habeeb Perwad 2014

151

電話番号がすべてのSIMカードに物理的に保存されたり、ネットワークから電話にブロードキャストされたりしないため、この問題の解決策は保証されていません。これは、物理的な住所の検証が必要な一部の国では特に当てはまり、番号の割り当てはその後のみ行われます。電話番号の割り当てはネットワーク上で行われ、SIMカードやデバイスを変更せずに変更できます(これが移植のサポート方法です)。

私はそれが苦痛であることを知っていますが、おそらく最良の解決策は、ユーザーに電話番号を一度入力して保存するように依頼することです。


18
取得した番号を確認するには、番号にSMS(コードを含む)を送信し、「android.provider.Telephony.SMS_RECEIVED」にリスナーを置くことで応答を制御できます。これにより、数値が正しく機能していることを確認できます
Hossein Shahdoost 2013年

1
クリエイティブな解決策ですが、料金が請求されている場合に備えて、ユーザーにそれを実行していることを通知することもできます。
Norman H

3
シンプルなテキストメッセージの受信に対して料金を請求するプロバイダーはありますか?
ThiefMaster 2014年

9
そのとおり。プランにテキストメッセージを追加する前に、受信したテキストメッセージごとに$ 0.30が請求されました。カナダのロジャース。
John Kroetch 14

44

更新: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);
}

actypeWhatsAppアカウントを確認する

if(actype.equals("com.whatsapp")){
    String phoneNumber = ac.name;
}

もちろん、ユーザーがWhatsAppをインストールしなかった場合は取得できない可能性がありますが、とにかく試す価値はあります。また、必ずユーザーに確認を求める必要があります。


1
今日私はアカウントをいじり回しているときにこれを見ました。このように数字が公開されているのはかなり悪いことです。もちろん、GET_ACCOUNTS権限が必要です。その時点で、ユーザーはおそらくアプリの権限を気にしません。
jargetz 14

9
このソリューションは古く、Whatsappはアカウント名の電話番号を保存しません。新しい更新後にwhatsappが電話番号を保存する場所を知っていますか?
Cohelad 2014年

@Cohelad更新してくれてありがとう。後でチェックして、確認後にこの回答に取り消しをします。その間、どこに数値を保存するのかわかりません
Chor Wai Chun

3
しかし、Viber EXPOSEの数!com.viber.voip.account
xnagyg

32

以前の回答に投稿されたとおり

以下のコードを使用してください:

TelephonyManager tMgr = (TelephonyManager)mAppContext.getSystemService(Context.TELEPHONY_SERVICE);
String mPhoneNumber = tMgr.getLine1Number();

AndroidManifest.xmlで、次の権限を付与します。

 <uses-permission android:name="android.permission.READ_PHONE_STATE"/> 

ただし、携帯電話番号はSIMカードとネットワークオペレーター/携帯電話会社によって異なるため、このコードが常に機能するとは限りません。

また、電話でチェックしてみてください->設定->バージョン情報->電話IDそこで番号を表示できる場合は、上記のコードから電話番号を取得する可能性が高くなります。設定で電話番号を表示できない場合、このコードを介して取得することはできません!

推奨される回避策:

  1. ユーザーからの手動入力としてユーザーの電話番号を取得します。
  2. SMS経由でユーザーの携帯電話番号にコードを送信します。
  3. 電話番号を確認するためのコードを入力するようユーザーに依頼します。
  4. 番号をsharedpreferenceに保存します。

上記の4つのステップは、アプリの初回起動時に1回限りのアクティビティとして実行します。後で、電話番号が必要な場合は常に、共有設定で使用可能な値を使用します。


この答えはすべての要因をカバーし、それは受け入れられるべきです=)
スラバフォミンII

電話でデュアルsimを利用できる場合、両方の携帯電話番号を取得するにはどうすればよいですか?上記のコードで。シングルシムの場合、問題なく機能
Amrit Chakradhari

26

つまり、許可なくハッキングせずにPlay Services APIを通じて電話番号をリクエストする方法です。ソース完全な例

build.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;
    }
}

これにより、次のようなダイアログが生成されます。

ここに画像の説明を入力してください


2
ヒント要求には、電話に接続されたメールアカウントの電話番号が表示されます。デバイスにsimがない場合でも、ドロップダウンが表示されます。
アリ

SIMが1つしかない場合、ダイアログに複数の数値が表示されますか?私には、5つの数字が表示されます。:/ :)
cgr

Androidで最初の電話番号を自動的に選択するにはどうすればよいですか?
Noorul

13
private String getMyPhoneNumber(){
    TelephonyManager mTelephonyMgr;
    mTelephonyMgr = (TelephonyManager)
        getSystemService(Context.TELEPHONY_SERVICE); 
    return mTelephonyMgr.getLine1Number();
}

private String getMy10DigitPhoneNumber(){
    String s = getMyPhoneNumber();
    return s != null && s.length() > 2 ? s.substring(2) : null;
}

http://www.androidsnippets.com/get-my-phone-numberから取得したコード


「s.substring(2)」が原因で@JaredBurrows。
クッキーモンスター

1
うまくいきません。NULL値を取得します(日の出SIMカード、スイス)
e-nature

リンクが壊れています。
Ümañgßürmån

11

ユーザーが許可なしに自分の電話番号を選択できる新しいAndroid APIがあります。ご覧くださいhttps : //android-developers.googleblog.com/2017/10/effective-phone-number-verification.html

// Construct a request for phone numbers and show the picker
private void requestHint() {
    HintRequest hintRequest = new HintRequest.Builder()
       .setPhoneNumberIdentifierSupported(true)
       .build();

    PendingIntent intent = Auth.CredentialsApi.getHintPickerIntent(
        apiClient, hintRequest);
    startIntentSenderForResult(intent.getIntentSender(),
        RESOLVE_HINT, null, 0, 0, 0);
} 

これにはFirebaseが必要です
Vlad

@Vladいいえ、ありません。これには、ほとんどのデバイスに付属するGoogle Play開発者サービスのみが必要です。ブログポストからの引用:「始める前に、これを構築してテストする必要があります。これは、SMSを受信し、Google Playサービス10.2.x以降を実行できる電話番号を備えたデバイスです。」
Wirling

9

上記の回答の上記の説明に少し追加したいだけです。他の人の時間も節約できます。

私の場合、このメソッドは携帯電話番号を返さず、空の文字列が返されました。私の番号を新しいシムに移植したことが原因でした。したがって、[設定]> [電話について]> [ステータス]> [私の電話番号]に移動すると、「不明」と表示されます。


鉱山も、この状態は何ですか?ローミング?あるいは、SIMカードに番号が格納されていないだけかもしれません。
Alexandre Marcondes

8

時々、以下のコードが返すnullか、空白の文字列。

TelephonyManager tMgr = (TelephonyManager)mAppContext.getSystemService(Context.TELEPHONY_SERVICE);
String mPhoneNumber = tMgr.getLine1Number();

以下の許可を得て

<uses-permission android:name="android.permission.READ_PHONE_STATE"/>

電話番号を取得できる別の方法があります。私はこれを複数のデバイスでテストしていませんが、上記のコードは毎回機能しません。

以下のコードを試してください:

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");
if (object != null) {
    do {
        if (!((Cursor) (object)).moveToNext())
            break;
        // This is the phoneNumber
        String s1 = ((Cursor) (object)).getString(4);
    } while (true);
    ((Cursor) (object)).close();
}

これら2つの権限を追加する必要があります。

<uses-permission android:name="android.permission.READ_CONTACTS" />
<uses-permission android:name="android.permission.READ_PROFILE" />

これが役に立てば幸い、ありがとう!


質問してください:セル番号である2番目のスニペットでは?
iOSAndroidWindowsMo​​bileAppsDev 2016年

1
の値はString s1電話番号になります。
activesince93

このコードは私には機能しません。(最後のコードスニペット)。空の文字列を返します。
Kristy Welsh

あなたの答えを説明してください。番号はどこに保存されており、これにはどのように番号が含まれていますか?何に依存していますか?
not2qubit 2017年

3
@ not2qubit 連絡先アプリの自己連絡先にアクセスしていると思います
Samplasion

4

これはより簡単な答えです:

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

3

まず最初にユーザーの携帯電話番号を取得することは倫理的ポリシーに違反していますが、以前は可能でしたが、今の私の研究によると、これに利用できる確実な解決策はありません。いくつかのデバイスでのみ。多くの調査の結果、3つの解決策しか見つかりませんでしたが、すべてのデバイスで機能するわけではありません。

届かないのには以下の理由があります。

1.Androidデバイスと新しいSIMカードは、デバイスとSIMで携帯電話番号が利用できない場合、携帯電話番号を保存しません。その後、番号を取得する方法、携帯電話番号を持つ古いSIMカードがある場合、テレフォニーマネージャーを使用して、他の番号を取得できます。賢明には、「null」または「」または「??????」を返します

<uses-permission android:name="android.permission.READ_PHONE_STATE"/>

 TelephonyManager tel= (TelephonyManager)this.getSystemService(Context.
            TELEPHONY_SERVICE);
    String PhoneNumber =  tel.getLine1Number();

注:-次のデバイスMoto x、Samsung Tab 4、Samsung S4、Nexus 5、およびRedmi 2プライムでこのソリューションをテストしましたが、空の文字列を返すたびに機能しないため、役に立たないという結論に達しました

  1. このメソッドはRedmi 2 Primeでのみ機能しますが、これにはマニフェストに連絡先の読み取り権限を追加する必要があります。

注:-これも保証された効率的なソリューションではありません。私は多くのデバイスでこのソリューションをテストしましたが、デュアルsimデバイスであるRedmi 2プライムでしか機能しませんでした。私の2つ目のsimに属しています。これは、使用していない古い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();
    }
  1. 私の調査では、以前にWhatsAppアカウントを使用して携帯電話番号を取得することが可能であったことを発見しましたが、新しいWhatsappバージョンはユーザーの携帯電話番号を保存しません。

結論:-Androidには、ユーザーの携帯電話番号をプログラムで取得するための保証されたソリューションがありません。

提案:-1.ユーザーの携帯電話番号を確認したい場合は、ユーザーに番号を提供するよう依頼します。otpを使用すると、それを確認できます。

  1. ユーザーのデバイスを識別したい場合は、このためにデバイスのIMEI番号を簡単に取得できます。

2

TelephonyManager番号がSIMに保存されていない場合があるため、適切なソリューションではありません。共有設定を使用して、アプリケーションを初めて開いたときにユーザーの電話番号を保存し、必要なときにいつでもその番号を使用することをお勧めします。


1
ただし、この方法はエラーが発生しやすく、ユーザーが間違った番号を入力する可能性があります。
Zohra Khan

3
はい、このために、テキストメッセージを使用しました。ユーザーが数値を入力すると、SmsManagerからアプリメッセージ自体が表示されます。これにより、smsRecieverを使用して元の数値を取得できます
Naveed Ahmad

1
もう1つ質問があります。この方法を使用すると、ユーザーからSMSの請求が行われます(無料の電話番号でない場合)。ユーザーの電話を取得できる他の方法はありますか?
Zohra Khan

はい、もちろん番号がフリーダイヤル番号でない場合、SMSにいくらかの料金がかかります。
Naveed Ahmad 2014

いいえ、TelephonyManagerなしでは、そのようなメソッドは今までないと思います。そして私は私の答えでTelephoneManagerの問題を指摘します。
Naveed Ahmad 2014

2

これが私が見つけたソリューションの組み合わせです(自動入力もチェックしたい場合は、サンプルプロジェクトはここにあります):

マニフェスト

    <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 ""
        }
    }
}

このメソッドを実装する前に、この回答stackoverflow.com/a/48210130/5457916のコメントを確認してください
humble_wolf

あなたが提供したリンクは、私がここでしたことの一部にすぎません。ここでは、最初に自分で自動入力を試みました。そして、これにフォールバックします。
Android開発者

ご存知のとおり、あなたの回答は素晴らしいものであり、どのような意味でも不正確ではありません。読者にこの方法に付随する条件を認識してもらいたかったのです。
humble_wolf

私はまだ自分が書いたものを好みます。申し訳ありません
Androidデベロッパー

1

少し貢献。私の場合、コードはエラー例外を起動しました。コードを実行してその問題を修正するための注釈を付ける必要がありました。ここでこのコードを使用します。

public static String getLineNumberPhone(Context scenario) {
    TelephonyManager tMgr = (TelephonyManager) scenario.getSystemService(Context.TELEPHONY_SERVICE);
    @SuppressLint("MissingPermission") String mPhoneNumber = tMgr.getLine1Number();
    return mPhoneNumber;
}

0

複数のボイスメールアカウントを作成することも可能ですが、自分の番号から電話をかけると、キャリアがボイスメールに転送します。だから、TelephonyManager.getVoiceMailNumber()またはTelephonyManager.getCompleteVoiceMailNumber()、あなたが必要とする味に応じて。

お役に立てれば。


5
「getCompleteVoiceMailNumber」関数はありません。さらに、getVoiceMailNumber()は電話の実際の番号とは異なる番号を返します。
Android開発者

これは、世界中のいくつかの携帯電話会社でのみ機能するトリックです。しかし、技術的には回避策になる可能性があります。
technik 2018年

0

この依存関係を追加します。 implementation '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
)

Playサービスダイアログをタップした後:

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)
        }
    }
}

-6

私の電話が手に入る可能性のある人の電話番号を取得する必要があるセキュリティアプリの作業中に、私はこれを行わなければなりませんでした。1.完了したBootを受信し、テレフォニーマネージャーからLine1_Numberを取得して、文字列の結果を返します。2.文字列の結果を自分の電話番号と比較し、一致しないか文字列がnullを返した場合、3。文字列の結果と特別な記号を含むSMSを秘密裏にオフィス番号に送信します。4.メッセージの送信が失敗した場合は、サービスを開始し、送信されたSMS保留インテントが成功を返すまで、1時間ごとに試行を続けます。この手順で、紛失した電話を使用している人の数を知ることができました。人が請求されているかどうかは関係ありません。


なぜ反対票を投じるのですか?
humble_wolf
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.