Bagaimana cara menemukan nomor seri perangkat Android?

115

Saya perlu menggunakan ID unik untuk aplikasi Android dan saya pikir nomor seri untuk perangkat tersebut adalah kandidat yang baik. Bagaimana cara mengambil nomor seri perangkat Android di aplikasi saya?

Eno
sumber
2
Jangan lupa untuk menambahkan android: name = "android.permission.READ_PHONE_STATE" ke manifes Anda
Michael SIlveus
Jika Anda ingin mendapatkan ID unik tanpa izin apa pun, Anda dapat menggunakan library ini untuk menghasilkan ID unik per perangkat dengan Identity.getDeviceId (konteks) atau pengenal untuk penginstalan aplikasi Anda melalui Identity.getInstallationId (konteks) .
gak

Jawaban:

105
TelephonyManager tManager = (TelephonyManager)myActivity.getSystemService(Context.TELEPHONY_SERVICE);
String uid = tManager.getDeviceId();

getSystemService adalah metode dari kelas Aktivitas. getDeviceID () akan mengembalikan MDN atau MEID perangkat tergantung pada radio mana yang digunakan telepon (GSM atau CDMA).

Setiap perangkat HARUS mengembalikan nilai unik di sini (dengan asumsi itu adalah telepon). Ini seharusnya berfungsi untuk perangkat Android apa pun dengan slot sim atau radio CDMA. Anda sendirian dengan microwave bertenaga Android itu ;-)

haseman
sumber
@Hasemam Ini tidak bekerja untuk saya, memberikan kesalahan "Tutup Paksa"
Paresh Mayani
23
@Hasemam berjalan dengan baik sekarang setelah menambahkan izin <using-permission android: name = "android.permission.READ_PHONE_STATE"> </uses-permission> di file androidManifest.xml.
Paresh Mayani
23
Ada beberapa saran di blog resmi pengembang Android tentang menggunakan pengenal ini: android-developers.blogspot.com/2011/03/…
David Snabel-Caunt
8
selain dari microwave bertenaga Android, bagaimana dengan Tablet bertenaga Android? :)
ajacian81
21
Metode ini harus dihindari, ini akan berfungsi pada ponsel tetapi tidak akan berfungsi pada perangkat tanpa chip ponsel (tablet menjadi salah satu contohnya). Dari 2.3 Anda dapat menggunakan android.os.Build.SERIAL tetapi lihat blog pengembang yang disarankan @DavidCaunt.
John Mitchell
71

Seperti yang disebutkan Dave Webb, Blog Pengembang Android memiliki artikel yang membahasnya.

Saya berbicara dengan seseorang di Google untuk mendapatkan klarifikasi tambahan tentang beberapa item. Inilah yang saya temukan yang TIDAK disebutkan dalam posting blog tersebut di atas:

  • ANDROID_ID adalah solusi yang disukai. ANDROID_ID sangat andal pada versi Android <= 2.1 atau> = 2.3. Hanya 2.2 yang memiliki masalah yang disebutkan dalam postingan.
  • Beberapa perangkat oleh beberapa pabrikan dipengaruhi oleh bug ANDROID_ID di 2.2.
  • Sejauh yang saya bisa tentukan, semua perangkat yang terpengaruh memiliki ANDROID_ID yang sama , yaitu 9774d56d682e549c . Yang juga merupakan id perangkat yang sama yang dilaporkan oleh emulator, btw.
  • Google yakin bahwa OEM telah menambal masalah untuk banyak atau sebagian besar perangkat mereka, tetapi saya dapat memverifikasi bahwa mulai April 2011, setidaknya, masih cukup mudah untuk menemukan perangkat yang memiliki ANDROID_ID rusak.

