android - 如何从图标包加载图标

标签 android resources icons drawable android-resources

我想使用图标包中的图标。我知道如何找到已安装的图标包。但是我找不到如何从图标包加载图标。

查找图标包 - 可行

这就是我找到图标包的方式:

private static ArrayList<String> getInstalledIconPacks(String filter)
{
    ArrayList<String> packs = new ArrayList<>();

    List<ResolveInfo> infos = MainApp.get().getPackageManager().queryIntentActivities(new Intent(filter), PackageManager.GET_META_DATA);
    if (infos != null)
    {
        for (int i = 0; i < infos.size(); i++)
        {
            ActivityInfo activity = infos.get(i).activityInfo;
            String packageName = activity.packageName;
            if (packageName != null)
                packs.add(packageName);
        }
    }

    return packs;
}

现在用户可以选择一个图标包。然后我尝试从图标包中加载一个图标,如下所示:

从图标包加载应用图标 - 不起作用

public static Drawable getIconPackIcon(String packageName)
{
    L.d(AppUtil.class, "PackageName: " + packageName);

    String componentName = MainApp.get().getPackageManager().getLaunchIntentForPackage(packageName).getComponent().toString();
    L.d(AppUtil.class, "componentName: " + componentName);

    try
    {
        //Resources res = MainApp.get().getResources();
        Resources res = MainApp.get().getPackageManager().getResourcesForApplication(packageName);
        int identifier = res.getIdentifier(componentName, "drawable", packageName);
        L.d(AppUtil.class, "identifier: " + identifier);

        if (identifier == 0)
            return null;

        Drawable d = res.getDrawable(identifier);
        L.d(AppUtil.class, "d: " + d);

        return d;
    } 
    catch (PackageManager.NameNotFoundException e) 
    {
        L.e(AppUtil.class, e);
        return null;
    }
}

但是标识符一直是0,不知道怎么正确...

例如,我知道 WhatsApp 在图标包中。我的调试输出是:

PackageName: com.whatsapp
componentName: ComponentInfo{com.whatsapp/com.whatsapp.Main}
identifier: 0

最佳答案

修改后的版本(希望是 rickythefoxes 类的无错误版本 - 在屏蔽和图标包不包含图标的情况下存在问题。)

import android.content.Context;
import android.content.Intent;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
import android.content.res.Resources;
import android.graphics.*;

import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserException;
import org.xmlpull.v1.XmlPullParserFactory;

import java.io.IOException;
import java.io.InputStream;
import java.util.*;

public class IconPackManager
{
    //@Inject
    //private android.app.Application mContext;

    private Context mContext;

    public void setContext (Context c) {
        mContext = c;
    }

    public class IconPack
    {
        public String packageName;
        public String name;

        private boolean mLoaded = false;
        private HashMap<String, String> mPackagesDrawables = new HashMap<String, String>();

        private List<Bitmap> mBackImages = new ArrayList<Bitmap>();
        private Bitmap mMaskImage = null;
        private Bitmap mFrontImage = null;
        private float mFactor = 1.0f;
        private int totalIcons;

        Resources iconPackres = null;

        public void load()
        {
            // load appfilter.xml from the icon pack package
            PackageManager pm = mContext.getPackageManager();
            try
            {
                XmlPullParser xpp = null;

                iconPackres = pm.getResourcesForApplication(packageName);
                int appfilterid = iconPackres.getIdentifier("appfilter", "xml", packageName);
                if (appfilterid > 0)
                {
                    xpp = iconPackres.getXml(appfilterid);
                }
                else
                {
                    // no resource found, try to open it from assests folder
                    try
                    {
                        InputStream appfilterstream = iconPackres.getAssets().open("appfilter.xml");

                        XmlPullParserFactory factory = XmlPullParserFactory.newInstance();
                        factory.setNamespaceAware(true);
                        xpp = factory.newPullParser();
                        xpp.setInput(appfilterstream, "utf-8");
                    }
                    catch (IOException e1)
                    {
                        //Ln.d("No appfilter.xml file");
                    }
                }

                if (xpp != null)
                {
                    int eventType = xpp.getEventType();
                    while (eventType != XmlPullParser.END_DOCUMENT)
                    {
                        if(eventType == XmlPullParser.START_TAG)
                        {
                            if (xpp.getName().equals("iconback"))
                            {
                                for(int i=0; i<xpp.getAttributeCount(); i++)
                                {
                                    if (xpp.getAttributeName(i).startsWith("img"))
                                    {
                                        String drawableName = xpp.getAttributeValue(i);
                                        Bitmap iconback = loadBitmap(drawableName);
                                        if (iconback != null)
                                            mBackImages.add(iconback);
                                    }
                                }
                            }
                            else if (xpp.getName().equals("iconmask"))
                            {
                                if (xpp.getAttributeCount() > 0 && xpp.getAttributeName(0).equals("img1"))
                                {
                                    String drawableName = xpp.getAttributeValue(0);
                                    mMaskImage = loadBitmap(drawableName);
                                }
                            }
                            else if (xpp.getName().equals("iconupon"))
                            {
                                if (xpp.getAttributeCount() > 0 && xpp.getAttributeName(0).equals("img1"))
                                {
                                    String drawableName = xpp.getAttributeValue(0);
                                    mFrontImage = loadBitmap(drawableName);
                                }
                            }
                            else if (xpp.getName().equals("scale"))
                            {
                                // mFactor
                                if (xpp.getAttributeCount() > 0 && xpp.getAttributeName(0).equals("factor"))
                                {
                                    mFactor = Float.valueOf(xpp.getAttributeValue(0));
                                }
                            }
                            else if (xpp.getName().equals("item"))
                            {
                                String componentName = null;
                                String drawableName = null;

                                for(int i=0; i<xpp.getAttributeCount(); i++)
                                {
                                    if (xpp.getAttributeName(i).equals("component"))
                                    {
                                        componentName = xpp.getAttributeValue(i);
                                    }
                                    else if (xpp.getAttributeName(i).equals("drawable"))
                                    {
                                        drawableName = xpp.getAttributeValue(i);
                                    }
                                }
                                if (!mPackagesDrawables.containsKey(componentName)) {
                                    mPackagesDrawables.put(componentName, drawableName);
                                    totalIcons = totalIcons + 1;
                                }
                            }
                        }
                        eventType = xpp.next();
                    }
                }
                mLoaded = true;
            }
            catch (PackageManager.NameNotFoundException e)
            {
                //Ln.d("Cannot load icon pack");
            }
            catch (XmlPullParserException e)
            {
                //Ln.d("Cannot parse icon pack appfilter.xml");
            }
            catch (IOException e) {
                e.printStackTrace();
            }
        }

