Android cihazın seri numarası nasıl bulunur?


115

Bir Android uygulaması için benzersiz bir kimlik kullanmam gerekiyor ve cihazın seri numarasının iyi bir aday olacağını düşündüm. Uygulamamdaki bir Android cihazın seri numarasını nasıl alırım?


2
Bildiriminize android: name = "android.permission.READ_PHONE_STATE" eklemeyi unutmayın
Michael SIlveus


Herhangi bir izin olmadan benzersiz bir kimlik almak istiyorsanız, bu kitaplığı , her cihaz için Identity.getDeviceId (bağlam) ile benzersiz bir kimlik veya Identity.getInstallationId (bağlam) aracılığıyla uygulama yüklemeniz için bir tanımlayıcı oluşturmak için kullanabilirsiniz .
gak

Yanıtlar:


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

getSystemService, Activity sınıfından bir yöntemdir. getDeviceID (), telefonun kullandığı radyoya (GSM veya CDMA) bağlı olarak cihazın MDN veya MEID bilgisini döndürür.

Her aygıt burada benzersiz bir değer döndürmelidir (bir telefon olduğu varsayılarak). Bu, sim yuvası veya CDMA radyosu olan herhangi bir Android cihaz için çalışmalıdır. Android destekli mikrodalga ile tek başınasın ;-)


@Hasemam Bu benim için çalışmıyor, "Kapatmaya Zorla" hatası veriyor
Paresh Mayani

23
@Hasemam, androidManifest.xml dosyasına <uses-allow android: name = "android.permission.READ_PHONE_STATE"> </uses-permission> iznini ekledikten sonra iyi çalışıyor.
Paresh Mayani

23
Resmi Android geliştiricisinin blogunda bu tanımlayıcının kullanımıyla ilgili bazı tavsiyeler var: android-developers.blogspot.com/2011/03/…
David Snabel-Caunt

8
Android destekli mikrodalgadan başka, Android destekli bir Tablet ne olacak? :)
ajacian81

21
Bu yöntemden kaçınılmalıdır, bu telefonlarda çalışacak, ancak telefon çipi olmayan cihazlarda çalışmayacaktır (tabletler bir örnektir). 2.3 sürümünden itibaren android.os.Build.SERIAL kullanabilirsiniz ancak @DavidCaunt'ın önerdiği geliştirici bloguna göz atın.
John Mitchell

71

Dave Webb'in bahsettiği gibi, Android Geliştirici Blogunda bunu kapsayan bir makale var.

Birkaç öğe hakkında ek açıklama almak için Google'dan biriyle görüştüm. Yukarıda bahsedilen blog gönderisinde bahsedilmediğini keşfettiğim şey:

  • ANDROID_ID tercih edilen çözümdür. ANDROID_ID, Android <= 2.1 veya> = 2.3 sürümlerinde mükemmel şekilde güvenilirdir. Sadece 2.2 yazıda belirtilen sorunlara sahiptir.
  • Çeşitli üreticilerin birkaç cihazı, 2.2'deki ANDROID_ID hatasından etkilenir.
  • Belirleyebildiğim kadarıyla, etkilenen tüm cihazlar 9774d56d682e549c olan aynı ANDROID_ID'ye sahip . Bu aynı zamanda öykünücü tarafından bildirilen aynı cihaz kimliğidir, btw.
  • Google, OEM'lerin bu sorunu cihazlarının birçoğunda veya çoğunda düzeltdiğine inanıyor, ancak en azından Nisan 2011'in başından itibaren bozuk ANDROID_ID'ye sahip cihazları bulmanın hala oldukça kolay olduğunu doğrulayabildim.

Google'ın önerilerine dayanarak, her cihaz için benzersiz bir UUID oluşturacak bir sınıf uyguladım, uygun olduğunda tohum olarak ANDROID_ID'yi kullanarak TelephonyManager.getDeviceId () 'e geri döndüm ve bu başarısız olursa rastgele oluşturulmuş benzersiz bir UUID'ye başvurdum bu, uygulama yeniden başlatılırken kalıcıdır (ancak uygulama yeniden yüklemelerinde kalmaz).

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

