Apakah ada ID perangkat Android yang unik?

2753

Apakah perangkat Android memiliki ID unik, dan jika demikian, apa cara sederhana untuk mengaksesnya menggunakan Java?

Tyler
sumber
38
Jika Anda menggunakan ANDROID_IDpastikan untuk membaca jawaban ini dan bug ini .
Dheeraj Vepakomma
Jika Anda membutuhkan solusi pada tahun 2020, Anda harus membaca pengenal android pada tahun 2020
Nikita Kurtin

Jawaban:

2026

Settings.Secure#ANDROID_IDmengembalikan ID Android sebagai unik untuk setiap string hex 64-bit pengguna .

import android.provider.Settings.Secure;

private String android_id = Secure.getString(getContext().getContentResolver(),
                                                        Secure.ANDROID_ID); 
Anthony Forloney
sumber
477
Terkadang dikenal sebagai nol, ini didokumentasikan sebagai "dapat berubah setelah reset pabrik". Gunakan dengan risiko Anda sendiri, dan dapat dengan mudah diubah pada ponsel yang di-root.
Seva Alekseyev
18
Saya pikir kita perlu berhati-hati dalam menggunakan ANDROID_ID dalam hash dalam jawaban pertama tentang karena mungkin tidak disetel saat aplikasi dijalankan pertama kali, dapat diatur kemudian, atau bahkan mungkin berubah secara teori, maka ID unik dapat berubah
46
Sadarilah ada batasan besar dengan solusi ini: android-developers.blogspot.com/2011/03/...
emmby
35
ANDROID_ID tidak lagi secara unik mengidentifikasi perangkat (per 4.2): stackoverflow.com/a/13465373/150016
Tom
1146

UPDATE : Pada versi Android terbaru, banyak masalah dengan ANDROID_IDtelah diselesaikan, dan saya percaya pendekatan ini tidak lagi diperlukan. Silakan lihat jawaban Anthony .

Pengungkapan penuh: aplikasi saya menggunakan pendekatan di bawah ini awalnya tetapi tidak lagi menggunakan pendekatan ini, dan kami sekarang menggunakan pendekatan yang diuraikan dalam entri Blog Pengembang Android yang terhubung dengan tautan emmby (yaitu, menghasilkan dan menyimpan a UUID#randomUUID()).


Ada banyak jawaban untuk pertanyaan ini, sebagian besar hanya akan berfungsi "sebagian" pada saat itu, dan sayangnya itu tidak cukup baik.

Berdasarkan pengujian perangkat saya (semua ponsel, setidaknya satu di antaranya tidak diaktifkan):

  1. Semua perangkat yang diuji mengembalikan nilai TelephonyManager.getDeviceId()
  2. Semua perangkat GSM (semua diuji dengan SIM) mengembalikan nilai TelephonyManager.getSimSerialNumber()
  3. Semua perangkat CDMA mengembalikan nol untuk getSimSerialNumber()(seperti yang diharapkan)
  4. Semua perangkat dengan akun Google yang ditambahkan mengembalikan nilai untuk ANDROID_ID
  5. Semua perangkat CDMA mengembalikan nilai yang sama (atau turunan dari nilai yang sama) untuk keduanya ANDROID_IDdan TelephonyManager.getDeviceId()- selama akun Google telah ditambahkan selama pengaturan.
  6. Saya belum memiliki kesempatan untuk menguji perangkat GSM tanpa SIM, perangkat GSM tanpa akun Google yang ditambahkan, atau perangkat apa pun dalam mode pesawat.

Jadi jika Anda menginginkan sesuatu yang unik untuk perangkat itu sendiri, TM.getDeviceId() harus cukup. Jelas beberapa pengguna lebih paranoid daripada yang lain, jadi mungkin berguna untuk hash 1 atau lebih dari pengidentifikasi ini, sehingga string masih hampir unik untuk perangkat, tetapi tidak secara eksplisit mengidentifikasi perangkat sebenarnya pengguna. Misalnya, menggunakan String.hashCode(), dikombinasikan dengan 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();

mungkin menghasilkan sesuatu seperti: 00000000-54b3-e7c7-0000-000046bffd97

Ini cukup berhasil bagi saya.

Seperti yang disebutkan Richard di bawah ini, jangan lupa bahwa Anda perlu izin untuk membaca TelephonyManagerproperti, jadi tambahkan ini ke manifes Anda:

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

impor libs

import android.content.Context;
import android.telephony.TelephonyManager;
import android.view.View;
Joe
sumber
151
ID berbasis telepon tidak akan ada di perangkat tablet, bukan?
Seva Alekseyev
22
Karenanya mengapa saya mengatakan sebagian besar tidak akan berfungsi sepanjang waktu :) Saya belum melihat jawaban untuk pertanyaan ini yang dapat diandalkan untuk semua perangkat, semua jenis perangkat, dan semua konfigurasi perangkat keras. Itu sebabnya pertanyaan ini ada di sini untuk memulai. Cukup jelas bahwa tidak ada solusi akhir untuk semua ini. Pabrikan perangkat individual mungkin memiliki nomor seri perangkat, tetapi tidak terpapar untuk kami gunakan, dan itu bukan keharusan. Jadi kita pergi dengan apa yang tersedia bagi kita.
Joe
31
Sampel kode berfungsi dengan baik. Ingatlah untuk menambahkan <uses-permission android:name="android.permission.READ_PHONE_STATE" />file manifes. Jika menyimpan dalam database, string yang dikembalikan adalah 36 karakter.
Richard
10
Sadarilah ada batasan besar dengan solusi ini: android-developers.blogspot.com/2011/03/...
emmby
18
@softarn: Saya yakin yang Anda maksud adalah Blog Pengembang Android yang sudah ditautkan, yang menjelaskan apa yang ingin Anda katakan, jadi mungkin Anda seharusnya hanya meningkatkan komentarnya saja. Either way, seperti emmby menyebutkan dalam jawabannya, masih ada masalah bahkan dengan info blog. Pertanyaannya meminta pengidentifikasi PERANGKAT unik (bukan pengidentifikasi instalasi), jadi saya tidak setuju dengan pernyataan Anda. Blog membuat asumsi bahwa apa yang Anda inginkan tidak harus melacak perangkat, sedangkan pertanyaannya hanya menanyakan hal itu. Saya setuju dengan blog sebaliknya.
Joe
439

Terakhir Diperbarui: 6/2/15


Setelah membaca setiap posting Stack Overflow tentang membuat ID unik, blog pengembang Google dan dokumentasi Android, saya merasa seolah-olah 'Pseudo ID' adalah pilihan terbaik.

Masalah Utama: Perangkat Keras vs Perangkat Lunak

Perangkat keras

  • Pengguna dapat mengubah perangkat keras, tablet Android atau ponsel mereka, jadi ID unik berdasarkan perangkat keras bukanlah ide yang baik untuk PENGGUNA PELACAKAN
  • Untuk TRACKING HARDWARE , ini adalah ide bagus

Perangkat lunak

  • Pengguna dapat menghapus / mengubah ROM mereka jika mereka di-root
  • Anda dapat melacak pengguna di berbagai platform (iOS, Android, Windows, dan Web)
  • Yang paling diinginkan untuk TRACK AN PENGGUNA INDIVIDU dengan persetujuan mereka adalah cukup minta mereka login (buat ini mulus menggunakan OAuth)

Kerusakan keseluruhan dengan Android

- Jaminan keunikan (termasuk perangkat yang di-rooting) untuk API> = 9/10 (99,5% dari perangkat Android)

- Tidak ada izin tambahan

Kode psuedo:

if API >= 9/10: (99.5% of devices)

return unique ID containing serial id (rooted devices may be different)

else

return the unique ID of build information (may overlap data - API < 9)

