diff --git a/library/src/main/AndroidManifest.xml b/library/src/main/AndroidManifest.xml
index b1b71a1..13f00ec 100644
--- a/library/src/main/AndroidManifest.xml
+++ b/library/src/main/AndroidManifest.xml
@@ -48,6 +48,8 @@
+
+
diff --git a/library/src/main/java/com/github/gzuliyujiang/oaid/OAIDRom.java b/library/src/main/java/com/github/gzuliyujiang/oaid/OAIDRom.java
index f3dbd76..70f69f4 100644
--- a/library/src/main/java/com/github/gzuliyujiang/oaid/OAIDRom.java
+++ b/library/src/main/java/com/github/gzuliyujiang/oaid/OAIDRom.java
@@ -172,4 +172,8 @@ public static boolean isSSUI() {
return !TextUtils.isEmpty(sysProperty("ro.ssui.product", ""));
}
+ public static boolean is360OS() {
+ // 360OS手机
+ return !TextUtils.isEmpty(sysProperty("ro.build.uiversion", ""));
+ }
}
diff --git a/library/src/main/java/com/github/gzuliyujiang/oaid/impl/OAIDFactory.java b/library/src/main/java/com/github/gzuliyujiang/oaid/impl/OAIDFactory.java
index 27c51e0..aa6ec7e 100644
--- a/library/src/main/java/com/github/gzuliyujiang/oaid/impl/OAIDFactory.java
+++ b/library/src/main/java/com/github/gzuliyujiang/oaid/impl/OAIDFactory.java
@@ -98,6 +98,9 @@ private static IOAID createManufacturerImpl(Context context) {
if (OAIDRom.isFreeme()) {
return new FreemeImpl(context);
}
+ if (OAIDRom.is360OS()) {
+ return new QikuImpl(context);
+ }
return null;
}
diff --git a/library/src/main/java/com/github/gzuliyujiang/oaid/impl/QikuImpl.java b/library/src/main/java/com/github/gzuliyujiang/oaid/impl/QikuImpl.java
new file mode 100644
index 0000000..8c89ea0
--- /dev/null
+++ b/library/src/main/java/com/github/gzuliyujiang/oaid/impl/QikuImpl.java
@@ -0,0 +1,74 @@
+package com.github.gzuliyujiang.oaid.impl;
+
+import android.content.Context;
+import android.content.Intent;
+import android.content.pm.PackageInfo;
+import android.os.IBinder;
+import android.os.RemoteException;
+
+import com.github.gzuliyujiang.oaid.IGetter;
+import com.github.gzuliyujiang.oaid.IOAID;
+import com.github.gzuliyujiang.oaid.OAIDException;
+import com.github.gzuliyujiang.oaid.OAIDLog;
+
+import repeackage.com.qiku.id.IOAIDInterface;
+import repeackage.com.qiku.id.QikuIdmanager;
+
+public class QikuImpl implements IOAID {
+ private final Context context;
+ private boolean mUseQikuId = true;
+
+ public QikuImpl(Context context){
+ this.context = context;
+ }
+
+ @Override
+ public boolean supported() {
+ if (context == null) {
+ return false;
+ }
+ try {
+ PackageInfo pi = context.getPackageManager().getPackageInfo("com.qiku.id", 0);
+ if (pi != null){
+ return true;
+ }else{
+ mUseQikuId = false;
+ return new QikuIdmanager().isSupported();
+ }
+ } catch (Exception e) {
+ OAIDLog.print(e);
+ return false;
+ }
+ }
+
+ @Override
+ public void doGet(IGetter getter) {
+ if (context == null || getter == null) {
+ return;
+ }
+ if (mUseQikuId){
+ Intent intent = new Intent("qiku.service.action.id");
+ intent.setPackage("com.qiku.id");
+ OAIDService.bind(context, intent, getter, new OAIDService.RemoteCaller() {
+ @Override
+ public String callRemoteInterface(IBinder service) throws OAIDException, RemoteException {
+ IOAIDInterface anInterface = IOAIDInterface.Stub.asInterface(service);
+ if (anInterface == null) {
+ throw new OAIDException("IdsSupplier is null");
+ }
+ return anInterface.getOAID();
+ }
+ });
+ }else{
+ try {
+ String oaid = new QikuIdmanager().getOAID();
+ if (oaid == null || oaid.length() == 0) {
+ throw new OAIDException("OAID/AAID acquire failed");
+ }
+ getter.onOAIDGetComplete(oaid);
+ } catch (Exception e) {
+ getter.onOAIDGetError(e);
+ }
+ }
+ }
+}
diff --git a/library/src/main/java/repeackage/com/qiku/id/IOAIDInterface.java b/library/src/main/java/repeackage/com/qiku/id/IOAIDInterface.java
new file mode 100644
index 0000000..2683919
--- /dev/null
+++ b/library/src/main/java/repeackage/com/qiku/id/IOAIDInterface.java
@@ -0,0 +1,357 @@
+/*
+ * This file is auto-generated. DO NOT MODIFY.
+ */
+package repeackage.com.qiku.id;
+public interface IOAIDInterface extends android.os.IInterface
+{
+ /** Default implementation for IOAIDInterface. */
+ public static class Default implements IOAIDInterface
+ {
+ @Override public boolean isSupported() throws android.os.RemoteException
+ {
+ return false;
+ }
+ @Override public String getUDID() throws android.os.RemoteException
+ {
+ return null;
+ }
+ @Override public String getOAID() throws android.os.RemoteException
+ {
+ return null;
+ }
+ @Override public String getVAID() throws android.os.RemoteException
+ {
+ return null;
+ }
+ @Override public String getAAID() throws android.os.RemoteException
+ {
+ return null;
+ }
+ @Override public void shutDown() throws android.os.RemoteException
+ {
+ }
+ @Override public void resetOAID() throws android.os.RemoteException
+ {
+ }
+ @Override public boolean limitReadOAID() throws android.os.RemoteException
+ {
+ return false;
+ }
+ @Override
+ public android.os.IBinder asBinder() {
+ return null;
+ }
+ }
+ /** Local-side IPC implementation stub class. */
+ public static abstract class Stub extends android.os.Binder implements IOAIDInterface
+ {
+ private static final String DESCRIPTOR = "com.qiku.id.IOAIDInterface";
+ /** Construct the stub at attach it to the interface. */
+ public Stub()
+ {
+ this.attachInterface(this, DESCRIPTOR);
+ }
+ /**
+ * Cast an IBinder object into an com.qiku.id.IOAIDInterface interface,
+ * generating a proxy if needed.
+ */
+ public static IOAIDInterface asInterface(android.os.IBinder obj)
+ {
+ if ((obj==null)) {
+ return null;
+ }
+ android.os.IInterface iin = obj.queryLocalInterface(DESCRIPTOR);
+ if (((iin!=null)&&(iin instanceof IOAIDInterface))) {
+ return ((IOAIDInterface)iin);
+ }
+ return new Proxy(obj);
+ }
+ @Override public android.os.IBinder asBinder()
+ {
+ return this;
+ }
+ @Override public boolean onTransact(int code, android.os.Parcel data, android.os.Parcel reply, int flags) throws android.os.RemoteException
+ {
+ String descriptor = DESCRIPTOR;
+ switch (code)
+ {
+ case INTERFACE_TRANSACTION:
+ {
+ reply.writeString(descriptor);
+ return true;
+ }
+ case TRANSACTION_isSupported:
+ {
+ data.enforceInterface(descriptor);
+ boolean _result = this.isSupported();
+ reply.writeNoException();
+ reply.writeInt(((_result)?(1):(0)));
+ return true;
+ }
+ case TRANSACTION_getUDID:
+ {
+ data.enforceInterface(descriptor);
+ String _result = this.getUDID();
+ reply.writeNoException();
+ reply.writeString(_result);
+ return true;
+ }
+ case TRANSACTION_getOAID:
+ {
+ data.enforceInterface(descriptor);
+ String _result = this.getOAID();
+ reply.writeNoException();
+ reply.writeString(_result);
+ return true;
+ }
+ case TRANSACTION_getVAID:
+ {
+ data.enforceInterface(descriptor);
+ String _result = this.getVAID();
+ reply.writeNoException();
+ reply.writeString(_result);
+ return true;
+ }
+ case TRANSACTION_getAAID:
+ {
+ data.enforceInterface(descriptor);
+ String _result = this.getAAID();
+ reply.writeNoException();
+ reply.writeString(_result);
+ return true;
+ }
+ case TRANSACTION_shutDown:
+ {
+ data.enforceInterface(descriptor);
+ this.shutDown();
+ reply.writeNoException();
+ return true;
+ }
+ case TRANSACTION_resetOAID:
+ {
+ data.enforceInterface(descriptor);
+ this.resetOAID();
+ reply.writeNoException();
+ return true;
+ }
+ case TRANSACTION_limitReadOAID:
+ {
+ data.enforceInterface(descriptor);
+ boolean _result = this.limitReadOAID();
+ reply.writeNoException();
+ reply.writeInt(((_result)?(1):(0)));
+ return true;
+ }
+ default:
+ {
+ return super.onTransact(code, data, reply, flags);
+ }
+ }
+ }
+ private static class Proxy implements IOAIDInterface
+ {
+ private android.os.IBinder mRemote;
+ Proxy(android.os.IBinder remote)
+ {
+ mRemote = remote;
+ }
+ @Override public android.os.IBinder asBinder()
+ {
+ return mRemote;
+ }
+ public String getInterfaceDescriptor()
+ {
+ return DESCRIPTOR;
+ }
+ @Override public boolean isSupported() throws android.os.RemoteException
+ {
+ android.os.Parcel _data = android.os.Parcel.obtain();
+ android.os.Parcel _reply = android.os.Parcel.obtain();
+ boolean _result;
+ try {
+ _data.writeInterfaceToken(DESCRIPTOR);
+ boolean _status = mRemote.transact(Stub.TRANSACTION_isSupported, _data, _reply, 0);
+ if (!_status && getDefaultImpl() != null) {
+ return getDefaultImpl().isSupported();
+ }
+ _reply.readException();
+ _result = (0!=_reply.readInt());
+ }
+ finally {
+ _reply.recycle();
+ _data.recycle();
+ }
+ return _result;
+ }
+ @Override public String getUDID() throws android.os.RemoteException
+ {
+ android.os.Parcel _data = android.os.Parcel.obtain();
+ android.os.Parcel _reply = android.os.Parcel.obtain();
+ String _result;
+ try {
+ _data.writeInterfaceToken(DESCRIPTOR);
+ boolean _status = mRemote.transact(Stub.TRANSACTION_getUDID, _data, _reply, 0);
+ if (!_status && getDefaultImpl() != null) {
+ return getDefaultImpl().getUDID();
+ }
+ _reply.readException();
+ _result = _reply.readString();
+ }
+ finally {
+ _reply.recycle();
+ _data.recycle();
+ }
+ return _result;
+ }
+ @Override public String getOAID() throws android.os.RemoteException
+ {
+ android.os.Parcel _data = android.os.Parcel.obtain();
+ android.os.Parcel _reply = android.os.Parcel.obtain();
+ String _result;
+ try {
+ _data.writeInterfaceToken(DESCRIPTOR);
+ boolean _status = mRemote.transact(Stub.TRANSACTION_getOAID, _data, _reply, 0);
+ if (!_status && getDefaultImpl() != null) {
+ return getDefaultImpl().getOAID();
+ }
+ _reply.readException();
+ _result = _reply.readString();
+ }
+ finally {
+ _reply.recycle();
+ _data.recycle();
+ }
+ return _result;
+ }
+ @Override public String getVAID() throws android.os.RemoteException
+ {
+ android.os.Parcel _data = android.os.Parcel.obtain();
+ android.os.Parcel _reply = android.os.Parcel.obtain();
+ String _result;
+ try {
+ _data.writeInterfaceToken(DESCRIPTOR);
+ boolean _status = mRemote.transact(Stub.TRANSACTION_getVAID, _data, _reply, 0);
+ if (!_status && getDefaultImpl() != null) {
+ return getDefaultImpl().getVAID();
+ }
+ _reply.readException();
+ _result = _reply.readString();
+ }
+ finally {
+ _reply.recycle();
+ _data.recycle();
+ }
+ return _result;
+ }
+ @Override public String getAAID() throws android.os.RemoteException
+ {
+ android.os.Parcel _data = android.os.Parcel.obtain();
+ android.os.Parcel _reply = android.os.Parcel.obtain();
+ String _result;
+ try {
+ _data.writeInterfaceToken(DESCRIPTOR);
+ boolean _status = mRemote.transact(Stub.TRANSACTION_getAAID, _data, _reply, 0);
+ if (!_status && getDefaultImpl() != null) {
+ return getDefaultImpl().getAAID();
+ }
+ _reply.readException();
+ _result = _reply.readString();
+ }
+ finally {
+ _reply.recycle();
+ _data.recycle();
+ }
+ return _result;
+ }
+ @Override public void shutDown() throws android.os.RemoteException
+ {
+ android.os.Parcel _data = android.os.Parcel.obtain();
+ android.os.Parcel _reply = android.os.Parcel.obtain();
+ try {
+ _data.writeInterfaceToken(DESCRIPTOR);
+ boolean _status = mRemote.transact(Stub.TRANSACTION_shutDown, _data, _reply, 0);
+ if (!_status && getDefaultImpl() != null) {
+ getDefaultImpl().shutDown();
+ return;
+ }
+ _reply.readException();
+ }
+ finally {
+ _reply.recycle();
+ _data.recycle();
+ }
+ }
+ @Override public void resetOAID() throws android.os.RemoteException
+ {
+ android.os.Parcel _data = android.os.Parcel.obtain();
+ android.os.Parcel _reply = android.os.Parcel.obtain();
+ try {
+ _data.writeInterfaceToken(DESCRIPTOR);
+ boolean _status = mRemote.transact(Stub.TRANSACTION_resetOAID, _data, _reply, 0);
+ if (!_status && getDefaultImpl() != null) {
+ getDefaultImpl().resetOAID();
+ return;
+ }
+ _reply.readException();
+ }
+ finally {
+ _reply.recycle();
+ _data.recycle();
+ }
+ }
+ @Override public boolean limitReadOAID() throws android.os.RemoteException
+ {
+ android.os.Parcel _data = android.os.Parcel.obtain();
+ android.os.Parcel _reply = android.os.Parcel.obtain();
+ boolean _result;
+ try {
+ _data.writeInterfaceToken(DESCRIPTOR);
+ boolean _status = mRemote.transact(Stub.TRANSACTION_limitReadOAID, _data, _reply, 0);
+ if (!_status && getDefaultImpl() != null) {
+ return getDefaultImpl().limitReadOAID();
+ }
+ _reply.readException();
+ _result = (0!=_reply.readInt());
+ }
+ finally {
+ _reply.recycle();
+ _data.recycle();
+ }
+ return _result;
+ }
+ public static IOAIDInterface sDefaultImpl;
+ }
+ static final int TRANSACTION_isSupported = (android.os.IBinder.FIRST_CALL_TRANSACTION + 0);
+ static final int TRANSACTION_getUDID = (android.os.IBinder.FIRST_CALL_TRANSACTION + 1);
+ static final int TRANSACTION_getOAID = (android.os.IBinder.FIRST_CALL_TRANSACTION + 2);
+ static final int TRANSACTION_getVAID = (android.os.IBinder.FIRST_CALL_TRANSACTION + 3);
+ static final int TRANSACTION_getAAID = (android.os.IBinder.FIRST_CALL_TRANSACTION + 4);
+ static final int TRANSACTION_shutDown = (android.os.IBinder.FIRST_CALL_TRANSACTION + 5);
+ static final int TRANSACTION_resetOAID = (android.os.IBinder.FIRST_CALL_TRANSACTION + 6);
+ static final int TRANSACTION_limitReadOAID = (android.os.IBinder.FIRST_CALL_TRANSACTION + 7);
+ public static boolean setDefaultImpl(IOAIDInterface impl) {
+ // Only one user of this interface can use this function
+ // at a time. This is a heuristic to detect if two different
+ // users in the same process use this function.
+ if (Proxy.sDefaultImpl != null) {
+ throw new IllegalStateException("setDefaultImpl() called twice");
+ }
+ if (impl != null) {
+ Proxy.sDefaultImpl = impl;
+ return true;
+ }
+ return false;
+ }
+ public static IOAIDInterface getDefaultImpl() {
+ return Proxy.sDefaultImpl;
+ }
+ }
+ public boolean isSupported() throws android.os.RemoteException;
+ public String getUDID() throws android.os.RemoteException;
+ public String getOAID() throws android.os.RemoteException;
+ public String getVAID() throws android.os.RemoteException;
+ public String getAAID() throws android.os.RemoteException;
+ public void shutDown() throws android.os.RemoteException;
+ public void resetOAID() throws android.os.RemoteException;
+ public boolean limitReadOAID() throws android.os.RemoteException;
+}
diff --git a/library/src/main/java/repeackage/com/qiku/id/QikuIdmanager.java b/library/src/main/java/repeackage/com/qiku/id/QikuIdmanager.java
new file mode 100644
index 0000000..dcc8ede
--- /dev/null
+++ b/library/src/main/java/repeackage/com/qiku/id/QikuIdmanager.java
@@ -0,0 +1,169 @@
+package repeackage.com.qiku.id;
+import android.os.IBinder;
+import android.os.Parcel;
+import android.os.RemoteException;
+import android.util.Log;
+
+import java.lang.reflect.Method;
+
+public class QikuIdmanager {
+ final static String TAG = "QikuIdmanager";
+ private IBinder mIBinder = null;
+
+
+ public static int CODE_IS_SUPPORTED =IBinder.FIRST_CALL_TRANSACTION + 1;
+ public static int CODE_GET_UDID =IBinder.FIRST_CALL_TRANSACTION + 2;
+ public static int CODE_GET_OAID =IBinder.FIRST_CALL_TRANSACTION + 3;
+ public static int CODE_GET_VAID =IBinder.FIRST_CALL_TRANSACTION + 4;
+ public static int CODE_GET_AAID =IBinder.FIRST_CALL_TRANSACTION + 5;
+ public static int CODE_SHUTDOWN =IBinder.FIRST_CALL_TRANSACTION + 6;
+ public static final int CODE_RESET_OAID =IBinder.FIRST_CALL_TRANSACTION + 7;
+ public static final int CODE_LIMIT_READ_OAID =IBinder.FIRST_CALL_TRANSACTION + 8;
+
+
+ public QikuIdmanager() {
+ try {
+ Class> c = Class.forName("android.os.SystemProperties");
+ Method get = c.getMethod("get", String.class, String.class);
+ String ui360 = (String)(get.invoke(c, "ro.build.uiversion", ""));
+
+ if (ui360.contains("360UI")) {
+ Class> ServiceManager = Class.forName("android.os.ServiceManager");
+ if (ServiceManager != null) {
+ Method method_getService = ServiceManager.getDeclaredMethod("getService", String.class);
+ if (method_getService != null) {
+ mIBinder = (IBinder)method_getService.invoke(null, "qikuid");
+ }
+ }
+ }
+ } catch (Exception e) {
+ Log.e(TAG, "Failure get qikuid service", e);
+ }
+ }
+
+
+ public boolean isSupported() {
+ if (mIBinder != null) {
+
+ Parcel data = Parcel.obtain();
+ Parcel reply = Parcel.obtain();
+ try {
+ mIBinder.transact(CODE_IS_SUPPORTED, data, reply, 0);
+ int result = reply.readInt();
+ return result == 1 ? true:false;
+ } catch (RemoteException e) {
+ e.printStackTrace();
+ }finally{
+ data.recycle();
+ reply.recycle();
+ }
+ }
+ return false;
+ }
+
+ public String getUDID() {
+ if (mIBinder != null) {
+ Parcel data = Parcel.obtain();
+ Parcel reply = Parcel.obtain();
+ try {
+ mIBinder.transact(CODE_GET_UDID, data, reply, 0);
+ String udid = reply.readString();
+ return udid;
+ } catch (RemoteException e) {
+ e.printStackTrace();
+ }finally{
+ data.recycle();
+ reply.recycle();
+ }
+ }
+ return null;
+ }
+
+ public String getOAID() {
+ if (mIBinder != null) {
+ Parcel data = Parcel.obtain();
+ Parcel reply = Parcel.obtain();
+ try {
+ mIBinder.transact(CODE_GET_OAID, data, reply, 0);
+ String oaid = reply.readString();
+ return oaid;
+ } catch (RemoteException e) {
+ e.printStackTrace();
+ }finally{
+ data.recycle();
+ reply.recycle();
+ }
+ }
+ return null;
+ }
+
+ public String getVAID() {
+ if (mIBinder != null) {
+ Parcel data = Parcel.obtain();
+ Parcel reply = Parcel.obtain();
+ try {
+ mIBinder.transact(CODE_GET_VAID, data, reply, 0);
+ String vaid = reply.readString();
+ return vaid;
+ } catch (RemoteException e) {
+ e.printStackTrace();
+ }finally{
+ data.recycle();
+ reply.recycle();
+ }
+ }
+ return null;
+ }
+
+ public String getAAID() {
+ if (mIBinder != null) {
+ Parcel data = Parcel.obtain();
+ Parcel reply = Parcel.obtain();
+ try {
+ mIBinder.transact(CODE_GET_AAID, data, reply, 0);
+ String aaid = reply.readString();
+ return aaid;
+ } catch (RemoteException e) {
+ e.printStackTrace();
+ }finally{
+ data.recycle();
+ reply.recycle();
+ }
+ }
+ return null;
+ }
+
+ public void shutDown() {
+ if (mIBinder != null) {
+ Parcel data = Parcel.obtain();
+ Parcel reply = Parcel.obtain();
+ try {
+ mIBinder.transact(CODE_SHUTDOWN, data, reply, 0);
+ } catch (RemoteException e) {
+ e.printStackTrace();
+ }finally{
+ data.recycle();
+ reply.recycle();
+ }
+ }
+ }
+
+ //true为限制了应用获取开放匿名设备标识符,false为未限制
+ public boolean isLimited() {
+ if (mIBinder != null) {
+ Parcel data = Parcel.obtain();
+ Parcel reply = Parcel.obtain();
+ try {
+ mIBinder.transact(CODE_LIMIT_READ_OAID, data, reply, 0);
+ boolean islimited = reply.readBoolean();
+ return islimited;
+ } catch (RemoteException e) {
+ e.printStackTrace();
+ }finally{
+ data.recycle();
+ reply.recycle();
+ }
+ }
+ return false;
+ }
+}
\ No newline at end of file