Berdasarkan rekomendasi Google, saya mengimplementasikan kelas yang akan menghasilkan UUID unik untuk setiap perangkat, menggunakan ANDROID_ID sebagai seed jika sesuai, mengembalikan TelephonyManager.getDeviceId () seperlunya, dan jika gagal, beralih ke UUID unik yang dibuat secara acak yang tetap ada setelah aplikasi dimulai ulang (tetapi tidak untuk pemasangan ulang aplikasi).

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 static volatile 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
1
Izin apa yang diperlukan aplikasi untuk menggunakan ini?
Dave L.
1
<using-permission android: name = "android.permission.READ_PHONE_STATE"> </uses-permission>
Gabrielle
1
@ ef2011 itu pola penguncian yang dicentang ganda: en.wikipedia.org/wiki/Double-checked_locking
emmby
3
Terima kasih telah memposting. Tetapi apa yang menghentikan seseorang dengan ponsel yang di-rooting dari sekadar mengedit device_id.xml untuk memasukkan UUID baru pilihan mereka? (yaitu untuk menghindari pemeriksaan 'uji coba gratis') Bukankah lebih baik jika kelas hanya menyimpan nilai dalam file preferensi jika harus menggunakan metode ID acak? Jika tidak, tidak perlu menyimpannya di antara aplikasi yang berjalan; lebih aman untuk dibuat ulang.
Carlos P
1
"ANDROID_ID" adalah solusi yang lebih disukai ". Perhatikan bahwa ANDROID_ID tidak lagi secara unik mengidentifikasi perangkat: stackoverflow.com/a/13465373/150016
Tom
32
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) {
}

Kode ini mengembalikan nomor seri perangkat menggunakan Android API tersembunyi.

Roman SL
sumber
7
ini hanya memberi saya nilai yang sama dengan yang saya dapatkan dengan android.os.Build.SERIAL
josephus
Apakah saya salah, atau apakah nomor seri ini sama di semua perangkat dengan custom rom tertentu? Nomor seri perangkat saya (di peluncur perangkat gerhana) menunjukkan 01234567890ABC untuk telepon dengan rom khusus.
Peterdk
@Peterdk pada perangkat saya dengan cyanogen-9 kedua metode (pra andy-9 seperti pada jawaban dan yang lebih mudah tersedia dari andy-9 pada) laporkan s / n yang benar (sama seperti pada stiker pabrikan). Ini mungkin tergantung pada versi custom rom tertentu. Rom / versi apa yang Anda gunakan?
morgwai
16
String deviceId = Settings.System.getString(getContentResolver(),
                                Settings.System.ANDROID_ID);

Meskipun, tidak ada jaminan bahwa ID Android akan menjadi pengenal unik.

Anthony Forloney
sumber
@Paresh Mayani, Sulit untuk mengetahui apa masalahnya tanpa melihat kodenya. Asumsi saya satu-satunya getContentResolveradalah kembali null. Namun, mungkin bermanfaat saat membuka pertanyaan dan memposting kode Anda.
Anthony Forloney
4
ID ini berasal dari akun Google yang terkait dengan telepon. Simulator biasanya tidak memilikinya. Ponsel asli mungkin juga tidak memilikinya. Selain itu, ini didokumentasikan sebagai "dapat berubah setelah reset pabrik", dan dapat diubah secara sewenang-wenang kapan saja pada telepon yang di-rooting. Gunakan dengan resiko Anda sendiri. Tidak ada alternatif yang baik - ID perangkat tentatif lainnya tidak tersedia secara universal, atau tidak unik, atau keduanya. Lihat jawaban lain untuk sisa cerita sedih ini.
Seva Alekseyev
14

Ada posting bagus di Blog Pengembang Android yang membahas hal ini .

Ini merekomendasikan untuk tidak menggunakan TelephonyManager.getDeviceId()karena tidak berfungsi pada perangkat Android yang bukan ponsel seperti tablet, ini memerlukan READ_PHONE_STATEizin dan tidak berfungsi dengan andal di semua ponsel.

