android ROM设置默认Launcher(主屏幕应用) 您所在的位置:网站首页 华为如何更改默认桌面 android ROM设置默认Launcher(主屏幕应用)

android ROM设置默认Launcher(主屏幕应用)

2023-12-01 15:48| 来源: 网络整理| 查看: 265

Launcher

Launcher是android系统的桌面、是android系统的主要组件。android系统允许存在多个Launcher并设置默认主界面。

应用程序作为Home(主界面)需在Activity的intent-filter节点中添加如下内容

当系统中存在多个Home app且没有设置默认,用户点击Home键会弹出如下图所示的界面(图一): 这里写图片描述 用户可以选择“只有一次”或者“总是”来启动选择的APP

一般情况下android ROM中只会存在一个Home APP,系统启动后会直接启动此APP为默认,不需要用户选择。但是当ROM存在多个Home APP时,系统第一次启动就会弹出上图所示界面,让用户选择其中一个APP作为主屏幕应用,如果用户通过“ALWAYS”确认会设置选择的APP为默认的Home,用户通过“JUST ONCE”则此次以选择的APP为Home,再次按home键还是会弹出选择窗口

android ROM默认Launcher设置: 1:无效方案

网上有很多博客介绍如何设置ROM的默认Home app思路,都是在packages/apps/Provision/src/com/android/provision/DefaultActivity.java 中添加一段设置默认Home的代码,代码如下

//网上的看到的 private void setupDefaultLauncher() { // remove this activity from the package manager. PackageManager pm = getPackageManager(); String examplePackageName = "******"; // package name String exampleActivityName = "******"; // launcher activity name ComponentName defaultLauncher = null; Intent intent = new Intent(Intent.ACTION_MAIN); intent.addCategory(Intent.CATEGORY_HOME); List resolveInfoList = pm.queryIntentActivities(intent, 0); if (resolveInfoList != null) { int size = resolveInfoList.size(); for (int j = 0; j < size; ) { final ResolveInfo r = resolveInfoList.get(j); if (!r.activityInfo.packageName.equals(examplePackageName)) { resolveInfoList.remove(j); size -= 1; } else { j++; } } ComponentName[] set = new ComponentName[size]; defaultLauncher = new ComponentName(examplePackageName, exampleActivityName); int defaultMatch = 0; for (int i = 0; i < size; i++) { final ResolveInfo resolveInfo = resolveInfoList.get(i); Log.d(TAG, resolveInfo.toString()); set[i] = new ComponentName(resolveInfo.activityInfo.packageName, resolveInfo.activityInfo.name); if (defaultLauncher.getClassName().equals(resolveInfo.activityInfo.name)) { defaultMatch = resolveInfo.match; } } Log.d(TAG, "defaultMatch =" + Integer.toHexString(defaultMatch)); IntentFilter filter = new IntentFilter(); filter.addAction(Intent.ACTION_MAIN); filter.addCategory(Intent.CATEGORY_HOME); filter.addCategory(Intent.CATEGORY_DEFAULT); pm.clearPackagePreferredActivities(defaultLauncher.getPackageName()); pm.addPreferredActivity(filter, defaultMatch, set, defaultLauncher); } } //系统设置中修改默认Launcher的代码, private void setupDefaultLauncher2() { String packageName = "******"; // package name PackageManager mPm = getPackageManager(); ArrayList homeActivities = new ArrayList(); ComponentName currentDefaultHome = mPm.getHomeActivities(homeActivities); IntentFilter mHomeFilter = new IntentFilter(Intent.ACTION_MAIN); mHomeFilter.addCategory(Intent.CATEGORY_HOME); mHomeFilter.addCategory(Intent.CATEGORY_DEFAULT); ComponentName[] mHomeComponentSet = new ComponentName[homeActivities.size()]; int prefIndex = 0; for (int i = 0; i < homeActivities.size(); i++) { final ResolveInfo candidate = homeActivities.get(i); final ActivityInfo info = candidate.activityInfo; ComponentName activityName = new ComponentName(info.packageName, info.name); mHomeComponentSet[i] = activityName; if(info.packageName.equals(packageName)){ currentDefaultHome = activityName; } } mPm.replacePreferredActivity(mHomeFilter, IntentFilter.MATCH_CATEGORY_EMPTY, mHomeComponentSet, currentDefaultHome); }

将以上任何一段代码添加到DefaultActivity的onCreate方法中,都无法实现修改启动后的默认Launcher,只能使设置的默认Launcher为选中状态如下图(图二): Launcher选择窗口

2:有效方案

既然使用上述设置默认主界面的做法无效,而在上述界面选择却有效,那么就从上面弹出的选择默认主界面的界面入手,通过追踪发现上述界面是一个Activity,Activity代码路径frameworks/base/core/java/com/android/internal/app/ResolverActivity.java

ResolverActivity分析

此Activity会获取系统中所有的Home app,并根据系统的设置情况显示如上界面。此类中有一个内部类ResolveListAdapter该类继承自BaseAdapter,该类是Home app选择界面的数据适配器。