Terima kasih kepada @stansult untuk memposting semua opsi kami (dalam pertanyaan Stack Overflow).

Daftar opsi - alasan mengapa / mengapa tidak menggunakannya:

  • Email Pengguna - Perangkat Lunak

    • Pengguna dapat mengubah email - SANGAT tidak mungkin
    • API 5+ <uses-permission android:name="android.permission.GET_ACCOUNTS" />atau
    • API 14+ <uses-permission android:name="android.permission.READ_PROFILE" /> <uses-permission android:name="android.permission.READ_CONTACTS" />( Cara mendapatkan alamat email utama perangkat Android )
  • Nomor Telepon Pengguna - Perangkat Lunak

    • Pengguna dapat mengubah nomor telepon - SANGAT tidak mungkin
    • <uses-permission android:name="android.permission.READ_PHONE_STATE" />
  • IMEI - Hardware (hanya telepon, kebutuhan android.permission.READ_PHONE_STATE)

    • Sebagian besar pengguna membenci kenyataan bahwa ia mengatakan "Panggilan Telepon" dalam izin. Beberapa pengguna memberikan peringkat buruk, karena mereka percaya Anda hanya mencuri informasi pribadi mereka ketika yang benar-benar ingin Anda lakukan adalah melacak pemasangan perangkat. Jelas bahwa Anda sedang mengumpulkan data.
    • <uses-permission android:name="android.permission.READ_PHONE_STATE" />
  • Android ID - Hardware (bisa nol, bisa berubah setelah reset pabrik, bisa diubah pada perangkat yang di-rooting)

    • Karena ini bisa menjadi 'nol', kami dapat memeriksa 'nol' dan mengubah nilainya, tetapi ini berarti tidak lagi unik.
    • Jika Anda memiliki pengguna dengan perangkat pengaturan ulang pabrik, nilainya mungkin telah berubah atau diubah pada perangkat yang di-root sehingga mungkin ada entri duplikat jika Anda melacak instalasi pengguna.
  • Alamat MAC WLAN - Perangkat Keras (kebutuhan android.permission.ACCESS_WIFI_STATE)

    • Ini bisa menjadi pilihan terbaik kedua, tetapi Anda masih mengumpulkan dan menyimpan pengenal unik yang datang langsung dari pengguna. Ini jelas bahwa Anda sedang mengumpulkan data.
    • <uses-permission android:name="android.permission.ACCESS_WIFI_STATE "/>
  • Bluetooth MAC Address - Hardware (perangkat dengan Bluetooth, kebutuhan android.permission.BLUETOOTH)

    • Sebagian besar aplikasi di pasar tidak menggunakan Bluetooth, dan jika aplikasi Anda tidak menggunakan Bluetooth dan Anda termasuk ini, pengguna dapat menjadi curiga.
    • <uses-permission android:name="android.permission.BLUETOOTH "/>
  • Pseudo-Unique ID - Software (untuk semua perangkat Android)

    • Sangat mungkin, mungkin mengandung benturan - Lihat metode saya yang diposting di bawah ini!
    • Ini memungkinkan Anda untuk memiliki ID 'hampir unik' dari pengguna tanpa mengambil apa pun yang bersifat pribadi. Anda dapat membuat ID anonim Anda sendiri dari informasi perangkat.

Saya tahu tidak ada cara 'sempurna' untuk mendapatkan ID unik tanpa menggunakan izin; namun, terkadang kita hanya perlu melacak pemasangan perangkat. Ketika membuat ID unik, kita dapat membuat 'id unik semu' hanya berdasarkan informasi yang diberikan oleh API Android tanpa menggunakan izin tambahan. Dengan cara ini, kami dapat menunjukkan rasa hormat pengguna dan mencoba menawarkan pengalaman pengguna yang baik juga.

Dengan id pseudo-unik, Anda benar-benar hanya menemukan fakta bahwa mungkin ada duplikat berdasarkan fakta bahwa ada perangkat serupa. Anda dapat mengubah metode gabungan untuk membuatnya lebih unik; namun, beberapa pengembang perlu melacak pemasangan perangkat dan ini akan melakukan trik atau kinerja berdasarkan perangkat yang serupa.

API> = 9:

Jika perangkat Android mereka adalah API 9 atau lebih, ini dijamin unik karena bidang 'Build.SERIAL'.

INGAT , Anda secara teknis hanya kehilangan sekitar 0,5% pengguna yang memiliki API <9 . Jadi Anda bisa fokus pada sisanya: Ini adalah 99,5% pengguna!

API <9:

