6

I need to uniquely identify an Android device. I read about ANDROID_ID but it seems to have problems with Android 2.2. Then there are other identifiers related to TelephonyManager, but I reckon they don't work on tablets.
So, looking for something working on every device I stumbled upon the GSF ID KEY (google service framework id). Do you guys think this is a reliable and always working solution? This is the code I found to retrieve the GSF ID KEY:

private static String getGsfAndroidId(Context context) 
{
    Uri URI = Uri.parse("content://com.google.android.gsf.gservices");
    String ID_KEY = "android_id";
    String params[] = {ID_KEY};
    Cursor c = context.getContentResolver().query(URI, null, null, params, null);
    if (!c.moveToFirst() || c.getColumnCount() < 2)
        return null;
    try 
    {
        return Long.toHexString(Long.parseLong(c.getString(1)));
    } 
    catch (NumberFormatException e) 
    {
        return null;
    }
}
user2461515
  • 339
  • 1
  • 3
  • 8

4 Answers4

5

In case someone is wondering if this method works the answer is yes, I tried it (and used it in an app I put on the Android market with thousands of downloads) and it works. Note: the GSF ID KEY changes every time the user does a factory reset or messes up with Google Services, but it was good enough for my purpose.

user2461515
  • 339
  • 1
  • 3
  • 8
  • Did you have to add `com.google.android.providers.gsf.permission.READ_GSERVICES` permission? – cprcrack Dec 31 '14 at 02:38
  • 1
    Well, I had to in my case (Nexus 5 with Android 5.0), otherwise an exception is raised. Can you verify if it's working for your users with a Nexus 5 with Android 5.0? – cprcrack Jan 02 '15 at 20:47
  • @cprcrack you have to add the pemission com.google.android.providers.gsf.permission.READ_GSERVICES – Abhijit Chakra Dec 14 '20 at 05:30
2

using Android Studio, I get auto-recommendations from lint. here is the code, after revised. it may solve exceptions reported by https://stackoverflow.com/users/423171/cprcrack

private static String getGsfAndroidId(Context context)
{
    Uri URI = Uri.parse("content://com.google.android.gsf.gservices");
    String ID_KEY = "android_id";
    String params[] = {ID_KEY};
    Cursor c = context.getContentResolver().query(URI, null, null, params, null);
    if (c != null && (!c.moveToFirst() || c.getColumnCount() < 2)){
        if(!c.isClosed())
            c.close();
        return null;
    }

    try {
        if (c != null) {
            String result = Long.toHexString(Long.parseLong(c.getString(1)));
            if(!c.isClosed())
                c.close();
            return result;
        }else {
            return null;
        }
    } catch (NumberFormatException e) {
        if(!c.isClosed())
            c.close();
        return null;
    }
}
Community
  • 1
  • 1
Dika
  • 2,213
  • 4
  • 33
  • 49
0

Can't talk about production tests, but I noticed that in my Nexus 5 with Android 5.0, I had to add the following permission: com.google.android.providers.gsf.permission.READ_GSERVICES. Otherwise an exception is raised when using your code.

cprcrack
  • 17,118
  • 7
  • 88
  • 91
0

Can't talk about production tests, but I noticed that in my Nexus 5 with Android 5.0, I had to add the following permission: com.google.android.providers.gsf.permission.READ_GSERVICES. Otherwise an exception is raised when using your code.

Share Improve this answ

Yeremy
  • 1
  • Your answer could be improved with additional supporting information. Please [edit] to add further details, such as citations or documentation, so that others can confirm that your answer is correct. You can find more information on how to write good answers [in the help center](/help/how-to-answer). – Community Sep 24 '21 at 18:34