uniqueidentifier device 확인 - 고유 한 Android 기기 ID가 있습니까?





15 Answers

업데이트 : Android 최신 버전에서 ANDROID_ID 와 관련된 많은 문제가 해결되었으며 더 이상이 방법이 필요하지 않다고 생각합니다. 앤서니의 대답 을 한번 보세요.

전체 공개 : 내 앱은 원래 아래 접근 방식을 사용했지만이 접근 방식을 더 이상 사용하지 않으며 emmby의 답변 링크 (즉, UUID#randomUUID() 생성 및 저장)가있는 android-developers.blogspot.com/2011/03/… 항목에 설명 된 접근 방식을 사용합니다.

이 질문에 대한 많은 대답이 있습니다. 대부분은 시간의 "일부"에서만 작동 할 것이며, 불행히도 충분하지 않습니다.

내 장치 테스트 (모든 전화 중 하나 이상이 활성화되지 않음)를 기반으로합니다.

  1. 테스트 된 모든 장치는 TelephonyManager.getDeviceId() 대한 값을 반환했습니다.
  2. 모든 GSM 장치 (모두 SIM으로 테스트 됨)는 TelephonyManager.getSimSerialNumber() 대한 값을 반환했습니다.
  3. 모든 CDMA 장치가 getSimSerialNumber() 대해 null을 반환 getSimSerialNumber() 예상대로).
  4. 추가 된 Google 계정이있는 모든 기기에서 ANDROID_ID 대한 값이 반환되었습니다.
  5. 모든 CDMA 기기는 ANDROID_IDTelephonyManager.getDeviceId() 대해 동일한 값 (또는 동일한 값의 파생 값)을 반환했습니다. 설치하는 동안 Google 계정이 추가 된 경우입니다.
  6. 아직 SIM이없는 GSM 장치, Google 계정이 추가되지 않은 GSM 장치 또는 비행기 모드의 장치를 테스트 할 기회가 없었습니다.

따라서 장치 자체에 고유 한 것이 있으면 TM.getDeviceId() 로 충분 해야 합니다. 분명히 일부 사용자는 다른 사용자보다 편집증 적입니다. 따라서이 식별자 중 하나 이상을 해시하는 것이 유용 할 수 있습니다. 따라서 문자열은 기기에서 거의 고유하지만 사용자의 실제 기기를 명시 적으로 식별하지는 않습니다. 예를 들어, String.hashCode() 를 사용하여 UUID와 결합하면 다음과 같습니다.

final TelephonyManager tm = (TelephonyManager) getBaseContext().getSystemService(Context.TELEPHONY_SERVICE);

final String tmDevice, tmSerial, androidId;
tmDevice = "" + tm.getDeviceId();
tmSerial = "" + tm.getSimSerialNumber();
androidId = "" + android.provider.Settings.Secure.getString(getContentResolver(), android.provider.Settings.Secure.ANDROID_ID);

UUID deviceUuid = new UUID(androidId.hashCode(), ((long)tmDevice.hashCode() << 32) | tmSerial.hashCode());
String deviceId = deviceUuid.toString();

다음과 같이 표시 될 수 있습니다. 00000000-54b3-e7c7-0000-000046bffd97

그것은 나를 위해 충분히 잘 작동합니다.

Richard가 아래에서 언급했듯이 TelephonyManager 속성을 읽을 수있는 권한이 필요하다는 것을 잊지 마세요. 따라서 매니페스트에 추가하십시오.

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

import libs

import android.content.Context;
import android.telephony.TelephonyManager;
import android.view.View;
변경 android_id 안드로이드

Android 기기에는 고유 한 ID가 있습니까? 그렇다면 Java를 사용하여 액세스하는 간단한 방법은 무엇입니까?




Dave Webb가 언급 하듯이 Android Developer Blog에는 이 문제를 다루는 기사 가 있습니다. 가장 선호하는 솔루션은 기기가 아닌 앱 설치를 추적하는 것이며 대부분의 사용 사례에서 잘 작동합니다. 블로그 게시물은 그 작업을하기 위해 필요한 코드를 보여줄 것이고, 나는 그것을 체크 아웃 할 것을 권한다.