Jika perangkat Android pengguna lebih rendah dari API 9; semoga, mereka belum melakukan reset pabrik dan 'Secure.ANDROID_ID' mereka akan dipertahankan atau tidak 'null'. (lihat http://developer.android.com/about/dashboards/index.html )

Jika semuanya gagal:

Jika semuanya gagal, jika pengguna memang memiliki lebih rendah dari API 9 (lebih rendah dari Gingerbread), telah mengatur ulang perangkat mereka atau 'Secure.ANDROID_ID' mengembalikan 'nol', maka ID yang dikembalikan hanya akan didasarkan pada informasi perangkat Android mereka. Di sinilah tabrakan dapat terjadi.

Perubahan:

  • Dihapus 'Android.SECURE_ID' karena pengaturan ulang pabrik dapat menyebabkan nilai berubah
  • Mengedit kode untuk diubah pada API
  • Mengubah Pseudo

Silakan lihat metode di bawah ini:

/**
 * Return pseudo unique ID
 * @return ID
 */
public static String getUniquePsuedoID() {
    // If all else fails, if the user does have lower than API 9 (lower
    // than Gingerbread), has reset their device or 'Secure.ANDROID_ID'
    // returns 'null', then simply the ID returned will be solely based
    // off their Android device information. This is where the collisions
    // can happen.
    // Thanks http://www.pocketmagic.net/?p=1662!
    // Try not to use DISPLAY, HOST or ID - these items could change.
    // If there are collisions, there will be overlapping data
    String m_szDevIDShort = "35" + (Build.BOARD.length() % 10) + (Build.BRAND.length() % 10) + (Build.CPU_ABI.length() % 10) + (Build.DEVICE.length() % 10) + (Build.MANUFACTURER.length() % 10) + (Build.MODEL.length() % 10) + (Build.PRODUCT.length() % 10);

    // Thanks to @Roman SL!
    // https://stackoverflow.com/a/4789483/950427
    // Only devices with API >= 9 have android.os.Build.SERIAL
    // http://developer.android.com/reference/android/os/Build.html#SERIAL
    // If a user upgrades software or roots their device, there will be a duplicate entry
    String serial = null;
    try {
        serial = android.os.Build.class.getField("SERIAL").get(null).toString();

        // Go ahead and return the serial for api => 9
        return new UUID(m_szDevIDShort.hashCode(), serial.hashCode()).toString();
    } catch (Exception exception) {
        // String needs to be initialized
        serial = "serial"; // some value
    }

    // Thanks @Joe!
    // https://stackoverflow.com/a/2853253/950427
    // Finally, combine the values we have found by using the UUID class to create a unique identifier
    return new UUID(m_szDevIDShort.hashCode(), serial.hashCode()).toString();
}

Baru (untuk aplikasi dengan iklan DAN Layanan Google Play):

Dari konsol Pengembang Google Play:

Mulai 1 Agustus 2014, Kebijakan Program Pengembang Google Play mengharuskan semua unggahan dan pembaruan aplikasi baru untuk menggunakan ID iklan sebagai pengganti pengenal persisten lainnya untuk tujuan iklan apa pun. Belajarlah lagi

Implementasi :

Izin:

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

Kode:

import com.google.android.gms.ads.identifier.AdvertisingIdClient;
import com.google.android.gms.ads.identifier.AdvertisingIdClient.Info;
import com.google.android.gms.common.GooglePlayServicesAvailabilityException;
import com.google.android.gms.common.GooglePlayServicesNotAvailableException;
import java.io.IOException;
...

// Do not call this function from the main thread. Otherwise, 
// an IllegalStateException will be thrown.
public void getIdThread() {

  Info adInfo = null;
  try {
    adInfo = AdvertisingIdClient.getAdvertisingIdInfo(mContext);

  } catch (IOException exception) {
    // Unrecoverable error connecting to Google Play services (e.g.,
    // the old version of the service doesn't support getting AdvertisingId).

  } catch (GooglePlayServicesAvailabilityException exception) {
    // Encountered a recoverable error connecting to Google Play services. 

  } catch (GooglePlayServicesNotAvailableException exception) {
    // Google Play services is not available entirely.
  }
  final String id = adInfo.getId();
  final boolean isLAT = adInfo.isLimitAdTrackingEnabled();
}

Sumber / Dokumen:

http://developer.android.com/google/play-services/id.html http://developer.android.com/reference/com/google/android/gms/ads/identifier/AdvertisingIdClient.html

Penting:

Ini dimaksudkan bahwa ID iklan sepenuhnya menggantikan penggunaan pengenal lain yang ada untuk tujuan iklan (seperti penggunaan ANDROID_ID di Pengaturan. Aman) ketika Layanan Google Play tersedia. Kasus di mana Layanan Google Play tidak tersedia ditunjukkan oleh GooglePlayServicesNotAvailableException dilemparkan oleh getAdvertisingIdInfo ().

Peringatan, pengguna dapat mengatur ulang:

http://en.kioskea.net/faq/34732-android-reset-your-advertising-id

Saya telah mencoba merujuk setiap tautan yang saya ambil informasinya. Jika Anda hilang dan perlu dimasukkan, beri komentar!

Layanan Pemain Google InstanceID

https://developers.google.com/instance-id/

Jared Burrows
sumber
Tetapi bukankah Buildkelas akan berubah setelah pembaruan OS? Terutama jika API diperbarui? Jika demikian, bagaimana Anda menjamin ini unik? (Berbicara tentang metode yang Anda tulis)
LuckyMe
2
saya menggunakan metode Anda di aplikasi saya untuk mengirim komentar. saya punya kabar buruk. sayangnya PsuedoID tidak sepenuhnya unik. server saya mencatat lebih dari 100 untuk 5 ID dan lebih dari 30 untuk hampir 30 ID. ID yang paling sering diulang adalah 'ffffffff-fc8f-6093-ffff-ffffd8' (catatan 159) dan 'ffffffff-fe99-b334-ffff-ffffef' (154 kali). juga berdasarkan waktu dan komentar sudah jelas ada orang yang berbeda. total catatan hingga sekarang adalah 10.000. tolong beri tahu saya mengapa ini terjadi. tank.
hojjat reyhane
1
Saya menulis ini 1,5+ tahun yang lalu. Saya tidak yakin mengapa itu tidak unik untuk Anda. Anda dapat mencoba ID iklan. Jika tidak, Anda dapat menemukan solusi Anda sendiri.
Jared Burrows
2
sorta..I'd sangat menghargai jika Anda pergi melalui pertanyaan dan memberikan pendapat anda tentang ini
Durai Amuthan.H
1
@ user1587329 Terima kasih. Saya mencoba untuk terus memperbarui ini untuk semua orang. Pertanyaan ini rumit ketika datang ke perangkat keras vs perangkat lunak dan lintas platform.
Jared Burrows
340

Seperti yang disebutkan Dave Webb, Blog Pengembang Android memiliki artikel yang membahas hal ini. Solusi pilihan mereka adalah melacak pemasangan aplikasi daripada perangkat, dan itu akan bekerja dengan baik untuk sebagian besar kasus penggunaan. Posting blog akan menunjukkan kepada Anda kode yang diperlukan untuk membuatnya bekerja, dan saya sarankan Anda memeriksanya.

Namun, posting blog berlanjut untuk membahas solusi jika Anda memerlukan pengenal perangkat daripada pengenal instalasi aplikasi. Saya berbicara dengan seseorang di Google untuk mendapatkan klarifikasi tambahan tentang beberapa item jika Anda perlu melakukannya. Inilah yang saya temukan tentang pengidentifikasi perangkat yang TIDAK disebutkan dalam posting blog tersebut:

  • ANDROID_ID adalah pengenal perangkat yang disukai. ANDROID_ID sangat dapat diandalkan pada versi Android <= 2.1 atau> = 2.3. Hanya 2,2 yang memiliki masalah yang disebutkan dalam pos.
  • Beberapa perangkat oleh beberapa produsen dipengaruhi oleh bug ANDROID_ID di 2.2.
  • Sejauh yang saya dapat menentukan, semua perangkat yang terkena dampak memiliki ANDROID_ID yang sama , yaitu 9774d56d682e549c . Yang juga merupakan id perangkat yang sama yang dilaporkan oleh emulator, btw.
  • Google percaya bahwa OEM telah menambal masalah untuk banyak atau sebagian besar perangkat mereka, tetapi saya dapat memverifikasi bahwa pada awal April 2011, setidaknya, masih cukup mudah untuk menemukan perangkat yang memiliki ANDROID_ID yang rusak.

Berdasarkan rekomendasi Google, saya menerapkan kelas yang akan menghasilkan UUID unik untuk setiap perangkat, menggunakan ANDROID_ID sebagai unggulan jika diperlukan, kembali ke TelephonyManager.getDeviceId () sebagaimana diperlukan, dan jika gagal, beralih ke UUID unik yang dibuat secara acak yang bertahan di seluruh aplikasi restart (tetapi tidak menginstal ulang aplikasi).

Perhatikan bahwa untuk perangkat yang harus mundur pada ID perangkat, ID unik AKAN bertahan di seluruh pabrik. Ini adalah sesuatu yang harus diperhatikan. Jika Anda perlu memastikan bahwa pengaturan ulang pabrik akan mengatur ulang ID unik Anda, Anda mungkin ingin mempertimbangkan untuk langsung kembali ke UUID acak daripada ID perangkat.

Sekali lagi, kode ini untuk ID perangkat, bukan ID instalasi aplikasi. Untuk sebagian besar situasi, ID penginstalan aplikasi mungkin adalah yang Anda cari. Tetapi jika Anda benar-benar membutuhkan ID perangkat, maka kode berikut mungkin akan bekerja untuk Anda.

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;
    }
}
emmby
sumber
6
Tidakkah Anda seharusnya mem-hashing berbagai ID sehingga semuanya berukuran sama? Selain itu, Anda harus membuat ID perangkat agar tidak mengekspos informasi pribadi secara tidak sengaja.
Steve Pomeroy
2
Poin bagus, Steve. Saya memperbarui kode untuk selalu mengembalikan UUID. Ini memastikan bahwa a) ID yang dihasilkan selalu berukuran sama, dan b) ID android dan perangkat di hash sebelum dikembalikan untuk menghindari pengungkapan informasi pribadi secara tidak sengaja. Saya juga memperbarui deskripsi untuk mencatat bahwa ID perangkat akan bertahan di seluruh pengaturan ulang pabrik dan bahwa ini mungkin tidak diinginkan untuk beberapa pengguna.
emmby
1
Saya percaya Anda salah; solusi yang lebih disukai adalah melacak instalasi, bukan pengidentifikasi perangkat. Kode Anda secara substansial lebih panjang dan lebih kompleks daripada yang ada di posting blog dan tidak jelas bagi saya bahwa itu menambah nilai.
Tim Bray
7
Poin baiknya, saya memperbarui komentar untuk sangat menyarankan pengguna menggunakan id instalasi aplikasi daripada id perangkat. Namun, saya pikir solusi ini masih berharga untuk orang yang membutuhkan perangkat daripada ID instalasi.
emmby
8
ANDROID_ID dapat berubah pada pengaturan ulang pabrik, sehingga tidak dapat mengidentifikasi perangkat juga
Samuel
180