Sebagai gantinya, Anda dapat menggunakan salah satu dari berikut ini:

  • Alamat MAC
  • Nomor seri
  • ANDROID_ID

Posting ini membahas pro dan kontra masing-masing dan itu layak dibaca sehingga Anda dapat menentukan mana yang terbaik untuk Anda gunakan.

Dave Webb
sumber
+1 hai dave terima kasih untuk klarifikasinya karena saat ini saya sedang mengembangkan aplikasi untuk tablet, di mana saya harus memiliki ID unik perangkat Android, lalu apa yang harus saya gunakan untuk mendapatkan perangkat tablet Android Unik?
Paresh Mayani
12

Untuk nomor sederhana yang unik untuk perangkat dan konstan selama masa pakainya (kecuali reset atau peretasan pabrik), gunakan Settings.Secure.ANDROID_ID .

String id = Secure.getString(getContentResolver(), Secure.ANDROID_ID);

Untuk menggunakan nomor seri perangkat (yang ditampilkan di "Pengaturan Sistem / Tentang / Status") jika tersedia dan kembali ke ID Android:

String serialNumber = Build.SERIAL != Build.UNKNOWN ? Build.SERIAL : Secure.getString(getContentResolver(), Secure.ANDROID_ID);
Edward Brey
sumber
jawaban langsung !!
faris faris
Build.SERİAL tidak digunakan lagi di Jawa
Eyyüp Alkış
7

IMEI bagus tetapi hanya berfungsi pada perangkat Android dengan telepon. Anda harus mempertimbangkan dukungan untuk Tablet atau perangkat Android lainnya juga, yang tidak memiliki telepon.

Anda memiliki beberapa alternatif seperti: Membangun anggota kelas, BT MAC, WLAN MAC, atau bahkan lebih baik - kombinasi dari semua ini.

Saya telah menjelaskan detail ini dalam artikel di blog saya, lihat: http://www.pocketmagic.net/?p=1662

radhoo
sumber
6

Karena tidak ada jawaban di sini yang menyebutkan ID sempurna dan tahan gagal yang PERSISTEN melalui pembaruan sistem dan ada di SEMUA perangkat (terutama karena fakta bahwa tidak ada solusi individual dari Google), saya memutuskan untuk memposting metode yang hal terbaik berikutnya dengan menggabungkan dua pengenal yang tersedia, dan pemeriksaan untuk memilih di antara keduanya pada saat proses.

Sebelum kode, 3 fakta:

  1. TelephonyManager.getDeviceId()(akaIMEI) tidak akan berfungsi dengan baik atau sama sekali untuk perangkat non-GSM, 3G, LTE, dll., tetapi akan selalu mengembalikan ID unik saat perangkat keras terkait ada , bahkan saat tidak ada SIM yang dimasukkan atau bahkan saat tidak ada slot SIM ( beberapa OEM telah melakukan ini).

  2. Karena Gingerbread (Android 2.3) android.os.Build.SERIAL harus ada di perangkat apa pun yang tidak menyediakan IMEI , yaitu tidak memiliki perangkat keras yang disebutkan di atas, sesuai dengan kebijakan Android.

  3. Karena fakta (2.), setidaknya satu dari dua pengenal unik ini akan SELALU hadir , dan SERIAL dapat hadir bersamaan dengan IMEI.

Catatan: Fakta (1.) dan (2.) didasarkan pada pernyataan Google

LARUTAN

Dengan fakta di atas, seseorang selalu dapat memiliki pengenal unik dengan memeriksa apakah ada perangkat keras yang terikat IMEI, dan kembali ke SERIAL jika tidak, karena seseorang tidak dapat memeriksa apakah SERIAL yang ada valid. Kelas statis berikut menyajikan 2 metode untuk memeriksa kehadiran tersebut dan menggunakan IMEI atau SERIAL:

import java.lang.reflect.Method;

