繁体   English   中英

Unity Android获取Google Play广告ID

[英]Unity Android Get Google Play Advertising ID

我正在尝试在Unity中获取Google Play广告ID,但似乎根本无法正常工作。

下面是我用我发现一对夫妇SO就像代码这一个

        AndroidJavaClass up = new AndroidJavaClass ("com.unity3d.player.UnityPlayer");
        AndroidJavaObject currentActivity = up.GetStatic<AndroidJavaObject> ("currentActivity");
        AndroidJavaClass client = new AndroidJavaClass ("com.google.android.gms.ads.identifier.AdvertisingIdClient");
        AndroidJavaObject adInfo = client.CallStatic<AndroidJavaObject> ("getAdvertisingIdInfo",currentActivity);

        advertisingID = adInfo.Call<string> ("getId").ToString();  

        using(AndroidJavaClass pluginClass = new AndroidJavaClass("example.com.Toast")) {
            if(pluginClass != null) {
                toastClass = pluginClass.CallStatic<AndroidJavaObject>("getInstance");
                activityContext.Call("runOnUiThread", new AndroidJavaRunnable(() => {
                    toastClass.Call("toastMessage", advertisingID);
                }));
            }
        } 

我必须在实际的设备上执行此操作,还没有找到一种很好的方法来实际记录除Toast消息以外的任何内容,该消息在此处未显示任何内容。 但是,如果我这样做(获取android设备ID),则吐司就可以了。

        AndroidJavaClass up = new AndroidJavaClass ("com.unity3d.player.UnityPlayer");
        AndroidJavaObject currentActivity = up.GetStatic<AndroidJavaObject> ("currentActivity");
        AndroidJavaObject contentResolver = currentActivity.Call<AndroidJavaObject> ("getContentResolver");  
        AndroidJavaClass secure = new AndroidJavaClass ("android.provider.Settings$Secure");
        string android_id = secure.CallStatic<string> ("getString", contentResolver, "android_id");

知道要获取Google Play广告ID应该怎么做吗?

我也尝试像这样在jar代码本身中执行此操作:

AsyncTask<Void, Void, String> task = new AsyncTask<Void, Void, String>() {
            @Override
            protected String doInBackground(Void... params) {
                AdvertisingIdClient.Info idInfo = null;
                try {
                    idInfo = AdvertisingIdClient.getAdvertisingIdInfo(ToastCLass.getInstance().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;
            }

            @Override
            protected void onPostExecute(String advertId) {
                Toast.makeText(ToastClass.getInstance().context, advertId, Toast.LENGTH_LONG).show();
            }

        };
        task.execute();

但这只会在我的应用程序运行时导致错误(我认为是因为它试图在UI线程上运行AsyncTask?)。 再次困难,因为我还没有真正找到显示日志/错误的方法。

看来,如果我在模拟器上运行我的应用程序,则可以进入日志,这有助于注销信息。

我知道这个答案有点晚了,但这对于面临此问题的人可能会有所帮助。

首先,汤姆给出的答案是正确的,确实有效。 但是发生此错误的原因是,当我们添加包的文件时,我们并未包括它具有的所有依赖关系。 您实际上可以通过检查pom文件来做到这一点。

因此在这里,为避免发生此错误,您只需添加play-services-ads-identifier-16.0.0.aar包以及play-service-ads。 你可以在这里找到这个包

我最终写了一个自定义类来访问它,因为错误是:

Caused by: java.lang.ClassNotFoundException: Didn't find class "com.google.android.gms.ads.identifier.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.io.IOException;
import java.util.concurrent.LinkedBlockingQueue;

public final class AdvertisingIdClientInfo {

    public static final class AdInfo {
        private final String advertisingId;
        private final boolean limitAdTrackingEnabled;

        AdInfo(String advertisingId, boolean limitAdTrackingEnabled) {
            this.advertisingId = advertisingId;
            this.limitAdTrackingEnabled = limitAdTrackingEnabled;
        }

        public String getId() {
            return this.advertisingId;
        }

        public boolean isLimitAdTrackingEnabled() {
            return this.limitAdTrackingEnabled;
        }
    }

    public static AdInfo getAdvertisingIdInfo(Context context) throws Exception {
        if(Looper.myLooper() == Looper.getMainLooper()) throw new IllegalStateException("Cannot be called from the main thread");

        try { PackageManager pm = context.getPackageManager(); pm.getPackageInfo("com.android.vending", 0); }
        catch (Exception e) { throw e; }

        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());
                AdInfo adInfo = new AdInfo(adInterface.getId(), adInterface.isLimitAdTrackingEnabled(true));
                return adInfo;
            } catch (Exception exception) {
                throw exception;
            } finally {
                context.unbindService(connection);
            }
        }
        throw new IOException("Google Play connection failed");
    }

    private static final class AdvertisingConnection implements ServiceConnection {
        boolean retrieved = false;
        private final LinkedBlockingQueue<IBinder> queue = new LinkedBlockingQueue<IBinder>(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 (IBinder)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;
        }
    }
}

然后访问它:

public void methodName(final Activity context) {
        new Thread(new Runnable() {
            public void run() {
                try {
                    AdvertisingIdClientInfo.AdInfo adInfo = AdvertisingIdClientInfo.getAdvertisingIdInfo(context);
                    this._googleAdvertiserId = adInfo.getId();
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }).start();
    }

然后将其包装在一个罐子中,在Unity中可以调用它:

if (activityContext == null) {
            using(AndroidJavaClass activityClass = new AndroidJavaClass("com.unity3d.player.UnityPlayer")) {
                activityContext = activityClass.GetStatic<AndroidJavaObject>("currentActivity");
            }
        }

        using(AndroidJavaClass pluginClass = new AndroidJavaClass("example.com.Class")) {
            if(pluginClass != null) {
                className = pluginClass.CallStatic<AndroidJavaObject>("getInstance");
                activityContext.Call("runOnUiThread", new AndroidJavaRunnable(() => {
                    className.Call("methodName", activityContext);
                }));
            }
        }

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM