【问题标题】:Retrieving xhdpi app icons from packageManager?从 packageManager 中检索 xhdpi 应用程序图标?
【发布时间】:2013-08-22 16:26:01
【问题描述】:

我的应用中有一个活动,其中生成了所有已安装应用的 ListView。除了应用程序名称之外,还会显示应用程序图标。我创建了一个对象数组,其中包含有关应用程序的所有信息,其中包括图标,并使用以下方法检索图标:

drawableAppIcon = mPackageManager.getApplicationIcon(apps.applicationInfo);

其中application<PackageInfo> 对象。这样做的问题是,虽然我可以轻松访问所有可绘制对象,但各种应用程序似乎可以提取各种质量的可绘制对象;一个应用程序图标将具有极高的分辨率,而另一个将是低分辨率版本。我原以为上面的代码行会考虑屏幕大小并找到合适的图标,但事实并非如此。有没有考虑屏幕尺寸的替代方案?或者更可取的是,有一种方法可以只提取最高分辨率的图标,然后根据屏幕尺寸缩小它,这基本上可以保证所有图标看起来都很干净?

编辑:我找到了一个解决方案,但它只适用于 Android 4.0+

try {
    Context otherAppCtxt = context.createPackageContext(apps.applicationInfo.packageName, Context.CONTEXT_IGNORE_SECURITY);
    info.drawableAppIcon = otherAppCtxt.getResources().getDrawableForDensity(apps.applicationInfo.icon, DisplayMetrics.DENSITY_XHIGH);
} catch (PackageManager.NameNotFoundException e) {
    e.printStackTrace();
}

供其他人参考,如果有人有旧版本 Android 的解决方案,这将非常有用。

【问题讨论】:

  • 应用程序图标在 Android 其他地方看起来还好吗?你在你的应用程序中调整它们的大小吗?我会开始确保您使用它们的固有宽度/高度来绘制它们。

标签: android icons drawable


【解决方案1】:
ApplicationInfo applicationInfo = 
        packagemanager.getApplicationInfo(packageName(), PackageManager.GET_META_DATA);
Resources res = packagemanager.getResourcesForApplication(applicationInfo);
Drawable appIcon = res.getDrawableForDensity(applicationInfo.icon, 
                                             DisplayMetrics.DENSITY_XXXHIGH, 
                                             null);

【讨论】:

  • 谢谢巫师!
  • 而不是'Drawable appIcon = res.getDrawableForDensity(applicationInfo.icon, DisplayMetrics.DENSITY_XXXHIGH, null);'使用这个 'Drawable appIcon = res.getDrawableForDensity(applicationInfo.icon, DisplayMetrics.DENSITY_XXXHIGH);'
【解决方案2】:

我怀疑图标看起来不好的其他原因(例如在您的应用中调整大小),但如果您需要为任何 Android 版本执行此操作:

// Get the application's resources
Resources res = mPackageManager.getResourcesForApplication(appInfo);

// Get a copy of the configuration, and set it to the desired resolution
Configuration config = res.getConfiguration();
Configuration originalConfig = new Configuration(config);
config.densityDpi = DisplayMetrics.DENSITY_XHIGH;

// Update the configuration with the desired resolution
DisplayMetrics dm = res.getDisplayMetrics();
res.updateConfiguration(config, dm);

// Grab the app icon
Drawable appIcon = res.getDrawable(appInfo.icon);

// Set our configuration back to what it was
res.updateConfiguration(originalConfig, dm);

【讨论】:

  • config.densityDpi 是 API17 字段,所以这个解决方案不能用于任何 Android 版本
  • 感谢弗拉德,这是我的一个重大疏忽。我将尝试设置 DisplayMetrics.densityDpi (API 4)。
  • 如果您有结果,请分享您的结果。当然可以。
  • @DaneWhite:您是否有任何反馈尝试设置 DisplayMetrics.densityDpi ?有用吗?
【解决方案3】:

这是一个老问题的新答案,只是为了将所有内容放在一个地方。您需要获取设备的默认密度,并调整图像大小以确保您具有正确一致的大小,因为仅请求图标并不总是返回正确的大小。

考虑这两种方法,一种是获取设备大小,另一种是调整你的drawable的大小:

private int getDeviceDpi(){
        DisplayMetrics dm = new DisplayMetrics();
        getWindowManager().getDefaultDisplay().getMetrics(dm);
        return dm.densityDpi;
}

private Drawable getSizedAppIcon(Context context, String packageName, int Density) throws PackageManager.NameNotFoundException {
    //for @param Density you can use a static from DisplayMetrics.<something>

        PackageManager pm = Objects.requireNonNull(context).getPackageManager();
        ApplicationInfo appInfo = this.getPackageManager().getApplicationInfo(packageName, 0);
        Drawable icon = pm.getApplicationIcon(appInfo);
        Bitmap bitmap = ((BitmapDrawable) icon).getBitmap();
        switch (Density){
            case DisplayMetrics.DENSITY_LOW: //120
                return new BitmapDrawable(getResources(), Bitmap.createScaledBitmap(bitmap,
                        32, 32, true));
            case DisplayMetrics.DENSITY_MEDIUM: //160
                return new BitmapDrawable(getResources(), Bitmap.createScaledBitmap(bitmap,
                        48, 48, true));
            case DisplayMetrics.DENSITY_HIGH: //240
                return new BitmapDrawable(getResources(), Bitmap.createScaledBitmap(bitmap,
                        72, 72, true));
            case DisplayMetrics.DENSITY_XHIGH: //320
                return new BitmapDrawable(getResources(), Bitmap.createScaledBitmap(bitmap,
                        96, 96, true));
            case DisplayMetrics.DENSITY_XXHIGH: //480
                return new BitmapDrawable(getResources(), Bitmap.createScaledBitmap(bitmap,
                        144, 144, true));
            case DisplayMetrics.DENSITY_XXXHIGH: //640
                return new BitmapDrawable(getResources(), Bitmap.createScaledBitmap(bitmap,
                        192, 192, true));
            default:
                return icon;
        }

}

然后像下面的例子那样调用它们:

try{
    getSizedAppIcon(this, "com.example.app",getDeviceDpi());
}catch (Exception ignore) {}

【讨论】:

    猜你喜欢
    • 2022-06-10
    • 1970-01-01
    • 2021-12-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-12-01
    相关资源
    最近更新 更多