52

I want to get users Advertising ID programmatically.I used the below code from the developer site.But its not working

         Info adInfo = null;
          try {
            adInfo = AdvertisingIdClient.getAdvertisingIdInfo(getApplicationContext());

          } catch (IOException e) {
            // Unrecoverable error connecting to Google Play services (e.g.,
            // the old version of the service doesn't support getting AdvertisingId).

          } catch (GooglePlayServicesNotAvailableException e) {
            // Google Play services is not available entirely.
          } catch (IllegalStateException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (GooglePlayServicesRepairableException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
          final String id = adInfo.getId();
          final boolean isLAT = adInfo.isLimitAdTrackingEnabled();

How can I get user's advertising id programmatically ?? please help me

Alex.F
  • 5,648
  • 3
  • 39
  • 63
user3868543
  • 553
  • 1
  • 4
  • 7
  • 5
    possible duplicate of [Using the new Android Advertiser id inside an SDK](http://stackoverflow.com/questions/20097506/using-the-new-android-advertiser-id-inside-an-sdk) – lxg Sep 15 '14 at 11:09

13 Answers13

57

I might be late but this might help someone else!

    AsyncTask<Void, Void, String> task = new AsyncTask<Void, Void, String>() {
        @Override
        protected String doInBackground(Void... params) {
            AdvertisingIdClient.Info idInfo = null;
            try {
                idInfo = AdvertisingIdClient.getAdvertisingIdInfo(getApplicationContext());
            } catch (GooglePlayServicesNotAvailableException e) {
                e.printStackTrace();
            } catch (GooglePlayServicesRepairableException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            }
            String advertId = null;
            try{
                advertId = idInfo.getId();
            }catch (NullPointerException e){
                e.printStackTrace();
            }

            return advertId;
        }

        @Override
        protected void onPostExecute(String advertId) {
            Toast.makeText(getApplicationContext(), advertId, Toast.LENGTH_SHORT).show();
        }

    };
    task.execute();
DaniZ
  • 596
  • 4
  • 4
  • 1
    It is not working. My application is unfortunately stopped. – Praveen Kumar Verma Aug 30 '16 at 10:08
  • Any idea what parameter in the Google Measurement Protocol needs to be used to transfer that advertising ID to the GA endpoint? Is it the client ID (cid)? The doc available is not clear at all about that... http://stackoverflow.com/questions/41875097/how-to-use-advertising-id-on-android – Gilbou Jan 26 '17 at 14:04
  • @DaniZ hi, i noticed that this solution with asynctask has been mentioned in this youtube video, which is fairly new (uploaded 11 months ago): https://www.youtube.com/watch?v=D2zq6yKdXuk. could you explain why using AsyncTask makes it work? – mangusta Jan 02 '23 at 09:33
20

Get GAID(Google’s advertising ID)

1. Download latest Google Play Services SDK.
2. Import the code and add it as a library project.
3. Modify AndroidManifest.xml.

<meta-data
        android:name="com.google.android.gms.version"
        android:value="@integer/google_play_services_version" />

4. Enable ProGuard to shrink and obfuscate your code in project.properties this line

 proguard.config=${sdk.dir}/tools/proguard/proguard-android.txt:proguard-project.txt

5. Add rules in proguard-project.txt.

     -keep class * extends java.util.ListResourceBundle {
    protected Object[][] getContents();  }

 -keep public class com.google.android.gms.common.internal.safeparcel.SafeParcelable {
        public static final *** NULL;      }
    
    -keepnames @com.google.android.gms.common.annotation.KeepName class *
    -keepclassmembernames class * {
        @com.google.android.gms.common.annotation.KeepName *;
    }
    
    -keepnames class * implements android.os.Parcelable {
        public static final ** CREATOR;
    }

6. Call AdvertisingIdClient.getAdvertisingIdInfo(getApplicationContext()).getId() in a worker thread to get the id in String. as like this

        AsyncTask<Void, Void, String> task = new AsyncTask<Void, Void, String>() {
        @Override
        protected String doInBackground(Void... params) {
            AdvertisingIdClient.Info idInfo = null;
            try {
                idInfo = AdvertisingIdClient.getAdvertisingIdInfo(getApplicationContext());
            } catch (GooglePlayServicesNotAvailableException e) {
                e.printStackTrace();
            } catch (GooglePlayServicesRepairableException e) {
                e.printStackTrace();
            } catch (Exception e) {
                e.printStackTrace();
            }
            String advertId = null;
            try{
                advertId = idInfo.getId();
            }catch (Exception e){
                e.printStackTrace();
            }
            return advertId;
        }
        @Override
        protected void onPostExecute(String advertId) {
            Toast.makeText(getApplicationContext(), advertId, Toast.LENGTH_SHORT).show();
        }
    };
    task.execute();

Enjoy!

Praveen Kumar Verma
  • 2,988
  • 2
  • 18
  • 31
11

You can call the below function in onCreate(Bundle savedInstanceState) of the activity

and in the logcat search for UIDMY then it will display the id like : I/UIDMY: a1cf5t4e-9eb2-4342-b9dc-10cx1ad1abe1

void getUIDs()
{
    AsyncTask.execute(new Runnable() {
        @Override
        public void run() {
            try {
                AdvertisingIdClient.Info adInfo = AdvertisingIdClient.getAdvertisingIdInfo(SplashScreen.this);
                String myId = adInfo != null ? adInfo.getId() : null;
             
                Log.i("UIDMY", myId);
            } catch (Exception e) {
                Toast toast = Toast.makeText(context, "error occurred ", Toast.LENGTH_SHORT);
                toast.setGravity(gravity, 0,0);
                toast.show();
            }
        }
    });
}
Alexander
  • 2,925
  • 3
  • 33
  • 36
muskomsoft
  • 111
  • 1
  • 3
11

The modern way is to use Coroutines in Kotlin, since AsyncTask is now being deprecated for Android. Here is how I did it:

import com.google.android.gms.ads.identifier.AdvertisingIdClient
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.withContext

class AdvertisingInfo(val context: Context) {

    private val adInfo = AdvertisingIdClient(context.applicationContext)

    suspend fun getAdvertisingId(): String =
        withContext(Dispatchers.IO) {
            //Connect with start(), disconnect with finish()
            adInfo.start()
            val adIdInfo = adInfo.info
            adInfo.finish()
            adIdInfo.id
        }
}

When you are ready to use the advertising ID, you need to call another suspending function:

suspend fun applyDeviceId(context: Context) {
    val advertisingInfo = AdvertisingInfo(context)
    // Here is the suspending function call, 
    // in this case I'm assigning it to a static object
    MyStaticObject.adId = advertisingInfo.getAdvertisingId()
}
Heath Kornblum
  • 111
  • 1
  • 4
  • Where do you use `applyDeviceId` ? And does `getAdvertisingId` gets reset to have new values on its fields when you do factory-reset? – android developer Aug 18 '20 at 08:24
  • In the above case I would call it during onCreate() or onResume() to store it for later use. If you call this after a factory reset and the advertising ID changes, this would pick it up. – Heath Kornblum Aug 19 '20 at 16:32
  • Can you please show how you use it? And when is it useful exactly? Is it only for ad-networks? What if you wish to identify the device itself? Seems quite impossible now, as Google added more and more restrictions for it... – android developer Aug 19 '20 at 18:33
  • It may be useful for organizations other than ad networks. It does identify the device itself. When I used it, it was for a company in advertising technology and digital marketing. We were creating a tool for app developers to use in privacy law compliance and it was needed well after creation of the main activity: `suspend fun getConfigString(context: Context): JSONObject { applySharedPreferencesToConfig(context) applyDeviceId(context) val configJson = JSONObject() val gvlJson = JSONObject() // etc. ` – Heath Kornblum Aug 20 '20 at 17:49
  • My above comment is hard to read, sorry. The point is that the data itself was useful as a member of a JSON object used to configure some marketing tools. Call it whenever you need to. Make sure you are using the IO coroutines dispatcher, Dispatchers.IO, since you are accessing data which belongs to the device itself, outside the scope of your app. HTH – Heath Kornblum Aug 20 '20 at 18:17
  • Can you please edit the answer to include the usage of it? Also, how do you say that it identifies the device, if it can get reset and then you get a different ID? – android developer Aug 20 '20 at 21:43
  • The device ID will change on a factory reset. That is a limitation of the ID which is used to identify the device. Period. The examples above show access and storage. Usage is really up to you. If you need to identify the device for marketing purposes, you may do so on a server back-end. Passing the data to a server from the device via http POST or GET or by some other means is beyond the scope the question I'm trying to answer here. – Heath Kornblum Aug 21 '20 at 19:19
  • Can you please update the answer to include the usage of `applyDeviceId` ? – android developer Aug 22 '20 at 13:51
  • Not sure what you need, android developer. What do you want to do with the device id once you have it? My answers above attempt to use applyDeviceId, but I don't know what is missing for you. – Heath Kornblum Aug 24 '20 at 16:09
  • About device id? I got tasked to work on some app that used what's restricted now on Android 10. As for the function, it isn't complete without showing how to use. – android developer Aug 25 '20 at 06:56
  • You can use the above as-is from a Kotlin suspending function context anywhere in your code like so: suspend fun getInfo(context: Context) : String { val adInfo = AdvertisingInfo(context); return advertisingInfo.getAdvertisingId() }. That's how you use it. It's a string that comes from the device itself, so coroutines are a critical part if you do it this way. The AdvertisingIdClient will return the ID after you 'start()' and then call for it. Remember to call finish() to avoid memory leaks. – Heath Kornblum Aug 25 '20 at 17:01
  • https://developers.google.com/android/reference/com/google/android/gms/ads/identifier/AdvertisingIdClient – Heath Kornblum Aug 25 '20 at 17:10
10

Just in case someone is interested in trying out the fetching AdvertisingId part while Rx-ing then this might be helpful.

private void fetchAndDoSomethingWithAdId() {
    Observable.fromCallable(new Callable<String>() {
        @Override
        public String call() throws Exception {
            return AdvertisingIdClient.getAdvertisingIdInfo(context).getId();
        }
    })
              .subscribeOn(Schedulers.io())
              .observeOn(AndroidSchedulers.mainThread())
              .subscribe(new Action1<String>() {
                  @Override
                  public void call(String id) {
                     //do what you want to do with id for e.g using it for tracking
                  }
              }, new Action1<Throwable>() {
                  @Override
                  public void call(Throwable throwable) {
                      throwable.printStackTrace();
                  }
              });
}
Wahib Ul Haq
  • 4,185
  • 3
  • 44
  • 41
9

Fetch the advertising id from background thread:

    AsyncTask.execute(new Runnable() {
        @Override
        public void run() {
            try {
                AdvertisingIdClient.Info adInfo = AdvertisingIdClient.getAdvertisingIdInfo(mContext);
                String adId = adInfo != null ? adInfo.getId() : null;
                // Use the advertising id
            } catch (IOException | GooglePlayServicesRepairableException | GooglePlayServicesNotAvailableException exception) {
                // Error handling if needed
            }
        }
    });

I added null checks to prevent any crashes. The Google example implementation code would crash with a NullPointerException if an exception occures.

Timo Bähr
  • 1,826
  • 2
  • 22
  • 26
  • I am getting this "00000000-0000-0000-0000-000000000000" by this background thread. I am not getting proper adId. why? – gaurav kumar Jun 27 '22 at 15:34
  • In the meantime (since April, 1 of 2022) you need a permission: `` Compare documentation: https://support.google.com/googleplay/android-developer/answer/6048248 – Timo Bähr Jun 28 '22 at 09:04
  • i wonder is there any reason why `getAdvertisingIdInfo` and `getId` work in the background thread, and fail otherwise? – mangusta Jan 02 '23 at 09:35
3

With OS validation.

Call this in an AsyncTask

/** Retrieve the Android Advertising Id 
     * 
     * The device must be KitKat (4.4)+ 
     * This method must be invoked from a background thread.
     * 
     * */
    public static synchronized String getAdId (Context context) {

        if (android.os.Build.VERSION.SDK_INT < android.os.Build.VERSION_CODES.KITKAT) {
            return null;
        }

        AdvertisingIdClient.Info idInfo = null;
        try {
            idInfo = AdvertisingIdClient.getAdvertisingIdInfo(context);
        } catch (GooglePlayServicesNotAvailableException e) {
            e.printStackTrace();
        } catch (GooglePlayServicesRepairableException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
        String advertId = null;
        try{
            advertId = idInfo.getId();
        }catch (NullPointerException e){
            e.printStackTrace();
        }

        return advertId;
    }
htafoya
  • 18,261
  • 11
  • 80
  • 104
3

If you are using Kotlin use this to get the Google Advertising ID of the device

CoroutineScope(Dispatchers.IO).launch {

        var idInfo: AdvertisingIdClient.Info? = null
        try {
            idInfo = AdvertisingIdClient.getAdvertisingIdInfo(applicationContext)
        } catch (e: GooglePlayServicesNotAvailableException) {
            e.printStackTrace()
        } catch (e: GooglePlayServicesRepairableException) {
            e.printStackTrace()
        } catch (e: IOException) {
            e.printStackTrace()
        }
        var advertId: String? = null
        try {
            advertId = idInfo!!.id
        } catch (e: NullPointerException) {
            e.printStackTrace()
        }
        Log.d(TAG, "onCreate:AD ID $advertId")

    }
metvsk
  • 189
  • 2
  • 4
1
import com.google.android.gms.ads.identifier.AdvertisingIdClient.Info;


Info adInfo = null;

try {
     adInfo = AdvertisingIdClient.getAdvertisingIdInfo(mContext);
} catch (IOException e) {
     e.printStackTrace();
} catch (GooglePlayServicesAvailabilityException e) {
     e.printStackTrace();
} catch (GooglePlayServicesNotAvailableException e) {
     e.printStackTrace();
}

String AdId = adInfo.getId();

You need add gms libs otherwise you cannot get the advertising id. It can be reset by user or when you do a factory reset (at factory reset time the Android id also reset).

1

Make sure you have added play identity services, then you can get advertising id by running a thread like this:

Thread thread = new Thread() {
        @Override
        public void run() {
            try {
                AdvertisingIdClient.Info adInfo = AdvertisingIdClient.getAdvertisingIdInfo(getApplicationContext());
                String advertisingId = adInfo != null ? adInfo.getId() : null;
            } catch (IOException | GooglePlayServicesRepairableException | GooglePlayServicesNotAvailableException exception) {
                exception.printStackTrace();
            }
        }
    };

    // call thread start for background process
    thread.start();
1

You only need this package: implementation("com.google.android.gms:play-services-ads-identifier:17.0.0") It's not really listed anywhere but it's published on Mavne.

Get Google Services using GoogleApiAvailabilityLight.getInstance

Meanman
  • 1,474
  • 20
  • 17
0

You need to run your code using Async Task

try this

Using the new Android Advertiser id inside an SDK

Community
  • 1
  • 1
Key_coder
  • 534
  • 3
  • 27
0

Using Kotlin & RxJava Observers

Import in your Gradle file

implementation 'com.google.android.gms:play-services-ads:15.0.0'

Import on top of your kotlin source file

import io.reactivex.Observable
import com.google.android.gms.ads.identifier.AdvertisingIdClient

Implement a helper function

    private fun fetchAdIdAndThen(onNext : Consumer<String>, onError : Consumer<Throwable>) {
        Observable.fromCallable(Callable<String> {
            AdvertisingIdClient.getAdvertisingIdInfo(context).getId()
        }).subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(onNext, onError);
    }

Then

    fetchAdIdAndThen(Consumer<String>() {
        adId ->
        performMyTaskWithADID(activity, 10000, adId);
    }, Consumer<Throwable>() {
        throwable ->
        throwable.printStackTrace();
        performMyTaskWithADID(activity, 10000, "NoADID");
    })
Ali Nadalizadeh
  • 2,726
  • 3
  • 22
  • 24