写点什么

Android 系统开发 - 选择并启动默认 Launcher,高级安卓开发技术

作者:嘟嘟侠客
  • 2021 年 11 月 27 日
  • 本文字数:1996 字

    阅读完需:约 7 分钟

//得到图标 val icon = ri.loadIcon(packageManager)//得到应用名称 val appName = ri.loadLabel(packageManager).toString()


//封装应用信息对象 val appInfo = AppInfo(icon, appName, packageName)//添加到 listlist.add(appInfo)}return list}


使用 PackageManager 提供的 queryIntentActivities 方法就可以获取所有 Launcher 应用,原生设置中也有 Activity 声明了 HOME 属性,在这里就把它屏蔽掉。


默认选择 Launcher3 应用为默认启动


private val DEFAULT_LAUNCHER = "my_default_launcher"defaultLauncher = Settings.Global.getString(contentResolver, DEFAULT_LAUNCHER)if (defaultLauncher.isNullOrEmpty()) {defaultLauncher = "com.android.launcher3"Settings.Global.putString(contentResolver, DEFAULT_LAUNCHER, defaultLauncher)}


当选择另一个应用,就把选择应用的包名设置到 Settings.Global 中。


这样应用选择页面完成,也设置了一个全局的参数提供给系统。

启动

最开始提到了 Launcher 选择弹窗,我们就考虑在这里做点事,把弹窗的逻辑给跳过,就可以实现默认启动。


弹窗源码位于frameworks/base/core/java/com/android/internal/app/ResolverActivity.java


在这里就不具体分析源码了,就看关键部分


public boolean configureContentView(List<Intent> payloadIntents, Intent[] initialIntents,List<ResolveInfo> rList, boolean alwaysUseOption) {// The last argument of createAdapter is whether to do special handling// of the last used choice to highlight it in the list. We need to always// turn this off when running under voice interaction, since it results in// a more complicated UI that the current voice interaction flow is not able// to handle.mAdapter = createAdapter(this, payloadIntents, initialIntents, rList,mLaunchedFromUid, alwaysUseOption && !isVoiceInteraction());


final int layoutId;if (mAdapter.hasFilteredItem()) {layoutId = R.layout.resolver_list_with_default;alwaysUseOption = false;} else {layoutId = getLayoutResource();}mAlwaysUseOption = alwaysUseOption;


int count = mAd


《Android 学习笔记总结+最新移动架构视频+大厂安卓面试真题+项目实战源码讲义》

【docs.qq.com/doc/DSkNLaERkbnFoS0ZF】 完整内容开源分享


apter.getUnfilteredCount();if (count == 1 && mAdapter.getOtherProfile() == null) {// Only one target, so we're a candidate to auto-launch!final TargetInfo target = mAdapter.targetInfoForPosition(0, false);if (shouldAutoLaunchSingleChoice(target)) {safelyStartActivity(target);mPackageMonitor.unregister();mRegistered = false;finish();return true;}}if (count > 0) {// add by liuwei,if set my_default_launcher,start defaultString defaultlauncher = Settings.Global.getString(this.getContentResolver(), "my_default_launcher");


final TargetInfo defaultTarget = mAdapter.targetInfoForDefault(defaultlauncher);if(defaultTarget != null){safelyStartActivity(defaultTarget);mPackageMonitor.unregister();mRegistered = false;finish();return true;}//endsetContentView(layoutId);mAdapterView = (AbsListView) findViewById(R.id.resolver_list);onPrepareAdapterView(mAdapterView, mAdapter, alwaysUseOption);} else {setContentView(R.layout.resolver_list);


final TextView empty = (TextView) findViewById(R.id.empty);empty.setVisibility(View.VISIBLE);


mAdapterView = (AbsListView) findViewById(R.id.resolver_list);mAdapterView.setVisibility(View.GONE);}return false;}


在 configureContentView 中判断 launcher 应用个数,如果为 1,则直接启动,finish 当前页面。下面判断 count>0,我们就在这里面增加自己的逻辑,获取配置的 Settings.Global 参数,再去 Adapter 中判断是否有应用包名和参数匹配,如果有就 safelyStartActivity(),关闭弹窗。如果没有匹配包名,就走正常流程,弹窗提示用户。


mAdapter.targetInfoForDefault 函数是在 public class ResolveListAdapter extends BaseAdapter中增加函数

最后

针对 Android 程序员,我这边给大家整理了一些资料,包括不限于高级 UI、性能优化、架构师课程、NDK、混合式开发(ReactNative+Weex)微信小程序、Flutter 等全方面的 Android 进阶实践技术;希望能帮助到大家,也节省大家在网上搜索资料的时间来学习,也可以分享动态给身边好友一起学习!


往期 Android 高级架构资料、源码、笔记、视频。高级 UI、性能优化、架构师课程、混合式开发(ReactNative+Weex)全方面的 Android 进阶实践技术,群内还有技术大牛一起讨论交流解决问题。




本文已被CODING开源项目:《Android学习笔记总结+移动架构视频+大厂面试真题+项目实战源码》收录

用户头像

嘟嘟侠客

关注

还未添加个人签名 2021.03.19 加入

还未添加个人简介

评论

发布
暂无评论
Android系统开发-选择并启动默认Launcher,高级安卓开发技术