Frage Gibt es eine eindeutige Android-Geräte-ID?


Verfügen Android-Geräte über eine eindeutige ID, und wenn ja, wie kann man mit Java einfach darauf zugreifen?


2309
2018-05-07 00:47


Ursprung


Antworten:


Settings.Secure#ANDROID_ID gibt die Android-ID als einzigartig für jeden Benutzer 64-Bit Hex-Zeichenfolge.

import android.provider.Settings.Secure;

private String android_id = Secure.getString(getContext().getContentResolver(),
                                                        Secure.ANDROID_ID); 

1697
2018-05-07 00:49



AKTUALISIEREN: Wie neuere Versionen von Android, viele der Probleme mit ANDROID_ID wurden gelöst, und ich glaube, dass dieser Ansatz nicht mehr notwendig ist. Bitte werfen Sie einen Blick auf Anthony's Antwort.

Vollständige Offenlegung: Meine App hat ursprünglich den folgenden Ansatz verwendet, verwendet diesen Ansatz jedoch nicht mehr, und wir verwenden jetzt den im Android Entwickler Blog Eintrag das Emmbys Antwort Links zu (nämlich Erzeugen und Speichern eines UUID#randomUUID()).


Es gibt viele Antworten auf diese Frage, von denen die meisten nur "einige" der Zeit funktionieren, und leider ist das nicht gut genug.

Basierend auf meinen Tests von Geräten (alle Telefone, von denen mindestens eines nicht aktiviert ist):

  1. Alle getesteten Geräte haben einen Wert für zurückgegeben TelephonyManager.getDeviceId()
  2. Alle GSM-Geräte (alle mit einer SIM getestet) gaben einen Wert für TelephonyManager.getSimSerialNumber()
  3. Alle CDMA-Geräte haben null für zurückgegeben getSimSerialNumber() (wie erwartet)
  4. Alle Geräte mit einem hinzugefügten Google-Konto haben einen Wert für zurückgegeben ANDROID_ID
  5. Alle CDMA-Geräte haben für beide den gleichen Wert (oder die Ableitung desselben Werts) zurückgegeben ANDROID_ID und TelephonyManager.getDeviceId() - so lange wie Ein Google-Konto wurde während der Einrichtung hinzugefügt.
  6. Ich hatte noch keine Gelegenheit, GSM-Geräte ohne SIM, ein GSM-Gerät ohne Google-Konto oder eines der Geräte im Flugzeugmodus zu testen.

Wenn Sie also etwas Einzigartiges für das Gerät selbst möchten, TM.getDeviceId()  sollte ausreichen. Offensichtlich sind manche Benutzer paranoider als andere, daher könnte es nützlich sein, einen oder mehrere dieser Identifikatoren zu hashen, so dass der String für das Gerät immer noch praktisch einzigartig ist, aber das tatsächliche Gerät des Benutzers nicht explizit identifiziert. Zum Beispiel mit String.hashCode(), kombiniert mit einer 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();

könnte etwas wie Folgendes ergeben: 00000000-54b3-e7c7-0000-000046bffd97

Es funktioniert gut genug für mich.

Wie Richard unten erwähnt, vergiss nicht, dass du die Erlaubnis brauchst, das zu lesen TelephonyManager Eigenschaften, also füge das zu deinem Manifest hinzu:

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

libs importieren

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

1056
2018-05-17 22:12



Zuletzt aktualisiert: 02.06.15


Nachdem ich jeden Stack Overflow-Beitrag über die Erstellung einer eindeutigen ID, den Google-Entwicklerblog und die Android-Dokumentation gelesen habe, habe ich das Gefühl, dass die "Pseudo-ID" die bestmögliche Option ist.

Hauptproblem: Hardware vs Software

Hardware

  • Benutzer können ihre Hardware, Android-Tablet oder Telefon ändern, so dass eindeutige IDs, die auf Hardware basieren, keine guten Ideen sind Benutzer verfolgen
  • Zum Tracking-HardwareDas ist eine großartige Idee

Software

  • Benutzer können ihren ROM löschen / ändern, wenn sie verwurzelt sind
  • Sie können Benutzer plattformübergreifend verfolgen (iOS, Android, Windows und Web)
  • Das Beste wollen SPIELEN SIE EINEN INDIVIDUELLEN BENUTZER mit deren Zustimmung ist, sie einfach einloggen zu lassen (mach das nahtlos mit OAuth)

Zusammenbruch mit Android

- Gewähre die Eindeutigkeit (verwende gerootete Geräte) für API> = 9/10 (99,5% der Android-Geräte)

- Keine zusätzlichen Berechtigungen

Psuedo-Code:

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

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

else

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

Danke an @stansult für das Posten alle unsere Möglichkeiten (in dieser Stapelüberlauffrage).

Liste der Optionen - Gründe warum / warum sie nicht zu verwenden sind:

  • Benutzer E-Mail - Software

    • Benutzer könnte E-Mail ändern - HOCH unwahrscheinlich
    • API 5+ <uses-permission android:name="android.permission.GET_ACCOUNTS" /> oder
    • API 14+ <uses-permission android:name="android.permission.READ_PROFILE" />  <uses-permission android:name="android.permission.READ_CONTACTS" /> (So erhalten Sie die primäre E-Mail-Adresse des Android-Geräts)
  • Benutzer Telefonnummer - Software

    • Benutzer könnten Telefonnummern ändern - HOCH unwahrscheinlich
    • <uses-permission android:name="android.permission.READ_PHONE_STATE" />
  • IMEI - Hardware (nur Telefone, Bedürfnisse android.permission.READ_PHONE_STATE)

    • Die meisten Benutzer hassen die Tatsache, dass in der Erlaubnis "Telefonanrufe" stehen. Einige Benutzer geben schlechte Bewertungen, weil sie glauben, dass Sie nur ihre persönlichen Daten stehlen, wenn Sie nur wirklich Geräte installieren möchten. Es liegt auf der Hand, dass Sie Daten sammeln.
    • <uses-permission android:name="android.permission.READ_PHONE_STATE" />
  • Android ID - Hardware (kann null sein, kann sich beim Zurücksetzen auf Werkseinstellungen ändern, kann auf einem gerooteten Gerät geändert werden)

    • Da es "Null" sein kann, können wir nach "Null" suchen und seinen Wert ändern, aber das bedeutet, dass es nicht mehr eindeutig ist.
    • Wenn Sie einen Benutzer mit einem Gerät zum Zurücksetzen auf die Werkseinstellungen haben, hat sich der Wert auf dem gerooteten Gerät möglicherweise geändert oder geändert, sodass möglicherweise doppelte Einträge vorhanden sind, wenn Sie Benutzerinstallationen verfolgen.
  • WLAN-MAC-Adresse - Hardware (Bedürfnisse android.permission.ACCESS_WIFI_STATE)

    • Dies könnte die zweitbeste Option sein, aber Sie sammeln und speichern immer noch eine eindeutige ID, die direkt von einem Benutzer stammt. Dies ist offensichtlich, dass Sie Daten sammeln.
    • <uses-permission android:name="android.permission.ACCESS_WIFI_STATE "/>
  • Bluetooth-MAC-Adresse - Hardware (Geräte mit Bluetooth, Bedürfnisse android.permission.BLUETOOTH)

    • Die meisten Anwendungen auf dem Markt verwenden kein Bluetooth, und wenn Ihre Anwendung nicht Bluetooth verwendet und Sie dies einschließen, könnte der Benutzer verdächtig werden.
    • <uses-permission android:name="android.permission.BLUETOOTH "/>
  • Pseudo-Eindeutige ID - Software (für alle Android-Geräte)

    • Sehr wahrscheinlich, kann Kollisionen enthalten - Siehe meine unten angegebene Methode!
    • Auf diese Weise können Sie eine "fast eindeutige" ID vom Benutzer erhalten, ohne etwas Privates zu nehmen. Sie können Ihre eigene anonyme ID aus Geräteinformationen erstellen.

Ich weiß, dass es keine "perfekte" Möglichkeit gibt, eine eindeutige ID zu erhalten, ohne Berechtigungen zu verwenden. Manchmal müssen wir jedoch nur die Geräteinstallation verfolgen. Wenn es darum geht, eine eindeutige ID zu erstellen, können wir eine "pseudo-eindeutige ID" erstellen, die ausschließlich auf Informationen basiert, die die Android-API ohne zusätzliche Berechtigungen bereitstellt. Auf diese Weise können wir dem Benutzer Respekt zeigen und versuchen, eine gute Benutzererfahrung zu bieten.

Bei einer pseudo-eindeutigen ID kommt man eigentlich nur auf die Tatsache, dass es aufgrund der Tatsache, dass es ähnliche Geräte gibt, zu Duplikaten kommen kann. Sie können die kombinierte Methode optimieren, um sie eindeutiger zu machen. Einige Entwickler müssen jedoch die Geräteinstallationen nachverfolgen und dies wird den Trick oder die Leistung basierend auf ähnlichen Geräten ausführen.

API> = 9:

Wenn das Android-Gerät über API 9 verfügt, ist dies aufgrund des Felds "Build.SERIAL" eindeutig.

MERKEN, Sie verpassen technisch nur etwa 0,5% der Benutzer Wer hat API <9. So können Sie sich auf den Rest konzentrieren: Das sind 99,5% der Nutzer!

API <9:

Wenn das Android-Gerät des Nutzers niedriger ist als API 9; hoffentlich haben sie keinen Factory-Reset durchgeführt und ihre 'Secure.ANDROID_ID' wird beibehalten oder nicht 'null'. (sehen http://developer.android.com/about/dashboards/index.html)

Wenn alle Stricke reißen:

Wenn alles andere fehlschlägt, wenn der Benutzer niedriger als API 9 (niedriger als Gingerbread) ist, sein Gerät zurückgesetzt hat oder "Secure.ANDROID_ID" den Wert 'null' zurückgibt, wird die zurückgegebene ID ausschließlich auf ihren Android-Geräteinformationen basieren. Hier können die Kollisionen passieren.

Änderungen:

  • "Android.SECURE_ID" wegen werkseitiger Rücksetzungen entfernt, kann dazu führen, dass sich der Wert ändert
  • Bearbeitete den Code, um die API zu ändern
  • Der Pseudo wurde geändert

Bitte sehen Sie sich die folgende Methode an:

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

Neu (für Apps mit Anzeigen und Google Play-Diensten):

Über die Google Play Developer-Konsole:

Ab dem 1. August 2014 die Google Play-Programmrichtlinien für Entwickler   erfordert, dass alle neuen App-Uploads und Updates die Werbe-ID verwenden   andere persistente Identifikatoren zu Werbezwecken.   Mehr erfahren

Implementierung:

Genehmigung:

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

Quelle / Dokumente:

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

Wichtig:

Es ist beabsichtigt, dass die Werbe-ID das vorhandene vollständig ersetzt   Verwendung anderer Identifikatoren für Anzeigenzwecke (z. B. Verwendung von ANDROID_ID)   in Settings.Secure), wenn Google Play-Dienste verfügbar sind. Fälle   Wo Google Play-Dienste nicht verfügbar sind, werden durch a angezeigt   GooglePlayServicesNotAvailableException wird ausgelöst von   getAdvertisingIdInfo ().

Warnung, Benutzer können zurücksetzen:

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

Ich habe versucht, auf jeden Link zu verweisen, von dem ich Informationen übernommen habe. Wenn Sie fehlen und einbezogen werden müssen, bitte Kommentar!

Instanz-ID der Google Player-Services

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


364
2017-07-12 23:58



Wie Dave Webb erwähnt, die Android Developer Blog hat einen Artikel das deckt das ab. Ihre bevorzugte Lösung besteht darin, App-Installationen statt Geräte zu verfolgen, und das wird für die meisten Anwendungsfälle gut funktionieren. Der Blogpost zeigt Ihnen den notwendigen Code, um diese Arbeit zu erledigen, und ich empfehle Ihnen, es auszuprobieren.

Der Blogpost diskutiert jedoch Lösungen, wenn Sie eine Geräte-ID und keine App-Installations-ID benötigen. Ich habe mit jemandem bei Google gesprochen, um einige zusätzliche Details zu klären, falls Sie dies tun sollten. Folgendes habe ich über Geräte-IDs herausgefunden, die im oben genannten Blogpost nicht erwähnt wurden:

  • ANDROID_ID ist die bevorzugte Gerätekennung. ANDROID_ID ist absolut zuverlässig auf Versionen von Android <= 2.1 oder> = 2.3. Nur 2.2 hat die in der Post genannten Probleme.
  • Mehrere Geräte mehrerer Hersteller sind vom ANDROID_ID-Fehler in 2.2 betroffen.
  • Soweit ich feststellen konnte, haben alle betroffenen Geräte die gleiche ANDROID_ID, welches ist 9774d56d682e549c. Welches ist auch die gleiche Geräte-ID, die vom Emulator gemeldet wird, BTW.
  • Google glaubt, dass OEMs das Problem für viele oder die meisten ihrer Geräte gepatcht haben, aber ich konnte bestätigen, dass es zumindest Anfang April 2011 immer noch recht einfach ist, Geräte mit der fehlerhaften ANDROID_ID zu finden.

Basierend auf den Empfehlungen von Google habe ich eine Klasse implementiert, die für jedes Gerät eine eindeutige UUID generiert, die ggf. ANDROID_ID als Seed verwendet, bei Bedarf auf TelephonyManager.getDeviceId () zurückgreift und, falls dies fehlschlägt, auf eine zufällig generierte eindeutige UUID zurückgreift Dies wird bei App-Neustarts beibehalten (aber nicht bei App-Neuinstallationen).

Beachten Sie, dass für Geräte, die auf die Geräte-ID zurückgreifen müssen, die eindeutige ID WERDEN persistent über Factory-Reset. Das ist etwas, dessen man sich bewusst sein muss. Wenn Sie sicherstellen müssen, dass ein Zurücksetzen auf die Werkseinstellungen Ihre eindeutige ID zurücksetzt, sollten Sie in Erwägung ziehen, direkt auf die zufällige UUID anstatt auf die Geräte-ID zurückzugreifen.

Dieser Code gilt wiederum für eine Geräte-ID und keine App-Installations-ID. In den meisten Fällen ist eine App-Installations-ID wahrscheinlich das, wonach Sie suchen. Wenn Sie jedoch eine Geräte-ID benötigen, funktioniert der folgende Code wahrscheinlich für Sie.

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

314
2018-04-11 19:06



Hier ist der Code, den Reto Meier in der Google I / O Präsentation in diesem Jahr, um eine eindeutige ID für den Benutzer zu erhalten:

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

Wenn Sie dies mit einer Backup-Strategie verbinden, um Einstellungen an die Cloud zu senden (auch in Reto's beschrieben) sich unterhaltenSie sollten eine ID haben, die mit einem Benutzer verknüpft ist und nach dem Löschen des Geräts oder sogar nach dem Ersetzen des Geräts angezeigt wird. Ich plane, dies in der Analytik in Zukunft zu verwenden (mit anderen Worten, ich habe dieses Bit noch nicht getan :).


165
2017-10-28 13:19



Sie können auch die MAC-Adresse des WLAN-Adapters berücksichtigen. So gefunden:

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

Erfordert Erlaubnis android.permission.ACCESS_WIFI_STATE im Manifest.

Berichtet, um verfügbar zu sein, auch wenn WLAN nicht verbunden ist. Wenn Joe aus der obigen Antwort diesen auf seinen vielen Geräten ausprobieren würde, wäre das nett.

Auf einigen Geräten ist es nicht verfügbar, wenn WLAN ausgeschaltet ist.

HINWEIS: Ab Android 6.x gibt es eine konsistente gefälschte Mac-Adresse zurück: 02:00:00:00:00:00


97
2018-06-23 14:27



Es gibt ziemlich nützliche Informationen Hier.

Es umfasst fünf verschiedene ID-Typen:

  1. IMEI (nur für Android-Geräte mit Telefon verwenden; Bedürfnisse android.permission.READ_PHONE_STATE)
  2. Pseudo-eindeutige ID (für alle Android-Geräte)
  3. Android-ID (kann Null sein, kann sich bei Werksreset ändern, kann auf gerootetem Telefon geändert werden)
  4. WLAN-MAC-Adresse Zeichenfolge (benötigt android.permission.ACCESS_WIFI_STATE)
  5. BT MAC Adresse String (Geräte mit Bluetooth, Bedürfnisse android.permission.BLUETOOTH)

78
2018-02-08 02:16



Der offizielle Android Developers Blog hat jetzt einen ganzen Artikel über genau dieses Thema, Identifizieren von App-Installationen.


43
2018-04-06 07:36



Beim Google I / O Reto Meier hat eine robuste Antwort auf diese Frage veröffentlicht, die den meisten Entwicklern gerecht werden sollte, um Benutzer über mehrere Installationen hinweg zu verfolgen. Anthony Nolan zeigt die Richtung in seiner Antwort, aber ich dachte, ich würde den vollständigen Ansatz aufschreiben, so dass andere leicht sehen können, wie es geht (es dauerte eine Weile, bis ich die Details herausgefunden hatte).

Dieser Ansatz bietet Ihnen eine anonyme, sichere Benutzer-ID, die für den Benutzer auf verschiedenen Geräten (basierend auf dem primären Google-Konto) und für alle Installationen persistent ist. Der grundlegende Ansatz besteht darin, eine zufällige Benutzer-ID zu generieren und diese in den gemeinsamen Einstellungen der Apps zu speichern. Anschließend verwenden Sie den Backup-Agenten von Google, um die mit dem Google-Konto verknüpften freigegebenen Einstellungen in der Cloud zu speichern.

Lassen Sie uns den vollständigen Ansatz durchgehen. Zuerst müssen wir ein Backup für unsere SharedPreferences mit dem Android Backup Service erstellen. Beginnen Sie mit der Registrierung Ihrer App über http://developer.android.com/google/backup/signup.html.

Google gibt Ihnen einen Backup-Service-Schlüssel, den Sie dem Manifest hinzufügen müssen. Sie müssen der Anwendung außerdem mitteilen, den BackupAgent wie folgt zu verwenden:

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

Dann müssen Sie den Sicherungsagenten erstellen und ihn anweisen, den Hilfsprogrammagenten für geteilte Präferenzen zu verwenden:

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

Um die Sicherung abzuschließen, müssen Sie in Ihrer Hauptaktivität eine Instanz von BackupManager erstellen:

BackupManager backupManager = new BackupManager(context);

Erstellen Sie schließlich eine Benutzer-ID, falls noch nicht vorhanden, und speichern Sie sie in den 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;
}

Diese Benutzer-ID ist nun bei allen Installationen persistent, auch wenn der Benutzer das Gerät verschiebt.

Weitere Informationen zu diesem Ansatz finden Sie unter Reto's Gespräch.

Und für vollständige Details, wie man den Backup-Agenten implementiert, siehe Datensicherung. Ich empfehle besonders den Abschnitt unten beim Testen, da das Backup nicht sofort stattfindet und Sie müssen das Backup erzwingen, um es zu testen.


36
2017-12-22 08:13