그러나 앱 설치 식별자가 아닌 기기 식별자가 필요한 경우 블로그 게시물을 통해 해결책을 논의합니다. 나는 당신이 그렇게해야 할 이벤트에서 몇 가지 항목에 대한 몇 가지 추가 설명을 얻기 위해 구글의 누군가와 이야기했다. 앞서 언급 한 블로그 게시물에 언급되지 않은 기기 식별자에 대해 알아 낸 내용은 다음과 같습니다.

  • ANDROID_ID는 선호되는 장치 식별자입니다. ANDROID_ID는 Android 버전 2.1 이상 또는 2.3 이상에서 완벽하게 신뢰할 수 있습니다. 이 게시물에 언급 된 문제는 2.2 개뿐입니다.
  • 여러 제조업체의 여러 장치는 2.2의 ANDROID_ID 버그의 영향을받습니다.
  • 내가 결정할 수있는 한 모든 영향을받는 기기 의 ANDROID_ID9774d56d682e549c . 또한 에뮬레이터에서보고 한 것과 동일한 장치 ID 인 btw입니다.
  • Google은 OEM이 대부분의 기기 또는 대부분의 기기에서 문제를 패치 한 것으로 판단하지만 적어도 2011 년 4 월 초부터 ANDROID_ID가 깨진 기기를 쉽게 찾을 수 있음을 확인할 수있었습니다.

Google의 권장 사항에 따라 필요한 경우 시드로 ANDROID_ID를 사용하여 각 장치에 대한 고유 한 UUID를 생성하는 클래스를 구현했습니다. 필요에 따라 TelephonyManager.getDeviceId ()를 사용하여 실패한 경우 무작위로 생성 된 고유 한 UUID 앱 재시작시에도 지속됩니다 (앱 재 설치가 아님).

기기 ID에서 폴백해야하는 기기의 경우 고유 ID는 초기화시에도 계속 유지됩니다. 이것은 알고 있어야 할 것입니다. 초기화를 통해 고유 ID가 재설정되어야하는 경우 기기 ID 대신 임의의 UUID로 직접 전환하는 것이 좋습니다.

다시 말하지만이 코드는 앱 설치 ID가 아닌 기기 ID 용입니다. 대부분의 상황에서 앱 설치 ID는 아마도 당신이 찾고있는 것일 것입니다. 하지만 장치 ID가 필요하다면 다음 코드가 도움이 될 것입니다.

import android.content.Context;
import android.content.SharedPreferences;
import android.provider.Settings.Secure;
import android.telephony.TelephonyManager;

import java.io.UnsupportedEncodingException;
import java.util.UUID;

public class DeviceUuidFactory {

    protected static final String PREFS_FILE = "device_id.xml";
    protected static final String PREFS_DEVICE_ID = "device_id";
    protected volatile static UUID uuid;

    public DeviceUuidFactory(Context context) {
        if (uuid == null) {
            synchronized (DeviceUuidFactory.class) {
                if (uuid == null) {
                    final SharedPreferences prefs = context
                            .getSharedPreferences(PREFS_FILE, 0);
                    final String id = prefs.getString(PREFS_DEVICE_ID, null);
                    if (id != null) {
                        // Use the ids previously computed and stored in the
                        // prefs file
                        uuid = UUID.fromString(id);
                    } else {
                        final String androidId = Secure.getString(
                            context.getContentResolver(), Secure.ANDROID_ID);
                        // Use the Android ID unless it's broken, in which case
                        // fallback on deviceId,
                        // unless it's not available, then fallback on a random
                        // number which we store to a prefs file
                        try {
                            if (!"9774d56d682e549c".equals(androidId)) {
                                uuid = UUID.nameUUIDFromBytes(androidId
                                        .getBytes("utf8"));
                            } else {
                                final String deviceId = (
                                    (TelephonyManager) context
                                    .getSystemService(Context.TELEPHONY_SERVICE))
                                    .getDeviceId();
                                uuid = deviceId != null ? UUID
                                    .nameUUIDFromBytes(deviceId
                                            .getBytes("utf8")) : UUID
                                    .randomUUID();
                            }
                        } catch (UnsupportedEncodingException e) {
                            throw new RuntimeException(e);
                        }
                        // Write the value out to the prefs file
                        prefs.edit()
                                .putString(PREFS_DEVICE_ID, uuid.toString())
                                .commit();
                    }
                }
            }
        }
    }

