ฉันจะรับหมายเลขโทรศัพท์ของอุปกรณ์ที่ใช้แอพ Android ของฉันโดยทางโปรแกรมได้อย่างไร
ฉันจะรับหมายเลขโทรศัพท์ของอุปกรณ์ที่ใช้แอพ Android ของฉันโดยทางโปรแกรมได้อย่างไร
คำตอบ:
รหัส:
TelephonyManager tMgr = (TelephonyManager)mAppContext.getSystemService(Context.TELEPHONY_SERVICE);
String mPhoneNumber = tMgr.getLine1Number();
สิทธิ์ที่จำเป็น:
<uses-permission android:name="android.permission.READ_PHONE_STATE"/>
จากความคิดเห็นที่มีผู้โหวตสูงมีข้อควรระวังเล็กน้อยที่ควรระวัง สิ่งนี้สามารถส่งคืนnull
หรือ""
หรือแม้กระทั่ง"???????"
และสามารถส่งคืนหมายเลขโทรศัพท์เก่าที่ไม่สามารถใช้งานได้อีกต่อไป หากคุณต้องการสิ่งที่ระบุอุปกรณ์โดยเฉพาะคุณควรใช้getDeviceId()
แทน
null
นอกจากนี้ยังมีรายงานว่าบางซิมทำให้เกิดวิธีการนี้เพื่อผลตอบแทน ที่ถูกกล่าวว่าฉันไม่ได้ตระหนักถึงคำตอบที่ดีกว่า
ไม่มีวิธีแก้ปัญหาที่รับประกันได้สำหรับปัญหานี้เนื่องจากหมายเลขโทรศัพท์ไม่ได้เก็บไว้ในซิมการ์ดทั้งหมดหรือออกอากาศจากเครือข่ายไปยังโทรศัพท์ นี่เป็นเรื่องจริงโดยเฉพาะอย่างยิ่งในบางประเทศที่ต้องการการยืนยันที่อยู่จริงด้วยการกำหนดหมายเลขที่จะเกิดขึ้นหลังจากนั้น การกำหนดหมายเลขโทรศัพท์เกิดขึ้นในเครือข่าย - และสามารถเปลี่ยนแปลงได้โดยไม่ต้องเปลี่ยนซิมการ์ดหรืออุปกรณ์ (เช่นนี่เป็นวิธีการที่พอร์ตรองรับ)
ฉันรู้ว่ามันเจ็บปวด แต่ส่วนใหญ่ทางออกที่ดีที่สุดคือขอให้ผู้ใช้ป้อนหมายเลขโทรศัพท์หนึ่งครั้งและเก็บไว้
จริงๆแล้วมีทางเลือกอื่นที่คุณอาจต้องพิจารณาหากคุณไม่สามารถรับมันผ่านบริการโทรศัพท์
ณ วันนี้คุณสามารถพึ่งพาโปรแกรมอื่นใหญ่ 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);
}
ตรวจสอบactype
บัญชี WhatsApp
if(actype.equals("com.whatsapp")){
String phoneNumber = ac.name;
}
แน่นอนคุณอาจไม่ได้รับหากผู้ใช้ไม่ได้ติดตั้ง WhatsApp แต่มันคุ้มค่าที่จะลอง และจำไว้ว่าคุณควรขอให้ผู้ใช้ยืนยันเสมอ
ดังที่โพสต์ในคำตอบก่อนหน้าของฉัน
ใช้รหัสด้านล่าง:
TelephonyManager tMgr = (TelephonyManager)mAppContext.getSystemService(Context.TELEPHONY_SERVICE);
String mPhoneNumber = tMgr.getLine1Number();
ใน AndroidManifest.xml ให้สิทธิ์ต่อไปนี้:
<uses-permission android:name="android.permission.READ_PHONE_STATE"/>
แต่โปรดจำไว้ว่ารหัสนี้ใช้ไม่ได้เนื่องจากหมายเลขโทรศัพท์มือถือขึ้นอยู่กับซิมการ์ดและผู้ให้บริการเครือข่าย / ผู้ให้บริการโทรศัพท์มือถือ
และลองตรวจสอบในโทรศัพท์ -> การตั้งค่า -> เกี่ยวกับ -> ข้อมูลระบุตัวตนของโทรศัพท์หากคุณสามารถดูหมายเลขได้โอกาสในการรับหมายเลขโทรศัพท์จากรหัสด้านบนจะสูงกว่า หากคุณไม่สามารถดูหมายเลขโทรศัพท์ในการตั้งค่าคุณจะไม่สามารถรับรหัสนี้ได้!
วิธีแก้ปัญหาที่แนะนำ:
ทำ 4 ขั้นตอนข้างต้นเป็นกิจกรรมครั้งเดียวระหว่างการเปิดตัวครั้งแรกของแอป ต่อมาเมื่อใดก็ตามที่ต้องการหมายเลขโทรศัพท์ให้ใช้ค่าที่มีอยู่ในการตั้งค่าที่ใช้ร่วมกัน
นั่นคือวิธีที่คุณร้องขอหมายเลขโทรศัพท์ผ่าน 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;
}
}
สิ่งนี้จะสร้างกล่องโต้ตอบเช่นนี้:
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
มี 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);
}
เพียงแค่ต้องการเพิ่มบิตที่นี่เพื่อคำอธิบายข้างต้นในคำตอบข้างต้น ซึ่งจะช่วยประหยัดเวลาให้กับผู้อื่นเช่นกัน
ในกรณีของฉันวิธีนี้ไม่ได้ส่งคืนหมายเลขโทรศัพท์มือถือใด ๆ สตริงว่างถูกส่งกลับ เป็นเพราะกรณีที่ฉันได้ย้ายหมายเลขของฉันในซิมใหม่ ดังนั้นหากฉันไปที่การตั้งค่า> เกี่ยวกับโทรศัพท์> สถานะ> หมายเลขโทรศัพท์ของฉันมันจะแสดง "ไม่ทราบ"
บางครั้งการส่งคืนโค้ดด้านล่าง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" />
หวังว่าจะช่วยได้ขอบคุณ!
String s1
จะเป็นหมายเลขโทรศัพท์
นี่เป็นคำตอบที่ง่ายกว่านี้:
public String getMyPhoneNumber()
{
return ((TelephonyManager) getSystemService(TELEPHONY_SERVICE))
.getLine1Number();
}
ก่อนอื่นการรับหมายเลขโทรศัพท์มือถือของผู้ใช้นั้นขัดต่อนโยบายจริยธรรมก่อนหน้านี้มันเป็นไปได้ แต่ตอนนี้ตามการวิจัยของฉันไม่มีวิธีแก้ปัญหาที่มั่นคงสำหรับการใช้รหัสบางอย่างมันเป็นไปได้ที่จะได้รับหมายเลขโทรศัพท์มือถือ เฉพาะในอุปกรณ์น้อย หลังจากการวิจัยจำนวนมากฉันพบวิธีแก้ปัญหาเพียงสามข้อเท่านั้น แต่อุปกรณ์เหล่านั้นไม่ทำงานในทุกอุปกรณ์
มีเหตุผลดังต่อไปนี้ทำไมเราไม่ได้รับ
1. อุปกรณ์ Android และซิมการ์ดใหม่ไม่ได้จัดเก็บหมายเลขโทรศัพท์มือถือหากหมายเลขโทรศัพท์ไม่สามารถใช้งานได้ในอุปกรณ์และในซิมแล้วจะสามารถรับหมายเลขได้อย่างไรหากซิมการ์ดเก่าที่มีหมายเลขโทรศัพท์มือถือแล้วใช้ผู้จัดการโทรศัพท์ ฉลาดก็จะส่งคืน“ โมฆะ” หรือ“” หรือ“ ??????”
<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 prime แต่มันไม่ทำงานทุกครั้งที่ส่งคืนสตริงว่างเปล่าดังนั้นข้อสรุปจึงไม่มีประโยชน์
หมายเหตุ: - นี่ไม่ใช่โซลูชันที่รับประกันและมีประสิทธิภาพฉันได้ทดสอบโซลูชันนี้ในอุปกรณ์จำนวนมาก แต่ใช้งานได้เฉพาะใน Redmi 2 prime ซึ่งเป็นอุปกรณ์สองซิมมันให้ฉันหมายเลขโทรศัพท์สองหมายเลขแรกหนึ่งถูกต้อง แต่อันที่สองไม่ใช่ เป็นของซิมที่สองของฉันมันเป็นของซิมการ์ดเก่า ๆ ที่ฉันไม่ได้ใช้
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();
}
สรุป : - Android ไม่มีโซลูชันที่รับประกันว่าจะได้รับหมายเลขโทรศัพท์มือถือของผู้ใช้โดยทางโปรแกรม
คำแนะนำ : - 1. หากคุณต้องการตรวจสอบหมายเลขโทรศัพท์มือถือของผู้ใช้จากนั้นขอให้ผู้ใช้แจ้งหมายเลขโทรศัพท์โดยใช้ otp คุณสามารถตรวจสอบได้
- หากคุณต้องการระบุอุปกรณ์ของผู้ใช้คุณสามารถรับหมายเลข IMEI ของอุปกรณ์ได้อย่างง่ายดาย
TelephonyManager
ไม่ใช่วิธีการแก้ปัญหาที่ถูกต้องเพราะในบางกรณีหมายเลขจะไม่ถูกเก็บไว้ใน SIM ฉันขอแนะนำให้คุณใช้การตั้งค่าที่ใช้ร่วมกันเพื่อเก็บหมายเลขโทรศัพท์ของผู้ใช้เป็นครั้งแรกที่มีการเปิดแอปพลิเคชันและจะใช้หมายเลขนั้นทุกครั้งที่คุณต้องการ
นี่คือการผสมผสานของโซลูชั่นที่ฉันได้พบ (ตัวอย่างโครงการที่นี่หากคุณต้องการตรวจสอบการป้อนอัตโนมัติด้วย):
ประจักษ์
<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 ""
}
}
}
ผลงานเล็กน้อย ในกรณีของฉันรหัสเปิดตัวข้อผิดพลาด ฉันจำเป็นต้องใส่คำอธิบายประกอบที่จะเรียกใช้รหัสและแก้ไขปัญหานั้น ที่นี่ฉันขอรหัสนี้
public static String getLineNumberPhone(Context scenario) {
TelephonyManager tMgr = (TelephonyManager) scenario.getSystemService(Context.TELEPHONY_SERVICE);
@SuppressLint("MissingPermission") String mPhoneNumber = tMgr.getLine1Number();
return mPhoneNumber;
}
แม้ว่าจะเป็นไปได้ที่จะมีบัญชีข้อความเสียงหลายบัญชี แต่เมื่อโทรจากหมายเลขของคุณเองผู้ให้บริการจะนำคุณไปยังข้อความเสียง ดังนั้นTelephonyManager.getVoiceMailNumber()
หรือTelephonyManager.getCompleteVoiceMailNumber()
ขึ้นอยู่กับรสชาติที่คุณต้องการ
หวังว่านี่จะช่วยได้
เพิ่มการพึ่งพานี้:
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)
}
}
}
ในขณะที่ทำงานกับแอพรักษาความปลอดภัยซึ่งต้องการหมายเลขโทรศัพท์ของผู้ที่โทรศัพท์ของฉันอาจเข้ามาอยู่ในมือพวกเขาฉันต้องทำเช่นนี้ 1. รับ Boot เสร็จสิ้นแล้วลองรับ Line1_Number จาก telephonyManager ซึ่งส่งคืนผลลัพธ์สตริง 2. เปรียบเทียบผลลัพธ์ String กับหมายเลขโทรศัพท์ของฉันเองและหากพวกเขาไม่ตรงกันหรือสตริงคืนค่า null แล้ว 3. ส่ง SMS ที่มีสตริงและแอบแฝงเครื่องหมายพิเศษไปยังหมายเลขสำนักงานของฉัน 4. หากการส่งข้อความล้มเหลวให้เริ่มบริการและพยายามต่อไปทุก ๆ ชั่วโมงจนกว่าความตั้งใจรอส่ง SMS จะส่งกลับสำเร็จ ด้วยขั้นตอนนี้ฉันสามารถรับจำนวนผู้ใช้โทรศัพท์ที่หายไป ไม่สำคัญว่าบุคคลนั้นจะถูกเรียกเก็บเงินหรือไม่