Berikut adalah kode yang digunakan Reto Meier dalam presentasi Google I / O tahun ini untuk mendapatkan id unik bagi pengguna:

private static String uniqueID = null;
private static final String PREF_UNIQUE_ID = "PREF_UNIQUE_ID";

public synchronized static String id(Context context) {
    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();
            Editor editor = sharedPrefs.edit();
            editor.putString(PREF_UNIQUE_ID, uniqueID);
            editor.commit();
        }
    }
    return uniqueID;
}

Jika Anda menyandingkan ini dengan strategi cadangan untuk mengirim preferensi ke cloud (juga dijelaskan dalam ceramah Reto , Anda harus memiliki id yang terkait dengan pengguna dan bertahan setelah perangkat dihapus, atau bahkan diganti. Saya berencana untuk menggunakan ini dalam analitik maju (dengan kata lain, saya belum melakukan itu sedikit :).

Anthony Nolan
sumber
Saya menggunakan metode @Lenn Dolling dengan waktu saat ini ditambahkan untuk id unik. Tapi ini sepertinya cara yang lebih sederhana dan dapat diandalkan. Terima kasih Reto Meier dan Antony Nolan
Gökhan Barış Aker
Ini bagus tapi bagaimana dengan perangkat yang di-rooting? Mereka dapat mengakses ini dan mengubah Anda ke yang berbeda dengan mudah.
tasomaniac
3
Opsi bagus jika Anda tidak memerlukan ID unik untuk bertahan setelah uninstall dan instal ulang (mis. Acara / permainan promosi tempat Anda mendapatkan tiga peluang untuk menang, titik).
Kyle Clegg
2
Presentasi Meier bergantung pada penggunaan Android Backup Manager, yang pada gilirannya tergantung pada pengguna yang memilih untuk mengaktifkan fitur itu. Itu bagus untuk preferensi pengguna aplikasi (penggunaan Meier), karena jika pengguna belum memilih opsi itu, dia tidak akan mendapatkan yang didukung. Namun, pertanyaan awal adalah tentang menghasilkan ID unik untuk perangkat , dan ID ini dihasilkan per aplikasi, dan bahkan tidak per instalasi, apalagi per perangkat, dan karena bergantung pada pengguna memilih opsi cadangan, penggunaannya di luar pengguna preferensi (misalnya, untuk uji coba terbatas waktu) terbatas.
Carl
12
Ini tidak akan berfungsi untuk menghapus atau menghapus data.
John Shelley
106

Anda juga dapat mempertimbangkan alamat MAC adaptor Wi-Fi. Diperoleh seperti ini:

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

Membutuhkan izin android.permission.ACCESS_WIFI_STATEdalam manifes.

Dilaporkan akan tersedia bahkan ketika Wi-Fi tidak terhubung. Jika Joe dari jawaban di atas mencoba ini di banyak perangkatnya, itu akan menyenangkan.

Pada beberapa perangkat, itu tidak tersedia ketika Wi-Fi dimatikan.

CATATAN: Dari Android 6.x, ia mengembalikan alamat mac palsu yang konsisten:02:00:00:00:00:00

Seva Alekseyev
sumber
8
Ini diperlukanandroid.permission.ACCESS_WIFI_STATE
ohhorob
5
Saya pikir Anda akan menemukan bahwa itu tidak tersedia ketika WiFi mati, di hampir semua perangkat android. Mematikan WiFi menghilangkan perangkat di tingkat kernel.
chrisdowney
12
@ Sanandrea - mari kita hadapi itu, pada perangkat yang di-root SEMUA yang bisa dipalsukan.
ocodo
5
Mengakses alamat MAC WiFi telah diblokir di Android M: stackoverflow.com/questions/31329733/...
breez
6
Dari Android 6.x ia mengembalikan alamat mac palsu yang konsisten:02:00:00:00:00:00
Behrouz.M
87

Ada info yang agak berguna di sini .

Ini mencakup lima jenis ID yang berbeda:

  1. IMEI (hanya untuk perangkat Android dengan penggunaan Telepon; kebutuhan android.permission.READ_PHONE_STATE)
  2. Pseudo-Unique ID (untuk semua perangkat Android)
  3. Android ID (bisa nol, bisa berubah setelah reset pabrik, bisa diubah di ponsel yang di-root)
  4. String Alamat MAC WLAN (kebutuhan android.permission.ACCESS_WIFI_STATE)
  5. String Alamat MAC BT (perangkat dengan Bluetooth, kebutuhan android.permission.BLUETOOTH)
sulit
sumber
2
Poin penting ditinggalkan (di sini dan di artikel): Anda tidak bisa mendapatkan WLAN atau BT MAC kecuali mereka dihidupkan! Kalau tidak, saya pikir WLAN MAC akan menjadi pengidentifikasi sempurna. Anda tidak memiliki jaminan bahwa pengguna akan pernah menyalakan Wi-Fi mereka, dan saya tidak berpikir itu 'tepat' untuk menyalakannya sendiri.
Tom
1
@ Tom kamu salah. Anda masih dapat membaca WLAN atau BT MAC bahkan saat sedang dimatikan. Namun, tidak ada jaminan bahwa perangkat memiliki modul WLAN atau BT.
Marqs
2
Terutama, WiFi lokal dan alamat MAC Bluetooth tidak lagi tersedia. Metode getMacAddress () dari objek WifiInfo dan metode BluetoothAdapter.getDefaultAdapter (). GetAddress () keduanya akan kembali02: 00: 00: 00: 00: 00 mulai dari sekarang
sarika kate
4
@sarikakate Benar hanya di 6.0 Marshmallow dan di atasnya ... Masih berfungsi seperti yang diharapkan di bawah 6.0 Marshmallow.
Smeet
@Setelah Ya Anda benar. Saya lupa menyebutkan bahwa ini berfungsi di bawah 6.0
sarika kate
51

Blog Pengembang Android resmi sekarang memiliki artikel lengkap tentang subjek ini, Mengidentifikasi Instalasi Aplikasi .

Direksi
sumber
4
Dan poin utama dari argumen itu adalah jika Anda mencoba untuk mendapatkan ID unik dari perangkat keras, Anda mungkin membuat kesalahan.
Tim Bray
3
Dan jika Anda membiarkan kunci perangkat diatur ulang oleh pengaturan ulang pabrik, model perangkat uji coba Anda akan mati.
Seva Alekseyev
43

Di Google I / O Reto Meier merilis jawaban yang kuat tentang cara melakukan pendekatan yang harus memenuhi sebagian besar pengembang untuk melacak pengguna di seluruh instalasi. Anthony Nolan menunjukkan arah dalam jawabannya, tetapi saya pikir saya akan menulis pendekatan lengkap sehingga orang lain dapat dengan mudah melihat bagaimana melakukannya (butuh beberapa saat untuk mengetahui detailnya).

Pendekatan ini akan memberi Anda ID pengguna anonim, aman yang akan bertahan untuk pengguna di berbagai perangkat (berdasarkan akun Google utama) dan di seluruh pemasangan. Pendekatan dasarnya adalah membuat ID pengguna acak dan menyimpannya di preferensi bersama aplikasi. Anda kemudian menggunakan agen cadangan Google untuk menyimpan preferensi bersama yang ditautkan ke akun Google di cloud.

Mari kita pergi melalui pendekatan penuh. Pertama, kita perlu membuat cadangan untuk SharedPreferences kita menggunakan Layanan Cadangan Android. Mulailah dengan mendaftarkan aplikasi Anda melalui http://developer.android.com/google/backup/signup.html.

Google akan memberi Anda kunci layanan cadangan yang perlu Anda tambahkan ke manifes. Anda juga perlu memberi tahu aplikasi untuk menggunakan BackupAgent sebagai berikut:

<application android:label="MyApplication"
         android:backupAgent="MyBackupAgent">
    ...
    <meta-data android:name="com.google.android.backup.api_key"
        android:value="your_backup_service_key" />
</application>

Maka Anda perlu membuat agen cadangan dan mengatakannya untuk menggunakan agen pembantu untuk preferensi bersama:

public class MyBackupAgent extends BackupAgentHelper {
    // The name of the SharedPreferences file
    static final String PREFS = "user_preferences";

    // A key to uniquely identify the set of backup data
    static final String PREFS_BACKUP_KEY = "prefs";

    // Allocate a helper and add it to the backup agent
    @Override
    public void onCreate() {
        SharedPreferencesBackupHelper helper = new SharedPreferencesBackupHelper(this,          PREFS);
        addHelper(PREFS_BACKUP_KEY, helper);
    }
}

Untuk menyelesaikan pencadangan, Anda perlu membuat instance dari BackupManager di Aktivitas utama Anda:

BackupManager backupManager = new BackupManager(context);

Terakhir buat ID pengguna, jika belum ada, dan simpan di SharedPreferences:

  public static String getUserID(Context context) {
            private static String uniqueID = null;
        private static final String PREF_UNIQUE_ID = "PREF_UNIQUE_ID";
    if (uniqueID == null) {
        SharedPreferences sharedPrefs = context.getSharedPreferences(
                MyBackupAgent.PREFS, Context.MODE_PRIVATE);
        uniqueID = sharedPrefs.getString(PREF_UNIQUE_ID, null);
        if (uniqueID == null) {
            uniqueID = UUID.randomUUID().toString();
            Editor editor = sharedPrefs.edit();
            editor.putString(PREF_UNIQUE_ID, uniqueID);
            editor.commit();

            //backup the changes
            BackupManager mBackupManager = new BackupManager(context);
            mBackupManager.dataChanged();
        }
    }

    return uniqueID;
}

User_ID ini sekarang akan tetap ada di seluruh instalasi, bahkan jika pengguna memindahkan perangkat.

Untuk informasi lebih lanjut tentang pendekatan ini lihat bicara Reto .

Dan untuk detail lengkap tentang cara menerapkan agen cadangan, lihat Cadangan Data . Saya terutama merekomendasikan bagian di bagian bawah pada pengujian karena cadangan tidak terjadi secara instan dan untuk menguji Anda harus memaksa cadangan.

TeknoTony
sumber
5
Bukankah ini mengarah ke beberapa perangkat dengan id yang sama ketika pengguna memiliki beberapa perangkat? Tablet dan telepon misalnya.
Tosa
Target minimal 8 diperlukan untuk ini.
halxinate
Apakah ini akan menjadi cara yang dipilih untuk membuat muatan verifikasi saat melakukan pembelian dalam aplikasi? Dari komentar kode contoh penagihan dalam aplikasi: "Jadi muatan pengembang yang baik memiliki karakteristik ini: 1. Jika dua pengguna berbeda membeli item, muatannya berbeda di antara mereka, sehingga pembelian satu pengguna tidak dapat diputar ulang ke pengguna lain. 2. Payload harus sedemikian rupa sehingga Anda dapat memverifikasinya bahkan ketika aplikasi bukan orang yang memulai alur pembelian (sehingga barang yang dibeli oleh pengguna pada satu perangkat bekerja pada perangkat lain yang dimiliki oleh pengguna). "
TouchBoarder
@Tosa saya punya pertanyaan yang sama. Tapi tidak bisakah kita menggunakan teknik yang sama ini lagi untuk membuat id perangkat virtual dan tidak mendukungnya dengan cara yang sama? Id perangkat tidak akan bertahan melewati penghapusan atau instal ulang tetapi jika kami memiliki id pengguna yang terus-menerus, kami mungkin tidak membutuhkan sebanyak itu dari id perangkat.
jwehrle
39

Saya pikir ini pasti cara api membangun kerangka untuk ID unik ... coba lihat.

Pseudo-Unique ID, yang berfungsi di semua perangkat Android Beberapa perangkat tidak memiliki ponsel (mis. Tablet) atau karena alasan tertentu, Anda tidak ingin menyertakan izin READ_PHONE_STATE. Anda masih dapat membaca detail seperti Versi ROM, nama Pabrikan, tipe CPU, dan detail perangkat keras lainnya, yang cocok jika Anda ingin menggunakan ID untuk pemeriksaan kunci seri, atau tujuan umum lainnya. ID yang dihitung dengan cara ini tidak akan unik: adalah mungkin untuk menemukan dua perangkat dengan ID yang sama (berdasarkan pada perangkat keras dan gambar ROM yang sama) tetapi perubahan dalam aplikasi dunia nyata dapat diabaikan. Untuk tujuan ini, Anda dapat menggunakan kelas Build:

String m_szDevIDShort = "35" + //we make this look like a valid IMEI
            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 ; //13 digits

Sebagian besar anggota Build adalah string, yang kami lakukan di sini adalah mengambil langkah panjang dan mengubahnya melalui modulo dalam digit. Kami memiliki 13 digit seperti itu dan kami menambahkan dua lagi di depan (35) untuk memiliki ID ukuran yang sama dengan IMEI (15 digit). Ada kemungkinan lain di sini baik-baik saja, lihat saja string ini. Mengembalikan sesuatu seperti 355715565309247. Tidak diperlukan izin khusus, membuat pendekatan ini sangat nyaman.


(Info tambahan: Teknik yang diberikan di atas disalin dari artikel di Pocket Magic .)

Lenn Dolling
sumber
7
Solusi menarik. Kedengarannya seperti ini adalah situasi di mana Anda benar-benar harus hanya hashing semua data yang disatukan daripada mencoba untuk datang dengan fungsi "hash" Anda sendiri. Ada banyak contoh di mana Anda akan mendapatkan tabrakan bahkan jika ada data substansial yang berbeda untuk setiap nilai. Rekomendasi saya: gunakan fungsi hash dan ubah hasil biner menjadi desimal dan potong sesuai kebutuhan. Untuk melakukannya dengan benar, meskipun Anda harus benar-benar menggunakan UUID atau string hash penuh.
Steve Pomeroy
21
Anda harus memberi kredit pada sumber Anda ... Ini telah dicabut langsung dari artikel berikut: pocketmagic.net/?p=1662
Steve Haley
8
ID ini terbuka untuk tabrakan seperti Anda tidak tahu apa. Praktis dijamin sama pada perangkat identik dari operator yang sama.
Seva Alekseyev
7
Ini juga dapat berubah jika perangkat ditingkatkan.
David Diberikan
8
Solusi yang sangat, sangat buruk. Diuji pada dua Nexus 5 ... Kembalikan nomor yang sama.
Sinan Dizdarević
38

Kode berikut mengembalikan nomor seri perangkat menggunakan API Android tersembunyi. Tetapi, kode ini tidak berfungsi pada Samsung Galaxy Tab karena "ro.serialno" tidak diset pada perangkat ini.

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

}
Roman SL
sumber
Saya baru saja membaca tentang pengembang xda yang ro.serialnodigunakan untuk menghasilkan Settings.Secure.ANDROID_ID. Jadi mereka pada dasarnya adalah representasi berbeda dari nilai yang sama.
Martin
@ Martin: tapi mungkin nomor seri tidak berubah saat mengatur ulang perangkat. Bukan? Hanya nilai baru untuk ANDROID_IDyang diturunkan darinya.
Ronnie
Sebenarnya pada semua perangkat saya sudah menguji mereka di mana identik sama. Atau setidaknya nilai hash yang sama (untuk alasan privasi saya tidak menulis nilai sebenarnya ke file log).
Martin
Nilai ini sama denganandroid.os.Build.SERIAL
eugeneek
android.os.Build.SERIALakan ditinggalkan di Android O, lihat android-developers.googleblog.com/2017/04/…
EpicPandaForce
32