    /**
     * Returns a unique UUID for the current android device. As with all UUIDs,
     * this unique ID is "very highly likely" to be unique across all Android
     * devices. Much more so than ANDROID_ID is.
     * 
     * The UUID is generated by using ANDROID_ID as the base key if appropriate,
     * falling back on TelephonyManager.getDeviceID() if ANDROID_ID is known to
     * be incorrect, and finally falling back on a random UUID that's persisted
     * to SharedPreferences if getDeviceID() does not return a usable value.
     * 
     * In some rare circumstances, this ID may change. In particular, if the
     * device is factory reset a new device ID may be generated. In addition, if
     * a user upgrades their phone from certain buggy implementations of Android
     * 2.2 to a newer, non-buggy version of Android, the device ID may change.
     * Or, if a user uninstalls your app on a device that has neither a proper
     * Android ID nor a Device ID, this ID may change on reinstallation.
     * 
     * Note that if the code falls back on using TelephonyManager.getDeviceId(),
     * the resulting ID will NOT change after a factory reset. Something to be
     * aware of.
     * 
     * Works around a bug in Android 2.2 for many devices when using ANDROID_ID
     * directly.
     * 
     * @see http://code.google.com/p/android/issues/detail?id=10603
     * 
     * @return a UUID that may be used to uniquely identify your device for most
     *         purposes.
     */
    public UUID getDeviceUuid() {
        return uuid;
    }
}



또한 Wi-Fi 어댑터의 MAC 주소를 고려할 수도 있습니다. suchly 검색된 :

WifiManager wm = (WifiManager)Ctxt.getSystemService(Context.WIFI_SERVICE);
return wm.getConnectionInfo().getMacAddress();

매니페스트에 android.permission.ACCESS_WIFI_STATE 권한이 필요합니다.

Wi-Fi가 연결되어 있지 않은 경우에도 사용할 수 있다고보고되었습니다. Joe가 위의 대답에서이 장치를 여러 장치에서 시험해 보면 좋을 것입니다.

일부 기기에서는 Wi-Fi가 꺼져있을 때 사용할 수 없습니다.

참고 : 안드로이드 6.x에서 일관된 가짜 mac 주소를 반환합니다 : 02:00:00:00:00:00







다음 코드는 숨겨진 Android API를 사용하여 기기 일련 번호를 반환합니다. 그러나이 코드는 "ro.serialno"가이 장치에 설정되어 있지 않으므로 Samsung Galaxy Tab에서 작동하지 않습니다.

String serial = null;

try {
    Class<?> c = Class.forName("android.os.SystemProperties");
    Method get = c.getMethod("get", String.class);
    serial = (String) get.invoke(c, "ro.serialno");
}
catch (Exception ignored) {

}



아래 코드를 사용하여 Android OS 장치의 고유 한 장치 ID를 문자열로 가져올 수 있습니다.

deviceId = Secure.getString(getApplicationContext().getContentResolver(), Secure.ANDROID_ID); 



내가 추가 할 한 가지는 - 나는 그 독특한 상황 중 하나를 가지고 있습니다.

사용 :

deviceId = Secure.getString(this.getContext().getContentResolver(), Secure.ANDROID_ID);

내 Viewsonic G Tablet이 Null이 아닌 DeviceID를보고하더라도 모든 단일 G Tablet은 동일한 번호를보고합니다.

"고유 한"DeviceID를 기반으로 다른 사람의 계정에 즉시 액세스 할 수있는 "Pocket Empires"게임을 재미있게 만듭니다.

내 장치에 셀 라디오가 없습니다.




아래 클래스 파일에 코드 추가 :

