最近一个项目要对接一个sdk, 里面要求传入imei, 没有imei的传入oaid。看了一下oaid的官网,无论下载还是看文档都要注册等审核, 等不了。 直接从别的地方下载了oaid的sdk开始弄。可惜网上没有太多的可以参考的东西, 有一篇写的很详细的在unity中使用oaid的文章, 但是操作方法太复杂了, 因为用的是unity5所以对java的调用极其繁琐。用了小半天时间弄好了, 现在记录一下方法。
1、下载oaid sdk, 解压,里面有用的是一个aar文件,一个json文件
2 、在unity Assets中创建Plugins\Android目录, 把aar文件拷贝到这个目录。再在Plugins\Android目录下创建一个assets目录, 把json文件拷贝进去。
3、在Plugins\Android目录下创建一个java文件,我的文件如下:
package com.unity.androidplugin;
import android.content.Context; import android.util.Log;
import com.bun.miitmdid.core.MdidSdkHelper; import com.bun.miitmdid.interfaces.IIdentifierListener; import com.bun.miitmdid.interfaces.IdSupplier; import com.unity3d.player.UnityPlayer;
public class OAIDHelper implements IIdentifierListener {
String cbGameObject = "";
String cbFunc = "";
public static OAIDHelper _inst = null;
public OAIDHelper(){
_inst = this;
}
public static OAIDHelper inst(){
if (_inst == null){
_inst = new OAIDHelper();
}
return _inst;
}
public int GetDeviceID(Context cxt, String gameObject, String cbFunc){
cbGameObject = gameObject;
this.cbFunc = cbFunc;
int r = MdidSdkHelper.InitSdk(cxt, true, this);
Log.i("GetDeviceID", "obj: " + cbGameObject + " cb:" + cbFunc + " init:" + r);
return r;
}
/** 获取id回调 */
@Override
public void OnSupport(boolean b, IdSupplier idSupplier) {
if(idSupplier != null) {
String oaid = idSupplier.getOAID();
if(!cbGameObject.isEmpty() && !cbFunc.isEmpty()){
UnityPlayer.UnitySendMessage(cbGameObject, cbFunc, oaid == null ? "" : oaid);
}
Log.i("GetDeviceID", "OnSupport: " + b + " id: " + (oaid == null ? "" : oaid));
} else {
Log.i("GetDeviceID", "OnSupport IdSupplier null");
if(!cbGameObject.isEmpty() && !cbFunc.isEmpty()){
UnityPlayer.UnitySendMessage(cbGameObject, cbFunc, "");
}
}
}
} 其中要注意两点, 包名是package com.unity.androidplugin,类必须继承自IIdentifierListener。使用时直接调用MdidSdkHelper.InitSdk, 看返回结果, 目前只有结果为ErrorCode.INIT_ERROR_RESULT_DELAY才是执行成功了, 此时等待OnSupport调用,用idSupplier取出oaid。
4、C#部分代码如下:
using System; using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEngine.Android;
public class DeviceIDHelperObject : MonoBehaviour { Action cbFunc = null; float timer = 0; bool waiting = false;
Func<bool> condition = null;
Action<bool> runFunc = null;
float tiemrWaitFor = 0;
public void setCbFunc(Action<string> cbFunc)
{
this.cbFunc = cbFunc;
}
public void waitResult(float timeout = 5)
{
timer = timeout;
waiting = true;
}
public void onOAIDRecv(string oaid)
{
if (cbFunc != null && waiting)
{
cbFunc(oaid);
waiting = false;
timer = 0;
}
}
public void waitFor(Func<bool> c, Action<bool> f, float timeout = 30)
{
condition = c;
runFunc = f;
tiemrWaitFor = timeout;
}
private void Update()
{
if (timer > 0)
{
timer -= Time.deltaTime;
if (timer <= 0)
{
waiting = false;
timer = 0;
if (cbFunc != null)
{
cbFunc("");
}
}
}
if ( condition != null && runFunc != null)
{
if (condition())
{
runFunc(true);
condition = null;
runFunc = null;
tiemrWaitFor = 0;
}
if (tiemrWaitFor > 0)
{
tiemrWaitFor -= Time.deltaTime;
if (tiemrWaitFor <= 0)
{
runFunc(false);
condition = null;
runFunc = null;
tiemrWaitFor = 0;
}
}
}
}
}
/**
-
oaid sdk定义的错误内容 */ public enum OAIDSdkErrorCode { INIT_ERROR_BEGIN = 1008610,
INIT_ERROR_MANUFACTURER_NOSUPPORT = 1008611,
INIT_ERROR_DEVICE_NOSUPPORT = 1008612,
INIT_ERROR_LOAD_CONFIGFILE = 1008613,
INIT_ERROR_RESULT_DELAY = 1008614,
INIT_HELPER_CALL_ERROR = 1008615, }
public class DeviceIDHelper { static string helperName = "DeviceHelper_Instance_Dont_Delete"; static DeviceIDHelper _inst = null; public static DeviceIDHelper inst { get { if (_inst == null) { _inst = new DeviceIDHelper(); } return _inst; } }
Action<Exception, string[]> cbFunc = null;
DeviceIDHelperObject helper = null;
public DeviceIDHelper()
{
var obj = GameObject.Find(helperName);
if (null == obj)
{
helper = new GameObject(helperName).AddComponent<DeviceIDHelperObject>();
helper.setCbFunc((string oaid) => {
if (cbFunc != null)
{
if (oaid != null && oaid.Length > 0)
{
cbFunc(null, new string[] { oaid });
}
else
{
cbFunc(new Exception("unknow error."), new string[] { SystemInfo.deviceUniqueIdentifier });
}
}
});
}
else
{
helper = obj.GetComponent<DeviceIDHelperObject>();
}
}
int GetSdkLevel()
{
#if UNITY_ANDROID var buildVersionClass = AndroidJNI.FindClass("android/os/Build$VERSION"); var sdkIntField = AndroidJNI.GetStaticFieldID(buildVersionClass, "SDK_INT", "I");
return AndroidJNI.GetStaticIntField(buildVersionClass, sdkIntField);
#endif return 0; }
/**
* 获取设备id, 如果有imei则返回imei
* 或者返回OAID
* 如果都获取不到, 返回错误和SystemInfo.deviceUniqueIdentifier
*/
public void getDeviceID(Action<Exception, string[]> cbFunc, bool onlyOAID = false)
{
#if UNITY_ANDROID if (onlyOAID) { realGet(cbFunc, onlyOAID); } else { Permission.RequestUserPermission("android.permission.READ_PHONE_STATE"); helper.waitFor(() => { return Permission.HasUserAuthorizedPermission("android.permission.READ_PHONE_STATE"); }, (c) => { if (c) { realGet(cbFunc, onlyOAID); } else { cbFunc(new Exception("wait permission timeout"), new string[] { SystemInfo.deviceUniqueIdentifier }); } }, 30); } #endif }
void realGet(Action<Exception, string[]> cbFunc, bool onlyOAID = false)
{
#if UNITY_ANDROID this.cbFunc = null;
List<string> result = new List<string>();
try
{
bool useOAID = true;
var lv = GetSdkLevel();
using (var unityPlayer = new AndroidJavaClass("com.unity3d.player.UnityPlayer"))
{
var context = unityPlayer.GetStatic<AndroidJavaObject>("currentActivity");
var telephoneyManager = context.Call<AndroidJavaObject>("getSystemService", "phone");
string v1 = null, v2 = null;
if (lv < 26 && !onlyOAID)
{
v1 = telephoneyManager.Call<string>("getDeviceId", 0);
v2 = telephoneyManager.Call<string>("getDeviceId", 1);
}
else if (lv >= 26 && lv < 29 && !onlyOAID)
{
v1 = telephoneyManager.Call<string>("getImei", 0);
v2 = telephoneyManager.Call<string>("getImei", 1);
if (v1 == null && v2 == null)
{
v1 = telephoneyManager.Call<string>("getMeid", 0);
v2 = telephoneyManager.Call<string>("getMeid", 1);
}
}
if (v1 != null && v1.Length > 0)
{
result.Add(v1);
useOAID = false;
}
if (v2 != null && v2.Length > 0)
{
result.Add(v2);
useOAID = false;
}
if (useOAID)
{
using (var jc = new AndroidJavaClass("com.unity.androidplugin.OAIDHelper"))
{
AndroidJavaObject oaHelper = jc.CallStatic<AndroidJavaObject>("inst");
helper.waitResult();
var res = (OAIDSdkErrorCode)oaHelper.Call<int>("GetDeviceID", context, helperName, "onOAIDRecv");
string err = "";
switch (res)
{
case OAIDSdkErrorCode.INIT_ERROR_DEVICE_NOSUPPORT: //不支持的设备
err = "不支持的设备";
break;
case OAIDSdkErrorCode.INIT_ERROR_LOAD_CONFIGFILE: //加载配置文件出错
err = "加载配置文件出错";
break;
case OAIDSdkErrorCode.INIT_ERROR_MANUFACTURER_NOSUPPORT: //不支持的设备厂商
err = "不支持的设备厂商";
break;
//case OAIDSdkErrorCode.INIT_ERROR_RESULT_DELAY: //获取接口是异步的,结果会在回调中返回,回调执行的回调可能在工作线程
// break;
case OAIDSdkErrorCode.INIT_HELPER_CALL_ERROR: //反射调用出错
err = "反射调用出错";
break;
default:
err = "unknow err.";
break;
}
if (res != OAIDSdkErrorCode.INIT_ERROR_RESULT_DELAY)
{
cbFunc(new Exception(err), new string[] { SystemInfo.deviceUniqueIdentifier });
}
else
{
this.cbFunc = cbFunc;
}
}
}
else
{
cbFunc(null, result.ToArray());
}
}
}
catch (Exception err)
{
cbFunc(err, new string[] { SystemInfo.deviceUniqueIdentifier });
}
#endif }
}
使用方法:
logdb.text = "";
DeviceIDHelper.inst.getDeviceID((err, res) =>
{
if (err != null)
{
logdb.text = err.Message + "\r\n";
}
foreach(var v in res)
{
logdb.text += "id: " + v + "\r\n";
}
});
正常情况可以取出imei, android10以上会尝试取出oaid, 出错时返回SystemInfo.deviceUniqueIdentifier的值。