1
Bir uygulamanın bunu kullanması için hangi izinler gereklidir?
Dave L.

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

1
@ ef2011 bu iki kez kontrol edilmiş kilitleme modelidir: en.wikipedia.org/wiki/Double-checked_locking
emmby

3
Gönderdiğiniz için teşekkürler. Ancak rootlu bir telefona sahip birinin, kendi seçtikleri yeni bir UUID'yi yerleştirmek için device_id.xml dosyasını düzenlemesini engelleyen şey nedir? (yani, bir 'ücretsiz deneme' kontrolünü atlatmak için) Sınıfın, rastgele kimlik yöntemine başvurması gerekiyorsa, değeri yalnızca bir tercih dosyasında saklaması daha iyi olmaz mıydı? Aksi takdirde, uygulama çalıştırmaları arasında bunu sürdürmeye gerek yoktur; yeniden oluşturmak daha güvenlidir.
Carlos P

1
"ANDROID_ID" tercih edilen çözümdür ". ANDROID_ID'nin artık bir cihazı benzersiz şekilde tanımlamadığını unutmayın: 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) {
}

Bu kod, gizli bir Android API kullanarak cihaz seri numarasını döndürür.


7
bu bana android.os.Build.SERIAL ile
aldığımla

Yanılıyor muyum yoksa bu seri numarası belirli bir özel rom bulunan tüm cihazlarda aynı mı? Cihazımın seri numarası (tutulma cihaz başlatıcısında), özel romlu bir telefon için 01234567890ABC'yi gösteriyor.
Peterdk

