Is er een unieke Android-apparaat-ID?

Hebben Android-apparaten een unieke ID, en zo ja, wat is een eenvoudige manier om toegang te krijgen met Java?


Antwoord 1, autoriteit 100%

Settings.Secure#ANDROID_IDretourneert de Android-ID als een uniek voor elke gebruiker64-bit hexadecimale tekenreeks.

import android.provider.Settings.Secure;
private String android_id = Secure.getString(getContext().getContentResolver(),
                                                        Secure.ANDROID_ID);

Lees ook Praktische tips voor unieke ID’s: https ://developer.android.com/training/articles/user-data-ids


Antwoord 2, autoriteit 55%

UPDATE: vanaf recente versies van Android zijn veel van de problemen met ANDROID_IDopgelost en ik denk dat deze aanpak niet langer nodig is. Bekijk a.u.b. Anthony’s antwoord.

Volledige openbaarmaking: Mijn app gebruikte oorspronkelijk de onderstaande benadering, maar gebruikt deze aanpak niet langer, en we gebruiken nu de aanpak die wordt geschetst in de Android-ontwikkelaar blog invoeren die Emmby’s antwoord links Naar (namelijk het genereren en opslaan en opslaan van een UUID#randomUUID()).


Er zijn veel antwoorden op deze vraag, waarvan de meeste alleen “sommige” van de tijd werken, en helaas is dat niet goed genoeg.

Op basis van mijn tests van apparaten (alle telefoons, waarvan er ten minste één niet is geactiveerd):

  1. Alle geteste apparaten heeft een waarde voor TelephonyManager.getDeviceId()
  2. Alle GSM-apparaten (alle getest met een SIM) kozen een waarde voor TelephonyManager.getSimSerialNumber()
  3. Alle CDMA-apparaten hebben null geretourneerd voor getSimSerialNumber()(zoals verwacht)
  4. Alle apparaten met een Google-account heeft een waarde geretourneerd voor ANDROID_ID
  5. Alle CDMA-apparaten hebben dezelfde waarde (of afleiding van dezelfde waarde) voor zowel ANDROID_IDen TelephonyManager.getDeviceId()zolang Een Google-account is toegevoegd tijdens Setup.
  6. Ik heb nog geen kans gehad om GSM-apparaten te testen zonder SIM, een GSM-apparaat zonder dat Google-account is toegevoegd, of een van de apparaten in de vliegtuigmodus.

Dus als u iets unieks wilt voor het apparaat zelf, TM.getDeviceId()moet voldoende zijn. Vanzelfsprekend zijn sommige gebruikers paranoïde dan andere, dus het kan nuttig zijn voor hash 1 of meer van deze identificatoren, zodat de string nog steeds vrijwel uniek is voor het apparaat, maar identificeert niet expliciet het eigenlijke apparaat van de gebruiker. Bijvoorbeeld, met behulp van String.hashCode(), gecombineerd met een 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();

kan resulteren in zoiets als: 00000000-54b3-e7c7-0000-000046bffd97

het werkt goed genoeg voor mij.

Zoals Richard hieronder vermeldt, vergeet niet dat u toestemming nodig hebt om de TelephonyManager-Eigenschappen te lezen, dus voeg dit toe aan uw manifest:

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

Bibliotheken importeren

import android.content.Context;
import android.telephony.TelephonyManager;
import android.view.View;

3, Autoriteit 21%

#Last bijgewerkt: 6/2/15


Na het lezen van elk Stack Overflow-bericht over het maken van een unieke ID, de Google-ontwikkelaarsblog en Android-documentatie, heb ik het gevoel dat de ‘Pseudo-ID’ de best mogelijke optie is.

Belangrijkste probleem: hardware versus software

Hardware

  • Gebruikers kunnen hun hardware, Android-tablet of telefoon wijzigen, dus unieke ID’s op basis van hardware zijn geen goede ideeën voor GEBRUIKERS VOLGEN
  • Voor TRACKING HARDWAREis dit een geweldig idee

Software

  • Gebruikers kunnen hun ROM wissen/wijzigen als ze geroot zijn
  • U kunt gebruikers volgen op verschillende platforms (iOS, Android, Windows en internet)
  • De beste manier om EEN INDIVIDUELE GEBRUIKER TE VOLGENmet hun toestemmingis om ze gewoon te laten inloggen (maak dit naadloos met OAuth)

#Algemeen overzicht met Android

###- Uniekheid garanderen (inclusief geroote apparaten) voor API >= 9/10 (99,5% van Android-apparaten)
###- Geen extra rechten

Psuedo-code:

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)