Ini pertanyaan sederhana, tanpa jawaban sederhana.

Terlebih lagi, semua jawaban yang ada di sini adalah ketinggalan zaman atau tidak dapat diandalkan.

Jadi, jika Anda mencari solusi pada tahun 2020 .

Berikut adalah beberapa hal yang perlu diingat:

Semua pengidentifikasi berbasis perangkat keras (SSAID, IMEI, MAC, dll) tidak dapat diandalkan untuk perangkat non-google (Semuanya kecuali Pixel dan Nexus), yang merupakan lebih dari 50% perangkat aktif di seluruh dunia. Oleh karena itu praktik terbaik pengidentifikasi Android resmi dengan jelas menyatakan:

Hindari menggunakan pengidentifikasi perangkat keras , seperti SSAID (Android ID), IMEI, alamat MAC, dll ...

Itu membuat sebagian besar jawaban di atas tidak valid. Juga karena pembaruan keamanan android yang berbeda, beberapa dari mereka memerlukan izin runtime yang lebih baru dan lebih ketat, yang dapat dengan mudah ditolak oleh pengguna.

Sebagai contoh CVE-2018-9489yang mempengaruhi semua teknik berbasis WIFI yang disebutkan di atas.

Itu membuat pengidentifikasi tersebut tidak hanya tidak dapat diandalkan, tetapi juga tidak dapat diakses dalam banyak kasus.

