programing

Android 전화기의 전화 번호를 프로그래밍 방식으로 가져옵니다.

yellowcard 2023. 6. 9. 21:56
반응형

Android 전화기의 전화 번호를 프로그래밍 방식으로 가져옵니다.

안드로이드 앱을 실행하는 장치의 전화 번호를 프로그래밍 방식으로 가져오는 방법은 무엇입니까?

코드:

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

필요한 권한:

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

주의사항:

높은 지지를 받은 댓글에 따르면, 주의해야 할 몇 가지 주의 사항이 있습니다.은 반할수있다니를 반환할 수 .null또는""아니 심지어는"???????"더 이상 유효하지 않은 오래된 전화 번호를 반환할 수 있습니다.할 수 장를고게식별수할있것는원다합사다니음용야해을면한다치을유하합▁if다▁use니▁that,▁you▁should▁device를 사용해야 합니다.getDeviceId()대신.

전화 번호가 모든 SIM 카드에 물리적으로 저장되거나 네트워크에서 전화기로 브로드캐스트되지 않기 때문에 이 문제에 대한 확실한 해결책은 없습니다.특히 물리적 주소 확인이 필요한 일부 국가에서는 번호 할당이 이후에만 수행됩니다.전화 번호 할당은 네트워크에서 수행되며 SIM 카드나 장치를 변경하지 않고 변경할 수 있습니다(예: 이러한 방식으로 포팅이 지원됨).

고통스럽겠지만, 가장 좋은 해결책은 사용자에게 전화번호를 한 번만 입력하고 저장하는 것입니다.

업데이트: 왓츠앱이 전화번호를 계정 이름으로 노출하는 것을 중단했기 때문에 이 답변은 더 이상 사용할 수 없습니다. 이 답변은 무시하십시오.

전화 서비스를 통해 얻을 수 없는 경우 고려해야 할 대안이 있습니다.

오늘날, 당신은 다른 큰 애플리케이션 왓츠앱에 의존할 수 있습니다.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을 설치하지 않았다면 받지 못했을 수도 있지만, 어쨌든 시도해 볼 가치가 있습니다.그리고 항상 사용자에게 확인을 요청해야 합니다.

그래서 당신은 허가 없이 플레이 서비스 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;
    }
}

그러면 다음과 같은 대화 상자가 생성됩니다.

여기에 이미지 설명 입력

이전 답변에 게시된 바와 같이

아래 코드 사용:

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. 공유 기본 설정에 번호를 저장합니다.

앱을 처음 실행하는 동안 위의 4단계를 한 번의 활동으로 수행합니다.나중에 전화 번호가 필요할 때마다 공유 환경설정에서 사용 가능한 값을 사용합니다.

사용자가 허가 없이 전화번호를 선택할 수 있는 새로운 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);
} 
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 에서 가져온 코드

위의 답변에서 위의 설명에 조금 더 추가하고 싶습니다.다른 사람들도 시간을 절약할 수 있습니다.

이 메소드가 모바일 번호를 반환하지 않은 경우 빈 문자열이 반환되었습니다.그것은 제가 새로운 심에 제 번호를 포팅한 경우 때문이었습니다.그래서 제가 Settings >로 들어가면,전화번호 > 상태 > 내 전화번호에 대해 "알 수 없음"으로 표시됩니다.

는 때로아래코반가환니다됩드때다니반▁returns▁sometimes를 반환합니다.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();
}

이 두 가지 권한을 추가해야 합니다.

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

이것이 도움이 되길 바랍니다, 감사합니다!

무엇보다도 사용자 모바일 번호를 얻는 것은 윤리적 정책에 위배됩니다. 이전에는 가능했지만 현재 제 연구에 따르면 이에 대한 확실한 해결책이 없습니다. 일부 코드를 사용하여 모바일 번호를 얻는 것은 가능하지만 일부 기기에서만 작동할 수 있다는 보장은 없습니다.많은 연구 끝에 세 가지 솔루션만 찾았지만 모든 기기에서 작동하지는 않습니다.

