如何从图标包加载图标 [英] How to load icon from icon pack

查看:194
本文介绍了如何从图标包加载图标的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I want to use an icon from an icon pack. I know how to find installed icon packs. But I can't find out how to load an icon from an icon pack.

查找图标包 - 工作

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

That's how I find icon packs:

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;
}

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

Now the user can select an icon pack. I then try to load an icon from an icon pack like following:

从图标包加载应用程序图标 - 不工作

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.我不知道知道如何正确地做到这一点...

But the identifier is always 0. I don't know how to do it correctly...

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

For example, I know WhatsApp is in the icon pack. My debug output for it is:

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


推荐答案

您忘记了从xml文件加载元数据的步骤。

You forgot the step where you load the metadata from the xml file.

以下是我在我的应用程序中用于加载图标包的类的完整源代码, load 方法执行appfilter.xml解析:

Here is full source for the class I use in my app to load icon packs, the load method does appfilter.xml parsing:

package se.amphisys;

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 com.google.inject.Inject;
import com.google.inject.Singleton;
import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserException;
import org.xmlpull.v1.XmlPullParserFactory;
import roboguice.util.Ln;

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

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

    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;

        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);
                            }
                        }
                        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)
            {
                return loadBitmap(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 loadBitmap(drawable);
                    }
                }
            }
            return generateBitmap(appPackageName, defaultBitmap);
        }

        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 = defaultBitmap;
            if (defaultBitmap != null && (defaultBitmap.getWidth() > w || defaultBitmap.getHeight()> h))
                Bitmap.createScaledBitmap(defaultBitmap, (int)(w * mFactor), (int)(h * mFactor), false);

            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 without mask
            {
                mCanvas.drawBitmap(scaledBitmap, (w - scaledBitmap.getWidth())/2, (h - scaledBitmap.getHeight())/2, 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;
    }
}

这篇关于如何从图标包加载图标的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