Unity之android Drawable数据传递以APPIcon为例

    xiaoxiao2022-07-06  199

           Unity之android Drawable数据传递以APPIcon为例。在Unity开发中,有时候需要与Android端传递数据,比如 Drawable,本节以Unity与Android之间传递Drawable为例,获取Android 的应用Icon,传递给Unity,并显示在UI上;主要思路:因为Unity和Android 之间可以byte[] 之间传递,所以首先把 Drawable 转为 byte[],Android在封装接口供Unity调用即可,具体如下

     

     

     

     

     

    1、打开Android studio,新建一个空工程,具体如下图

     

     

     

    2、在工程中添加一个新模块,设置为 Android Library,用来构建aar 给Unity调用,具体如下图

     

     

     

    3、然后在模块中 new Java Class,可以命名为 FileTool,用来做一个图片的格式转换类使用,主要包括 Drawable 格式转为 Bitmap ,Bitmap 转为 byte[]的功能函数,具体如下图

     

     

     

     

    4、FileTool 脚本的具体内容如下:

    package com.example.drawableunity;

    import android.graphics.Bitmap;

    import android.graphics.drawable.Drawable;

    import android.util.Base64;

    import java.io.ByteArrayOutputStream;

    /// 该类用来作为文件工具

    /// 1、包括文件格式转换功能

    /// 2、Drawable 转为 Bitmap

    /// 3、Bitmap 转为 byte[]

    public class FileTool {

       /// Bitmap 转为 byte[]

       public synchronized static byte[] BitmapToByte(Bitmap bitmap) {

           ByteArrayOutputStream baos = new ByteArrayOutputStream();

           bitmap.compress(Bitmap.CompressFormat.PNG, 100, baos);

           return baos.toByteArray();

       }

       /// byte[] 转为 字符串

       public synchronized static String BytesToString(byte[] imagedata) {

           return Base64.encodeToString(imagedata, Base64.DEFAULT);

       }

       /// Drawable 转为 Bitmap

       public synchronized static Bitmap DrawableToBitmap(Drawable drawable) {

           return (((android.graphics.drawable.BitmapDrawable) drawable).getBitmap());

       }

       /// byte[] 转为 HexString

       public static String bytesToHexString(byte[] src) {

           StringBuilder stringBuilder = new StringBuilder("");

           if (src == null || src.length <= 0) {

               return null;

           }

           for (int i = 0; i < src.length; i++) {

               int v = src[i] & 0xFF;

               String hv = Integer.toHexString(v);

               if (hv.length() < 2) {

                   stringBuilder.append(0);

               }

               stringBuilder.append(hv);

           }

           return stringBuilder.toString();

       }

    }

    5、再在模块中 new Java Class,可以命名为 DrawableToUnity,内容主要是,通过包名获取对应的APP icon 得到Drawable图片数据,在转为 byte[] 数据,供Unity调用的接口,具体如下图

     

     

    6、DrawableToUnity 脚本的具体内容如下:

    package com.example.drawableunity;

    import android.app.Activity;

    import android.content.pm.ApplicationInfo;

    import android.content.pm.PackageManager;

    import android.graphics.Bitmap;

    import android.graphics.drawable.Drawable;

    /// 作为给 Unity 调用的类

    /// 调用 getDrawableIconByPackageName 即可获得图片 byte[] 数据

    public class DrawableToUnity {

       /// 外界接口函数

       /// 通过包名获取应用的 Drawable icon 并转为 byte[] 数据

       public byte[] getDrawableIconByPackageName(String packageName) {

           Drawable icon = getAppIcon(packageName);

           Bitmap bitmap =FileTool.DrawableToBitmap(icon);

           return FileTool.BitmapToByte(bitmap);

       }

       /// 通过包名获取对应的 Drawable 数据

       private Drawable getAppIcon(String packageName) {

           try {

               PackageManager pm = getActivity().getPackageManager();

               ApplicationInfo info = pm.getApplicationInfo(packageName, 0);

               return info.loadIcon(pm);

           } catch (Exception e) {

               e.printStackTrace();

           }

           return null;

       }

       /// 设置一个 Activity 参数

       private Activity _unityActivity;

       /// 通过反射获取 Unity 的 Activity 的上下文

       Activity getActivity(){

           if(null == _unityActivity){

               try{

                   Class<?> classtype = Class.forName("com.unity3d.player.UnityPlayer");

                   Activity activity = (Activity) classtype.getDeclaredField("currentActivity").get(classtype);

                   _unityActivity = activity;

               }catch (ClassNotFoundException e){

                   e.printStackTrace();

               }catch (IllegalAccessException e){

                   e.printStackTrace();

               }catch (NoSuchFieldException e){

                   e.printStackTrace();

               }

           }

           return _unityActivity;

       }

    }

    7、在 Build - Make Module “????”,把刚才的module 编译生成 aar 包,在文件结构中即可生成的aar,具体如下图

    8、在文件夹中打开显示aar包,然后打开Unity,新建一个工程,添加 Plugins - Android 文件结构,把aar拖入 Android 文件夹下,作为插件供Unity调用,具体如下图

     

    9、在工程中新建一个脚本,双击或右键打开进行编辑,具体如下图

    10、脚本的大概是,new AndroidJavaObject,在 call 调用对应接口获得对应图标的 byte[]数据,在转为Unity可用的图片数据,在UI上显示,具体如下图

    11、脚本内容具体如下:

    using UnityEngine;

    using UnityEngine.UI;

     

    public class Test : MonoBehaviour {

     

        // 展示获取APPicon的UI参数

        public RawImage rawImage;

        // android Java 实体的参数

        AndroidJavaObject androidJavaObject;

        

        // Use this for initialization

        void Start () {

            // 其中的参数,是 aar 的 包名 + 对应的 class 名

            androidJavaObject = new AndroidJavaObject("com.example.drawableunity.DrawableToUnity");

     

            // 通过安卓类的接口类获取Drawable的byte[],这里以百度地图的为例

            // 第一个参数:对应函数接口的名称

            // 第二个参数:对应函数接口的包名参数,这里以百度地图包名为例

            byte[] drawableBytes = androidJavaObject.Call<byte[]>("getDrawableIconByPackageName",

                "com.Baidu.BaiduMap");

     

            // 新建一个 Texture2D 来加载获得的byte[]图像

            Texture2D texture2D = new Texture2D(100,100);

            texture2D.LoadImage(drawableBytes);

     

            // 在UI上显示获得的 APP icon

            rawImage.texture = texture2D; 

        }

    }

    12、脚本编译正确,回到Unity,在场景中添加一个 RawImage 图标,把脚本挂载到 Canvas 上,把 RawImage 赋值给脚本,具体如下图

    13、把工程切换为 Android 平台,然后编译打包到设备上运行,具体如下图

    14、设备上即可获得对应的应用图标显示出来,具体如下图

     

    注意事项:

    AndroidJavaObject new的时候注意是 包名+类名,中间点隔开

     

     

     

    最新回复(0)