dor*_*ors 23 android ads uniqueidentifier google-play-services
Android广告SDK将使用Android的新广告客户ID非常有意义.
您似乎只能通过使用google服务sdk来获取ID,如下所述:http: //developer.android.com/google/play-services/id.html.
使用google play服务sdk,需要引用google-play-services_lib项目,这会导致一些问题:
有没有办法只获取广告客户ID,而不使用资源?
Adr*_*ian 40
我遇到了同样的问题,如果您只需要广告客户,您可以直接使用Intent与Google Play服务进行互动.自定义类的示例:
import java.io.IOException;
import java.util.concurrent.LinkedBlockingQueue;
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;
public final class AdvertisingIdClient {
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;
}
}
}
Run Code Online (Sandbox Code Playgroud)
确保您没有从主UI线程调用它.例如,使用以下内容:
new Thread(new Runnable() {
public void run() {
try {
AdInfo adInfo = AdvertisingIdClient.getAdvertisingIdInfo(context);
advertisingId = adInfo.getId();
optOutEnabled = adInfo.isLimitAdTrackingEnabled();
} catch (Exception e) {
e.printStackTrace();
}
}
}).start();
Run Code Online (Sandbox Code Playgroud)
Adrian的解决方案很棒,我自己也用它.
但是,今天我发现当设备上没有安装Google Play服务时,它有一个错误.ServiceConnection当您的活动/服务停止时,您将收到有关泄漏信息的消息.这实际上是一个错误Context.bindService:当绑定到服务失败时(在这种情况下,因为没有安装Google Play服务),Context.bindService返回false,但它不会清除对该引用的引用ServiceConnection,并且Context.unbindService即使服务没有,也希望您调用不存在!
解决方法是更改这样的代码getAdvertisingIdInfo:
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");
try {
if(context.bindService(intent, connection, Context.BIND_AUTO_CREATE)) {
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");
}
Run Code Online (Sandbox Code Playgroud)
Context.unbindService即使Context.bindService返回,也会调用这种方式false.
注意:我的答案已过时Gradle,因为现在您可以选择要包含在项目中的GooglePlayServices库的哪些部分
当我正在进行的项目达到65k dex限制时,我最近遇到了同样的问题.
这是我如何解决它:
转到https://code.google.com/p/jarjar/downloads/list并以.jar格式下载最新的Jar jar链接.将文件放在工作文件夹中.对于这个例子,我将使用桌面.
转到[Android SDK路径]\extras\google\google_play_services\libproject\google-play-services_lib\libs并将google-play-services.jar复制到同一工作文件夹.
在同一文件夹中创建一个名为rules.txt的文本文件(名称并不重要).
在rules.txt里面粘贴文本(不带引号):
"keep com.google.android.gms.ads.identifier.AdvertisingIdClient"
如果您想要保留其他课程,可以在此处添加.
打开命令提示符文件并更改工作文件夹的路径.在Windows上使用[cd]命令.
编写以下命令:
java -jar [jarjar archive] process [rulesFile] [inJar] [outJar]
您可以在此处找到有关JarJar链接命令和规则的更多详细信息:https://code.google.com/p/jarjar/wiki/CommandLineDocs
举一个例子,我必须写的命令看起来像这样(根据你的文件名改变你的命令):
java -jar jarjar-1.4.jar process rules.txt google-play-services.jar google-play-services-lite.jar
它能做什么:
如何使用它:
像往常一样将sdk中的google play服务导入到项目中,请务必将其复制到工作区中.在libs文件夹中,将google-play-services.jar替换为您之前生成的jar.
如果你在那里,你也可以删除资源,以释放另一个0.5 MB.确保保留values/common_strings.xml和values/version.xml.
不要忘记为Google Play服务添加清单元数据.
这有助于我减少超过2.5 MB的项目规模,并在能够访问Google广告客户ID的同时保持在65k dex类和方法限制之下.
希望它也能帮到你.
| 归档时间: |
|
| 查看次数: |
17575 次 |
| 最近记录: |