Android 设置默认Launcher

在Android系统中,为了使自己的Launcher成为默认且不允许被替换,需要在Framework层进行修改。具体步骤包括:1) 在Intent.java中添加自定义Filter;2) 在PackageParser.java中实现过滤处理;3) 在Launcher的AndroidManifest.xml中使用定义的Filter;4) 重新编译系统并通过make update-api编译,最终烧录验证。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Android 设置默认Launcher(Home)简介:

       如果定制Android系统,想让我们自己的Launcher(Home)成为默系统认Launcher,不希望用户安装了第三Launcher来替换我们的Launcher,并且不希望系统启动后弹出选择Launcher的界面,我们可以通过修改Framework层来实现,实现之后用户安装的第三方Launcher,系统仅当成一个普通应用来对待。

1、定义自己的Filter:

      在frameworks/base/core/java/android/content/Intent.java 中添加一个自己的Filter:

    @SdkConstant(SdkConstantType.INTENT_CATEGORY) 
    public static final String CATEGORY_HOME_FIRST = “android.intent.category.HOME_FIRST”;
 2、通过自己的Filter进行过滤处理:

        在frameworks/base/core/java/android/content/pm/PackageParser.java 中做过滤:

        Android 安装一个APK的时候首先会解析APK,这里要做很多事情,其中一个事情就是解析Manifest.xml文件,并将所有APK的Manifest封装到各种对象中并保存在内存当中解析Manifest的类是非常重要的,PackageParser.java类注意用于解析Manifest.xml文件,在寻找Launcher的时候是根据AndroidManifest.xml中Launcher的filter(在Manifest中定义的<category android:name="android.intent.category.HOME" />)来过滤。然后根据filter出来的HOME来启动,如果只有一个HOME,则启动这个HOME,如果用户自己装了Launcher,那就会弹出来一个列表供用户选择。

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);
        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);
        
        outInfo.logo = sa.getResourceId(
                com.android.internal.R.styleable.AndroidManifestIntentFilter_logo, 0);

        sa.recycle();

        int outerDepth = parser.getDepth();
        int type;
        while ((type = parser.next()) != XmlPullParser.END_DOCUMENT
                && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) {
            if (type == XmlPullParser.END_TAG || type == XmlPullParser.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 <android:name>";
                    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 <android:name>";
                    return false;
                }
                XmlUtils.skipCurrentTag(parser);
		// 在此进行过滤处理,处理开始,当解析到我们自己的定义的Intent.CATEGORY_HOME_FIRST时才将value设置为Intent.CATEGORY_HOME
	        if (value.equals(Intent.CATEGORY_HOME)) {
		     value = "nothing";
		}else if (value.equals(Intent.CATEGORY_HOME_FIRST)) {
		     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) {
                Slog.w(TAG, "Unknown element under <intent-filter>: "
                        + parser.getName() + " at " + mArchiveSourcePath + " "
                        + parser.getPositionDescription());
                XmlUtils.skipCurrentTag(parser);
            } else {
                outError[0] = "Bad element under <intent-filter>: " + parser.getName();
                return false;
            }
        }

        outInfo.hasDefault = outInfo.hasCategory(Intent.CATEGORY_DEFAULT);

        if (DEBUG_PARSER) {
            final StringBuilder cats = new StringBuilder("Intent d=");
            cats.append(outInfo.hasDefault);
            cats.append(", cat=");

            final Iterator<String> it = outInfo.categoriesIterator();
            if (it != null) {
                while (it.hasNext()) {
                    cats.append(' ');
                    cats.append(it.next());
                }
            }
            Slog.d(TAG, cats.toString());
        }

        return true;
    }
3、在Launcher AndroidManifest.xml中使用定义的Filter

       在自己Launcher  AndroidManifest.xml 中使用我们刚才自己定义的Filter,当系统解析到此Filter时就会把我们自己的Launcher作为系统默认的Launcher进行处理。

   <category android:name="android.intent.category.HOME_FIRST" />

<application android:icon="@drawable/icon" android:label="@string/app_name">
        <activity android:name=".MainActivity"
                  android:label="@string/app_name">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
				<!--在此添加我们定于的Filter-->
                <category android:name="android.intent.category.HOME_FIRST" />
                <category android:name="android.intent.category.DEFAULT" />
            </intent-filter>
        </activity>
</application>

4、重新编译系统,编译时在源码根目录执行make update-api,编译完成烧写板卡进行验证。

Android设备的默认launcher设置是指系统默认的启动器(Launcher)应用程序。启动器是用户在设备上看到和操作的主屏幕,它提供了桌面、应用程序列表、小部件和壁纸等功能。 在Android设备上,不同的制造商可能会有不同的默认启动器设置,例如Samsung可能会有自己的启动器样式,而Google的Pixel设备则使用原生的Android启动器。 默认启动器有以下几个主要特点和功能: 1. 桌面:默认启动器会在设备主屏幕上显示桌面,用户可以在桌面上添加和管理应用程序、小部件和快捷方式等。 2. 应用程序列表:用户可以通过默认启动器访问设备上安装的所有应用程序的列表,并进行搜索和排序。 3. 小部件:默认启动器支持用户在桌面上添加各种小部件,例如天气、日历、音乐播放器等,以便用户更方便地获取相关信息。 4. 壁纸:默认启动器还允许用户更改桌面背景壁纸,可以选择自己喜欢的图片或者使用系统提供的预设壁纸。 对于用户来说,选择适合自己的默认启动器可以增加使用Android设备的个性化和便利性。用户可以根据自己的需求和偏好,选择不同功能和样式的启动器来进行设置。有些启动器还提供了更多的自定义选项,例如主题、图标包等,使用户能够将设备界面个性化到自己喜欢的样子。 总之,Android设备的默认启动器设置是一个重要的用户体验方面的设置选项,通过它可以实现设备主屏幕的个性化和功能拓展。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值