        private Bitmap loadBitmap(String drawableName)
        {
            int id = iconPackres.getIdentifier(drawableName, "drawable", packageName);
            if (id > 0)
            {
                Drawable bitmap = iconPackres.getDrawable(id);
                if (bitmap instanceof BitmapDrawable)
                    return ((BitmapDrawable)bitmap).getBitmap();
            }
            return null;
        }

        private Drawable loadDrawable(String drawableName)
        {
            int id = iconPackres.getIdentifier(drawableName, "drawable", packageName);
            if (id > 0)
            {
                Drawable bitmap = iconPackres.getDrawable(id);
                return bitmap;
            }
            return null;
        }

        public Drawable getDrawableIconForPackage(String appPackageName, Drawable defaultDrawable) {
            if (!mLoaded)
                load();

            PackageManager pm = mContext.getPackageManager();

            Intent launchIntent = pm.getLaunchIntentForPackage(appPackageName);

            String componentName = null;

            if (launchIntent != null) componentName = pm.getLaunchIntentForPackage(appPackageName).getComponent().toString();

            String drawable = mPackagesDrawables.get(componentName);

            if (drawable != null)
            {
                return loadDrawable(drawable);
            }

            else
            {
                // try to get a resource with the component filename
                if (componentName != null)
                {
                    int start = componentName.indexOf("{")+1;
                    int end = componentName.indexOf("}",  start);
                    if (end > start)
                    {
                        drawable = componentName.substring(start,end).toLowerCase(Locale.getDefault()).replace(".","_").replace("/", "_");
                        if (iconPackres.getIdentifier(drawable, "drawable", packageName) > 0)
                            return loadDrawable(drawable);
                    }
                }
            }
            return defaultDrawable;
        }

        public Bitmap getIconForPackage(String appPackageName, Bitmap defaultBitmap)
        {
            if (!mLoaded)
                load();

            PackageManager pm = mContext.getPackageManager();
            Intent launchIntent = pm.getLaunchIntentForPackage(appPackageName);
            String componentName = null;
            if (launchIntent != null)
                componentName = pm.getLaunchIntentForPackage(appPackageName).getComponent().toString();
            String drawable = mPackagesDrawables.get(componentName);
            if (drawable != null)
            {
                Bitmap BMP = loadBitmap(drawable);
                if (BMP == null) {
                    return generateBitmap(appPackageName, defaultBitmap);
                } else {
                    return BMP;
                }
            }
            else
            {
                // try to get a resource with the component filename
                if (componentName != null)
                {
                    int start = componentName.indexOf("{")+1;
                    int end = componentName.indexOf("}",  start);
                    if (end > start)
                    {
                        drawable = componentName.substring(start,end).toLowerCase(Locale.getDefault()).replace(".","_").replace("/", "_");
                        if (iconPackres.getIdentifier(drawable, "drawable", packageName) > 0)
                            return loadBitmap(drawable);
                    }
                }
            }
            return generateBitmap(appPackageName, defaultBitmap);
        }

        public int getTotalIcons() {
            return totalIcons;
        }