final TelephonyManager tm = (TelephonyManager) getBaseContext()
            .getSystemService(SplashActivity.TELEPHONY_SERVICE);
    final String tmDevice, tmSerial, androidId;
    tmDevice = "" + tm.getDeviceId();
    Log.v("DeviceIMEI", "" + tmDevice);
    tmSerial = "" + tm.getSimSerialNumber();
    Log.v("GSM devices Serial Number[simcard] ", "" + tmSerial);
    androidId = "" + android.provider.Settings.Secure.getString(getContentResolver(),
            android.provider.Settings.Secure.ANDROID_ID);
    Log.v("androidId CDMA devices", "" + androidId);
    UUID deviceUuid = new UUID(androidId.hashCode(),
            ((long) tmDevice.hashCode() << 32) | tmSerial.hashCode());
    String deviceId = deviceUuid.toString();
    Log.v("deviceIdUUID universally unique identifier", "" + deviceId);
    String deviceModelName = android.os.Build.MODEL;
    Log.v("Model Name", "" + deviceModelName);
    String deviceUSER = android.os.Build.USER;
    Log.v("Name USER", "" + deviceUSER);
    String devicePRODUCT = android.os.Build.PRODUCT;
    Log.v("PRODUCT", "" + devicePRODUCT);
    String deviceHARDWARE = android.os.Build.HARDWARE;
    Log.v("HARDWARE", "" + deviceHARDWARE);
    String deviceBRAND = android.os.Build.BRAND;
    Log.v("BRAND", "" + deviceBRAND);
    String myVersion = android.os.Build.VERSION.RELEASE;
    Log.v("VERSION.RELEASE", "" + myVersion);
    int sdkVersion = android.os.Build.VERSION.SDK_INT;
    Log.v("VERSION.SDK_INT", "" + sdkVersion);

AndroidManifest.xml에 추가 :

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



장점과 단점을 가지고 이러한 ANDROID_ID문제를 해결 하기위한 다양한 접근 방식 이 있습니다 ( null때로는 특정 모델의 장치가 항상 동일한 ID를 반환 할 수 있음).

  • 사용자 정의 ID 생성 알고리즘 구현 (정적이면서 변경되지 않는 장치 속성을 기반으로 -> 아는 사용자)
  • IMEI , 일련 번호, Wi-Fi / 블루투스 -MAC 주소 와 같은 다른 ID를 악용 합니다 (모든 기기에 존재하지 않거나 추가 권한이 필요함)

