目录
4.Unity3D调用Android功能与组件(四)——文字、图片分享到社交平台
AndroidJNI
JNI(Java Native Interface):java本地开发接口
JNI是一个协议,这个协议用来沟通java代码和外部的本地代码
AndroidJavaClass
AndroidJavaClass("全类名") ---new一个Android原生类
AndroidJavaObject
简单示例:
//获取当前App的Activity
public static AndroidJavaObject CurrentActive()
{
if (Application.platform == RuntimePlatform.Android)
return new AndroidJavaClass("com.unity3d.player.UnityPlayer").GetStatic<AndroidJavaObject>("currentActivity");
else
return null;
}
//获取指定包名的Activity
public static AndroidJavaObject GetActivity(string package_name,string activity_name)
{
return new AndroidJavaClass(package_name).GetStatic<AndroidJavaObject>(activity_name);
}
//2.获取原生类型: android.provider.Settings中的属性,以android_id为例(只要系统有写就可以)
public string GetAndroidID()
{
string android_id = "NONE";
try
{
#if UNITY_ANDROID && !UNITY_EDITOR
AndroidJavaClass up = new AndroidJavaClass("com.unity3d.player.UnityPlayer");
//new AndroidJavaClass("全类名") ---new一个Android原生类
AndroidJavaObject currentActivity = up.GetStatic<AndroidJavaObject>("currentActivity");
AndroidJavaObject contentResolver = currentActivity.Call<AndroidJavaObject>("getContentResolver");
AndroidJavaClass secure = new AndroidJavaClass("android.provider.Settings$Secure");
//CallStatic 的使用:静态方法获取一个Android原生类型
android_id = secure.CallStatic<string>("getString", contentResolver, "android_id");
#endif
}
catch (System.Exception e)
{
Debug.LogError(e);
}
return android_id;
}
/获取包名
public static string getPackageName()
{
return CurrentActive().Call<string>("getPackageName");
}
// UI线程中运行
public static void RunOnUIThread(AndroidJavaRunnable r)
{
CurrentActive().Call("runOnUiThread", r);
}
//讲解:call<返回值类型>("方法名");
//设置 不自动锁屏
public static void DisableScreenLock()
{
//new AndroidJavaClass("全类名") ---new一个Android原生类
CurrentActive().Call<AndroidJavaObject>("getWindow")
.Call("addFlags",128);
}
//讲解:call("方法名",参数1);
// 获取内置SD卡路径
public static string GetStoragePath()
{
if (Application.platform == RuntimePlatform.Android)
return new AndroidJavaClass("android.os.Environment").CallStatic<AndroidJavaObject>("getExternalStorageDirectory").Call<string>("getPath");
else
return "d:/movie";
}
Unity中如何正确使用AndroidJNI
概念知识或JNI使用可参考:
https://www.cnblogs.com/rocomp/p/4892866.html
public static string GetAndroidAseet(string filePath)
{
string str = "";
try
{
#if UNITY_ANDROID && !UNITY_EDITOR
//取得应用的Activity
var activity = new AndroidJavaClass("com.unity3d.player.UnityPlayer").GetStatic<AndroidJavaObject>("currentActivity");
//从Activity取得AssetManager实例
var assetManager = activity.Call<AndroidJavaObject>("getAssets");
//打开文件流
var stream = assetManager.Call<AndroidJavaObject>("open", filePath);
//获取文件长度
var availableBytes = stream.Call<int>("available");
//取得InputStream.read的MethodID
var clsPtr = AndroidJNI.FindClass("java.io.InputStream");
var METHOD_read = AndroidJNIHelper.GetMethodID(clsPtr, "read", "([B)I");
//申请一个Java ByteArray对象句柄
var byteArray = AndroidJNI.NewByteArray(availableBytes);
//调用方法
int readCount = AndroidJNI.CallIntMethod(stream.GetRawObject(), METHOD_read, new[] { new jvalue() { l = byteArray } });
//从Java ByteArray中得到C# byte数组
var bytes = AndroidJNI.FromByteArray(byteArray);
//删除Java ByteArray对象句柄
AndroidJNI.DeleteLocalRef(byteArray);
//关闭文件流
stream.Call("close");
stream.Dispose();
//返回结果
str = System.Text.Encoding.Default.GetString(bytes);
#endif
}
catch (System.Exception e)
{
Debug.LogError(e);
}
return str;
}
apk接入中经常遇到的问题记录:
CommandInvokationFailure: Unable to convert classes into dex format.
解决方案:jar包重复(一般supportv4会有不同版本的重复,或者被其它jar包所引用)
android 实用UnityAndroid功能汇总
感谢游戏蛮牛大神(MemoryC)大部分文章只是将简单的整理备忘在这,更多Android功能请访问
附上连接地址:http://www.manew.com/thread-100075-1-1.html
1.如何调用Toast
a. AndroidJavaClass对应着Android里面的Java类,而AndroidJavaObject对应着Android里面实例化的对象。
b. 一定要切记C#里的String和Java的String不是一码事,所以调用Android方法时如果需要传字符串为参数时,不能直接给个字符串,应该给个Java里的String,例如 new AndroidJavaObject("java.lang.String","你想传的字符串");
c. 由于AndroidJavaClass对应的是类,所以一般用之来调用对应的类的静态变量(GetStatic<Type>)或者静态方法(CallStatic<Type>("functionName",param1,param2,....));其中的Type为返回类型,注意是Java的返回类型不是C#的,一般整型和布尔型是通用的,其他的如果不清除可以统一写返回类型为AndroidJavaObject,当然没有返回类型的不需要写Type。
d. AndroidJavaObject对应的是实例对象,所以用new方法给其初始化时要注意说明其是哪个类的实例对象。再比如刚才那个例子: AndroidJavaObject javaString=new AndroidJavaObject("java.lang.String","字符串的值");
private void toastText(object str){
#if UNITY_ANDROID
AndroidJavaClass UnityPlayer = new AndroidJavaClass("com.unity3d.player.UnityPlayer");
AndroidJavaObject currentActivity= UnityPlayer.GetStatic<AndroidJavaObject>("currentA