@Peterdk cihazımda cyanogen-9 ile her iki yöntem de (yanıtta olduğu gibi pre andy-9 ve andy-9'dan daha kolay olanı) doğru s / n bildiriyor (üretici etiketindeki ile aynı). Yine de belirli özel rom sürümüne bağlı olabilir. Hangi rom / sürümü kullanıyorsunuz?
morgwai

16
String deviceId = Settings.System.getString(getContentResolver(),
                                Settings.System.ANDROID_ID);

Bununla birlikte, Android kimliğinin benzersiz bir tanımlayıcı olacağı garanti edilmez.


@Paresh Mayani, Koda bakmadan sorunun ne olabileceğini söylemek zor. Benim tek varsayımım bunun getContentResolvergeri döndüğü null. Ancak, bir soruyu açarken ve kodunuzu gönderirken buna değer olabilir.
Anthony Forloney

4
Bu kimlik, telefonla ilişkili Google hesabından gelir. Simülatörde tipik olarak bir tane yoktur. Gerçek bir telefonda da olmayabilir. Ayrıca, "fabrika ayarlarına sıfırlandığında değişebilir" olarak belgelenmiştir ve root erişimli bir telefonda herhangi bir zamanda isteğe bağlı olarak değiştirilebilir. Kendi sorumluluğunuzdadır kullanın. İyi bir alternatif yoktur - diğer geçici cihaz kimlikleri ya evrensel olarak mevcut değildir ya da benzersiz değildir ya da her ikisi de vardır. Bu üzücü hikayenin geri kalanı için diğer cevaplara bakın.
Seva Alekseyev

14

Orada Android Geliştirici blog bu tartışmaya üzerinde mükemmel sonrası .

TelephonyManager.getDeviceId()Tablet gibi telefon olmayan Android cihazlarda çalışmadığı için kullanılmamasını önerir ,READ_PHONE_STATE izin ve tüm telefonlarda güvenilir bir şekilde .

Bunun yerine aşağıdakilerden birini kullanabilirsiniz:

  • Mac Adresi
  • Seri numarası
  • ANDROID_ID

Gönderi, her birinin artılarını ve eksilerini tartışıyor ve okumaya değer, böylece kullanımınız için hangisinin en iyisi olduğunu anlayabilirsiniz.


+1, merhaba dave, açıklama için teşekkürler çünkü şu anda tablet için bir uygulama geliştiriyorum, burada Android cihazın Benzersiz Kimliğine sahip olmam gerekiyor, peki Benzersiz Android tablet cihaz almak için ne kullanmalıyım?
Paresh Mayani

12

Cihaza özgü ve kullanım ömrü boyunca sabit olan (fabrika ayarlarına sıfırlama veya bilgisayar korsanlığı dışında) basit bir numara için Settings.Secure.ANDROID_ID öğesini kullanın .

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

Varsa cihaz seri numarasını ("Sistem Ayarları / Hakkında / Durum" bölümünde gösterilen) kullanmak ve Android Kimliğine geri dönmek için:

String serialNumber = Build.SERIAL != Build.UNKNOWN ? Build.SERIAL : Secure.getString(getContentResolver(), Secure.ANDROID_ID);

basit cevap !!
faris faris

Build.SERİAL java'da kullanımdan kaldırıldı
Eyyüp Alkış

7

IMEI iyidir, ancak yalnızca telefonlu Android cihazlarda çalışır. Telefon içermeyen Tabletler veya diğer Android cihazlar için desteği de düşünmelisiniz.

Aşağıdakiler gibi bazı alternatifleriniz var: Derleme sınıfı üyeleri, BT MAC, WLAN MAC veya daha iyisi - tüm bunların bir kombinasyonu.

Bu ayrıntıları blogumdaki bir makalede açıkladım, bkz: http://www.pocketmagic.net/?p=1662


6

Yana hiçbir cevap burada mükemmel bahseder, tedbirli sistem güncellemeleri yoluyla PERSİSTAN olduğundan hem de TÜM cihazlarda mevcut kimliği (özellikle nedeniyle Google'dan bireysel bir çözüm olmadığı gerçeği için), bir yöntem sonrası karar bir sonraki en iyi şey, mevcut tanımlayıcılardan ikisini birleştirerek ve çalışma zamanında bunlar arasında seçim yapmak için bir kontrol.

Kodlamadan önce 3 gerçek:

  1. TelephonyManager.getDeviceId()(akaIMEI), GSM dışı, 3G, LTE vb. cihazlar için iyi veya hiç çalışmayacaktır, ancak ilgili donanım mevcut olduğunda, SIM takılı olmadığında veya SIM yuvası olmadığında bile her zaman benzersiz bir kimlik döndürecektir ( bazı OEM'ler bunu yaptı).

  2. Gingerbread (Android 2.3) android.os.Build.SERIAL , IMEI sağlamayan herhangi bir cihazda bulunması gerektiğinden , yani Android politikasına göre yukarıda belirtilen donanıma sahip değildir.

  3. Durum (2.) nedeniyle , bu iki benzersiz tanımlayıcıdan en az biri HER ZAMAN mevcut olacak ve SERIAL , IMEI ile aynı anda mevcut olabilir .

Not: Gerçek (1.) ve (2.) Google ifadelerine dayanmaktadır

ÇÖZÜM

Yukarıdaki gerçeklerle, IMEI'ye bağlı donanım olup olmadığını kontrol ederek her zaman benzersiz bir tanımlayıcıya sahip olabilir ve mevcut SERIAL'in geçerli olup olmadığını kontrol edemeyeceğinden, olmadığı zaman SERIAL'e geri dönülebilir. Aşağıdaki statik sınıf, bu tür bir varlığı denetlemek ve IMEI veya SERIAL kullanmak için 2 yöntem sunar:

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


}

Kullanmayı tavsiye ederim getCleartextID_HARDCHECK. Yansıma çevrenize yapışmazsa,getCleartextID_SIMCHECK bunun yerine yöntemi kullanın, ancak özel SIM varlığı ihtiyaçlarınıza göre uyarlanması gerektiğini dikkate alın.

Not : Lütfen OEM'lerin Google politikasına (aynı SERİ'ye sahip birden fazla cihaz) SERIAL'i engellemeyi başardığını ve Google'ın belirtildiği gibi, büyük bir OEM'de en az bir bilinen durum olduğunu (açıklanmadı ve hangi markayı bilmiyorum) ya, sanırım Samsung).

Feragatname : Bu, özgün bir cihaz kimliği alma sorusunu yanıtlar, ancak OP, bir APP için benzersiz bir kimliğe ihtiyaç duyduğunu belirterek belirsizlik yarattı. Bu tür senaryolar için Android_ID daha iyi olsa bile, bir uygulamanın 2 farklı ROM yüklemesi yoluyla bir Titanyum Yedeklemesinden sonra (aynı ROM bile olabilir) ÇALIŞMAYACAKTIR. Çözümüm, flaştan veya fabrika ayarlarına sıfırlamadan bağımsız kalıcılığı koruyor ve yalnızca IMEI veya SERİ kurcalama korsanlar / donanım modları aracılığıyla gerçekleştiğinde başarısız oluyor.


5

Yukarıdaki tüm yaklaşımlarla ilgili sorunlar var. Google i / o'da Reto Meier, buna nasıl yaklaşılacağına dair sağlam bir yanıt yayınladı. Bu yanıt, çoğu geliştiricinin kurulumlarda kullanıcıları izlemek için ihtiyaçlarını karşılamalıdır.

Bu yaklaşım size, kullanıcı için farklı cihazlarda (tabletler dahil, birincil Google hesabına dayalı) ve aynı cihazdaki yüklemelerde kalıcı olacak anonim, güvenli bir kullanıcı kimliği verecektir. Temel yaklaşım, rastgele bir kullanıcı kimliği oluşturmak ve bunu uygulamaların paylaşılan tercihlerinde saklamaktır. Ardından, Google hesabına bağlı paylaşılan tercihleri ​​bulutta depolamak için Google'ın yedekleme aracısını kullanırsınız.

Tam yaklaşımı inceleyelim. Öncelikle, Android Yedekleme Hizmetini kullanarak Paylaşılan Tercihlerimiz için bir yedek oluşturmamız gerekiyor. Bu bağlantı yoluyla uygulamanızı kaydettirerek başlayın: http://developer.android.com/google/backup/signup.html

Google size bildirime eklemeniz gereken bir yedek hizmet anahtarı verecektir. Ayrıca, uygulamaya aşağıdaki gibi BackupAgent'ı kullanmasını söylemeniz gerekir:

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

Ardından, yedekleme aracısını oluşturmanız ve ona, paylaşılan tercihler için yardımcı aracıyı kullanmasını söylemeniz gerekir:

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

Yedeklemeyi tamamlamak için ana Etkinliğinizde bir BackupManager örneği oluşturmanız gerekir:

BackupManager backupManager = new BackupManager(context);

Son olarak, mevcut değilse bir kullanıcı kimliği oluşturun ve bunu SharedPreferences'da saklayın:

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

Bu User_ID, kullanıcı cihazları değiştirse bile artık kurulumlarda kalıcı olacaktır.

Bu yaklaşım hakkında daha fazla bilgi için http://www.google.com/events/io/2011/sessions/android-protips-advanced-topics-for-expert-android-app-developers.html Reto'nun konuşmasına bakın

Yedekleme aracısının nasıl uygulanacağına ilişkin tüm ayrıntılar için geliştirici sitesine buradan bakın: http://developer.android.com/guide/topics/data/backup.html Yedeklemede olduğu gibi test etmek için en alttaki bölümü özellikle tavsiye ederim anında gerçekleşmez ve bu nedenle test etmek için yedeklemeyi zorlamanız gerekir.


2

Başka bir yol da / sys / class / android_usb / android0 / iSerial'ı herhangi bir izne sahip olmayan bir Uygulamada kullanmaktır.

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

Bunu java'da yapmak için, iSerial dosyasını açmak ve karakterleri okumak için sadece bir FileInputStream kullanılır. Sadece bir istisna işleyicisine sardığınızdan emin olun çünkü tüm cihazlarda bu dosya yoktur.

En azından aşağıdaki cihazların bu dosyanın herkes tarafından okunabilir olduğu bilinmektedir:

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

Blog gönderimi burada da görebilirsiniz: http://insitusec.blogspot.com/2013/01/leaking-android-hardware-serial-number.html , bilgi için başka hangi dosyaların mevcut olduğunu tartıştığım yer.


Cevabınızı gönderdiğiniz için teşekkürler! Lütfen Kendini Tanıtma ile ilgili SSS'yi dikkatlice okuduğunuzdan emin olun . Ayrıca , kendi sitenize / ürününüze her bağlandığınızda bir sorumluluk reddi beyanı göndermeniz gerektiğini unutmayın .
Andrew Barber

1

@Haserman'ın dediği gibi:

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

Ancak, manifest dosyasındaki iznin dahil edilmesi gereklidir:

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

1

Dize olarak Android OS Cihazının benzersiz cihaz kimliği.

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

ancak Google tarafından önerilen bu yöntemi şiddetle tavsiye ediyorum ::

Uygulama Kurulumlarını Tanımlama


1

Build.SERIALtamamen güvenilir olmasa da , boş olabileceği veya bazen cihazınızın ayarlarında görebildiğinizden farklı bir değer ( kanıt 1 , kanıt 2 ) döndürebileceği için en basit yoldur .

Cihazın üreticisine ve Android sürümüne bağlı olarak bu numarayı elde etmenin birkaç yolu vardır, bu yüzden bulabildiğim her olası çözümü tek bir özde derlemeye karar verdim . İşte bunun basitleştirilmiş bir versiyonu:

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

0

Bu sorunun eski olduğunu biliyorum ama bir satır kodla yapılabilir

String deviceID = Build.SERIAL;


AFAIK, bu, cihazın işletim sistemi güncellemesinden sonra değişecektir, örneğin 4.4.2'den 4.4.4'e veya her neyse.
Den Drobiazko

-1

Yukarıda @emmby tarafından yayınlanan örnek sınıfı harika bir başlangıç ​​noktası olarak buldum. Ancak diğer afişlerde de belirtildiği gibi birkaç kusuru var. Bunlardan en önemlisi, UUID'yi gereksiz yere bir XML dosyasına devam ettirmesi ve daha sonra her zaman bu dosyadan almasıdır. Bu, sınıfı kolay bir saldırıya açık hale getirir: Rootlu bir telefonu olan herkes, kendilerine yeni bir UUID vermek için XML dosyasını düzenleyebilir.

Kodu, yalnızca kesinlikle gerekliyse (yani rastgele oluşturulmuş bir UUID kullanırken) XML'de kalması için güncelledim ve @Brill Pappin'in cevabına göre mantığı yeniden faktörlendirdim:

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

Kimliği paylaşılan tercihlere koymak, gerçekten benzersiz bir kimlik elde etmek için orijinal amacı tehlikeye atar. Örneğin, bu kimliği bazı kısıtlamalar için anahtar olarak kullanmak istiyorsanız, yetenekli kullanıcılar bir cihazı köklendirdiğinde ve paylaşılan tercihler dosyanıza eriştiğinde mahvolacaksınız. İçeriği kopyalanabilir, yani ...
Eugene Wechsler

MB'nin cevabında ve sizin yanıtınızda başka bir hata daha var ... Eğer randomUUID'yi bir cihaz kimliği ve uygulama kimliği olarak kullanırsanız, telefon olsun veya olmasın, google exp cihazı olsun veya olmasın, tüm cihazlarda çalışır.
Fred Grott

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.