나는 기존의 OpenUDID 구현 (참조하여 자신 선호 https://github.com/ylechelle/OpenUDID 안드로이드)을 (참조 https://github.com/vieux/OpenUDID ). ANDROID_ID위에서 언급 한 문제에 대해 대체로 쉽게 통합하고 사용할 수 있습니다 .




내 두 센트 -주의 안드로이드 개발자의 블로그 에서 논의 된 설치되지 않은 장치 ID (잘못된) 고유 ID 입니다.

SharedPreferences가 여러 프로세스에서 동기화되지 않으므로 @emmby가 제공 하는 solution 은 응용 프로그램 ID에서 제외됩니다 ( here 및 here 참조 ). 그래서 나는이 모든 것을 피했다.

대신 열거 형에 (장치) ID를 가져 오는 다양한 전략을 캡슐화했습니다. 열거 형 상수의 순서를 변경하면 ID를 가져 오는 다양한 방법의 우선 순위가 영향을받습니다. 첫 번째 null이 아닌 ID가 반환되거나 예외가 throw됩니다 (null을 의미하지 않는 Java 사용법에 따라). 그래서 예를 들어 TELEPHONY가 먼저 있습니다.하지만 좋은 기본 선택은 ANDROID_ID 베타입니다.

import android.Manifest.permission;
import android.bluetooth.BluetoothAdapter;
import android.content.Context;
import android.content.pm.PackageManager;
import android.net.wifi.WifiManager;
import android.provider.Settings.Secure;
import android.telephony.TelephonyManager;
import android.util.Log;

// TODO : hash
public final class DeviceIdentifier {

    private DeviceIdentifier() {}

    /** @see http://code.google.com/p/android/issues/detail?id=10603 */
    private static final String ANDROID_ID_BUG_MSG = "The device suffers from "
        + "the Android ID bug - its ID is the emulator ID : "
        + IDs.BUGGY_ANDROID_ID;
    private static volatile String uuid; // volatile needed - see EJ item 71
    // need lazy initialization to get a context

    /**
     * Returns a unique identifier for this device. The first (in the order the
     * enums constants as defined in the IDs enum) non null identifier is
     * returned or a DeviceIDException is thrown. A DeviceIDException is also
     * thrown if ignoreBuggyAndroidID is false and the device has the Android ID
     * bug
     *
     * @param ctx
     *            an Android constant (to retrieve system services)
     * @param ignoreBuggyAndroidID
     *            if false, on a device with the android ID bug, the buggy
     *            android ID is not returned instead a DeviceIDException is
     *            thrown
     * @return a *device* ID - null is never returned, instead a
     *         DeviceIDException is thrown
     * @throws DeviceIDException
     *             if none of the enum methods manages to return a device ID
     */
    public static String getDeviceIdentifier(Context ctx,
            boolean ignoreBuggyAndroidID) throws DeviceIDException {
        String result = uuid;
        if (result == null) {
            synchronized (DeviceIdentifier.class) {
                result = uuid;
                if (result == null) {
                    for (IDs id : IDs.values()) {
                        try {
                            result = uuid = id.getId(ctx);
                        } catch (DeviceIDNotUniqueException e) {
                            if (!ignoreBuggyAndroidID)
                                throw new DeviceIDException(e);
                        }
                        if (result != null) return result;
                    }
                    throw new DeviceIDException();
                }
            }
        }
        return result;
    }

    private static enum IDs {
        TELEPHONY_ID {

            @Override
            String getId(Context ctx) {
                // TODO : add a SIM based mechanism ? tm.getSimSerialNumber();
                final TelephonyManager tm = (TelephonyManager) ctx
                        .getSystemService(Context.TELEPHONY_SERVICE);
                if (tm == null) {
                    w("Telephony Manager not available");
                    return null;
                }
                assertPermission(ctx, permission.READ_PHONE_STATE);
                return tm.getDeviceId();
            }
        },
        ANDROID_ID {

            @Override
            String getId(Context ctx) throws DeviceIDException {
                // no permission needed !
                final String andoidId = Secure.getString(
                    ctx.getContentResolver(),
                    android.provider.Settings.Secure.ANDROID_ID);
                if (BUGGY_ANDROID_ID.equals(andoidId)) {
                    e(ANDROID_ID_BUG_MSG);
                    throw new DeviceIDNotUniqueException();
                }
                return andoidId;
            }
        },
        WIFI_MAC {

            @Override
            String getId(Context ctx) {
                WifiManager wm = (WifiManager) ctx
                        .getSystemService(Context.WIFI_SERVICE);
                if (wm == null) {
                    w("Wifi Manager not available");
                    return null;
                }
                assertPermission(ctx, permission.ACCESS_WIFI_STATE); // I guess
                // getMacAddress() has no java doc !!!
                return wm.getConnectionInfo().getMacAddress();
            }
        },
        BLUETOOTH_MAC {

            @Override
            String getId(Context ctx) {
                BluetoothAdapter ba = BluetoothAdapter.getDefaultAdapter();
                if (ba == null) {
                    w("Bluetooth Adapter not available");
                    return null;
                }
                assertPermission(ctx, permission.BLUETOOTH);
                return ba.getAddress();
            }
        }
        // TODO PSEUDO_ID
        // http://www.pocketmagic.net/2011/02/android-unique-device-id/
        ;

        static final String BUGGY_ANDROID_ID = "9774d56d682e549c";
        private final static String TAG = IDs.class.getSimpleName();

        abstract String getId(Context ctx) throws DeviceIDException;

        private static void w(String msg) {
            Log.w(TAG, msg);
        }

        private static void e(String msg) {
            Log.e(TAG, msg);
        }
    }

    private static void assertPermission(Context ctx, String perm) {
        final int checkPermission = ctx.getPackageManager().checkPermission(
            perm, ctx.getPackageName());
        if (checkPermission != PackageManager.PERMISSION_GRANTED) {
            throw new SecurityException("Permission " + perm + " is required");
        }
    }

    // =========================================================================
    // Exceptions
    // =========================================================================
    public static class DeviceIDException extends Exception {

        private static final long serialVersionUID = -8083699995384519417L;
        private static final String NO_ANDROID_ID = "Could not retrieve a "
            + "device ID";

        public DeviceIDException(Throwable throwable) {
            super(NO_ANDROID_ID, throwable);
        }

        public DeviceIDException(String detailMessage) {
            super(detailMessage);
        }

        public DeviceIDException() {
            super(NO_ANDROID_ID);
        }
    }

    public static final class DeviceIDNotUniqueException extends
            DeviceIDException {

        private static final long serialVersionUID = -8940090896069484955L;

        public DeviceIDNotUniqueException() {
            super(ANDROID_ID_BUG_MSG);
        }
    }
}



또 다른 방법은 /sys/class/android_usb/android0/iSerial허가없이 앱에서 사용 하는 것입니다.

user@creep:~$ adb shell ls -l /sys/class/android_usb/android0/iSerial
-rw-r--r-- root     root         4096 2013-01-10 21:08 iSerial
user@creep:~$ adb shell cat /sys/class/android_usb/android0/iSerial
0A3CXXXXXXXXXX5

Java에서이를 수행하려면 FileInputStream을 사용하여 iSerial 파일을 열고 문자를 읽어야합니다. 모든 장치에이 파일이있는 것은 아니므로 예외 처리기에서이 파일을 래핑해야합니다.

최소한 다음 장치가이 파일을 세계에서 읽을 수 있도록하는 것으로 알려져 있습니다.

  • Galaxy Nexus
  • Nexus S
  • Motorola Xoom 3G
  • 도시바 AT300
  • HTC One V
  • 미니 MK802
  • 삼성 갤럭시 S II

내 블로그 게시물을 볼 수도 있습니다. 안드로이드 하드웨어 시리얼 넘버가 권한이없는 앱으로 유출 되는 경우 다른 파일을 통해 정보를 얻을 수 있습니다.




다음 코드를 IMEI사용하여 Secure를 사용하거나 Secure를 사용합니다. ANDROID_ID휴대 전화 기능이없는 기기의 경우

String identifier = null;
TelephonyManager tm = (TelephonyManager)context.getSystemService(Context.TELEPHONY_SERVICE));
if (tm != null)
      identifier = tm.getDeviceId();