Met dank aan @stansult voor het plaatsen van al onze opties(in deze Stack Overflow-vraag ).

##Lijst met opties – redenen waarom/waarom ze niet te gebruiken:

  • E-mailadres van gebruiker – Software

  • Gebruiker kan e-mail wijzigen – ZEER onwaarschijnlijk

  • API 5+ <uses-permission android:name="android.permission.GET_ACCOUNTS" />of

  • API 14+ <uses-permission android:name="android.permission.READ_PROFILE" /><uses-permission android:name="android.permission.READ_CONTACTS" />(Het primaire e-mailadres van het Android-apparaat ophalen)

  • Telefoonnummer gebruiker – Software

  • Gebruikers kunnen telefoonnummers wijzigen – ZEER onwaarschijnlijk

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

  • IMEI – Hardware(alleen telefoons, heeft android.permission.READ_PHONE_STATEnodig)

  • De meeste gebruikers haten het feit dat er “Telefoongesprekken” in de toestemming staat. Sommige gebruikers geven slechte beoordelingen omdat ze denken dat je gewoon hun persoonlijke gegevens steelt, terwijl je eigenlijk alleen maar apparaatinstallaties wilt volgen. Het is duidelijk dat u gegevens verzamelt.

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

  • Android ID – Hardware(kan nul zijn, kan worden gewijzigd na fabrieksreset, kan worden gewijzigd op een geroot apparaat)

  • Aangezien het ‘null’ kan zijn, kunnen we controleren op ‘null’ en de waarde ervan wijzigen, maar dit betekent dat het niet langer uniek is.

  • Als je een gebruiker hebt met een apparaat dat de fabrieksinstellingen terugzet, is de waarde mogelijk gewijzigd of gewijzigd op het geroote apparaat, dus er kunnen dubbele vermeldingen zijn als je gebruikersinstallaties bijhoudt.

  • WLAN MAC-adres – Hardware(vereist android.permission.ACCESS_WIFI_STATE)

  • Dit kan de op één na beste optie zijn, maar u verzamelt en opbergt nog steeds een unieke identifier die rechtstreeks van een gebruiker komt. Dit is duidelijk dat u gegevens verzamelt.

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

  • Bluetooth MAC-adres – hardware (apparaten met Bluetooth, behoeften android.permission.BLUETOOTH)

  • De meeste toepassingen op de markt gebruiken geen Bluetooth, en als uw toepassing geen Bluetooth gebruikt en u hiervoor bent, kan de gebruiker achterdochtig worden.

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

  • Pseudo-unieke ID – Software (voor alle Android-apparaten)

  • Zeer mogelijk, kan botsingen bevatten – zie mijn hieronder geplaatst methode!

  • Hiermee kunt u een ‘bijna unieke’ ID van de gebruiker hebben zonder iets te nemen dat privé is. U kunt uw eigen anonieme ID van apparaatinformatie maken.


Ik weet dat er geen ‘perfecte’ manier is om een ​​unieke ID te krijgen zonder gebruik te maken van machtigingen; Soms moeten we echter alleen de installatie van het apparaat volgen. Als het gaat om het maken van een unieke ID, kunnen we een ‘pseudo unieke ID’ maken die uitsluitend is gebaseerd op informatie die de Android API ons geeft zonder extra machtigingen te gebruiken. Op deze manier kunnen we het respect van de gebruiker tonen en proberen ook een goede gebruikerservaring te bieden.

