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

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

 

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

 

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

 

 

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

 

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

 

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

 

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

 

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

 

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

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

 

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

 

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

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

 

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

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

 

 

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

 

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

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调用的接口,具体如下图

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

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

 

 

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

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

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,具体如下图

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

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

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

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

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

 

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

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

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

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

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 赋值给脚本,具体如下图

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

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

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

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

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

 

注意事项:

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