import android.content.Context;
import android.content.pm.PackageManager;
import android.os.Build;
import android.provider.Settings;
import android.telephony.TelephonyManager;
import android.util.Log;

public class IDManagement {

    public static String getCleartextID_SIMCHECK (Context mContext){
        String ret = "";

        TelephonyManager telMgr = (TelephonyManager) mContext.getSystemService(Context.TELEPHONY_SERVICE);

        if(isSIMAvailable(mContext,telMgr)){
            Log.i("DEVICE UNIQUE IDENTIFIER",telMgr.getDeviceId());
            return telMgr.getDeviceId();

        }
        else{
            Log.i("DEVICE UNIQUE IDENTIFIER", Settings.Secure.ANDROID_ID);

//          return Settings.Secure.ANDROID_ID;
            return android.os.Build.SERIAL;
        }
    }


    public static String getCleartextID_HARDCHECK (Context mContext){
        String ret = "";

        TelephonyManager telMgr = (TelephonyManager) mContext.getSystemService(Context.TELEPHONY_SERVICE);
        if(telMgr != null && hasTelephony(mContext)){           
            Log.i("DEVICE UNIQUE IDENTIFIER",telMgr.getDeviceId() + "");

            return telMgr.getDeviceId();    
        }
        else{
            Log.i("DEVICE UNIQUE IDENTIFIER", Settings.Secure.ANDROID_ID);

//          return Settings.Secure.ANDROID_ID;
            return android.os.Build.SERIAL;
        }
    }


    public static boolean isSIMAvailable(Context mContext, 
            TelephonyManager telMgr){

        int simState = telMgr.getSimState();

        switch (simState) {
        case TelephonyManager.SIM_STATE_ABSENT:
            return false;
        case TelephonyManager.SIM_STATE_NETWORK_LOCKED:
            return false;
        case TelephonyManager.SIM_STATE_PIN_REQUIRED:
            return false;
        case TelephonyManager.SIM_STATE_PUK_REQUIRED:
            return false;
        case TelephonyManager.SIM_STATE_READY:
            return true;
        case TelephonyManager.SIM_STATE_UNKNOWN:
            return false;
        default:
            return false;
        }
    }

    static public boolean hasTelephony(Context mContext)
    {
        TelephonyManager tm = (TelephonyManager) mContext.getSystemService(Context.TELEPHONY_SERVICE);
        if (tm == null)
            return false;

        //devices below are phones only
        if (Build.VERSION.SDK_INT < 5)
            return true;

        PackageManager pm = mContext.getPackageManager();

        if (pm == null)
            return false;

        boolean retval = false;
        try
        {
            Class<?> [] parameters = new Class[1];
            parameters[0] = String.class;
            Method method = pm.getClass().getMethod("hasSystemFeature", parameters);
            Object [] parm = new Object[1];
            parm[0] = "android.hardware.telephony";
            Object retValue = method.invoke(pm, parm);
            if (retValue instanceof Boolean)
                retval = ((Boolean) retValue).booleanValue();
            else
                retval = false;
        }
        catch (Exception e)
        {
            retval = false;
        }

        return retval;
    }


}

Saya akan menyarankan penggunaan getCleartextID_HARDCHECK. Jika pantulan tidak menempel di lingkungan Anda, gunakan getCleartextID_SIMCHECKmetode ini, tetapi pertimbangkan bahwa itu harus disesuaikan dengan kebutuhan kehadiran SIM khusus Anda.

NB : Harap diperhatikan bahwa OEM telah berhasil mengeluarkan SERIAL dari kebijakan Google (beberapa perangkat dengan SERIAL yang sama), dan Google seperti yang dinyatakan, setidaknya ada satu kasus yang diketahui dalam OEM besar (tidak diungkapkan dan saya tidak tahu merek mana itu baik, saya menebak Samsung).

