在网上找了好久唯一launcher的实现方式,发现都是一同一个人写的,而且并没有实现这个功能,因为按照这个方式去做的话,当你按下HOME键还是出现了选择launcher的对话框,然后自己研究了一天,找到了最直接有效的而且是最简单的方法实现全局唯一launcher的功能:

        

        修改frameworks\base\core\java\android\content\pm\PackageParser.java,在parseIntent这个私有方法,因为APK在安装的时候会通过这个方法解析Manifest清单文件,然后将每个Activity的intent-filter保存在内存中,所以修改这个方法就相当于修改了内存的应用注册表的信息,也就是偷换概念的做法,等于是在安装的时候就把问题解决了,扼杀在萌芽状态:


       修改部分为:

        这里xxx随便你输入,例如你在你自己的launcher的Manifest的Activity里Intent-filter里加入:

        



        那么在代码里修改的地方的xxx就替换成你自己起的名字

        原理就是安装每个APK的时候 只要是launcher ,就把category是HOME的值改成x,只要是你的launcher就把category的值改成HOME,那么全局就只有你一个launcher了


        这里是修改的部分:

/*************************************************************************************/                if(Intent.CATEGORY_HOME.equals(value)) {                value = "x";                } else if((Intent.CATEGORY_HOME + ".xxx").equals(value)) {                value = Intent.CATEGORY_HOME;                }                /*************************************************************************************/

使用这种方法修改时必须确保你的launcher被安装了或者放在了syste/app下了且Manifest的Activity里的intent-filter为android.category.HOME.xxx




 具体的原理请参考我的另外一篇博客:http://blog.csdn.net/zhbinary/article/details/7353739





修改frameworks\base\core\java\android\content\pm\PackageParser.java里的parseIntent方法
private boolean parseIntent(Resources res,            XmlPullParser parser, AttributeSet attrs, int flags,            IntentInfo outInfo, String[] outError, boolean isActivity)            throws XmlPullParserException, IOException {        TypedArray sa = res.obtainAttributes(attrs,                com.android.internal.R.styleable.AndroidManifestIntentFilter);        int priority = sa.getInt(                com.android.internal.R.styleable.AndroidManifestIntentFilter_priority, 0);        if (priority > 0 && isActivity && (flags&PARSE_IS_SYSTEM) == 0) {            Log.w(TAG, "Activity with priority > 0, forcing to 0 at "                    + mArchiveSourcePath + " "                    + parser.getPositionDescription());            priority = 0;        }        outInfo.setPriority(priority);                TypedValue v = sa.peekValue(                com.android.internal.R.styleable.AndroidManifestIntentFilter_label);        if (v != null && (outInfo.labelRes=v.resourceId) == 0) {            outInfo.nonLocalizedLabel = v.coerceToString();        }        outInfo.icon = sa.getResourceId(                com.android.internal.R.styleable.AndroidManifestIntentFilter_icon, 0);        sa.recycle();        int outerDepth = parser.getDepth();        int type;        while ((type=parser.next()) != parser.END_DOCUMENT               && (type != parser.END_TAG || parser.getDepth() > outerDepth)) {            if (type == parser.END_TAG || type == parser.TEXT) {                continue;            }            String nodeName = parser.getName();            if (nodeName.equals("action")) {                String value = attrs.getAttributeValue(                        ANDROID_RESOURCES, "name");                if (value == null || value == "") {                    outError[0] = "No value supplied for ";                    return false;                }                XmlUtils.skipCurrentTag(parser);                outInfo.addAction(value);            } else if (nodeName.equals("category")) {                String value = attrs.getAttributeValue(                        ANDROID_RESOURCES, "name");                if (value == null || value == "") {                    outError[0] = "No value supplied for ";                    return false;                }                XmlUtils.skipCurrentTag(parser);                                                                /*************************************************************************************/                if(Intent.CATEGORY_HOME.equals(value)) {                value = "x";                } else if((Intent.CATEGORY_HOME + ".xxx").equals(value)) {                value = Intent.CATEGORY_HOME;                }                /*************************************************************************************/                                                                outInfo.addCategory(value);            } else if (nodeName.equals("data")) {                sa = res.obtainAttributes(attrs,                        com.android.internal.R.styleable.AndroidManifestData);                String str = sa.getNonConfigurationString(                        com.android.internal.R.styleable.AndroidManifestData_mimeType, 0);                if (str != null) {                    try {                        outInfo.addDataType(str);                    } catch (IntentFilter.MalformedMimeTypeException e) {                        outError[0] = e.toString();                        sa.recycle();                        return false;                    }                }                str = sa.getNonConfigurationString(                        com.android.internal.R.styleable.AndroidManifestData_scheme, 0);                if (str != null) {                    outInfo.addDataScheme(str);                }                String host = sa.getNonConfigurationString(                        com.android.internal.R.styleable.AndroidManifestData_host, 0);                String port = sa.getNonConfigurationString(                        com.android.internal.R.styleable.AndroidManifestData_port, 0);                if (host != null) {                    outInfo.addDataAuthority(host, port);                }                str = sa.getNonConfigurationString(                        com.android.internal.R.styleable.AndroidManifestData_path, 0);                if (str != null) {                    outInfo.addDataPath(str, PatternMatcher.PATTERN_LITERAL);                }                str = sa.getNonConfigurationString(                        com.android.internal.R.styleable.AndroidManifestData_pathPrefix, 0);                if (str != null) {                    outInfo.addDataPath(str, PatternMatcher.PATTERN_PREFIX);                }                str = sa.getNonConfigurationString(                        com.android.internal.R.styleable.AndroidManifestData_pathPattern, 0);                if (str != null) {                    outInfo.addDataPath(str, PatternMatcher.PATTERN_SIMPLE_GLOB);                }                sa.recycle();                XmlUtils.skipCurrentTag(parser);            } else if (!RIGID_PARSER) {                Log.w(TAG, "Unknown element under : "                        + parser.getName() + " at " + mArchiveSourcePath + " "                        + parser.getPositionDescription());                XmlUtils.skipCurrentTag(parser);            } else {                outError[0] = "Bad element under : " + parser.getName();                return false;            }        }        outInfo.hasDefault = outInfo.hasCategory(Intent.CATEGORY_DEFAULT);        if (false) {            String cats = "";            Iterator it = outInfo.categoriesIterator();            while (it != null && it.hasNext()) {                cats += " " + it.next();            }            System.out.println("Intent d=" +                    outInfo.hasDefault + ", cat=" + cats);        }        return true;    }


更多相关文章

  1. 实现自己的Camera
  2. Android面试题(一)
  3. conversion to dalvik format failed with error 1的解决办法
  4. Android菜单详解(四)——使用上下文菜单ContextMenu
  5. Android(安卓)Activity类应用技巧分享
  6. Android测试方法总结
  7. Android(安卓)反编译apk 到java源码的方法
  8. 浅谈Java中Collections.sort对List排序的两种方法
  9. Python list sort方法的具体使用

随机推荐

  1. bridge和原生交互的简单用法
  2. 安卓(android)使用GPS,获取经纬度
  3. Titanium 使用刘明星的Jpush module做and
  4. Android RabbitMQ使用之RabbitMQ安装及配
  5. Android中的常用的对话框
  6. 《阿里巴巴Android开发手册》v1.0.1更新,
  7. Android(安卓)monkey 命令详解
  8. Android修改字体样式
  9. android 数字证书具体应用机制
  10. android插件汇总