Met een pseudo-unieke ID, loop je echt alleen in het feit dat er duplicaten kunnen zijn op basis van het feit dat er vergelijkbare apparaten zijn. Je kunt de gecombineerde methode aanpassen om het unieker te maken; Sommige ontwikkelaars moeten echter apparaatinstallaties volgen en dit doen de truc of prestaties op basis van vergelijkbare apparaten.

## API & GT; = 9:

Als hun Android-apparaat API 9 of ouder is, is dit gegarandeerd uniek vanwege het veld ‘Build.seration’.

Vergeet niet , u ontbreekt technisch gezien slechts 0,5% van de gebruikers die API & LT hebben; 9 . Dus je kunt je focussen op de rest: dit is 99,5% van de gebruikers!

## API & LT; 9:

Als het Android-apparaat van de gebruiker lager is dan API 9; Hopelijk hebben ze geen fabrieksreset gedaan en zullen hun ‘Secure.android_id’ bewaard worden of niet ‘null’. (Zie http://developer.android.com/about/dashboards/index.html)

## als al het andere faalt:

Als al het andere faalt, als de gebruiker lager heeft dan API 9 (lager dan peperkoek), is het opnieuw instellen van hun apparaat, of ‘secure.android_id’ retourneert ‘null’, dan is het opnieuw op basis van hun geretourneerde ID. Android-apparaatinformatie. Dit is waar de botsingen kunnen gebeuren.

Wijzigingen:

  • verwijderde ‘Android.secure_id’ omdat fabrieksresets de waarde kan veranderen om
  • te veranderen

  • bewerkte de code om te veranderen op API
  • veranderde de pseudo

Neem een ​​kijkje op de onderstaande methode:

/**
 * 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();
}

#Nieuw (voor apps met advertenties EN Google Play-services):

Vanaf de Google Play-ontwikkelaarsconsole:

Vanaf 1 augustus 2014 geldt het Google Play-programmabeleid voor ontwikkelaars
vereist geheel nieuwe app-uploads en updates om de advertentie-ID te gebruiken in
in plaats van andere persistente identifiers voor reclamedoeleinden.
Meer informatie

Implementatie:

Toestemming:

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

Code:

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

Bron/Documenten:

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

##Belangrijk:

Het is de bedoeling dat de advertentie-ID de bestaande
gebruik van andere identifiers voor advertentiedoeleinden (zoals het gebruik van ANDROID_ID
in Instellingen.Secure) Wanneer Google Play Services beschikbaar is. Gevallen
waar Google Play-services niet beschikbaar zijn, worden aangegeven door een
GooglePlayservicesNotAmailableException wordt geworpen door
getADvertisingidinfo ().

## WAARSCHUWING, gebruikers kunnen resetten:

http://en.kioskea.net/faq/ 34732-Android-reset-uw-reclame-ID

Ik heb geprobeerd om elke link te verwijzen waar ik informatie van heb gemaakt. Als u ontbreekt en moet worden opgenomen, neem dan op!

Google Player Services ExextID

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


4, Autoriteit 16%

Zoals Dave Webb vermeldingen, de Android-ontwikkelaar blog heeft een artikel die dit dekt. Hun gewenste oplossing is om de app-installaties te volgen in plaats van apparaten, en dat zal goed werken voor de meeste gebruiksgevallen. Het blogpost toont u de benodigde code om dat werk te maken, en ik raad u aan het te bekijken.

De blogpost gaat echter door om oplossingen te bespreken als u een apparaatidentificatie nodig hebt in plaats van een identificatie van een app-installatie. Ik sprak met iemand bij Google om wat extra verduidelijking te krijgen op een paar items in het geval dat je dat moet doen. Dit is wat ik heb ontdekt over apparaat-ID’s die niet worden vermeld in de bovengenoemde blogpost:

  • Android_ID is de identificatie van de voorkeur. Android_ID is perfect betrouwbaar op versies van Android & LT; = 2.1 of & GT; = 2.3. Slechts 2.2 heeft de problemen die in de post worden genoemd.
  • Verschillende apparaten door verschillende fabrikanten worden beïnvloed door de Android_ID-bug in 2.2.
  • Voor zover ik heb kunnen vaststellen, hebben alle betrokken apparaten dezelfde ANDROID_ID, dat 9774d56d682e549cis. Dat is trouwens hetzelfde apparaat-ID als gerapporteerd door de emulator.
  • Google is van mening dat OEM’s het probleem voor veel of de meeste van hun apparaten hebben gepatcht, maar ik heb kunnen verifiëren dat het in ieder geval vanaf begin april 2011 nog steeds vrij eenvoudig is om apparaten te vinden met de kapotte ANDROID_ID.

Op basis van de aanbevelingen van Google heb ik een klasse geïmplementeerd die een unieke UUID voor elk apparaat genereert, waarbij waar nodig ANDROID_ID als seed wordt gebruikt, zo nodig terugvalt op TelephonyManager.getDeviceId() en als dat niet lukt, toevlucht neemt tot een willekeurig unieke UUID gegenereerd die blijft bestaan bij het opnieuw opstarten van de app (maar niet bij herinstallaties van de app).

Houd er rekening mee dat voor apparaten die moeten terugvallen op de apparaat-ID, de unieke ID ZALblijven bestaan tijdens fabrieksresets. Dit is iets om rekening mee te houden. Als je er zeker van wilt zijn dat een fabrieksreset je unieke ID reset, kun je overwegen direct terug te vallen op de willekeurige UUID in plaats van de apparaat-ID.

Nogmaals, deze code is voor een apparaat-ID, niet voor een app-installatie-ID. Voor de meeste situaties is een app-installatie-ID waarschijnlijk wat u zoekt. Maar als u wel een apparaat-ID nodig heeft, dan zal de volgende code waarschijnlijk voor u werken.

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

Antwoord 5, autoriteit 9%

Hier is de code die Reto Meier dit jaar in de Google I/O-presentatie heeft gebruikt om een unieke ID voor de gebruiker:

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

Als je dit koppelt aan een back-upstrategie om voorkeuren naar de cloud te sturen (ook beschreven in Reto’s praat, je zou een id moeten hebben die aan een gebruiker is gekoppeld en blijft hangen nadat het apparaat is gewist of zelfs is vervangen. Ik ben van plan om te gebruiken dit in toekomstige analyses (met andere woorden, dat heb ik nog niet gedaan :).


Antwoord 6, autoriteit 5%

U kunt ook rekening houden met het MAC-adres van de Wi-Fi-adapter. Op deze manier opgehaald:

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

Vereist toestemming android.permission.ACCESS_WIFI_STATEin het manifest.

Gerapporteerd om beschikbaar te zijn, zelfs wanneer Wi-Fi niet is aangesloten. Als Joe uit het bovenstaande antwoord deze een hoop op zijn vele apparaten geeft, zou dat leuk zijn.

Op sommige apparaten is het niet beschikbaar wanneer Wi-Fi is uitgeschakeld.

Opmerking: van Android 6.x, het retourneert consistent nep Mac-adres: 02:00:00:00:00:00


7, Autoriteit 2%

De officiële Android-ontwikkelaars Blog heeft nu een volledig artikel over dit onderwerp, App-installaties identificeren .


8, Autoriteit 2%

Op Google I/Oheeft Reto Meier een robuust antwoord uitgebracht op hoe dit te benaderen, dat de meeste ontwikkelaars zou moeten ontmoeten gebruikers moeten volgen over installaties heen. Anthony Nolan geeft de richting aan in zijn antwoord, maar ik dacht dat ik de volledige aanpak zou opschrijven, zodat anderen gemakkelijk kunnen zien hoe het moet (het kostte me een tijdje om de details te achterhalen).

Met deze aanpak krijgt u een anonieme, veilige gebruikers-ID die permanent is voor de gebruiker op verschillende apparaten (op basis van het primaire Google-account) en tussen installaties. De basisaanpak is om een willekeurige gebruikers-ID te genereren en deze op te slaan in de gedeelde voorkeuren van de apps. Vervolgens gebruikt u de back-upagent van Google om de gedeelde voorkeuren die aan het Google-account zijn gekoppeld op te slaan in de cloud.

Laten we de volledige aanpak doornemen. Eerst moeten we een back-up maken voor onze SharedPreferences met behulp van de Android Backup Service. Begin met het registreren van uw app via http://developer.android.com/google/backup/signup.html.

Google geeft u een back-upservicesleutel die u aan het manifest moet toevoegen. U moet de toepassing ook als volgt vertellen om de BackupAgent te gebruiken:

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

Vervolgens moet je de back-upagent maken en hem vertellen om de helper-agent te gebruiken voor gedeelde voorkeuren:

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

Om de back-up te voltooien, moet u een instantie van BackupManager maken in uw hoofdactiviteit:

BackupManager backupManager = new BackupManager(context);

Maak ten slotte een gebruikers-ID aan, als deze nog niet bestaat, en sla deze op in de 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;
}

Deze User_ID is nu permanent voor alle installaties, zelfs als de gebruiker het apparaat verplaatst.

Voor meer informatie over deze aanpak, zie Reto’s gesprek.

En voor volledige details over het implementeren van de back-upagent, zie Gegevensback-up. Ik raad met name het gedeelte onderaan over testen aan, omdat de back-up niet onmiddellijk plaatsvindt en dus om te testen moet je de back-up forceren.


Antwoord 9, autoriteit 2%

Ik denk dat dit een goede manier is om een skelet te bouwen voor een unieke ID… check it out.

Pseudo-unieke ID, die werkt op alle Android-apparaten
Sommige apparaten hebben geen telefoon (bijv. tablets) of om de een of andere reden wilt u de READ_PHONE_STATE-machtiging niet opnemen. U kunt nog steeds details lezen zoals de ROM-versie, de naam van de fabrikant, het CPU-type en andere hardwaredetails, die zeer geschikt zijn als u de ID wilt gebruiken voor een seriële sleutelcontrole of voor andere algemene doeleinden. De ID die op deze manier wordt berekend, zal niet uniek zijn: het is mogelijk om twee apparaten met dezelfde ID te vinden (gebaseerd op dezelfde hardware en ROM-image), maar de veranderingen in toepassingen in de echte wereld zijn te verwaarlozen. Voor dit doel kun je de Build-klasse gebruiken:

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

De meeste build-leden zijn snaren, wat we hier doen is om hun lengte te nemen en deze via modulo in een cijfer te transformeren. We hebben 13 dergelijke cijfers en we voegen er nog twee aan de voorkant (35) toe om dezelfde formaat-ID te hebben als de IMEI (15 cijfers). Er zijn andere mogelijkheden hier goed, kijk maar eens naar deze snaren.
Retourneert zoiets als 355715565309247. Er is geen speciale toestemming vereist, waardoor deze aanpak erg handig is.


(Extra info: de hierboven gegeven techniek werd gekopieerd van een artikel over pocket magic . )


10, Autoriteit 2%

De volgende code retourneert het serienummer van het apparaat met een verborgen Android-API. Maar deze code werkt niet op het tabblad Samsung Galaxy omdat “RO.SERIALNO” niet op dit apparaat is ingesteld.

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

11

Gebruik de onderstaande code, u kunt de unieke apparaat-ID van een Android OS-apparaat als een tekenreeks krijgen.

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

12

a serieel veld is toegevoegd aan de Buildklasse in API-niveau 9 (Android 2.3 – Gingerbread). Documentatie zegt dat het het serienummer van de hardware vertegenwoordigt. Zo zou het uniek moeten zijn, als het op het apparaat bestaat.

Ik weet niet of het daadwerkelijk wordt ondersteund (= niet null) door alle apparaten met API-niveau & GT; = 9.


13

Een ding dat ik zal toevoegen – ik heb een van die unieke situaties.

Gebruik:

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

blijkt dat, hoewel mijn viewsonic g tablet een inrichting rapportend rapporteert die niet null is, elke g-tablet rapporteert hetzelfde nummer.

Maakt het interessant spelen “Pocket Empires” die u direct toegang geeft tot iemands account op basis van het “unieke” DeviceID.

Mijn apparaat heeft geen mobiele radio.


14

Voor gedetailleerde instructies over het krijgen van een unieke ID voor elk Android-apparaat is uw toepassing geïnstalleerd van, zie de officiële Android-ontwikkelaars Blog Posten App-installaties identificeren .

Het lijkt erop dat de beste manier is om er zelf een te genereren bij installatie en vervolgens leest wanneer de aanvraag opnieuw wordt gelanceerd.

Ik vind persoonlijk dit acceptabele maar niet ideaal. Niemand Identifier verstrekt door Android werkt in alle gevallen, omdat de meesten afhankelijk zijn van de radiobestanden van de telefoon (Wi-Fi aan / uit, cellulair aan / uit, bluetooth aan / uit). De anderen, zoals Settings.Secure.ANDROID_IDmoeten door de fabrikant worden geïmplementeerd en zijn niet gegarandeerd uniek.

Het volgende is een voorbeeld van het schrijven van gegevens naar een -installatie -bestand dat zou worden opgeslagen, samen met andere gegevens die de toepassing lokaal bespaart.

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

15

Voeg hieronder Code in Class File toe:

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

Toevoegen in AndroidManifest.xml:

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

Antwoord 16

Er zijn veel verschillende benaderingen om deze ANDROID_IDproblemen te omzeilen (kan soms nullzijn of apparaten van een specifiek model retourneren altijd dezelfde ID) met pro’s en nadelen:

  • Een aangepast algoritme voor het genereren van ID’s implementeren (gebaseerd op apparaateigenschappen die statisch zouden moeten zijn en niet zullen veranderen -> wie weet)
  • Andere ID’s misbruiken, zoals IMEI, serienummer, wifi-/Bluetooth-MAC-adres ( ze bestaan niet op alle apparaten of er zijn aanvullende machtigingen nodig)

Ik gebruik zelf liever een bestaande OpenUDID-implementatie (zie https://github.com/ylechelle/OpenUDID) voor Android (zie https://github.com/vieux/OpenUDID). Het is eenvoudig te integreren en maakt gebruik van de ANDROID_IDmet fallbacks voor de bovengenoemde problemen.


Antwoord 17

De unieke apparaat-ID van een Android OS-apparaat als String, met behulp van TelephonyManageren ANDROID_ID, wordt verkregen door:

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

Maar ik raad ten zeerste een methode aan die door Google wordt aanbevolen, zie App-installaties identificeren.


Antwoord 18

Er zijn hier meer dan 30 antwoorden en sommige zijn hetzelfde en sommige zijn uniek. Dit antwoord is gebaseerd op enkele van die antwoorden. Een daarvan is het antwoord van @Lenn Dolling.

Het combineert 3 ID’s en creëert een 32-cijferige hexadecimale tekenreeks. Het heeft voor mij heel goed gewerkt.

3 ID’s zijn:
Pseudo-ID– Het wordt gegenereerd op basis van fysieke apparaatspecificaties
ANDROID_IDSettings.Secure.ANDROID_ID
Bluetooth-adres– Bluetooth-adapteradres

Het geeft zoiets als dit terug: 551F27C060712A72730B0A0F734064B1

Opmerking: je kunt altijd meer ID’s toevoegen aan de tekenreeks longId. Bijvoorbeeld serienummer. adres van de wifi-adapter. IMEI. Zo maak je het per apparaat unieker.

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

19

Hoe zit het met de imei . Dat is uniek voor Android of andere mobiele apparaten.


20

Hier is hoe ik de unieke ID genereer:

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

21

Mijn TWEE CENTEN – NB Dit is voor een -apparaat (err) unieke ID – niet de installatie één zoals besproken in de Android-ontwikkelaars blog .

Merk op dat de oplossingvan @emmby terugvalt in een per applicatie-ID, aangezien de SharedPreferences niet over processen (zie hieren hier ). Dus ik heb dit helemaal vermeden.

In plaats daarvan heb ik de verschillende strategieën voor het verkrijgen van een (apparaat)-ID ingekapseld in een opsomming – het veranderen van de volgorde van de opsommingsconstanten beïnvloedt de prioriteit van de verschillende manieren om de ID te verkrijgen. De eerste niet-null-ID wordt geretourneerd of er wordt een uitzondering gegenereerd (volgens goede Java-praktijken om null geen betekenis te geven). Dus ik heb bijvoorbeeld eerst de TELEFONIE – maar een goede standaardkeuze zou de ANDROID_ID zijn
bèta:

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

Antwoord 22

Een andere manier is om /sys/class/android_usb/android0/iSerialte gebruiken in een app zonder enige toestemming.

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

Om dit in Java te doen zou men gewoon een FileInputStream gebruiken om het iSerial-bestand te openen en de karakters uit te lezen. Zorg er wel voor dat u het in een uitzonderingshandler verpakt, omdat niet alle apparaten dit bestand hebben.

Van de volgende apparaten is bekend dat ze dit bestand voor de hele wereld leesbaar hebben:

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

Je kunt ook mijn blogpost bekijken Serienummer van Android-hardware lekken naar niet-bevoorrechte appswaar ik bespreek welke andere bestanden beschikbaar zijn voor informatie.


Antwoord 23

TelephonyManger.getDeviceId()Retourneert de unieke apparaat-ID, bijvoorbeeld de IMEI voor GSM en de MEID of ESN voor CDMA-telefoons.

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

Maar ik raad aan om:

Settings.Secure.ANDROID_IDdie de Android-ID retourneert als een unieke 64-bits hexadecimale tekenreeks.

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

Soms retourneert TelephonyManger.getDeviceId()null, dus om een unieke id te garanderen, gebruikt u deze methode:

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

Antwoord 24

Google-instantie-ID

Uitgebracht op I/O 2015; op Android vereist afspeelservices 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

Het lijkt erop dat Google van plan is deze ID te gebruiken om installaties op Android, Chrome en iOS te identificeren.

Het identificeert een installatie in plaats van een apparaat, maar nogmaals, ANDROID_ID (wat het geaccepteerde antwoord is) identificeert nu ook geen apparaten meer. Met de ARC-runtime wordt voor elke installatie een nieuwe ANDROID_ID gegenereerd (details hier), net als deze nieuwe instantie-ID. Ik denk ook dat de meesten van ons eigenlijk op zoek zijn naar het identificeren van installaties (geen apparaten).

De voordelen van instantie-ID

Het lijkt mij dat Google het voor dit doel wil gebruiken (uw installaties identificeren), het is platformonafhankelijk en kan voor een aantal andere doeleinden worden gebruikt (zie de links hierboven).

Als u GCM gebruikt, moet u uiteindelijk deze instantie-ID gebruiken omdat u deze nodig hebt om de GCM-token te verkrijgen (die de oude GCM-registratie-ID vervangt).

De nadelen/problemen

In de huidige implementatie (GPS 7.5) wordt de instantie-ID opgehaald van een server wanneer uw app hierom vraagt. Dit betekent dat de bovenstaande oproep een blokkerende oproep is – in mijn onwetenschappelijke testen duurt het 1-3 seconden als het apparaat online is en 0,5 – 1,0 seconden als het offline is (vermoedelijk is dit hoe lang het wacht voordat het opgeeft en een willekeurige identificatie). Dit is getest in Noord-Amerika op Nexus 5 met Android 5.1.1 en GPS 7.5.

Als u de ID gebruikt voor de doeleinden waarvoor ze bedoeld zijn, bijv. app-authenticatie, app-identificatie, GCM – ik denk dat deze 1-3 seconden hinderlijk kan zijn (afhankelijk van je app natuurlijk).


Antwoord 25

Voor hardwareherkenning van een specifiek Android-apparaat kunt u de MAC-adressen controleren.

je kunt het zo doen:

in AndroidManifest.xml

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

Nu in uw code:

List<NetworkInterface> interfacesList = Collections.list(NetworkInterface.getNetworkInterfaces());
for (NetworkInterface interface : interfacesList) {
   // This will give you the interface MAC ADDRESS
   interface.getHardwareAddress();
}

In elk Android-apparaat is hun ten minste een “WLAN0” -interface-heks de Wi-Fi-chip.
Deze code werkt zelfs wanneer Wi-Fi niet is ingeschakeld.

P.S.
Hun zijn een stel andere interfaces die u krijgt uit de lijst met MACS, maar dit kan veranderen tussen telefoons.


26

Ik gebruik de volgende code om de IMEIte krijgen of veilig te gebruiken. ANDROID_IDAls alternatief, wanneer het apparaat geen telefoonmogelijkheden heeft:

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

27

Om de beschikbare unieke ID’s in Android-apparaten te begrijpen. Gebruik deze officiële gids.

beste praktijken voor unieke identifiers:

IMEI, MAC-adressen, instantie-ID, GUIDS, SSAID, Reclame-ID, Veiligheidsnet API om apparaten te verifiëren.

https://developer.android.com/training/articles/User- Data-ID’s


28

1. Gebruik de telefoniemanager, die een unieke ID (d.w.z. imei) biedt. Zie het voorbeeld,

import android.telephony.TelephonyManager;
import android.content.Context;
// ...
TelephonyManager telephonyManager;
telephonyManager = (TelephonyManager) getSystemService(Context.
                TELEPHONY_SERVICE);
/*
* getDeviceId() returns the unique device ID.
* For example,the IMEI for GSM and the MEID or ESN for CDMA phones.
*/
String deviceId = telephonyManager.getDeviceId();
/*
* getSubscriberId() returns the unique subscriber ID,
*/
String subscriberId = telephonyManager.getSubscriberId();

Dit vereist android.permission.READ_PHONE_STATEvoor uw gebruiker, wat moeilijk te rechtvaardigen kan zijn om het type applicatie dat u heeft gemaakt te volgen.

  1. Apparaten zonder telefonieservices, zoals tablets, moeten een unieke apparaat-ID rapporteren die beschikbaar is via android.os.Build.SERIALsinds Android 2.3 Gingerbread. Sommige telefoons met telefoondiensten kunnen ook een serienummer definiëren. Omdat niet alle Android-apparaten een serienummer hebben, is deze oplossing niet betrouwbaar.

  2. Bij de eerste keer opstarten van een apparaat wordt een willekeurige waarde gegenereerd en opgeslagen. Deze waarde is beschikbaar via Settings.Secure.ANDROID_ID. Het is een 64-bits getal dat constant moet blijven gedurende de levensduur van een apparaat. ANDROID_IDlijkt een goede keuze voor een unieke apparaat-ID, omdat deze beschikbaar is voor smartphones en tablets. Om de waarde op te halen, kunt u de volgende code gebruiken,

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

De waarde kan echter veranderen als een fabrieksreset wordt uitgevoerd op het apparaat. Er is ook een bug bekend met een populaire handset van een fabrikant waarbij elke instantie dezelfde ANDROID_IDheeft. Het is duidelijk dat de oplossing niet 100% betrouwbaar is.

  1. Gebruik UUID. Aangezien de vereiste voor de meeste toepassingen is om een bepaalde installatie te identificeren en niet een fysiek apparaat, is dit een goede oplossing om de unieke id voor een gebruiker te krijgen als hij de UUID-klasse wil gebruiken. De volgende oplossing is gepresenteerd door Reto Meier van Google in een Google I/O-presentatie,
SharedPreferences sharedPrefs = context.getSharedPreferences(
         PREF_UNIQUE_ID, Context.MODE_PRIVATE);
uniqueID = sharedPrefs.getString(PREF_UNIQUE_ID, null);

Update: de optie #1en #2zijn niet langer beschikbaar na Android 10 als de privacy-updates van Google. omdat voor optie 2 en 3 kritieke toestemming vereist is.

Other episodes