Android 以编程方式存储和检索所有已安装应用的应用图标

Android 以编程方式存储和检索所有已安装应用的应用图标,android,android-package-managers,android-sharedpreferences,Android,Android Package Managers,Android Sharedpreferences,我正在构建一个应用程序,其中我以编程方式收集设备上安装的所有应用程序的详细信息(appName、packageName、appIcon和一些其他appDetails) 然而,我观察到,获取这些应用程序细节并将其存储在数据结构中需要相当长的时间。我曾尝试使用SharedReferences存储一些应用程序详细信息,以便在不同的应用程序执行之间保留数据,而不是每次启动应用程序时都启动抓取 但是,存储应用程序图标(drawables)会占用大量空间,让我想知道是否有更有效的方法在应用程序执行之间保留上

我正在构建一个应用程序,其中我以编程方式收集设备上安装的所有应用程序的详细信息(appName、packageName、appIcon和一些其他appDetails)

然而,我观察到,获取这些应用程序细节并将其存储在数据结构中需要相当长的时间。我曾尝试使用SharedReferences存储一些应用程序详细信息,以便在不同的应用程序执行之间保留数据,而不是每次启动应用程序时都启动抓取

但是,存储应用程序图标(drawables)会占用大量空间,让我想知道是否有更有效的方法在应用程序执行之间保留上述应用程序数据,当然,除非在最后一次以编程方式获取已安装的应用程序后安装了新的应用程序


因此,我的问题是,是否有一种有效的方法来存储应用程序图标(可绘制图标),这样它们就不会占用太多空间,同时,应用程序集可以在不同的应用程序执行之间保留?

我相信你最好的办法是保存应用程序数据库中安装的应用程序列表。您可以将应用程序的可绘制图标存储为编码字符串

String image = getImageFromDrawable(app.loadIcon(pm));
其中app是ApplicationInfo,pm是PackageManager

public String getImageFromDrawable(Drawable drawable){
    String img = null;
    if(drawable instanceof  BitmapDrawable) {
        Bitmap bitmap = ((BitmapDrawable) drawable).getBitmap();
        ByteArrayOutputStream stream = new ByteArrayOutputStream();
        bitmap.compress(Bitmap.CompressFormat.PNG, 100, stream);
        byte[] arr = stream.toByteArray();
        img = Base64.encodeToString(arr, Base64.URL_SAFE);
        return img;
    }
    return null;
}

然后,您可以将应用程序的详细信息存储在应用程序数据库中。

我认为您最好的办法是保存安装在应用程序数据库中的应用程序列表。您可以将应用程序的可绘制图标存储为编码字符串

String image = getImageFromDrawable(app.loadIcon(pm));
其中app是ApplicationInfo,pm是PackageManager

public String getImageFromDrawable(Drawable drawable){
    String img = null;
    if(drawable instanceof  BitmapDrawable) {
        Bitmap bitmap = ((BitmapDrawable) drawable).getBitmap();
        ByteArrayOutputStream stream = new ByteArrayOutputStream();
        bitmap.compress(Bitmap.CompressFormat.PNG, 100, stream);
        byte[] arr = stream.toByteArray();
        img = Base64.encodeToString(arr, Base64.URL_SAFE);
        return img;
    }
    return null;
}

然后,您可以将应用程序的详细信息存储在应用程序数据库中。

这可以通过将图标转换为字符串并使用Parceler将其存储在文件中来完成。为此,

  • 创建一个应用程序类,将icon作为位图类型的属性
  • 上课
  • 使用要存储的所有图标初始化此类类型的ArrayList
  • 将这些对象打包并存储在文件中
  • 现在,位图类型的属性是不可包裹的,因此您必须将它们转换为可包裹类型。您可以使用此功能进行转换:

    static String bitMapToString(Bitmap bitmap) {
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        bitmap.compress(Bitmap.CompressFormat.PNG, 100, baos);
        return Base64.encodeToString(baos.toByteArray(), Base64.DEFAULT);
    }
    
    和下面的函数将数据转换回位图类型

    static Bitmap stringToBitMap(String encodedString) {
        try {
            byte[] encodeByte = Base64.decode(encodedString, Base64.DEFAULT);
            return BitmapFactory.decodeByteArray(encodeByte, 0, encodeByte.length);
        } catch (Exception e) {
            e.getMessage();
            return null;
        }
    }
    

    这可以通过将图标转换为字符串并使用Parceler将其存储在文件中来实现。为此,

  • 创建一个应用程序类,将icon作为位图类型的属性
  • 上课
  • 使用要存储的所有图标初始化此类类型的ArrayList
  • 将这些对象打包并存储在文件中
  • 现在,位图类型的属性是不可包裹的,因此您必须将它们转换为可包裹类型。您可以使用此功能进行转换:

    static String bitMapToString(Bitmap bitmap) {
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        bitmap.compress(Bitmap.CompressFormat.PNG, 100, baos);
        return Base64.encodeToString(baos.toByteArray(), Base64.DEFAULT);
    }
    
    和下面的函数将数据转换回位图类型

    static Bitmap stringToBitMap(String encodedString) {
        try {
            byte[] encodeByte = Base64.decode(encodedString, Base64.DEFAULT);
            return BitmapFactory.decodeByteArray(encodeByte, 0, encodeByte.length);
        } catch (Exception e) {
            e.getMessage();
            return null;
        }
    }