ResolveListAdapter会在ResolverActivity的onCreate方法中被初始化并会传入一个ResolveInfo类型的List,ResolveListAdapter根据会传入的List初始化一个List mList ,用户的点击事件都会在ResolveListAdapter获取数据。 用户点击”ALWAYS”的事件发生在ResolverActivity的onButtonClick 方法中,此方法会获取选中的Item的position、或者获取用户上一次启动的Home app的,mAlwaysUseOption代表用户选中的是否为历史选择(如2图中的Launcher3),并调用startSelected。

public void onButtonClick(View v) { final int id = v.getId(); startSelected(mAlwaysUseOption ? mListView.getCheckedItemPosition() : mAdapter.getFilteredPosition(), id == R.id.button_always, mAlwaysUseOption); dismiss(); }

StartSeletced中通过ResolveListAdapter获取选择的item代表的Home app。并且finish此activity onIntentSelected会根据传入的ResolveInfo设置默认的Home,并根据Intent跳转到相应界面,onIntentSelected的代码在这里就不列出。

/** * 设置默认Home app并跳转,结束此Activity * @param which 用户选择的Item的position * @param always 是否设置为总是 * @param filtered 是否非历史选择 */ void startSelected(int which, boolean always, boolean filtered) { if (isFinishing()) { return; } ResolveInfo ri = mAdapter.resolveInfoForPosition(which, filtered); Intent intent = mAdapter.intentForPosition(which, filtered); //设置默认Home,并启动 onIntentSelected(ri, intent, always); finish(); }

ResolveListAdapter的相关代码

/** * * @param position * @param filtered * @return */ public ResolveInfo resolveInfoForPosition(int position, boolean filtered) { //mList为List return (filtered ? getItem(position) : mList.get(position)).ri; } /** * * @param position * @param filtered * @return */ public Intent intentForPosition(int position, boolean filtered) { //mList为List DisplayResolveInfo dri = filtered ? getItem(position) : mList.get(position); return intentForDisplayResolveInfo(dri); } 解决办法

此Activity的onCreate方法中判断是否为第一次启动,如果是则调用startSelected方法设置默认Home app。

默认Home app的从ResolveListAdapter中获取,所以在ResolveListAdapter中添加getDefaultHomePosition(String packageName)方法,用于获取默认home app在List 中的位置,代码如下:

public int getDefaultHomePosition(String packageName){ for (int i = 0; i < mList.size(); i++) { ResolveInfo info = mList.get(i).ri; if (DEBUG) Log.w(TAG,"getDefaultHomePosition " + info.activityInfo.packageName); if (info.activityInfo.packageName.equals(packageName)) { return i; } } return -1; }

在ResolverActivity中添加设置默认app的方法setupDefaultLauncher(),代码如下:

//用于记录默认home app是否设置过 private static final String DEFAULT_HOME = "persist.sys.default.home"; private void setupDefaultLauncher() { String first = ""; try{ first = SystemProperties.get(DEFAULT_HOME); }catch(Exception e){ Log.w(TAG,"exception error get DEFAULT_HOME"); } //判断默认home 是否设置过,如果获取的字符串为空代表,未设置,否则return不在进行设置 if (!TextUtils.isEmpty(first)) { return; } //使用包名获取所需设置的默认home app在ResolveListAdapter中的位置 int position = mAdapter.getDefaultHomePosition("home app包名"); //如果不存在则return if (position == -1) { if (DEBUG) Log.w(TAG,"not find default Home"); return; } //设置默认home app后,则添加记录 try{ SystemProperties.set(DEFAULT_HOME,DEFAULT_HOME); }catch(Exception e){ Log.w(TAG,"exception error set DEFAULT_HOME"); } //设置默认home app,并跳转 startSelected(position, true, true); //结束此activity dismiss(); }

为了保证mAdapter被初始化 setupDefaultLauncher()的调用添加到ResolverActivity的onCreate函数中,代码如下:

protected void onCreate(Bundle savedInstanceState, Intent intent, CharSequence title, int defaultTitleRes, Intent[] initialIntents, List rList, boolean alwaysUseOption) { //其他初始化代码 ............ mIntent = new Intent(intent); mAdapter = new ResolveListAdapter(this, initialIntents, rList, mLaunchedFromUid, alwaysUseOption); //其它初始化代码 ............ if (mLaunchedFromUid < 0 || UserHandle.isIsolated(mLaunchedFromUid)) { // Gulp! finish(); return; } int count = mAdapter.mList.size(); //添加的代码 setupDefaultLauncher(); //原有逻辑 //如果系统中home app大于1 if (count > 1 || (count == 1 && mAdapter.getOtherProfile() != null)) { //初始化代码 ......... //如果home app等于1则设置唯一的home app为Home } else if (count == 1) { safelyStartActivity(mAdapter.intentForPosition(0, false)); mPackageMonitor.unregister(); mRegistered = false; finish(); return; } else { setContentView(R.layout.resolver_list); final TextView empty = (TextView) findViewById(R.id.empty); empty.setVisibility(View.VISIBLE); mListView = (ListView) findViewById(R.id.resolver_list); mListView.setVisibility(View.GONE); } //其它初始化代码 .......... }

通过以上方法即可实现设置默认home的功能



【本文地址】

公司简介

联系我们

今日新闻

    推荐新闻

    专题文章
      CopyRight 2018-2019 实验室设备网 版权所有