Penafian : Ini menjawab pertanyaan asli tentang mendapatkan ID perangkat yang unik, tetapi OP memperkenalkan ambiguitas dengan menyatakan bahwa dia memerlukan ID unik untuk sebuah APP. Bahkan jika untuk skenario seperti itu Android_ID akan lebih baik, itu TIDAK AKAN BEKERJA setelah, katakanlah, Titanium Backup dari suatu aplikasi melalui 2 pemasangan ROM yang berbeda (bahkan dapat berupa ROM yang sama). Solusi saya mempertahankan ketekunan yang tidak tergantung pada flash atau reset pabrik, dan hanya akan gagal ketika gangguan IMEI atau SERIAL terjadi melalui peretasan / mod perangkat keras.

leRobot
sumber
5

Ada masalah dengan semua pendekatan di atas. Di Google i / o Reto Meier merilis jawaban yang kuat tentang bagaimana mendekati ini yang harus memenuhi sebagian besar kebutuhan pengembang untuk melacak pengguna di seluruh instalasi.

Pendekatan ini akan memberi Anda ID pengguna anonim dan aman yang akan tetap ada untuk pengguna di berbagai perangkat (termasuk tablet, berdasarkan akun Google utama) dan di seluruh penginstalan pada perangkat yang sama. 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 awan.

Mari kita lakukan pendekatan lengkap. Pertama kita perlu membuat cadangan untuk SharedPreferences menggunakan Android Backup Service. Mulailah dengan mendaftarkan aplikasi Anda melalui tautan ini: 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>

Kemudian Anda perlu membuat agen cadangan dan memintanya untuk menggunakan agen pembantu untuk sharedpreferences:

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 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 penginstalan, meskipun pengguna berpindah perangkat.

Untuk informasi lebih lanjut tentang pendekatan ini, lihat pembicaraan Reto di sini http://www.google.com/events/io/2011/sessions/android-protips-advanced-topics-for-expert-android-app-developers.html

Dan untuk detail lengkap tentang cara menerapkan agen cadangan, lihat situs pengembang di sini: http://developer.android.com/guide/topics/data/backup.html Saya sangat merekomendasikan bagian di bawah tentang pengujian seperti halnya cadangan tidak terjadi secara instan dan untuk menguji Anda harus memaksa cadangan.

TechnoTony
sumber
2

Cara lain adalah menggunakan / sys / class / android_usb / android0 / iSerial di Aplikasi 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 seseorang hanya akan menggunakan FileInputStream untuk membuka file iSerial dan membaca karakternya. Pastikan Anda membungkusnya dengan penangan pengecualian karena tidak semua perangkat memiliki file ini.

Setidaknya perangkat berikut diketahui memiliki file ini yang 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 di sini: http://insitusec.blogspot.com/2013/01/leaking-android-hardware-serial-number.html tempat saya mendiskusikan file lain apa yang tersedia untuk info.

insitusec
sumber
Terima kasih telah memposting jawaban Anda! Harap pastikan untuk membaca FAQ tentang Promosi Mandiri dengan cermat. Perhatikan juga bahwa Anda diharuskan memposting disclaimer setiap kali Anda menautkan ke situs / produk Anda sendiri.
Andrew Barber
1

Seperti yang dikatakan @haserman:

TelephonyManager tManager = (TelephonyManager)myActivity.getSystemService(Context.TELEPHONY_SERVICE);
String uid = tManager.getDeviceId();

Tapi itu perlu termasuk izin dalam file manifes:

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

ID perangkat unik Perangkat OS Android sebagai String.

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 ini yang disarankan oleh Google ::

Mengidentifikasi Penginstalan Aplikasi

Jorgesys
sumber
1

Build.SERIALadalah cara termudah untuk melakukannya, meskipun tidak sepenuhnya dapat diandalkan karena dapat kosong atau terkadang mengembalikan nilai yang berbeda ( bukti 1 , bukti 2 ) dari yang dapat Anda lihat di pengaturan perangkat Anda.