우리가 받지 못하는 이유는 다음과 같습니다.

1.Android 장치와 새로운 심 카드는 모바일 번호를 저장하지 않습니다. 장치에서 모바일 번호를 사용할 수 없다면 어떻게 번호를 얻을 수 있습니까? 모바일 번호를 가진 오래된 심 카드가 있으면 Telephony Manager를 사용하여 번호를 얻을 수 있습니다. 그렇지 않으면 "null" 또는 "?"을 반환합니다.

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

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

참고:- 저는 이 솔루션을 Motox, Samsung Tab 4, Samsung S4, Nexus 5, Redmi 2 프라임 기기에서 테스트했지만 빈 문자열을 반환할 때마다 작동하지 않으므로 결론은 쓸모가 없다는 것입니다.

  1. 이 방법은 Redmi 2 프라임에서만 작동하지만, 이를 위해서는 매니페스트에 읽기 연락처 권한을 추가해야 합니다.

참고:- 이것은 또한 보장되고 효율적인 솔루션이 아닙니다. 저는 많은 장치에서 이 솔루션을 테스트했지만 Redmi 2 프라임에서만 작동했습니다. Redmi 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. 제가 조사한 바로는 이전에 왓츠앱 계정을 사용하여 모바일 번호를 얻는 것이 가능했지만, 지금은 새로운 왓츠앱 버전이 사용자의 모바일 번호를 저장하지 않습니다.

결론:- Android는 사용자의 모바일 번호를 프로그래밍 방식으로 얻을 수 있는 보장된 솔루션이 없습니다.

제안:- 1.사용자의 휴대폰 번호를 확인하고 싶다면 사용자에게 번호를 알려달라고 요청하면 otp를 사용하여 확인할 수 있습니다.

  1. 사용자의 기기를 식별하려면 기기 IMEI 번호를 쉽게 얻을 수 있습니다.

TelephonyManager일부 경우 SIM에 번호가 저장되지 않기 때문에 올바른 솔루션이 아닙니다.공유 기본 설정을 사용하여 응용 프로그램을 처음 열 때 사용자의 전화 번호를 저장하고 필요할 때마다 번호를 사용할 것을 제안합니다.

이것은 더 단순한 대답입니다.

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

다음은 제가 찾은 솔루션의 조합입니다(자동 채우기도 확인하려면 여기 샘플 프로젝트).

명백한

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

빌드.그래들

    implementation "com.google.android.gms:play-services-auth:17.0.0"

기본 활동.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 ""
        }
    }
}

을 추가합니다.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
)

서비스 재생 대화 상자를 누른 후:

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

약간의 기여.저의 경우, 코드에서 오류 예외가 발생했습니다.코드를 실행하고 그 문제를 해결하기 위해 주석을 달아야 했습니다.여기서 코드를 입력합니다.

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

안드로이드 버전 >= 롤리팝_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)
        }
    }

저는 같은 글을 올리는 여러 개의 답변을 보았습니다. 우년선기점을으고바뀌었것이모든로년,고바었▁first뀌▁as,onActivityResult사용되지 않습니다.여기에 사용되지 않는 솔루션이 있습니다.

private fun requestHint() {

    val hintRequest = HintRequest.Builder()
        .setPhoneNumberIdentifierSupported(true)
        .build()

    val intent = Credentials.getClient(this).getHintPickerIntent(hintRequest)
    val intentSender = IntentSenderRequest.Builder(intent.intentSender).build()

    val resultLauncher = registerForActivityResult(
        ActivityResultContracts.StartIntentSenderForResult()
    ) { result ->
        if (result.resultCode == Activity.RESULT_OK) {
            val credential: Credential? = result.data?.getParcelableExtra(Credential.EXTRA_KEY)
            // Phone number with country code
            Log.i("mTag", "Selected phone No: ${credential?.id}")
        }
    }
    resultLauncher.launch(intentSender)
}

