안드로이드 10 에서는 TelephonyManager에서 개인을 특정할 수 있는 정보를 가져올수 없도록 변경되었다.TelephonyManager().getDeviceId()
TelephonyManager().getImei()
TelephonyManager().getMeid()
그리고 하드웨어의 시리얼넘버도 사용이 불가능해졌다.
Builde.SERIAL
In android 10, couldn't get device id using permission "READ_PHONE_STATE".
getDeviceId() has been deprecated since API level 26.
You can use an instance id from firebase e.g FirebaseInstanceId.getInstance().getId();.
String deviceId = android.provider.Settings.Secure.getString(
context.getContentResolver(), android.provider.Settings.Secure.ANDROID_ID);
삼성갤럭시 S10(Android 10) 에서 테스트한 결과 코드를 적어둔다.
기존 안드로이드 폰은 IMEI 값이 15자리 숫자로만 되어 있었는데
아래 코드에서 제공하는 deviceID값은 IMEI 값이 아닌 다른 값을 제공하는 거 같다.
개발자모드에서 수집한 deviceID 와 release 모드로 앱을 만든 것과 값이 다르더라.
cc64a5b80853bc8d
36f7660af1dc22f2
public static String getDeviceId(Context context) {
// 단말기의 ID 정보를 얻기 위해서는 READ_PHONE_STATE 권한이 필요 String deviceId;
if (android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) { deviceId = Settings.Secure.getString(context.getContentResolver(), Settings.Secure.ANDROID_ID); } else { final TelephonyManager mTelephony = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE); if (ActivityCompat.checkSelfPermission(context, Manifest.permission.READ_PHONE_STATE) != PackageManager.PERMISSION_GRANTED) { //권한 없을 경우 if (ActivityCompat.shouldShowRequestPermissionRationale((Activity) context, Manifest.permission.READ_PHONE_STATE)) { // 사용자에게 해당 권한이 필요한 이유에 대해 설명 Toast.makeText(context, "앱 실행을 위해서는 전화 관리 권한을 설정해야 합니다.", Toast.LENGTH_SHORT).show(); } // 최초로 권한을 요청하는 경우 ActivityCompat.requestPermissions((Activity) context, new String[]{Manifest.permission.READ_PHONE_STATE} , 2); return null; } else { Log.v("TAG","Permission is granted"); if (mTelephony.getDeviceId() != null) { deviceId = mTelephony.getDeviceId(); } else { deviceId = Settings.Secure.getString(context.getContentResolver(), Settings.Secure.ANDROID_ID); } } } return deviceId; }
@Override public void onRequestPermissionsResult(int requestCode, String permissions[], int[] grantResults) { switch (requestCode) { case 2: { if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) { Toast.makeText(getApplicationContext(), "Permission granted", Toast.LENGTH_SHORT).show(); } else { Toast.makeText(getApplicationContext(), "Permission denied", Toast.LENGTH_SHORT).show(); } return; } } } |
만약 deviceId = Settings.Secure.getString(context.getContentResolver(), Settings.Secure.ANDROID_ID); 가 제대로 동작하지 않는다면, 다른 대책을 세워야 할 거 같다.
if (android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
//deviceId = Settings.Secure.getString(context.getContentResolver(), Settings.Secure.ANDROID_ID);
deviceId = getUniqueID(context);
}
public synchronized static String getUniqueID(Context context) {
// 자바에서는 기본적으로 UUID를 생성하는 클래스를 지원한다.
// UUID를 생성하면 간단하게 유니크한 ID를 얻을 수 있다.
if (uniqueID == null) {
SharedPreferences sharedPrefs = context.getSharedPreferences(PREF_UNIQUE_ID, Context.MODE_PRIVATE);
uniqueID = sharedPrefs.getString(PREF_UNIQUE_ID, null);
if (uniqueID == null) {
uniqueID = UUID.randomUUID().toString().replace("-", "");
Log.e("UUID : ",uniqueID);
SharedPreferences.Editor editor = sharedPrefs.edit();
editor.putString(PREF_UNIQUE_ID, uniqueID);
editor.commit();
}
}
// 앱을 삭제하면 정보 삭제되므로 앱 삭제시에는 관리자에게 초기화 요청 필요
return uniqueID;
}
Eclipse 테스트 일시 : 2020.3.19일
오래전에 Eclipse 개발툴로 개발한 걸 테스트 해봤다.
디바이스를 구분하는 고유 번호로 ANDROID_ID 로 대체하면 해결되더라.
릴리즈 버전과 디버깅 버전 APK 의 Android ID 가 다르지만 사용자에게는 문제는 없다.
//TelephonyManager tm = (TelephonyManager) getSystemService(Context.TELEPHONY_SERVICE); String uID = Settings.Secure.getString(getApplicationContext().getContentResolver(), Settings.Secure.ANDROID_ID);
|