简体   繁体   English

如何在 Unity 中获取 Android 安装的应用程序图标

[英]How to get Android Installed App Icon in Unity

Quickly, I want to get all the installed apps in the device (icon and label).很快,我想获取设备中所有已安装的应用程序(图标和标签)。 I'm using a simple code that works getting the name of the app.我正在使用一个简单的代码来获取应用程序的名称。

I use Android Java Class to get these informations.我使用 Android Java Class 来获取这些信息。 The problem is that Android optains app icon as a Drawable .问题是 Android 选择应用程序图标作为Drawable Unity cannot read and display it as Sprite . Unity 无法读取并将其显示为Sprite

I am wondering if there is a way to sort this issue out.我想知道是否有办法解决这个问题。 I have tried to encode the drawable to base64 string but Unity "replies" me with a "Invalid string length" error, maybe for the "infinite" length of the base64 string.我试图将 drawable 编码为 base64 字符串,但 Unity“回复”了我“无效的字符串长度”错误,可能是因为 base64 字符串的“无限”长度。

I am trying to convert the Drawable to a byte array and then use it to create a texture with Texture.loadImage(byte[]) but it doesn't work.我正在尝试将 Drawable 转换为字节数组,然后使用它来创建带有Texture.loadImage(byte[])的纹理,但它不起作用。 Here is the code:这是代码:

 AndroidJavaClass jc = new AndroidJavaClass("com.unity3d.player.UnityPlayer");
    AndroidJavaObject currentActivity = jc.GetStatic<AndroidJavaObject>("currentActivity");
    int flag = new AndroidJavaClass("android.content.pm.PackageManager").GetStatic<int>("GET_META_DATA");
    AndroidJavaObject pm = currentActivity.Call<AndroidJavaObject>("getPackageManager");
    AndroidJavaObject packages = pm.Call<AndroidJavaObject>("getInstalledApplications", flag);

    int count = packages.Call<int>("size");
    string[] names = new string[count];
    int ii =0;
    for(int i=0; ii<count;){
            //get the object
        AndroidJavaObject currentObject = packages.Call<AndroidJavaObject>("get", ii );
        try{
                //try to add the variables to the next entry
            names[i] = pm.Call<string>("getApplicationLabel", currentObject);
            AndroidJavaObject icon = pm.Call<AndroidJavaObject>("getApplicationIcon", currentObject);//this part is the Java (Android Studio) code using Android Java Object and Class of Unity. Maybe the error is from here
            AndroidJavaObject bitmap = icon.Call<AndroidJavaObject>("getBitmap");
            AndroidJavaClass stream = new AndroidJavaClass("java.io.ByteArrayOutputStream");
            bitmap.Call("compress",(new AndroidJavaClass("java.io.ByteArrayOutputStream")).Call<AndroidJavaObject>("JPEG"), 100, stream);
            byte[] bitMapData = stream.Call<byte[]>("toByteArray");//to here
            Texture2D mytexture = new Texture2D(50, 50); // no idea what default size would be?? is it important??
            if (!mytexture.LoadImage(bitMapData)) {
                Debug.Log("Failed loading image data!");
            }
            else {
                Debug.Log("LoadImage - Still sane here - size: " + mytexture.width + "x" + mytexture.height);
                GameObject app = (GameObject)Instantiate(App, Vector3.zero, Quaternion.identity);
                app.GetComponent<RawImage>().texture = mytexture;//here is the code should display the icon as texture (sprite would be the best)
            }
            i++;
            ii++;
        }
        catch(Exception e){
            Debug.LogError(e,this);
                //if it fails, just go to the next app and try to add to that same entry.
            ii++;
        }

    }

Here there is the Java Android Studio working code:这里有 Java Android Studio 工作代码:

        Bitmap bitmap = ((BitmapDrawable) item.getIcon()).getBitmap(); //item.getIcon() returns the Drawable correctly
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        bitmap.compress(Bitmap.CompressFormat.PNG, 100, baos);
        byte[] byteArray = baos.toByteArray();