Jadi dengan kata sederhana: jangan gunakan teknik itu .

Banyak jawaban lain di sini menyarankan untuk menggunakan AdvertisingIdClient, yang juga tidak kompatibel, karena desainnya harus digunakan hanya untuk pembuatan profil iklan. Itu juga dinyatakan dalam referensi resmi

Hanya gunakan ID Iklan untuk pembuatan profil pengguna atau kasus penggunaan iklan

Ini tidak hanya tidak dapat diandalkan untuk identifikasi perangkat, tetapi Anda juga harus mengikuti privasi pengguna mengenai kebijakan pelacakan iklan , yang menyatakan dengan jelas bahwa pengguna dapat mengatur ulang atau memblokirnya kapan saja.

Jadi jangan gunakan itu juga .

Karena Anda tidak dapat memiliki pengidentifikasi perangkat statis yang diinginkan secara global unik dan andal. Referensi resmi Android menyarankan:

Gunakan FirebaseInstanceId atau GUID yang disimpan secara pribadi jika memungkinkan untuk semua kasus penggunaan lainnya, kecuali untuk pencegahan penipuan pembayaran dan telepon.

Ini unik untuk instalasi aplikasi pada perangkat, jadi ketika pengguna menghapus aplikasi - itu terhapus, sehingga tidak 100% dapat diandalkan, tetapi itu adalah hal terbaik berikutnya.

Untuk menggunakan FirebaseInstanceIdtambahkan dependensi firebase-messaging terbaru ke dalam gradle Anda

implementation 'com.google.firebase:firebase-messaging:20.2.0'

Dan gunakan kode di bawah ini di utas latar:

String reliableIdentifier = FirebaseInstanceId.getInstance().getId();

Jika Anda perlu menyimpan identifikasi perangkat di server jauh Anda, maka jangan menyimpannya seperti (teks biasa), tetapi hash dengan garam .

Hari ini bukan hanya praktik terbaik, Anda benar-benar harus melakukannya oleh hukum sesuai dengan GDPR - pengidentifikasi dan peraturan serupa.

Nikita Kurtin
sumber
3
Untuk saat ini, ini adalah jawaban terbaik, dan kalimat pertama adalah ringkasan terbaik: "Ini pertanyaan sederhana, tanpa jawaban sederhana - suka saja.
b2mob
Anda harus menghargai komentar "kecuali untuk pencegahan penipuan pembayaran dan telepon" tanpa jawaban bagaimana cara mengatasi kasus penggunaan itu.
Eran Boudjnah
@EranBoudjnah Kutipan dari referensi resmi, yang terhubung dalam jawaban. Saya dapat mencoba untuk mengatasi kasus penggunaan itu, tetapi karena itu tidak spesifik untuk pertanyaan OP, Menurut kebijakan stackoverflow - itu harus dilakukan dalam pertanyaan khusus yang terpisah.
Nikita Kurtin
Saya hanya mengatakan bahwa jawabannya tidak lengkap. Tapi saya sadar itu bukan salah Anda karena itu adalah kutipan.
Eran Boudjnah
1
@ M.UsmanKhan, jawabannya ditulis tepat setelah itu: " Hari ini bukan hanya praktik terbaik, Anda benar-benar harus melakukannya oleh hukum sesuai dengan GDPR - pengidentifikasi dan peraturan serupa. "
Nikita Kurtin
27

Menggunakan kode di bawah ini, Anda bisa mendapatkan ID perangkat unik dari perangkat OS Android sebagai string.

deviceId = Secure.getString(getApplicationContext().getContentResolver(), Secure.ANDROID_ID); 
Mohit Kanada
sumber
21

Sebuah Serial lapangan telah ditambahkan ke Buildkelas dalam API level 9 (Android 2.3 - Gingerbread). Dokumentasi mengatakan itu mewakili nomor seri perangkat keras. Jadi itu harus unik, jika ada di perangkat.

Saya tidak tahu apakah itu benar-benar didukung (= bukan nol) oleh semua perangkat dengan level API> = 9.

rony l
sumber
2
Sayangnya, ini "tidak dikenal".
m0skit0
18

Satu hal yang akan saya tambahkan - Saya punya satu dari situasi unik itu.

Menggunakan:

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

Ternyata meskipun Tablet Viewsonic G saya melaporkan DeviceID yang bukan Null, setiap Tablet G melaporkan nomor yang sama.

Jadikan itu menarik dengan bermain "Pocket Empires" yang memberi Anda akses instan ke akun seseorang berdasarkan pada DeviceID "unik".

Perangkat saya tidak memiliki radio seluler.

Tony Maro
sumber
Apa id? apakah ini mungkin 9774d56d682e549c?
Mr_and_Mrs_D
Wow itu sudah lama sekali saya sudah lama melemparkan tablet itu. Tidak bisa mengatakan
Tony Maro
Bekerja Juga, jauh lebih kompak daripada ID yang saya dapatkan dari UUID acak.
Treewallie
1
@ Wallewallie tidak berfungsi? Bisakah Anda mendapatkan ID perangkat yang sama dari Aplikasi yang berbeda?
Arnold Brown
@ArnoldBrown Ya. Pastikan untuk mengujinya secara menyeluruh. Semoga hari Anda menyenangkan: D
Treewallie
16

Untuk instruksi terperinci tentang cara mendapatkan pengenal unik untuk setiap perangkat Android tempat aplikasi Anda terinstal, lihat posting Blog Pengembang Android resmi Mengidentifikasi Instalasi Aplikasi .

Tampaknya cara terbaik bagi Anda untuk membuat sendiri setelah instalasi dan kemudian membacanya ketika aplikasi diluncurkan kembali.

Saya pribadi menemukan ini dapat diterima tetapi tidak ideal. Tidak ada satu pun pengidentifikasi yang disediakan oleh Android yang berfungsi dalam semua keadaan karena sebagian besar tergantung pada kondisi radio ponsel (Wi-Fi on / off, seluler on / off, Bluetooth on / off). Yang lain, suka Settings.Secure.ANDROID_IDharus diterapkan oleh pabrikan dan tidak dijamin unik.

