Получение уникального ID Android

108
06 мая 2021, 03:10

Создаю в игре функцию сохранения некоторых игровых данных пользователя, чтобы в случае переустановки приложения можно было эти данные восстановить. В связи с чем возник вопрос: как получить такой уникальный ID, чтобы при переустановке игры можно было точно сопоставить данные из БД для данного пользователя (естественно, при условии, что устройство то же), не прибегая к использованию опасных и запрашиваемых разрешений? Поделитесь, кто как решает данный вопрос. Спасибо.

Answer 1

Начну с конца.

Если будете хранить ту же БД на устройстве, то разрешения на файловую систему Вам всё равно потребуются. Без них Вам будут доступны только те папки, до которых можно достучаться через контекст. А, они обычно удаляются автоматически вместе с приложением.

Если планируете выгружать данные на сервер, Вам понадобится разрешение INTERNET.

Так что без разрешений никак.

Что касается ID. В зависимости от задачи его можно гененировать различными способами (GUID, CUID, etc...) или использовать идентификаторы связанные с аппаратной частью телефона (тот же IMEI и пр.).

Answer 2

Решил использовать метод получения уникального ID, который используется для обозначения устройства как тестового, при билде запроса в AdMob. Может еще как-то модифицирую его с данными о железе.

Вызов generateDeviceUniqueIdentifier(false);

static string generateDeviceUniqueIdentifier(bool oldBehavior) {
    string id = "";
    AndroidJavaClass jc = new AndroidJavaClass("com.unity3d.player.UnityPlayer");
    AndroidJavaObject activity = jc.GetStatic<AndroidJavaObject>("currentActivity");
    AndroidJavaClass contextClass = new AndroidJavaClass("android.content.Context");
    string TELEPHONY_SERVICE = contextClass.GetStatic<string>("TELEPHONY_SERVICE");
    AndroidJavaObject telephonyService = activity.Call<AndroidJavaObject>("getSystemService", TELEPHONY_SERVICE);
    bool noPermission = false;
    try {
        id = telephonyService.Call<string>("getDeviceId");
    } catch(Exception e) {
        noPermission = true;
    }
    if(id == null)
        id = "";
    if((noPermission && !oldBehavior) || (!noPermission && id == "" && oldBehavior)) {
        AndroidJavaClass settingsSecure = new AndroidJavaClass("android.provider.Settings$Secure");
        string ANDROID_ID = settingsSecure.GetStatic<string>("ANDROID_ID");
        AndroidJavaObject contentResolver = activity.Call<AndroidJavaObject>("getContentResolver");
        id = settingsSecure.CallStatic<string>("getString", contentResolver, ANDROID_ID);
        if(id == null)
            id = "";
    }
    if(id == "") {
        string mac = "00000000000000000000000000000000";
        try {
            StreamReader reader = new StreamReader("/sys/class/net/wlan0/address");
            mac = reader.ReadLine();
            reader.Close();
        } catch(Exception e) { }
        id = mac.Replace(":", "");
    }
    return getMd5Hash(id);
}
static string getMd5Hash(string input) {
    if(input == "")
        return "";
    MD5CryptoServiceProvider md5Hasher = new MD5CryptoServiceProvider();
    byte[] data = md5Hasher.ComputeHash(Encoding.Default.GetBytes(input));
    StringBuilder sBuilder = new StringBuilder();
    for(int i = 0; i < data.Length; i++)
        sBuilder.Append(data[i].ToString("x2"));
    return sBuilder.ToString();
}

Еще как вариант можно использовать только Settings.Secure.ANDROID_ID.

public static string Retrieve(){
    AndroidJavaClass clsUnity = new AndroidJavaClass("com.unity3d.player.UnityPlayer");
    AndroidJavaObject objActivity = clsUnity.GetStatic<AndroidJavaObject>("currentActivity");
    AndroidJavaObject objResolver = objActivity.Call<AndroidJavaObject>("getContentResolver");
    AndroidJavaClass clsSecure = new AndroidJavaClass("android.provider.Settings$Secure");
    string ANDROID_ID = clsSecure.GetStatic<string>("ANDROID_ID");
    string androidId = clsSecure.CallStatic<string>("getString", objResolver, ANDROID_ID);
    return androidId;
}
READ ALSO
Пишу приложение &ldquo;Викторина&rdquo; на java под Android

Пишу приложение “Викторина” на java под Android

Пишу приложение "Викторина" на java под Android

111
int на byte стоит ли?

int на byte стоит ли?

Говорят что все равно машина заменяет byte на int так как ей лучше работать с Int, если заменить все int на byte потребление ресурсов будет меньше ?

79
Stack overflow при маппинге JPA-DTO при отношении one/many to one/many

Stack overflow при маппинге JPA-DTO при отношении one/many to one/many

Суть в том, что есть неких 2 класса А и БПоскольку есть отношение, то соответственно класс А ссылается на Б и наоборот

91
intellij idea выдает Abnormal Build process Determination [закрыт]

intellij idea выдает Abnormal Build process Determination [закрыт]

Хотите улучшить этот вопрос? Обновите вопрос так, чтобы он вписывался в тематику Stack Overflow на русском

149