참고: 대부분의 사용자는 이 기능을 통해 사용자의 휴대폰 번호를 검색할 수 있다고 생각합니다.보통은 그렇지 않습니다.Google Play Services는 몇 개의 전화 번호를 캐시했으며 대화 상자에 사용자의 전화 번호가 없는 경우도 있습니다.

한 수입품com.google.android.gms.auth.api.credentials.Credential

참조 문서는 세부 정보를 제공하지만 코드는 다소 사용되지 않습니다.

여러 개의 음성 메일 계정을 가질 수 있지만, 사용자 번호로 전화를 걸 때 통신사는 사용자를 음성 메일로 라우팅합니다.그렇게,TelephonyManager.getVoiceMailNumber()또는TelephonyManager.getCompleteVoiceMailNumber()필요한 맛에 따라 달라집니다.

이게 도움이 되길 바랍니다.

사용할 것을 권장하지 않습니다.TelephonyManager앱이 요구하기 때문에READ_PHONE_STATE실행 중인 사용 권한입니다.

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

Google의 인증 플레이 서비스를 사용해야 하며, 사용자는 기본 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
            }
        }
    }
}

제가 전화를 받고 있다면요.voiceMailNumer은 잘 - 러면그잘작다니합동그것은 -

val telephonyManager = getSystemService(TELEPHONY_SERVICE) as TelephonyManager
    if (ActivityCompat.checkSelfPermission(this,
                    Manifest.permission.READ_PHONE_STATE) == PackageManager.PERMISSION_GRANTED
    ) {
        Log.d("number", telephonyManager.voiceMailNumber.toString())
    }

먼저 이렇게 인텐트에서 당신의 사인을 초기화합니다.

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

Google Play 의도를 열고 Google 계정과 연결된 전화 번호를 표시하려면 다음을 사용합니다.

val phoneNumberHintIntentRequest = GetPhoneNumberHintIntentRequest.builder()
            .build()
        Identity.getSignInClient(requireContext())
            .getPhoneNumberHintIntent(phoneNumberHintIntentRequest)
            .addOnSuccessListener { pendingIntent ->
                signInIntent.launch(IntentSenderRequest.Builder(pendingIntent).build())
            }.addOnFailureListener {
                it.printStackTrace()
            }

참고:

  1. 사용자가 전화 번호 공유를 사용할 수 없는 경우 이 작업은 실패합니다.사용자가 설정 -> Google -> 자동 입력 -> 전화 번호 공유에서 이 기능을 활성화해야 하는 경우
  2. 재생 서비스를 사용할 수 없는 에뮬레이트 장치를 사용하는 경우에는 이 기능이 작동하지 않습니다.

내 전화기가 그들의 손에 들어갈 수 있는 사람의 전화번호를 얻어야 하는 보안 앱을 작업하는 동안, 나는 이것을 해야만 했습니다. 1. 부팅 완료를 받은 다음 telephonyManager에서 문자열 결과를 반환하는 Line1_Number를 가져오려고 합니다. 2.String 결과를 내 전화번호와 비교하고 만약 그들이 일치하지 않거나 문자열이 null을 반환한다면, 3. 문자열 결과와 특별한 기호가 포함된 SMS를 내 사무실 번호로 몰래 보냅니다. 4. 메시지 전송이 실패하면 서비스를 시작하고 전송된 SMS 보류 의도가 성공적으로 돌아올 때까지 매 시간 후 계속 시도합니다.이 단계를 통해 저는 잃어버린 전화기를 사용하여 그 사람의 번호를 알 수 있었습니다.그 사람이 기소되든 상관없습니다.

언급URL : https://stackoverflow.com/questions/2480288/programmatically-obtain-the-phone-number-of-the-android-phone

반응형