Berikut ini adalah contoh penulisan data ke file instalasi yang akan disimpan bersama dengan data lain yang disimpan aplikasi secara lokal.

public class Installation {
    private static String sID = null;
    private static final String INSTALLATION = "INSTALLATION";

    public synchronized static String id(Context context) {
        if (sID == null) {
            File installation = new File(context.getFilesDir(), INSTALLATION);
            try {
                if (!installation.exists())
                    writeInstallationFile(installation);
                sID = readInstallationFile(installation);
            } 
            catch (Exception e) {
                throw new RuntimeException(e);
            }
        }
        return sID;
    }

    private static String readInstallationFile(File installation) throws IOException {
        RandomAccessFile f = new RandomAccessFile(installation, "r");
        byte[] bytes = new byte[(int) f.length()];
        f.readFully(bytes);
        f.close();
        return new String(bytes);
    }

    private static void writeInstallationFile(File installation) throws IOException {
        FileOutputStream out = new FileOutputStream(installation);
        String id = UUID.randomUUID().toString();
        out.write(id.getBytes());
        out.close();
    }
}
Kevin Parker
sumber
Jika Anda ingin melacak instalasi aplikasi ini sempurna. Meskipun demikian, alat pelacak jauh lebih rumit, dan tampaknya tidak ada solusi yang sepenuhnya kedap udara.
Luca Spiller
Bagaimana dengan perangkat yang di-rooting? Mereka dapat mengubah id instalasi ini dengan mudah, bukan?
tasomaniac
Benar. Root dapat mengubah ID instalasi. Anda dapat memeriksa root menggunakan blok kode ini: stackoverflow.com/questions/1101380/…
Kevin Parker
jika kita mengatur ulang pabrik, apakah file akan dihapus?
Jamshid
Jika Anda mengatur ulang pabrik dan menghapus atau memformat partisi / data, UUID berbeda.
Kevin Parker
12

Tambahkan kode di bawah ini dalam file kelas:

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

Tambahkan di AndroidManifest.xml:

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

ID perangkat unik dari perangkat Android OS sebagai String, menggunakan TelephonyManagerdan ANDROID_ID, diperoleh oleh:

String deviceId;
final TelephonyManager mTelephony = (TelephonyManager) getSystemService(Context.TELEPHONY_SERVICE);
if (mTelephony.getDeviceId() != null) {
    deviceId = mTelephony.getDeviceId();
}
else {
    deviceId = Secure.getString(
                   getApplicationContext().getContentResolver(),
                   Secure.ANDROID_ID);
}

Tetapi saya sangat merekomendasikan metode yang disarankan oleh Google, lihat Mengidentifikasi Instalasi Aplikasi .

Jorgesys
sumber
9

Ada banyak pendekatan berbeda untuk mengatasi ANDROID_IDmasalah - masalah tersebut (mungkin nullkadang - kadang atau perangkat model tertentu selalu mengembalikan ID yang sama) dengan pro dan kontra:

  • Menerapkan algoritma pembuatan ID khusus (berdasarkan properti perangkat yang seharusnya statis dan tidak akan berubah -> siapa tahu)
  • Menyalahgunakan ID lain seperti IMEI , nomor seri, alamat Wi-Fi / Bluetooth-MAC (mereka tidak akan ada di semua perangkat atau izin tambahan menjadi perlu)

Saya sendiri lebih suka menggunakan implementasi OpenUDID yang ada (lihat https://github.com/ylechelle/OpenUDID ) untuk Android (lihat https://github.com/vieux/OpenUDID ). Sangat mudah untuk diintegrasikan dan memanfaatkanANDROID_ID fallback untuk masalah yang disebutkan di atas.

Andreas Klöber
sumber
8

Bagaimana dengan IMEI . Itu unik untuk Android atau perangkat seluler lainnya.

Elzo Valugi
sumber
9
Bukan untuk tablet saya, yang tidak memiliki IMEI karena tidak terhubung ke operator seluler saya.
Brill Pappin
2
Belum lagi perangkat CDMA yang memiliki ESN bukan IMEI.
David Diberikan
@ David Diberikan apakah ada CDMA dengan Android?
Elzo Valugi
1
Ini hanya akan melakukan itu adalah telepon :) Tablet mungkin tidak.
Brill Pappin
3
@ ElzoValugi Sudah "hari ini" dan masih belum semua tablet memiliki kartu SIM.
Matthew Quiros
8

Inilah cara saya menghasilkan id unik:

public static String getDeviceId(Context ctx)
{
    TelephonyManager tm = (TelephonyManager) ctx.getSystemService(Context.TELEPHONY_SERVICE);

    String tmDevice = tm.getDeviceId();
    String androidId = Secure.getString(ctx.getContentResolver(), Secure.ANDROID_ID);
    String serial = null;
    if(Build.VERSION.SDK_INT > Build.VERSION_CODES.FROYO) serial = Build.SERIAL;

    if(tmDevice != null) return "01" + tmDevice;
    if(androidId != null) return "02" + androidId;
    if(serial != null) return "03" + serial;
    // other alternatives (i.e. Wi-Fi MAC, Bluetooth MAC, etc.)

    return null;
}
Eng.Fouad
sumber
jika kita pengguna ReadPhoneState dalam versi 6.0 meminta izin runtime
Harsha
8

Dua sen saya - NB ini untuk perangkat (err) ID unik - bukan instalasi seperti yang dibahas di blog pengembang Android .

Perlu dicatat bahwa solusi yang disediakan oleh @emmby jatuh kembali dalam per aplikasi ID sebagai SharedPreferences tidak disinkronkan di seluruh proses (lihat di sini dan di sini ). Jadi saya menghindari ini sama sekali.

Sebaliknya, saya merangkum berbagai strategi untuk mendapatkan ID (perangkat) dalam enum - mengubah urutan konstanta enum memengaruhi prioritas berbagai cara untuk mendapatkan ID. ID non-null pertama dikembalikan atau pengecualian dilemparkan (sesuai praktik Java yang baik untuk tidak memberikan arti nol). Jadi misalnya saya punya TELEPHONY yang pertama - tetapi pilihan default yang bagus adalah beta 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);
        }
    }
}
Mr_and_Mrs_D
sumber
8

Ada 30+ jawaban di sini dan ada yang sama dan ada yang unik. Jawaban ini didasarkan pada beberapa jawaban itu. Salah satunya adalah jawaban @Lenn Dolling.

Ini menggabungkan 3 ID dan menciptakan string hex 32-digit. Ini bekerja sangat baik untuk saya.

3 ID adalah:
Pseudo-ID - Ini dibuat berdasarkan spesifikasi perangkat fisik
ANDROID_ID - Settings.Secure.ANDROID_ID
Alamat Bluetooth - Alamat adaptor Bluetooth

Ini akan mengembalikan sesuatu seperti ini: 551F27C060712A72730B0A0F734064B1

Catatan: Anda selalu dapat menambahkan lebih banyak ID ke longIdstring. Misalnya, Serial #. alamat adaptor wifi. IMEI. Dengan cara ini Anda membuatnya lebih unik per perangkat.

