Android 获取Google广告ID (adid)

Android 市面上其实有很多获取唯一标识的方法,但是海外广告投放时有很多时候都需要用到广告ID ,也就是 Google Advertising ID 简写 ADID.
在Android系统中提供了了AndroidId,但AndroidId有时候会为null,同时root手机用户,androidId可以改变。所以AndroidId并不能作为唯一识别码。

对于Google推荐使用Google Advertising ID,通过Google Service可以获取Google Advertising ID(如果没有Google Service就获取不到Google Advertising ID)。下面看看代码吧

AdvertisingIdClient类

import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.ServiceConnection;
import android.content.pm.PackageManager;
import android.os.IBinder;
import android.os.IInterface;
import android.os.Looper;
import android.os.Parcel;
import android.os.RemoteException;
import java.util.concurrent.LinkedBlockingQueue;
 * date:2020-11-13
 * desc:
public class AdvertisingIdClient {
     * 这个方法是耗时的,不能在主线程调用
    public static String getGoogleAdId(Context context) throws Exception {
        if (Looper.getMainLooper() == Looper.myLooper()) {
            return "Cannot call in the main thread, You must call in the other thread";
        PackageManager pm = context.getPackageManager();
        pm.getPackageInfo("com.android.vending", 0);
        AdvertisingConnection connection = new AdvertisingConnection();
        Intent intent = new Intent(
                "com.google.android.gms.ads.identifier.service.START");
        intent.setPackage("com.google.android.gms");
        if (context.bindService(intent, connection, Context.BIND_AUTO_CREATE)) {
            try {
                AdvertisingInterface adInterface = new AdvertisingInterface(
                        connection.getBinder());
                return adInterface.getId();
            } finally {
                context.unbindService(connection);
        return "";
    private static final class AdvertisingConnection implements ServiceConnection {
        boolean retrieved = false;
        private final LinkedBlockingQueue<IBinder> queue = new LinkedBlockingQueue<>(1);
        public void onServiceConnected(ComponentName name, IBinder service) {
            try {
                this.queue.put(service);
            } catch (InterruptedException localInterruptedException) {
        public void onServiceDisconnected(ComponentName name) {
        public IBinder getBinder() throws InterruptedException {
            if (this.retrieved)
                throw new IllegalStateException();
            this.retrieved = true;
            return this.queue.take();
    private static final class AdvertisingInterface implements IInterface {
        private IBinder binder;
        public AdvertisingInterface(IBinder pBinder) {
            binder = pBinder;
        public IBinder asBinder() {
            return binder;
        public String getId() throws RemoteException {
            Parcel data = Parcel.obtain();
            Parcel reply = Parcel.obtain();
            String id;
            try {
                data.writeInterfaceToken("com.google.android.gms.ads.identifier.internal.IAdvertisingIdService");
                binder.transact(1, data, reply, 0);
                reply.readException();
                id = reply.readString();
            } finally {
                reply.recycle();
                data.recycle();
            return id;
        public boolean isLimitAdTrackingEnabled(boolean paramBoolean)
                throws RemoteException {
            Parcel data = Parcel.obtain();
            Parcel reply = Parcel.obtain();
            boolean limitAdTracking;
            try {
                data.writeInterfaceToken("com.google.android.gms.ads.identifier.internal.IAdvertisingIdService");
                data.writeInt(paramBoolean ? 1 : 0);
                binder.transact(2, data, reply, 0);
                reply.readException();
                limitAdTracking = 0 != reply.readInt();
            } finally {
                reply.recycle();
                data.recycle();
            return limitAdTracking;

其实在Application类中获取即可,有一点需要注意就是 这个方法是耗时的,不能在主线程调用

private void initAdid() {
        Executors.newSingleThreadExecutor().execute(new Runnable() {
            @Override
            public void run() {
                try {
                    String adid = AdvertisingIdClient.getGoogleAdId(getApplicationContext());
                    LogUtils.e(TAG,"adid:"+adid);
                    SPStaticUtils.put(SPKeys.USER_ADID,adid);
                } catch (Exception e) {
                    e.printStackTrace();