Ada beberapa cara untuk mendapatkan nomor itu tergantung pada pabrikan perangkat dan versi Android, jadi saya memutuskan untuk mengumpulkan setiap solusi yang mungkin saya temukan dalam satu inti . Berikut adalah versi yang disederhanakan:

public static String getSerialNumber() {
    String serialNumber;

    try {
        Class<?> c = Class.forName("android.os.SystemProperties");
        Method get = c.getMethod("get", String.class);

        serialNumber = (String) get.invoke(c, "gsm.sn1");
        if (serialNumber.equals(""))
            serialNumber = (String) get.invoke(c, "ril.serialnumber");
        if (serialNumber.equals(""))
            serialNumber = (String) get.invoke(c, "ro.serialno");
        if (serialNumber.equals(""))
            serialNumber = (String) get.invoke(c, "sys.serialnumber");
        if (serialNumber.equals(""))
            serialNumber = Build.SERIAL;

        // If none of the methods above worked
        if (serialNumber.equals(""))
            serialNumber = null;
    } catch (Exception e) {
        e.printStackTrace();
        serialNumber = null;
    }

    return serialNumber;
}
cacat
sumber
0

Saya tahu pertanyaan ini sudah tua tetapi dapat dilakukan dalam satu baris kode

String deviceID = Build.SERIAL;

MichaelStoddart
sumber
AFAIK, ini akan berubah setelah pembaruan OS perangkat, misalnya dari 4.4.2 ke 4.4.4 atau apa pun.
Den Drobiazko
-1

Saya menemukan kelas contoh yang diposting oleh @emmby di atas sebagai titik awal yang bagus. Tetapi ada beberapa kekurangan, seperti yang disebutkan oleh poster lain. Yang utama adalah ia mempertahankan UUID ke file XML secara tidak perlu dan setelah itu selalu mengambilnya dari file ini. Hal ini membuat kelas terbuka untuk peretasan yang mudah: siapa pun dengan ponsel yang di-rooting dapat mengedit file XML untuk membuat UUID baru.

Saya telah memperbarui kode sehingga hanya tetap ke XML jika benar-benar diperlukan (yaitu saat menggunakan UUID yang dibuat secara acak) dan memfaktorkan ulang logika sesuai jawaban @Brill Pappin:

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 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) || (androidId == null) ) {
                                final String deviceId = ((TelephonyManager) context.getSystemService( Context.TELEPHONY_SERVICE )).getDeviceId();

                                if (deviceId != null)
                                {
                                    uuid = UUID.nameUUIDFromBytes(deviceId.getBytes("utf8"));
                                }
                                else
                                {
                                    uuid = UUID.randomUUID();

                                    // Write the value out to the prefs file so it persists
                                    prefs.edit().putString(PREFS_DEVICE_ID, uuid.toString() ).commit();
                                }
                            }
                            else
                            {
                                uuid = UUID.nameUUIDFromBytes(androidId.getBytes("utf8"));
                            } 
                        } catch (UnsupportedEncodingException e) {
                            throw new RuntimeException(e);
                        }



                    }

                }
            }
        }

    }


    /**
     * 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;
    }
Carlos P.
sumber
Menempatkan id ke dalam prefs bersama membahayakan tujuan awal untuk mendapatkan id yang benar-benar unik. Misalnya Anda jika Anda ingin menggunakan id itu sebagai kunci untuk beberapa batasan maka Anda akan kacau ketika pengguna ahli melakukan root pada perangkat dan mendapat akses ke file preferensi bersama Anda. Isinya dapat disalin yang berarti ...
Eugene Wechsler
ada juga satu kesalahan lain untuk jawaban MB dan milik Anda..Jika Anda menggunakan randomUUID sebagai deviceID dan appID, ini berfungsi untuk semua perangkat di seluruh dunia tidak peduli apakah itu ponsel atau bukan atau apakah itu perangkat google exp atau bukan.
Fred Grott