@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 "";
}
ᴛʜᴇᴘᴀᴛᴇʟ
sumber
1
Menambahkan UUID ke longIddan menyimpannya dalam file, akan membuatnya menjadi pengidentifikasi yang paling unik:String uuid = UUID.randomUUID().toString();
Mousa Alfhaily
1
Jika semuanya gagal, jika pengguna memang memiliki lebih rendah dari API 9 (lebih rendah dari Gingerbread), telah mengatur ulang ponsel mereka atau 'Secure.ANDROID_ID'. jika mengembalikan 'nol', maka ID yang dikembalikan hanya akan didasarkan pada informasi perangkat Android mereka. Di sinilah tabrakan dapat terjadi. Cobalah untuk tidak menggunakan DISPLAY, HOST atau ID - item ini dapat berubah. Jika ada tabrakan, akan ada data yang tumpang tindih. Sumber: gist.github.com/pedja1/fe69e8a80ed505500caa
Mousa Alfhaily
Jika kita mencoba mendapatkan nomor Unik melalui baris kode ini, dapatkah kita mengatakan itu Id Unik dan tidak akan pernah bertentangan dengan perangkat lain?
Ninja
1
@ Ninja Karena alamat mac BLE unik, ya ID yang dihasilkan akan selalu unik. Namun, jika Anda benar-benar ingin memastikan, saya sarankan untuk menambahkan UUID ke longId. Ubah satu baris seperti ini: String longId = pseudoId + androidId + btId + UUID.randomUUID().toString();Ini menjamin bahwa ID yang dihasilkan akan unik.
ᴛʜᴇᴘᴀᴛᴇʟ
@ ᴛʜᴇᴘᴀᴛᴇʟ Terima kasih banyak atas bantuannya. Sebenarnya aplikasi saya adalah data yang sangat sensitif sehingga saya harus yakin tentang hal itu karena itu saya hanya mengkonfirmasi hal ini.
Ninja
7

Cara lain adalah menggunakan /sys/class/android_usb/android0/iSerialaplikasi tanpa izin apa pun.

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

Untuk melakukan ini di Java, cukup gunakan FileInputStream untuk membuka file iSerial dan membacakan karakter. Pastikan Anda membungkusnya dengan penangan pengecualian, karena tidak semua perangkat memiliki file ini.

Setidaknya perangkat berikut diketahui memiliki file ini dapat dibaca dunia:

  • Galaxy Nexus
  • Nexus S
  • Motorola Xoom 3G
  • Toshiba AT300
  • HTC One V
  • Mini MK802
  • Samsung Galaxy S II

Anda juga dapat melihat posting blog saya Membocorkan nomor seri perangkat keras Android ke aplikasi yang tidak terjangkau di mana saya membahas file apa yang tersedia untuk informasi.

insitusec
sumber
Saya baru saja membaca posting blog Anda. Saya percaya bahwa ini tidak unik: Build.SERIAL juga tersedia tanpa izin, dan (secara teori) nomor seri perangkat keras yang unik.
Tom
1
Kamu benar. Hanya satu cara lagi agar perangkat Anda dapat dilacak, dan seperti yang Anda katakan, kedua cara ini tidak memerlukan izin aplikasi.
insitusec
7

TelephonyManger.getDeviceId () Mengembalikan ID perangkat unik, misalnya, IMEI untuk GSM dan MEID atau ESN untuk telepon CDMA.

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

Tetapi saya merekomendasikan untuk menggunakan:

Pengaturan. Aman.ANDROID_ID yang mengembalikan ID Android sebagai string hex 64-bit yang unik.

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

Terkadang TelephonyManger.getDeviceId () akan mengembalikan nol, jadi untuk memastikan id unik Anda akan menggunakan metode ini:

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;
}
Jorgesys
sumber
Saya baru-baru ini menemukan bahwa perangkat klien tipe SM-G928F / Galaxy S6 edge + hanya memberikan 15 bukannya 16 digit hex untuk ID Android.
Holger Jakobs
7

Untuk pengenalan perangkat keras dari perangkat Android tertentu, Anda dapat memeriksa Alamat MAC.

Anda bisa melakukannya dengan cara itu:

di AndroidManifest.xml

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

sekarang dalam kode Anda:

List<NetworkInterface> interfacesList = Collections.list(NetworkInterface.getNetworkInterfaces());

for (NetworkInterface interface : interfacesList) {
   // This will give you the interface MAC ADDRESS
   interface.getHardwareAddress();
}

Di setiap perangkat Android, setidaknya penyihir Antarmuka "wlan0" adalah chip WI-FI. Kode ini berfungsi bahkan ketika WI-FI tidak dihidupkan.

PS Mereka adalah banyak Antarmuka lain yang akan Anda dapatkan dari daftar yang berisi MACS Tetapi ini dapat berubah di antara telepon.

Ilan.b
sumber
7

Saya menggunakan kode berikut untuk mendapatkan IMEIatau menggunakan Secure. ANDROID_IDsebagai alternatif, ketika perangkat tidak memiliki kemampuan telepon:

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);
Asaf Pinhassi
sumber
7

Lebih khusus lagi Settings.Secure.ANDROID_ID,. Ini adalah jumlah 64-bit yang dihasilkan dan disimpan saat perangkat melakukan booting pertama kali. Di-reset ketika perangkat dihapus.

ANDROID_IDtampaknya merupakan pilihan yang baik untuk pengidentifikasi perangkat unik. Ada kelemahan: Pertama, itu tidak 100% dapat diandalkan pada rilis Android sebelum 2.2 (“Froyo”).Juga, telah ada setidaknya satu bug yang diamati secara luas di handset populer dari produsen utama, di mana setiap instance memiliki ANDROID_ID yang sama.

mumu123
sumber
1
jawaban ini adalah copypaste dari blog google lama android-developers.googleblog.com/2011/03/… . Jadi bug sudah teratasi?
Sergii
6

ID Google Instance

Dirilis pada I / O 2015; di Android membutuhkan layanan bermain 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

Tampaknya Google bermaksud agar ID ini digunakan untuk mengidentifikasi instalasi di Android, Chrome, dan iOS.

Ini mengidentifikasi instalasi daripada perangkat, tetapi sekali lagi, ANDROID_ID (yang merupakan jawaban yang diterima) sekarang tidak lagi mengidentifikasi perangkat. Dengan runtime ARC, ANDROID_ID baru dihasilkan untuk setiap instalasi ( detail di sini ), sama seperti ID instance baru ini. Juga, saya pikir mengidentifikasi instalasi (bukan perangkat) adalah apa yang sebenarnya dicari oleh kebanyakan dari kita.

Keuntungan dari instance ID

Tampaknya bagi saya bahwa Google bermaksud untuk menggunakannya untuk tujuan ini (mengidentifikasi instalasi Anda), ini adalah lintas platform, dan dapat digunakan untuk sejumlah tujuan lain (lihat tautan di atas).

Jika Anda menggunakan GCM, pada akhirnya Anda harus menggunakan ID instance ini karena Anda memerlukannya untuk mendapatkan token GCM (yang menggantikan ID registrasi GCM lama).

Kerugian / masalah

Dalam implementasi saat ini (GPS 7.5) ID instance diambil dari server ketika aplikasi Anda memintanya. Ini berarti bahwa panggilan di atas adalah panggilan pemblokiran - dalam pengujian tidak ilmiah saya perlu 1-3 detik jika perangkat online, dan 0,5 - 1,0 detik jika offline (mungkin ini adalah berapa lama menunggu sebelum menyerah dan menghasilkan ID acak). Ini diuji di Amerika Utara pada Nexus 5 dengan Android 5.1.1 dan GPS 7.5.

Jika Anda menggunakan ID untuk tujuan yang mereka maksud - misalnya. otentikasi aplikasi, identifikasi aplikasi, GCM - Saya pikir ini 1-3 detik bisa menjadi gangguan (tergantung pada aplikasi Anda, tentu saja).

Tom
sumber
1
Kelemahan lain yang signifikan dari instanceID adalah instanceID baru akan dihasilkan untuk Anda jika pengguna menghapus data aplikasi.
idanakav
Menarik, tapi saya rasa itu tidak benar-benar mengubah kasus penggunaan potensial: ID contoh, seperti android_id, tidak cocok untuk mengidentifikasi perangkat. Jadi server Anda akan melihat data kliring pengguna seperti menghapus instalan pengguna dan menginstal ulang aplikasi Anda - yang tidak masuk akal.
Tom