        private Bitmap generateBitmap(String appPackageName, Bitmap defaultBitmap)
        {
            // the key for the cache is the icon pack package name and the app package name
            String key = packageName + ":" + appPackageName;

            // if generated bitmaps cache already contains the package name return it
//            Bitmap cachedBitmap = BitmapCache.getInstance(mContext).getBitmap(key);
//            if (cachedBitmap != null)
//                return cachedBitmap;

            // if no support images in the icon pack return the bitmap itself
            if (mBackImages.size() == 0) return defaultBitmap;

            Random r = new Random();
            int backImageInd = r.nextInt(mBackImages.size());
            Bitmap backImage = mBackImages.get(backImageInd);
            int w = backImage.getWidth();
            int h = backImage.getHeight();

            // create a bitmap for the result
            Bitmap result = Bitmap.createBitmap(w, h, Bitmap.Config.ARGB_8888);
            Canvas mCanvas = new Canvas(result);

            // draw the background first
            mCanvas.drawBitmap(backImage, 0, 0, null);

            // create a mutable mask bitmap with the same mask
            Bitmap scaledBitmap;
            if (defaultBitmap.getWidth() > w || defaultBitmap.getHeight()> h) {
                scaledBitmap = Bitmap.createScaledBitmap(defaultBitmap, (int)(w * mFactor), (int)(h * mFactor), false);
            } else {
                scaledBitmap = Bitmap.createBitmap(defaultBitmap);
            }

            if (mMaskImage != null)
            {
                // draw the scaled bitmap with mask
                Bitmap mutableMask = Bitmap.createBitmap(w, h, Bitmap.Config.ARGB_8888);
                Canvas maskCanvas = new Canvas(mutableMask);
                maskCanvas.drawBitmap(mMaskImage,0, 0, new Paint());

                // paint the bitmap with mask into the result
                Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG);
                paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.DST_OUT));
                mCanvas.drawBitmap(scaledBitmap, (w - scaledBitmap.getWidth())/2, (h - scaledBitmap.getHeight())/2, null);
                mCanvas.drawBitmap(mutableMask, 0, 0, paint);
                paint.setXfermode(null);
            }
            else // draw the scaled bitmap with the back image as mask
            {
                Bitmap mutableMask = Bitmap.createBitmap(w, h, Bitmap.Config.ARGB_8888);
                Canvas maskCanvas = new Canvas(mutableMask);
                maskCanvas.drawBitmap(backImage,0, 0, new Paint());

                // paint the bitmap with mask into the result
                Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG);
                paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.DST_IN));
                mCanvas.drawBitmap(scaledBitmap, (w - scaledBitmap.getWidth())/2, (h - scaledBitmap.getHeight())/2, null);
                mCanvas.drawBitmap(mutableMask, 0, 0, paint);
                paint.setXfermode(null);

            }

            // paint the front
            if (mFrontImage != null)
            {
                mCanvas.drawBitmap(mFrontImage, 0, 0, null);
            }

            // store the bitmap in cache
//            BitmapCache.getInstance(mContext).putBitmap(key, result);

            // return it
            return result;
        }
    }

    private HashMap<String, IconPack> iconPacks = null;

    public HashMap<String, IconPack> getAvailableIconPacks(boolean forceReload)
    {
        if (iconPacks == null || forceReload)
        {
            iconPacks = new HashMap<String, IconPack>();

            // find apps with intent-filter "com.gau.go.launcherex.theme" and return build the HashMap
            PackageManager pm = mContext.getPackageManager();

            List<ResolveInfo> adwlauncherthemes = pm.queryIntentActivities(new Intent("org.adw.launcher.THEMES"), PackageManager.GET_META_DATA);
            List<ResolveInfo> golauncherthemes = pm.queryIntentActivities(new Intent("com.gau.go.launcherex.theme"), PackageManager.GET_META_DATA);

            // merge those lists
            List<ResolveInfo> rinfo = new ArrayList<ResolveInfo>(adwlauncherthemes);
            rinfo.addAll(golauncherthemes);

            for(ResolveInfo ri  : rinfo)
            {
                IconPack ip = new IconPack();
                ip.packageName = ri.activityInfo.packageName;

                ApplicationInfo ai = null;
                try
                {
                    ai = pm.getApplicationInfo(ip.packageName, PackageManager.GET_META_DATA);
                    ip.name  = mContext.getPackageManager().getApplicationLabel(ai).toString();
                    iconPacks.put(ip.packageName, ip);
                }
                catch (PackageManager.NameNotFoundException e)
                {
                    // shouldn't happen
                    e.printStackTrace();
                }
            }
        }
        return iconPacks;
    }
}

关于android - 如何从图标包加载图标,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31490630/

相关文章:

android - 查看android wifip2p连接是否成功?

documentation - 如何为 IT Assets 创建 "dependency graph"

c# - 如何在 C# 中获取文件类型/扩展名的 64x64 图标?

objective-c - 如何在 mac osx 中为文件类型设置自定义图标

android - 如何在 Eclipse for Android 中更改 Control+Space 自动完成快捷键

android - 在 fragment android 中的 CursorLoader 中显示进度对话框

winapi - Windows 跳过特定于语言的资源

linux - 侏儒图标包

java - Android:IllegalStateException: Activity 已被销毁

c# - C# 应用程序中的资源和嵌入式资源有什么区别?