if (identifier == null || identifier .length() == 0)
      identifier = Secure.getString(activity.getContentResolver(),Secure.ANDROID_ID);



Google 인스턴스 ID

I / O 2015에서 출시되었습니다. Android에서 Play 서비스가 필요합니다. 7.5.

https://developers.google.com/instance-id/
https://developers.google.com/instance-id/guides/android-implementation

InstanceID iid = InstanceID.getInstance( context );   // Google docs are wrong - this requires context
String id = iid.getId();  // blocking call

Google은이 ID를 사용하여 Android, Chrome 및 iOS의 설치를 식별합니다.

그것은 장치가 아닌 설치를 식별하지만, 다시 한번 ANDROID_ID (허용 된 응답)는 더 이상 장치를 식별하지 않습니다. ARC 런타임 에서이 새로운 인스턴스 ID처럼 모든 설치 ( 새로운 세부 사항 )에 대해 새로운 ANDROID_ID가 생성됩니다 . 또한, 나는 장치 (장치가 아닌)를 확인하는 것이 우리 중 대부분이 실제로 찾고있는 것이라고 생각합니다.

인스턴스 ID의 장점

구글이이를 목적으로 사용하고 (설치를 식별하는), 플랫폼을 넘어서고, 다른 많은 목적으로 사용될 수 있다고 생각합니다. (위 링크 참조)

GCM을 사용하는 경우 GCM 토큰 (이전 GCM 등록 ID를 대체)을 얻기 위해 필요하기 때문에 결국이 인스턴스 ID를 사용해야합니다.

단점 / 문제점

현재 구현 (GPS 7.5)에서는 앱이 요청할 때 인스턴스 ID가 서버에서 검색됩니다. 위의 호출이 차단 호출 인 것을 의미합니다. 비 과학적 테스트에서 장치가 온라인 상태 인 경우 1-3 초, 오프라인 상태 인 경우 0.5 - 1.0 초가 걸릴 것입니다 (아마도 이것은 포기하기 전에 기다리는 시간 일 것입니다). 임의의 ID). 북미 지역에서는 Android 5.1.1 및 GPS 7.5가 설치된 Nexus 5에서 테스트되었습니다.