I have created an Android Jar Plugin on Android Studio (No Activity) and then I have imported it in Unity3D (AndroidManifest.xml and classes.jar in Assets>Plugins>Android>libs).我在 Android Studio(无活动)上创建了一个 Android Jar 插件,然后我将它导入到 Unity3D(AndroidManifest.xml 和 classes.jar 在 Assets>Plugins>Android>libs 中)。 Inside the plugin I have added a class and then the void to get the byte[] of the icon.在插件中,我添加了一个类,然后添加了 void 来获取图标的字节 []。 Java Android Plugin Class: Java Android 插件类:

public class PluginClass {

public static byte[] getIcon(PackageManager pm, ApplicationInfo applicationInfo) {
    try {
        BitmapDrawable icon = (BitmapDrawable) pm.getApplicationIcon(applicationInfo);
        Bitmap bmp = icon.getBitmap();
        ByteArrayOutputStream stream = new ByteArrayOutputStream();
        bmp.compress(Bitmap.CompressFormat.PNG, 100, stream);
        byte[] byteArray = stream.toByteArray();
        return byteArray;
    } catch (Exception e) {
        return null;
    }
}

public static boolean isSystem(ApplicationInfo applicationInfo){
    return (applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM ) != 0;
   }
}
Then I have invoked it in Unity C# script:

void Start () {
    AndroidJavaClass jc = new AndroidJavaClass("com.unity3d.player.UnityPlayer");
    AndroidJavaObject currentActivity = jc.GetStatic<AndroidJavaObject>("currentActivity");
    int flag = new AndroidJavaClass("android.content.pm.PackageManager").GetStatic<int>("GET_META_DATA");
    AndroidJavaObject pm = currentActivity.Call<AndroidJavaObject>("getPackageManager");
    AndroidJavaObject packages = pm.Call<AndroidJavaObject>("getInstalledApplications", 0);
    int count = packages.Call<int>("size");
    string[] names = new string[count];
    List<byte[]> byteimg = new List<byte[]>();
    int ii =0;
    for(int i=0; ii<count;){
        AndroidJavaObject currentObject = packages.Call<AndroidJavaObject>("get", ii );
        try{
            names[i] = pm.Call<string>("getApplicationLabel", currentObject);
            var plugin = new AndroidJavaClass("com.mypackagename.PluginClass");
            if(plugin.CallStatic<bool>("isSystem",currentObject)){
                ii++;
                continue;
            }
            byte[] decodedBytes = plugin.CallStatic<byte[]>("getIcon", pm, currentObject);
            Texture2D text = new Texture2D(1, 1, TextureFormat.ARGB32, false);
            text.LoadImage(decodedBytes);
            Sprite sprite = Sprite.Create (text, new Rect(0,0,text.width,text.height), new Vector2(.5f,.5f));
            i++;
            ii++;
        }
        catch(Exception e){
            Debug.LogError(e,this);
            ii++;
        }

    }

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 Android-如果未安装应用程序图标,如何获取? - Android - How can I get Application Icon if it isn't installed? 如何以编程方式从 android 上已安装的应用程序中显示特定应用程序的图标? - How to show a specific app's icon from the installed apps on android programmatically? 安装的应用程序中缺少图标? - Icon missing in installed app? 如何在Android + GCM中使用声音+自定义应用程序图标获取推送通知 - How to get a push notification with sound + custom app icon in Android + GCM 获取android中所有已安装应用程序的名称,图标和包名称 - Get the name, icon and package name of all the installed applications in android 如何为上次安装的应用程序的图标提取png文件 - how to extract a png file for the icon of the last installed app 在设备上安装App后的Android通知 - 如何? - Android Notification after App is installed on device - How to? 在 Android 如何检查手机中是否安装了应用程序 - In Android how to check app is installed in your phone or not 如何使Android应用程序的图标背景透明? - How to make the icon background of an Android app transparent? 如何获取Android中已安装应用程序的缓存大小 - how to get the cache size of installed applications in android
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM