Để xác định duy nhất mỗi thiết bị, tôi muốn sử dụng IMEI (hoặc số ESN cho các thiết bị CDMA). Làm thế nào để truy cập chương trình này?
Để xác định duy nhất mỗi thiết bị, tôi muốn sử dụng IMEI (hoặc số ESN cho các thiết bị CDMA). Làm thế nào để truy cập chương trình này?
Câu trả lời:
Bạn muốn gọi android.telephony.TelephonyManager.getDeviceId()
.
Điều này sẽ trả về bất kỳ chuỗi nào xác định duy nhất thiết bị (IMEI trên GSM, MEID cho CDMA).
Bạn sẽ cần sự cho phép sau đây trong AndroidManifest.xml
:
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
để làm điều này.
Điều đó đang được nói, hãy cẩn thận về việc này. Người dùng không chỉ thắc mắc tại sao ứng dụng của bạn truy cập vào ngăn xếp điện thoại của họ, có thể khó di chuyển dữ liệu nếu người dùng có thiết bị mới.
Cập nhật: Như đã đề cập trong các bình luận bên dưới, đây không phải là cách an toàn để xác thực người dùng và làm tăng mối lo ngại về quyền riêng tư. Nó không được khuyến khích. Thay vào đó, hãy xem API đăng nhập Google+ nếu bạn muốn triển khai hệ thống đăng nhập không ma sát.
Các API Android Backup cũng có sẵn nếu bạn chỉ muốn một cách nhẹ để tồn tại một bó dây cho khi người dùng reset điện thoại của họ (hoặc mua một thiết bị mới).
Ngoài câu trả lời của Trevor Johns, bạn có thể sử dụng câu này như sau:
TelephonyManager telephonyManager = (TelephonyManager)getSystemService(Context.TELEPHONY_SERVICE);
telephonyManager.getDeviceId();
Và bạn nên thêm quyền sau vào tệp Manifest.xml của mình:
<uses-permission android:name="android.permission.READ_PHONE_STATE"/>
Trong trình giả lập, có thể bạn sẽ nhận được giá trị như "00000 ...". getDeviceId () trả về NULL nếu ID thiết bị không khả dụng.
READ_PHONE_STATE
quyền?
Tôi sử dụng mã sau đây để nhận IMEI hoặc sử dụng Secure.ANDROID_ID thay thế, khi thiết bị không có khả năng của điện thoại:
/**
* Returns the unique identifier for the device
*
* @return unique identifier for the device
*/
public String getDeviceIMEI() {
String deviceUniqueIdentifier = null;
TelephonyManager tm = (TelephonyManager) this.getSystemService(Context.TELEPHONY_SERVICE);
if (null != tm) {
deviceUniqueIdentifier = tm.getDeviceId();
}
if (null == deviceUniqueIdentifier || 0 == deviceUniqueIdentifier.length()) {
deviceUniqueIdentifier = Settings.Secure.getString(this.getContentResolver(), Settings.Secure.ANDROID_ID);
}
return deviceUniqueIdentifier;
}
null
cho thiết bị điện thoạiId ... Có ai biết cách lấy IMEI từ máy tính bảng không?
Hoặc bạn có thể sử dụng cài đặt ANDROID_ID từ Android.Provider.Sinstall.System (như được mô tả ở đây strazerre.com ).
Điều này có lợi thế là nó không yêu cầu quyền đặc biệt nhưng có thể thay đổi nếu một ứng dụng khác có quyền truy cập ghi và thay đổi nó (điều này rõ ràng là bất thường nhưng không phải là không thể).
Chỉ để tham khảo ở đây là mã từ blog:
import android.provider.Settings;
import android.provider.Settings.System;
String androidID = System.getString(this.getContentResolver(),Secure.ANDROID_ID);
Lưu ý triển khai : nếu ID rất quan trọng đối với kiến trúc hệ thống, bạn cần lưu ý rằng trong thực tế, một số điện thoại và máy tính bảng Android cấp thấp đã được tìm thấy sử dụng lại ANDROID_ID (9774d56d682e549c là giá trị hiển thị trong nhật ký của chúng tôi)
String androidID = android.provider.Settings.System.getString(this.getContentResolver(), Secure.ANDROID_ID);
Từ: http://mytechead.wordpress.com/2011/08/28/how-to-get-imei-number-of-android-device/ :
Đoạn mã sau giúp lấy số IMEI của thiết bị Android:
TelephonyManager tm = (TelephonyManager)getSystemService(Context.TELEPHONY_SERVICE);
String device_id = tm.getDeviceId();
Quyền yêu cầu trong Bản kê khai Android:
android.permission.READ_PHONE_STATE
LƯU Ý: Trong trường hợp máy tính bảng hoặc thiết bị không thể hoạt động như IMEI của Điện thoại di động sẽ không có giá trị.
để nhận IMEI ( số nhận dạng thiết bị di động quốc tế)
public String getIMEI(Activity activity) {
TelephonyManager telephonyManager = (TelephonyManager) activity
.getSystemService(Context.TELEPHONY_SERVICE);
return telephonyManager.getDeviceId();
}
để có được id duy nhất của thiết bị
public String getDeviceUniqueID(Activity activity){
String device_unique_id = Secure.getString(activity.getContentResolver(),
Secure.ANDROID_ID);
return device_unique_id;
}
Đối với Android 6.0+, trò chơi đã thay đổi, vì vậy tôi khuyên bạn nên sử dụng tính năng này;
Cách tốt nhất để đi là trong thời gian chạy khác, bạn nhận được lỗi cho phép.
/**
* A loading screen after AppIntroActivity.
*/
public class LoadingActivity extends BaseActivity {
private static final int MY_PERMISSIONS_REQUEST_READ_PHONE_STATE = 0;
private TextView loading_tv2;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_loading);
//trigger 'loadIMEI'
loadIMEI();
/** Fading Transition Effect */
overridePendingTransition(android.R.anim.fade_in, android.R.anim.fade_out);
}
/**
* Called when the 'loadIMEI' function is triggered.
*/
public void loadIMEI() {
// Check if the READ_PHONE_STATE permission is already available.
if (ActivityCompat.checkSelfPermission(this, Manifest.permission.READ_PHONE_STATE)
!= PackageManager.PERMISSION_GRANTED) {
// READ_PHONE_STATE permission has not been granted.
requestReadPhoneStatePermission();
} else {
// READ_PHONE_STATE permission is already been granted.
doPermissionGrantedStuffs();
}
}
/**
* Requests the READ_PHONE_STATE permission.
* If the permission has been denied previously, a dialog will prompt the user to grant the
* permission, otherwise it is requested directly.
*/
private void requestReadPhoneStatePermission() {
if (ActivityCompat.shouldShowRequestPermissionRationale(this,
Manifest.permission.READ_PHONE_STATE)) {
// Provide an additional rationale to the user if the permission was not granted
// and the user would benefit from additional context for the use of the permission.
// For example if the user has previously denied the permission.
new AlertDialog.Builder(LoadingActivity.this)
.setTitle("Permission Request")
.setMessage(getString(R.string.permission_read_phone_state_rationale))
.setCancelable(false)
.setPositiveButton(android.R.string.yes, new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
//re-request
ActivityCompat.requestPermissions(LoadingActivity.this,
new String[]{Manifest.permission.READ_PHONE_STATE},
MY_PERMISSIONS_REQUEST_READ_PHONE_STATE);
}
})
.setIcon(R.drawable.onlinlinew_warning_sign)
.show();
} else {
// READ_PHONE_STATE permission has not been granted yet. Request it directly.
ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.READ_PHONE_STATE},
MY_PERMISSIONS_REQUEST_READ_PHONE_STATE);
}
}
/**
* Callback received when a permissions request has been completed.
*/
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions,
@NonNull int[] grantResults) {
if (requestCode == MY_PERMISSIONS_REQUEST_READ_PHONE_STATE) {
// Received permission result for READ_PHONE_STATE permission.est.");
// Check if the only required permission has been granted
if (grantResults.length == 1 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
// READ_PHONE_STATE permission has been granted, proceed with displaying IMEI Number
//alertAlert(getString(R.string.permision_available_read_phone_state));
doPermissionGrantedStuffs();
} else {
alertAlert(getString(R.string.permissions_not_granted_read_phone_state));
}
}
}
private void alertAlert(String msg) {
new AlertDialog.Builder(LoadingActivity.this)
.setTitle("Permission Request")
.setMessage(msg)
.setCancelable(false)
.setPositiveButton(android.R.string.yes, new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
// do somthing here
}
})
.setIcon(R.drawable.onlinlinew_warning_sign)
.show();
}
public void doPermissionGrantedStuffs() {
//Have an object of TelephonyManager
TelephonyManager tm =(TelephonyManager)getSystemService(Context.TELEPHONY_SERVICE);
//Get IMEI Number of Phone //////////////// for this example i only need the IMEI
String IMEINumber=tm.getDeviceId();
/************************************************
* **********************************************
* This is just an icing on the cake
* the following are other children of TELEPHONY_SERVICE
*
//Get Subscriber ID
String subscriberID=tm.getDeviceId();
//Get SIM Serial Number
String SIMSerialNumber=tm.getSimSerialNumber();
//Get Network Country ISO Code
String networkCountryISO=tm.getNetworkCountryIso();
//Get SIM Country ISO Code
String SIMCountryISO=tm.getSimCountryIso();
//Get the device software version
String softwareVersion=tm.getDeviceSoftwareVersion()
//Get the Voice mail number
String voiceMailNumber=tm.getVoiceMailNumber();
//Get the Phone Type CDMA/GSM/NONE
int phoneType=tm.getPhoneType();
switch (phoneType)
{
case (TelephonyManager.PHONE_TYPE_CDMA):
// your code
break;
case (TelephonyManager.PHONE_TYPE_GSM)
// your code
break;
case (TelephonyManager.PHONE_TYPE_NONE):
// your code
break;
}
//Find whether the Phone is in Roaming, returns true if in roaming
boolean isRoaming=tm.isNetworkRoaming();
if(isRoaming)
phoneDetails+="\nIs In Roaming : "+"YES";
else
phoneDetails+="\nIs In Roaming : "+"NO";
//Get the SIM state
int SIMState=tm.getSimState();
switch(SIMState)
{
case TelephonyManager.SIM_STATE_ABSENT :
// your code
break;
case TelephonyManager.SIM_STATE_NETWORK_LOCKED :
// your code
break;
case TelephonyManager.SIM_STATE_PIN_REQUIRED :
// your code
break;
case TelephonyManager.SIM_STATE_PUK_REQUIRED :
// your code
break;
case TelephonyManager.SIM_STATE_READY :
// your code
break;
case TelephonyManager.SIM_STATE_UNKNOWN :
// your code
break;
}
*/
// Now read the desired content to a textview.
loading_tv2 = (TextView) findViewById(R.id.loading_tv2);
loading_tv2.setText(IMEINumber);
}
}
Hy vọng điều này sẽ giúp bạn hoặc ai đó.
Cập nhật mới:
Đối với Android Phiên bản 6 trở lên, Địa chỉ MAC WLAN đã không được chấp nhận, hãy làm theo câu trả lời của Trevor Johns
Cập nhật:
Để nhận dạng duy nhất các thiết bị, Bạn có thể sử dụng Secure.ANDROID_ID .
Câu trả lời cũ:
Nhược điểm của việc sử dụng IMEI làm ID thiết bị duy nhất:
Bạn có thể sử dụng chuỗi Địa chỉ MAC của mạng WLAN (Không được đề xuất cho Marshmallow và Marshmallow + vì Địa chỉ MAC của mạng WLAN không được chấp nhận trên Marshmallow về phía trước. Vì vậy, bạn sẽ nhận được giá trị không có thật)
Chúng tôi cũng có thể nhận ID duy nhất cho điện thoại Android bằng địa chỉ MAC WLAN. Địa chỉ MAC là duy nhất cho tất cả các thiết bị và nó hoạt động cho tất cả các loại thiết bị.
Ưu điểm của việc sử dụng địa chỉ MAC MAC làm ID thiết bị:
Nó là định danh duy nhất cho tất cả các loại thiết bị (điện thoại thông minh và máy tính bảng).
Nó vẫn là duy nhất nếu ứng dụng được cài đặt lại
Nhược điểm của việc sử dụng địa chỉ MAC MAC làm ID thiết bị:
Cung cấp cho bạn một giá trị không thể tin được từ Marshmallow trở lên.
Nếu thiết bị không có phần cứng wifi thì bạn sẽ nhận được địa chỉ MAC null, nhưng nhìn chung, hầu hết các thiết bị Android đều có phần cứng wifi và hầu như không có thiết bị nào trên thị trường không có phần cứng wifi.
NGUỒN: technetexperts.com
Vì trong API 26 không getDeviceId()
được dùng nữa nên bạn có thể sử dụng mã sau để phục vụ API 26 và các phiên bản cũ hơn
TelephonyManager telephonyManager = (TelephonyManager)getSystemService(Context.TELEPHONY_SERVICE);
String imei="";
if (android.os.Build.VERSION.SDK_INT >= 26) {
imei=telephonyManager.getImei();
}
else
{
imei=telephonyManager.getDeviceId();
}
Đừng quên thêm các yêu cầu cấp phép READ_PHONE_STATE
để sử dụng mã trên.
CẬP NHẬT: Từ Android 10, ứng dụng người dùng bị hạn chế để nhận các số nhận dạng phần cứng không thể cài đặt lại như IMEI.
Phương thức getDeviceId () của TelephonyManager trả về ID thiết bị duy nhất, ví dụ: IMEI cho GSM và MEID hoặc ESN cho điện thoại CDMA. Trả về null nếu ID thiết bị không khả dụng.
Mã Java
package com.AndroidTelephonyManager;
import android.app.Activity;
import android.content.Context;
import android.os.Bundle;
import android.telephony.TelephonyManager;
import android.widget.TextView;
public class AndroidTelephonyManager extends Activity {
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
TextView textDeviceID = (TextView)findViewById(R.id.deviceid);
//retrieve a reference to an instance of TelephonyManager
TelephonyManager telephonyManager = (TelephonyManager)getSystemService(Context.TELEPHONY_SERVICE);
textDeviceID.setText(getDeviceID(telephonyManager));
}
String getDeviceID(TelephonyManager phonyManager){
String id = phonyManager.getDeviceId();
if (id == null){
id = "not available";
}
int phoneType = phonyManager.getPhoneType();
switch(phoneType){
case TelephonyManager.PHONE_TYPE_NONE:
return "NONE: " + id;
case TelephonyManager.PHONE_TYPE_GSM:
return "GSM: IMEI=" + id;
case TelephonyManager.PHONE_TYPE_CDMA:
return "CDMA: MEID/ESN=" + id;
/*
* for API Level 11 or above
* case TelephonyManager.PHONE_TYPE_SIP:
* return "SIP";
*/
default:
return "UNKNOWN: ID=" + id;
}
}
}
XML
<linearlayout android:layout_height="fill_parent" android:layout_width="fill_parent" android:orientation="vertical" xmlns:android="http://schemas.android.com/apk/res/android">
<textview android:layout_height="wrap_content" android:layout_width="fill_parent" android:text="@string/hello">
<textview android:id="@+id/deviceid" android:layout_height="wrap_content" android:layout_width="fill_parent">
</textview></textview></linearlayout>
Yêu cầu cấp phép READ_PHONE_STATE trong tệp kê khai.
Bạn có thể sử dụng chức năng TelephonyManager TELEPHONY_SERVICE này để nhận ID thiết bị duy nhất , Yêu cầu quyền: READ_PHONE_STATE
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
Ví dụ: IMEI cho GSM và MEID hoặc ESN cho điện thoại CDMA .
/**
* Gets the device unique id called IMEI. Sometimes, this returns 00000000000000000 for the
* rooted devices.
**/
public static String getDeviceImei(Context ctx) {
TelephonyManager telephonyManager = (TelephonyManager) ctx.getSystemService(Context.TELEPHONY_SERVICE);
return telephonyManager.getDeviceId();
}
Trả về null nếu ID thiết bị không khả dụng .
Phương pháp getDeviceId()
không được chấp nhận. Có một phương pháp mới cho việc nàygetImei(int)
Hãy thử điều này (cần lấy IMEI đầu tiên luôn)
TelephonyManager mTelephony = (TelephonyManager) getSystemService(Context.TELEPHONY_SERVICE);
if (ActivityCompat.checkSelfPermission(LoginActivity.this,Manifest.permission.READ_PHONE_STATE)!= PackageManager.PERMISSION_GRANTED) {
return;
}
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
if (mTelephony.getPhoneCount() == 2) {
IME = mTelephony.getImei(0);
}else{
IME = mTelephony.getImei();
}
}else{
if (mTelephony.getPhoneCount() == 2) {
IME = mTelephony.getDeviceId(0);
} else {
IME = mTelephony.getDeviceId();
}
}
} else {
IME = mTelephony.getDeviceId();
}
Sử dụng mã dưới đây cung cấp cho bạn số IMEI:
TelephonyManager telephonyManager = (TelephonyManager) getSystemService(Context.TELEPHONY_SERVICE);
System.out.println("IMEI::" + telephonyManager.getDeviceId());
Mã Kotlin để nhận DeviceId (IMEI) với quyền xử lý và kiểm tra so sánh cho tất cả các phiên bản Android:
val telephonyManager = getSystemService(Context.TELEPHONY_SERVICE) as TelephonyManager
if (ContextCompat.checkSelfPermission(this, Manifest.permission.READ_PHONE_STATE)
== PackageManager.PERMISSION_GRANTED) {
// Permission is granted
val imei : String? = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) telephonyManager.imei
// older OS versions
else telephonyManager.deviceId
imei?.let {
Log.i("Log", "DeviceId=$it" )
}
} else { // Permission is not granted
}
Đồng thời thêm quyền này vào AndroidManifest.xml:
<uses-permission android:name="android.permission.READ_PHONE_STATE"/> <!-- IMEI-->
Bạn sẽ cần sự cho phép sau trong AndroidManifest.xml của bạn:
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
Để có được IMEI ( số nhận dạng thiết bị di động quốc tế) và nếu nó ở trên cấp độ API 26 thì chúng tôi sẽ telephonyManager.getImei()
là null vì vậy, chúng tôi sử dụng ANDROID_ID làm Mã định danh duy nhất.
public static String getIMEINumber(@NonNull final Context context)
throws SecurityException, NullPointerException {
TelephonyManager tm = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);
String imei;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
assert tm != null;
imei = tm.getImei();
//this change is for Android 10 as per security concern it will not provide the imei number.
if (imei == null) {
imei = Settings.Secure.getString(context.getContentResolver(), Settings.Secure.ANDROID_ID);
}
} else {
assert tm != null;
if (tm.getDeviceId() != null && !tm.getDeviceId().equals("000000000000000")) {
imei = tm.getDeviceId();
} else {
imei = Settings.Secure.getString(context.getContentResolver(), Settings.Secure.ANDROID_ID);
}
}
return imei;
}
Đối với những người tìm kiếm một phiên bản Kotlin, bạn có thể sử dụng một cái gì đó như thế này;
private fun telephonyService() {
val telephonyManager = getSystemService(TELEPHONY_SERVICE) as TelephonyManager
val imei = if (android.os.Build.VERSION.SDK_INT >= 26) {
Timber.i("Phone >= 26 IMEI")
telephonyManager.imei
} else {
Timber.i("Phone IMEI < 26")
telephonyManager.deviceId
}
Timber.i("Phone IMEI $imei")
}
LƯU Ý: Bạn phải bọc telephonyService()
bên trên bằng kiểm tra quyền sử dụng checkSelfPermission hoặc bất kỳ phương pháp nào bạn sử dụng.
Đồng thời thêm quyền này trong tệp kê khai;
<uses-permission android:name="android.permission.READ_PHONE_STATE"/>
sử dụng mã dưới đây:
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
String[] permissions = {Manifest.permission.READ_PHONE_STATE};
if (ActivityCompat.checkSelfPermission(this,
Manifest.permission.READ_PHONE_STATE) != PackageManager.PERMISSION_GRANTED) {
requestPermissions(permissions, READ_PHONE_STATE);
}
} else {
try {
TelephonyManager telephonyManager = (TelephonyManager) getSystemService(Context.TELEPHONY_SERVICE);
if (ActivityCompat.checkSelfPermission(this, Manifest.permission.READ_PHONE_STATE) != PackageManager.PERMISSION_GRANTED) {
return;
}
String imei = telephonyManager.getDeviceId();
} catch (Exception e) {
e.printStackTrace();
}
}
Và gọi phương thức onRequestPermissionsResult theo mã sau:
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
switch (requestCode) {
case READ_PHONE_STATE:
if (grantResults.length > 0
&& grantResults[0] == PackageManager.PERMISSION_GRANTED)
try {
TelephonyManager telephonyManager = (TelephonyManager) getSystemService(Context.TELEPHONY_SERVICE);
if (ActivityCompat.checkSelfPermission(this, Manifest.permission.READ_PHONE_STATE) != PackageManager.PERMISSION_GRANTED) {
return;
}
String imei = telephonyManager.getDeviceId();
} catch (Exception e) {
e.printStackTrace();
}
}
}
Thêm quyền sau trong AndroidManifest.xml của bạn:
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
Đối với Android 10 Mã sau đang hoạt động với tôi.
val uid: String = Settings.Secure.getString(ctx.applicationContext.contentResolver, Settings.Secure.ANDROID_ID)
if (ContextCompat.checkSelfPermission(ctx, Manifest.permission.READ_PHONE_STATE) == PackageManager.PERMISSION_GRANTED) {
imei = when {
Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q -> {
uid
}
Build.VERSION.SDK_INT >= Build.VERSION_CODES.O -> {
telephonyManager.imei
}
else -> {
telephonyManager.deviceId
}
}
}