자신이 의도 한 목적으로 ID를 사용하면 - 예. 앱 인증, 앱 식별, GCM -이 1-3 초가 귀찮은 일이라고 생각합니다 (물론 앱에 따라 다름).




여기에 30 개 이상의 답변이 있으며 일부는 동일하고 일부는 고유합니다. 이 답변은 몇 가지 답변을 기반으로합니다. 그들 중 하나는 @ Lenn Dolling의 대답입니다.

3 개의 ID를 결합하고 32 자리 16 진수 문자열을 만듭니다. 그것은 저를 위해 아주 잘 작동했습니다.

3 ID :
Pseudo-ID - 물리적 장치 사양에 따라 생성됩니다.
ANDROID_ID - Settings.Secure.ANDROID_ID
Bluetooth 주소 - Bluetooth 어댑터 주소

다음과 같이 반환 할 것입니다 : 551F27C060712A72730B0A0F734064B1

참고 : longId문자열에 ID를 더 추가 할 수 있습니다 . 예 : 일련 번호. 와이파이 어댑터 주소. IMEI. 이렇게하면 기기별로 더욱 독특 해집니다.

@SuppressWarnings("deprecation")
@SuppressLint("HardwareIds")
public static String generateDeviceIdentifier(Context context) {

        String pseudoId = "35" +
                Build.BOARD.length() % 10 +
                Build.BRAND.length() % 10 +
                Build.CPU_ABI.length() % 10 +
                Build.DEVICE.length() % 10 +
                Build.DISPLAY.length() % 10 +
                Build.HOST.length() % 10 +
                Build.ID.length() % 10 +
                Build.MANUFACTURER.length() % 10 +
                Build.MODEL.length() % 10 +
                Build.PRODUCT.length() % 10 +
                Build.TAGS.length() % 10 +
                Build.TYPE.length() % 10 +
                Build.USER.length() % 10;

        String androidId = Settings.Secure.getString(context.getContentResolver(), Settings.Secure.ANDROID_ID);

        BluetoothAdapter bluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
        String btId = "";

        if (bluetoothAdapter != null) {
            btId = bluetoothAdapter.getAddress();
        }

        String longId = pseudoId + androidId + btId;

        try {
            MessageDigest messageDigest = MessageDigest.getInstance("MD5");
            messageDigest.update(longId.getBytes(), 0, longId.length());

            // get md5 bytes
            byte md5Bytes[] = messageDigest.digest();

            // creating a hex string
            String identifier = "";

            for (byte md5Byte : md5Bytes) {
                int b = (0xFF & md5Byte);

                // if it is a single digit, make sure it have 0 in front (proper padding)
                if (b <= 0xF) {
                    identifier += "0";
                }

                // add number to string
                identifier += Integer.toHexString(b);
            }

            // hex string to uppercase
            identifier = identifier.toUpperCase();
            return identifier;
        } catch (Exception e) {
            Log.e("TAG", e.toString());
        }
        return "";
}



TelephonyManger.getDeviceId () 고유 한 장치 ID를 반환합니다 ( 예 : GSM 용 IMEI 및 CDMA 전화 용 MEID 또는 ESN).

final TelephonyManager mTelephony = (TelephonyManager) getSystemService(Context.TELEPHONY_SERVICE);            
String myAndroidDeviceId = mTelephony.getDeviceId(); 

그러나 나는 다음을 사용하는 것이 좋습니다.

Settings.Secure.ANDROID_ID 는 Android ID를 고유 한 64 비트 16 진수 문자열로 반환합니다.

    String   myAndroidDeviceId = Secure.getString(getApplicationContext().getContentResolver(), Secure.ANDROID_ID); 

경우에 따라 TelephonyManger.getDeviceId () 는 null을 반환하므로 고유 한 ID를 보장하기 위해이 메서드를 사용합니다.

public String getUniqueID(){    
    String myAndroidDeviceId = "";
    TelephonyManager mTelephony = (TelephonyManager) getSystemService(Context.TELEPHONY_SERVICE);
    if (mTelephony.getDeviceId() != null){
        myAndroidDeviceId = mTelephony.getDeviceId(); 
    }else{
         myAndroidDeviceId = Secure.getString(getApplicationContext().getContentResolver(), Secure.ANDROID_ID); 
    }
    return myAndroidDeviceId;
}



Related