马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。
您需要 登录 才可以下载或查看,没有账号?立即注册
x
目录
第一部分、android10之前
一.多个launcher 启动设置默认launcher的核心类
二 在自定义服务里面设置默认Launcher
第二部分、android10之后
一、Launcher应用内置并设置为默认Launcher
1.通过ResolverActivity.java设置为默认Launcher
改法一:
改法二:
2.通过ActivityManagerService.java设置为默认Launcher主要修改getHomeIntent(),将其替换成必要默认的Launcher即可。
改法一(常规):
改法二(简化):
二、普通应用内置并设置为默认Launcher
1.欺压替换
2.添加属性
Android11之前的
在Android系统中,设置默认Launcher(启动器)是一个涉及系统权限和配置的过程。通常,这个过程不是通过简单地修改几个文件或设置就能完成的,由于它必要系统级别的权限。不过,我可以概述一下在Android源码级别如何设置或答应用户选择默认Launcher的大抵步调。
第一部分、android10之前
一.多个launcher 启动设置默认launcher的核心类
代码路径:frameworks/base/core/java/com/android/internal/app/ResolverActivity.java
2.多个launcher 启动设置默认launcher的核心功能实现和分析
通过在系统中内置其他Launcher时,在系统进入启动Launcher的过程中,会在ResolverActivity.java中,首先查询系统中由几个Launcher,当有多个Launcher时,会让用户选择启动的Launcher,然后作为默认启动Launcher. 以是就来分析该怎么设置默认Launcher,而不用用户选择启动Launcher.
先来看下ResolverActivity.java的相关源码
- @UiThread
- public class ResolverActivity extends Activity {
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- // Use a specialized prompt when we're handling the 'Home' app startActivity()
- final Intent intent = makeMyIntent();
- final Set<String> categories = intent.getCategories();
- if (Intent.ACTION_MAIN.equals(intent.getAction())
- && categories != null
- && categories.size() == 1
- && categories.contains(Intent.CATEGORY_HOME)) {
- // Note: this field is not set to true in the compatibility version.
- mResolvingHome = true;
- }
-
- setSafeForwardingMode(true);
-
- onCreate(savedInstanceState, intent, null, 0, null, null, true);
- }
-
- /**
- * Compatibility version for other bundled services that use this overload without
- * a default title resource
- */
- @UnsupportedAppUsage
- protected void onCreate(Bundle savedInstanceState, Intent intent,
- CharSequence title, Intent[] initialIntents,
- List<ResolveInfo> rList, boolean supportsAlwaysUseOption) {
- onCreate(savedInstanceState, intent, title, 0, initialIntents, rList,
- supportsAlwaysUseOption);
- }
-
- protected void onCreate(Bundle savedInstanceState, Intent intent,
- CharSequence title, int defaultTitleRes, Intent[] initialIntents,
- List<ResolveInfo> rList, boolean supportsAlwaysUseOption) {
- setTheme(R.style.Theme_DeviceDefault_Resolver);
- super.onCreate(savedInstanceState);
-
- // Determine whether we should show that intent is forwarded
- // from managed profile to owner or other way around.
- setProfileSwitchMessageId(intent.getContentUserHint());
-
- try {
- mLaunchedFromUid = ActivityTaskManager.getService().getLaunchedFromUid(
- getActivityToken());
- } catch (RemoteException e) {
- mLaunchedFromUid = -1;
- }
-
- if (mLaunchedFromUid < 0 || UserHandle.isIsolated(mLaunchedFromUid)) {
- // Gulp!
- finish();
- return;
- }
-
- mPm = getPackageManager();
-
- mPackageMonitor.register(this, getMainLooper(), false);
- mRegistered = true;
- mReferrerPackage = getReferrerPackageName();
-
- final ActivityManager am = (ActivityManager) getSystemService(ACTIVITY_SERVICE);
- mIconDpi = am.getLauncherLargeIconDensity();
-
- // Add our initial intent as the first item, regardless of what else has already been added.
- mIntents.add(0, new Intent(intent));
- mTitle = title;
- mDefaultTitleResId = defaultTitleRes;
-
- mUseLayoutForBrowsables = getTargetIntent() == null
- ? false
- : isHttpSchemeAndViewAction(getTargetIntent());
-
- mSupportsAlwaysUseOption = supportsAlwaysUseOption;
-
- if (configureContentView(mIntents, initialIntents, rList)) {
- return;
- }
-
- final ResolverDrawerLayout rdl = findViewById(R.id.contentPanel);
- if (rdl != null) {
- rdl.setOnDismissedListener(new ResolverDrawerLayout.OnDismissedListener() {
- @Override
- public void onDismissed() {
- finish();
- }
- });
- if (isVoiceInteraction()) {
- rdl.setCollapsed(false);
- }
-
- rdl.setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
- | View.SYSTEM_UI_FLAG_LAYOUT_STABLE);
- rdl.setOnApplyWindowInsetsListener(this::onApplyWindowInsets);
-
- mResolverDrawerLayout = rdl;
- }
-
- mProfileView = findViewById(R.id.profile_button);
- if (mProfileView != null) {
- mProfileView.setOnClickListener(this::onProfileClick);
- bindProfileView();
- }
-
- initSuspendedColorMatrix();
-
- if (isVoiceInteraction()) {
- onSetupVoiceInteraction();
- }
- final Set<String> categories = intent.getCategories();
- MetricsLogger.action(this, mAdapter.hasFilteredItem()
- ? MetricsProto.MetricsEvent.ACTION_SHOW_APP_DISAMBIG_APP_FEATURED
- : MetricsProto.MetricsEvent.ACTION_SHOW_APP_DISAMBIG_NONE_FEATURED,
- intent.getAction() + ":" + intent.getType() + ":"
- + (categories != null ? Arrays.toString(categories.toArray()) : ""));
- }
复制代码 在ResolverActivity.java中的onCreate中首先读取系统中的Home属性的Launcher列表,然后在
ResolveListAdapter中展示Launcher的列表,以是可以在这些直接设置默认的Launcher,然后finish掉这个页面,直接进入默认Launcher页面
具体修改为:
- --- a/frameworks/base/core/java/com/android/internal/app/ResolverActivity.java
- +++ b/frameworks/base/core/java/com/android/internal/app/ResolverActivity.java
- @@ -278,9 +278,53 @@ public class ResolverActivity extends Activity {
- intent.setFlags(intent.getFlags()&~Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
- return intent;
- }
- -
- + private void setDefaultLauncher(String defPackageName,String defClassName) {
- + if ((defPackageName != null && defPackageName.trim().length() > 1) && (defClassName != null && defClassName.trim().length() > 0)) {
- + IntentFilter filter = new IntentFilter();
- + filter.addAction("android.intent.action.MAIN");
- + filter.addCategory("android.intent.category.HOME");
- + filter.addCategory("android.intent.category.DEFAULT");
- +
- + Intent intent=new Intent(Intent.ACTION_MAIN);
- + intent.addCategory(Intent.CATEGORY_HOME);
- + List<ResolveInfo> list = new ArrayList<ResolveInfo>();
- + list = getPackageManager().queryIntentActivities(intent, 0);
- + final int N = list.size();
- + ComponentName[] set = new ComponentName[N];
- + int bestMatch = 0;
- + for (int i=0; i<N; i++) {
- + ResolveInfo r = list.get(i);
- + set[i] = new ComponentName(r.activityInfo.packageName,
- + r.activityInfo.name);
- + if (r.match > bestMatch) bestMatch = r.match;
- + }
- + ComponentName preActivity = new ComponentName(defPackageName, defClassName);
- + getPackageManager().addPreferredActivity(filter, bestMatch, set,preActivity);
- + }
- + }
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- + boolean firstBoot = (Settings.Global.getInt(getApplication().getContentResolver(),
- + "default_home_launcher", 0) == 0);
- + String defPackageName = Settings.Global.getString(getContentResolver(),"launcher_pkgname");
- + String defClassName = Settings.Global.getString(getContentResolver(),"launcher_classname");
- + Log.e(TAG,"pkgname:"+defPackageName+"---defClassName:"+defClassName);
- + if(firstBoot &&!TextUtils.isEmpty(defPackageName)){
- + try {
- + setDefaultLauncher(defPackageName,defClassName);
- + Intent defIntent = new Intent();
- + defIntent.setClassName(defPackageName, defClassName);
- + defIntent.setAction("android.intent.action.MAIN");
- + defIntent.addCategory("android.intent.category.HOME");
- + defIntent.addCategory("android.intent.category.DEFAULT");
- + startActivity(defIntent);
- + Settings.Global.putInt(getApplication().getContentResolver(),
- + "default_home_launcher",1);
- + this.finish();
- + } catch (Exception e) {
- + e.printStackTrace();
- + }
- + }
- ActivityDebugConfigs.addConfigChangedListener(mDebugConfigListener);
-
- // Use a specialized prompt when we're handling the 'Home' app startActivity()
- @@ -1291,7 +1335,6 @@ public class ResolverActivity extends Activity {
- setContentView(mLayoutId);
复制代码 在onCreate中的增长setDefaultLauncher(String defPackageName,String defClassName)这个设置默认Launcher的方法,而PM的addPreferredActivity设置默认Launcher,就实现了功能
二 在自定义服务里面设置默认Launcher
- public class MdmManagerService extends IMdmManager.Stub {
- private static String TAG ="MdmManagerService";
- private Context mContext;
- private Handler mHandler = new Handler(Looper.getMainLooper());
- public MdmManagerService(Context context){
- this.mContext = context;
- mHandler.postDelayed(mRunnable, 0);
- //IntentFilter mintent=new IntentFilter("com.sprd.settings.action.apistart");
- //mContext.registerReceiver(mBroadcastReceiver,mintent);
- }
- private BroadcastReceiver mBroadcastReceiver =new BroadcastReceiver() {
- @Override
- public void onReceive(Context context, Intent intent) {
- Log.e(TAG,"action");
- //mHandler.postDelayed(mRunnable, 500);
- }
- };
- private Runnable mRunnable = new Runnable() {
- @Override
- public void run() {
- Log.e(TAG, "actionRun");
- try {
- //setStatusBarExpandPanelDisabled(true);
- String defaultLauncher = SystemProperties.get("persist.sys.ployer.default.launcher", "");
- if(TextUtils.isEmpty(defaultLauncher)){
- setDefaultLauncher("com.android.launcher3", "com.android.launcher3.Launcher");
- //setDefaultLauncher("com.ployer.interfacedemo", "com.ployer.interfacedemo.MainActivity");
- }
- } catch (Exception e) {
- e.printStackTrace();
- }
- }
- };
- private void setDefaultApplication(String roleName, String packageName) {
- RoleManager roleManager = mContext.getSystemService(RoleManager.class);
- Executor executor = mContext.getMainExecutor();
- Consumer<Boolean> callback = successful -> {
- if (successful) {
- Log.e(TAG, "setDefaultApplication packageName:"+packageName+" successful");
- }
- };
- roleManager.addRoleHolderAsUser(roleName, packageName, 0, android.os.Process.myUserHandle(), executor, callback);
- }
- public void setDefaultLauncher(String packageName, String className) throws RemoteException {
- Log.e(TAG, "setDefaultLauncher:packageName="+packageName+"--className:"+className);
- final long ident = Binder.clearCallingIdentity();
- try {
- if (isPkgInstalled(mContext, packageName)) {
- Settings.Global.putString(mContext.getContentResolver(),"launcher_pkgname",packageName);
- Settings.Global.putString(mContext.getContentResolver(),"launcher_classname",className);
- String value = packageName + "/" + className;
- SystemProperties.set("persist.sys.ployer.default.launcher", value);
- setDefaultApplication("android.app.role.HOME",packageName);
- } else {
- Log.e(TAG, "setDefaultLauncher packageName is not exist");
- }
- } catch (Exception e) {
- e.printStackTrace();
- }finally {
- Binder.restoreCallingIdentity(ident);
- }
- }
- private boolean isPkgInstalled(Context context, String packageName) {
- if (packageName == null || "".equals(packageName))
- return false;
- ApplicationInfo info = null;
- try {
- info = context.getPackageManager().getApplicationInfo(packageName, 0);
- return info != null;
- } catch (Exception e) {
- Log.e(TAG, "apk is not installed packageName:" + packageName);
- return false;
- }
- }
复制代码
第二部分、android10之后
一、Launcher应用内置并设置为默认Launcher
主要使用ResolverActivity.java或ActivityManagerService.java来实现,接下来我将分别举例阐明:
1.通过ResolverActivity.java设置为默认Launcher
主要是由addPreferredActivity设置默认Launcher实现。
改法一:
代码路径:frameworks/base/core/java/com/android/internal/app/ResolverActivity.java
以下基于Android11代码:
- protected void onCreate(Bundle savedInstanceState, Intent intent,
- CharSequence title, int defaultTitleRes, Intent[] initialIntents,
- List<ResolveInfo> rList, boolean supportsAlwaysUseOption) {
- setTheme(appliedThemeResId());
- super.onCreate(savedInstanceState);
-
- //add
- if(mResolvingHome){
- setDefaultLauncher();
- finish();
- return;
- }
- //add
- ...
- }
-
-
- private void setDefaultLauncher() {
- try {
- final PackageManager pm = getPackageManager();
- String defPackageName = "com.android.launcher3";//默认launcher包名
- String defClassName = "com.android.searchlauncher.SearchLauncher";//默认launcher类名
- IntentFilter filter = new IntentFilter();
- filter.addAction("android.intent.action.MAIN");
- filter.addCategory("android.intent.category.HOME");
- filter.addCategory("android.intent.category.DEFAULT");
- Intent intent = new Intent(Intent.ACTION_MAIN);
- intent.addCategory(Intent.CATEGORY_HOME);
- List<ResolveInfo> list = new ArrayList<ResolveInfo>();
- list = pm.queryIntentActivities(intent, 0);
- final int N = list.size();
- ComponentName[] set = new ComponentName[N];
- int bestMatch = 0;
- for (int i = 0; i < N; i++) {
- ResolveInfo r = list.get(i);
- set[i] = new ComponentName(r.activityInfo.packageName,
- r.activityInfo.name);
- if (r.match > bestMatch) bestMatch = r.match;
- }
- ComponentName preActivity = new ComponentName(defPackageName, defClassName);
- pm.addPreferredActivity(filter, bestMatch, set, preActivity);
-
- } catch (Exception e) {
- e.printStackTrace();
- }
-
- }
复制代码 改法二:
代码路径:frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java
- boolean startHomeActivityLocked(int userId, String reason) {
- setDefaultLauncher();//调用设置默认launcher方法
- SystemProperties.set("persist.sys.boot.bootcomplete","1");
- if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
- && mTopAction == null) {
- // We are running in factory test mode, but unable to find
- // the factory test app, so just sit around displaying the
- // error message and don't try to start anything.
- return false;
- }
-
- ...
- ...
- }
-
-
- private void setDefaultLauncher() {
- boolean mFirstLaunch = true;
- String packageName = "包名";//launcher包名
- String className = "类名";
- if ((packageName != null && packageName.trim().length() > 1) && (className != null && className.trim().length() > 0)) {
- if(mFirstLaunch){
- IPackageManager pm = ActivityThread.getPackageManager();
- ArrayList<IntentFilter> intentList = new ArrayList<IntentFilter>();
- ArrayList<ComponentName> cnList = new ArrayList<ComponentName>();
- mContext.getPackageManager().getPreferredActivities(intentList, cnList, null);
- IntentFilter dhIF;
- for(int i = 0; i < cnList.size(); i++){
- dhIF = intentList.get(i);
- if(dhIF.hasAction(Intent.ACTION_MAIN) &&
- dhIF.hasCategory(Intent.CATEGORY_HOME)) {
- mContext.getPackageManager().clearPackagePreferredActivities(cnList.get(i).getPackageName());
- }
- }
- Intent intent = new Intent(Intent.ACTION_MAIN);
- intent.addCategory(Intent.CATEGORY_HOME);
- List<ResolveInfo> list = new ArrayList<ResolveInfo>();
- try {
- list = pm.queryIntentActivities(intent,
- intent.resolveTypeIfNeeded(mContext.getContentResolver()),
- PackageManager.MATCH_DEFAULT_ONLY,UserHandle.getCallingUserId()).getList(); //add .getList()
- }catch (RemoteException e) {
- throw new RuntimeException("Package manager has died", e);
- }
- IntentFilter filter = new IntentFilter();
- filter.addAction(Intent.ACTION_MAIN);
- filter.addCategory(Intent.CATEGORY_HOME);
- filter.addCategory(Intent.CATEGORY_DEFAULT);
- final int N = list.size();
- ComponentName[] set = new ComponentName[N];
- int bestMatch = 0;
- for (int i = 0; i < N; i++)
- {
- ResolveInfo r = list.get(i);
- set[i] = new ComponentName(r.activityInfo.packageName,
- r.activityInfo.name);
- if (r.match > bestMatch) bestMatch = r.match;
- }
- ComponentName launcher = new ComponentName(packageName, className);
- try{
- pm.addPreferredActivity(filter, bestMatch, set, launcher,UserHandle.getCallingUserId());
- } catch (RemoteException e) {
- throw new RuntimeException("Package manager has died", e);
- }
- }
- }
- }
复制代码 2.通过ActivityManagerService.java设置为默认Launcher
主要修改getHomeIntent(),将其替换成必要默认的Launcher即可。
代码路径:frameworks\base\services\core\java\com\android\server\am\ActivityManagerService.java
改法一(常规):
- Intent getHomeIntent() {
- //add
- Settings.Global.putInt(mContext.getContentResolver(), Settings.Global.DEVICE_PROVISIONED, 1);
- Settings.Secure.putInt(mContext.getContentResolver(), Settings.Secure.USER_SETUP_COMPLETE, 1);
- String defStartPkg = "你的包名";
- Intent queryIntent = new Intent();
- final PackageManager mPm = mContext.getPackageManager();
- queryIntent.addCategory(Intent.CATEGORY_HOME);///没有home可去掉
- queryIntent.addCategory(Intent.CATEGORY_LAUNCHER);
- queryIntent.setAction(Intent.ACTION_MAIN);
- List<ResolveInfo> homeActivities = mPm.queryIntentActivities(queryIntent, 0);
- if(homeActivities != null) {
- int activityNum = homeActivities.size();
- ComponentName[] set = new ComponentName[activityNum];
- for(int i = 0; i < activityNum; i++){
- ResolveInfo info = homeActivities.get(i);
- set[i] = new ComponentName(info.activityInfo.packageName, info.activityInfo.name);
- if(defStartPkg.equals(info.activityInfo.packageName)){
- Intent intentaa = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null);
- intentaa.setComponent(set[i]);
- intentaa.addCategory(Intent.CATEGORY_HOME);
- return intentaa;
- }
- }
- }
- //add
- Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null);
- intent.setComponent(mTopComponent);
- if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
- intent.addCategory(Intent.CATEGORY_HOME);
- }
- return intent;
- }
复制代码 改法二(简化):
- Intent getHomeIntent() {
- Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null);
- //add
- //intent.setComponent(mTopComponent);
- intent.setComponent(new ComponentName("包名", "类名"));
- //add
- intent.addFlags(Intent.FLAG_DEBUG_TRIAGED_MISSING);
- if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
- intent.addCategory(Intent.CATEGORY_HOME);
- }
- return intent;
- }
复制代码 二、普通应用内置并设置为默认Launcher
由于这类应用通常没有android.intent.category.HOME这个Category,故无法使用上述常规方式来设置为默认应用,使用必要我们另辟蹊径,这边也是为各位提供两种方法。
1.欺压替换
首先将应用设置为默认开机启动,但由于没有android.intent.category.HOME这个Category以是提供通过ResolverActivity.java设置是不行的,必要通过修改ActivityManagerService.java来实现,只要把改法一中的queryIntent.addCategory(Intent.CATEGORY_HOME);注释掉即可:
- Intent getHomeIntent() {
- //add
- Settings.Global.putInt(mContext.getContentResolver(), Settings.Global.DEVICE_PROVISIONED, 1);
- Settings.Secure.putInt(mContext.getContentResolver(), Settings.Secure.USER_SETUP_COMPLETE, 1);
- String defStartPkg = "你的包名";
- Intent queryIntent = new Intent();
- final PackageManager mPm = mContext.getPackageManager();
- //queryIntent.addCategory(Intent.CATEGORY_HOME);///没有home可去掉
- queryIntent.addCategory(Intent.CATEGORY_LAUNCHER);
- queryIntent.setAction(Intent.ACTION_MAIN);
- List<ResolveInfo> homeActivities = mPm.queryIntentActivities(queryIntent, 0);
- if(homeActivities != null) {
- int activityNum = homeActivities.size();
- ComponentName[] set = new ComponentName[activityNum];
- for(int i = 0; i < activityNum; i++){
- ResolveInfo info = homeActivities.get(i);
- set[i] = new ComponentName(info.activityInfo.packageName, info.activityInfo.name);
- if(defStartPkg.equals(info.activityInfo.packageName)){
- Intent intentaa = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null);
- intentaa.setComponent(set[i]);
- intentaa.addCategory(Intent.CATEGORY_HOME);
- return intentaa;
- }
- }
- }
- //add
- Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null);
- intent.setComponent(mTopComponent);
- if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
- intent.addCategory(Intent.CATEGORY_HOME);
- }
- return intent;
- }
复制代码 通过上面的修改就可以开机默认启动了,但是会出现按home、recent、back键会退出应用从而进入原生Launcher的情况,以是我们必要对这些按键进行拦截定制:
代码路径:frameworks/base/services/core/java/com/android/server/policy/PhoneWindowManager.java
- mHomeIntent = new Intent(Intent.ACTION_MAIN, null);
- mHomeIntent.addCategory(Intent.CATEGORY_HOME);
- //add
- ComponentName mHomecom = new ComponentName("包名", "类名");
- mHomeIntent.setComponent(mHomecom);
- //add
- mHomeIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK
- | Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED);
-
- @Override
- public long interceptKeyBeforeDispatching(WindowState win, KeyEvent event, int policyFlags) {
- ....
- ....
- //add
- if(keyCode == KeyEvent.KEYCODE_BACK){ if(getClsName(mContext).equals("com.ryanheise.audioservice.AudioServiceFragmentActivity")
- &&(getInputMethodWindowVisibleHeightLw()==0)){
- return -1;
- }
- }
- //add
- ....
- ....
- }
-
- private String getClsName(Context context) {
- try {
- ActivityManager am = context.getSystemService(ActivityManager.class);
- List<ActivityManager.RunningTaskInfo> tasks = am.getRunningTasks(1);
- return tasks.get(0).topActivity.getClassName();
- } catch (Exception e) {
- //ignore
- }
- return "";
- }
复制代码 代码路径:SystemUI\src\com\android\systemui\recents\RecentsActivity.java
- import android.content.ComponentName;
-
- Intent homeIntent = new Intent(Intent.ACTION_MAIN, null);
- homeIntent.addCategory(Intent.CATEGORY_HOME);
- ComponentName mHomecom = new ComponentName("包名", "类名");
- homeIntent.setComponent(mHomecom);
- homeIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK |
- Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED);
复制代码 2.添加属性
Android11开始的
android11开始谷歌对pms的分析部分做了一些重构和优化,将一些类和方法从PackageManagerService和PackageParser中分离出来,放到了parsing包和component包下,路径为:frameworks/base/core/java/android/content/pm/
以是我们要修改的文件为frameworks/base/core/java/android/content/pm/parsing/component/ParsedActivityUtils.java
-
- @NonNull
- private static ParseResult<ParsedActivity> parseActivityOrAlias(ParsedActivity activity,
- ParsingPackage pkg, String tag, XmlResourceParser parser, Resources resources,
- TypedArray array, boolean isReceiver, boolean isAlias, boolean visibleToEphemeral,
- ParseInput input, int parentActivityNameAttr, int permissionAttr,
- int exportedAttr) throws IOException, XmlPullParserException {
- String parentActivityName = array.getNonConfigurationString(parentActivityNameAttr, Configuration.NATIVE_CONFIG_VERSION);
- if (parentActivityName != null) {
- String packageName = pkg.getPackageName();
- String parentClassName = ParsingUtils.buildClassName(packageName, parentActivityName);
- if (parentClassName == null) {
- Log.e(TAG, "Activity " + activity.getName()
- + " specified invalid parentActivityName " + parentActivityName);
- } else {
- activity.setParentActivity(parentClassName);
- }
- }
-
- String permission = array.getNonConfigurationString(permissionAttr, 0);
- if (isAlias) {
- // An alias will override permissions to allow referencing an Activity through its alias
- // without needing the original permission. If an alias needs the same permission,
- // it must be re-declared.
- activity.setPermission(permission);
- } else {
- activity.setPermission(permission != null ? permission : pkg.getPermission());
- }
-
- final boolean setExported = array.hasValue(exportedAttr);
- if (setExported) {
- activity.exported = array.getBoolean(exportedAttr, false);
- }
-
- final int depth = parser.getDepth();
- int type;
- while ((type = parser.next()) != XmlPullParser.END_DOCUMENT
- && (type != XmlPullParser.END_TAG
- || parser.getDepth() > depth)) {
- if (type != XmlPullParser.START_TAG) {
- continue;
- }
-
- final ParseResult result;
- if (parser.getName().equals("intent-filter")) {
- ParseResult<ParsedIntentInfo> intentResult = parseIntentFilter(pkg, activity,
- !isReceiver, visibleToEphemeral, resources, parser, input);
- if (intentResult.isSuccess()) {
- ParsedIntentInfo intent = intentResult.getResult();
- if (intent != null) {
- activity.order = Math.max(intent.getOrder(), activity.order);
-
- //add core start
- if ("类名".equals(activity.getName())) {
- intent.addCategory("android.intent.category.HOME");
- intent.addCategory("android.intent.category.DEFAULT");
- intent.setPriority(1000);
- }
- //add core end
-
- activity.addIntent(intent);
- if (PackageParser.LOG_UNSAFE_BROADCASTS && isReceiver
- && pkg.getTargetSdkVersion() >= Build.VERSION_CODES.O) {
- int actionCount = intent.countActions();
- for (int i = 0; i < actionCount; i++) {
- final String action = intent.getAction(i);
- if (action == null || !action.startsWith("android.")) {
- continue;
- }
-
- if (!PackageParser.SAFE_BROADCASTS.contains(action)) {
- Slog.w(TAG,
- "Broadcast " + action + " may never be delivered to "
- + pkg.getPackageName() + " as requested at: "
- + parser.getPositionDescription());
- }
- }
- }
- }
- }
- result = intentResult;
- } else if (parser.getName().equals("meta-data")) {
- result = ParsedComponentUtils.addMetaData(activity, pkg, resources, parser, input);
- } else if (!isReceiver && !isAlias && parser.getName().equals("preferred")) {
- ParseResult<ParsedIntentInfo> intentResult = parseIntentFilter(pkg, activity,
- true /*allowImplicitEphemeralVisibility*/, visibleToEphemeral,
- resources, parser, input);
- if (intentResult.isSuccess()) {
- ParsedIntentInfo intent = intentResult.getResult();
- if (intent != null) {
- pkg.addPreferredActivityFilter(activity.getClassName(), intent);
- }
- }
- result = intentResult;
- } else if (!isReceiver && !isAlias && parser.getName().equals("layout")) {
- ParseResult<ActivityInfo.WindowLayout> layoutResult = parseLayout(resources, parser,
- input);
- if (layoutResult.isSuccess()) {
- activity.windowLayout = layoutResult.getResult();
- }
- result = layoutResult;
- } else {
- result = ParsingUtils.unknownTag(tag, pkg, parser, input);
- }
-
- if (result.isError()) {
- return input.error(result);
- }
- }
-
- ParseResult<ActivityInfo.WindowLayout> layoutResult = resolveWindowLayout(activity, input);
- if (layoutResult.isError()) {
- return input.error(layoutResult);
- }
- activity.windowLayout = layoutResult.getResult();
-
- if (!setExported) {
- activity.exported = activity.getIntents().size() > 0;
- }
-
- return input.success(activity);
- }
复制代码 Android11之前的
Android11之前修改的文件为:
frameworks\base\core\java\android\content\pm\PackageParser.java
- private Activity parseActivityAlias(Package owner, Resources res,
- XmlPullParser parser, AttributeSet attrs, int flags, String[] outError)
- throws XmlPullParserException, IOException {
- TypedArray sa = res.obtainAttributes(attrs,
- com.android.internal.R.styleable.AndroidManifestActivityAlias);
-
- ...
- ...
- 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;
- }
-
- if (parser.getName().equals("intent-filter")) {
- ActivityIntentInfo intent = new ActivityIntentInfo(a);
- if (!parseIntent(res, parser, attrs, true, true, intent, outError)) {
- return null;
- }
- //add
- android.util.Log.e("hqb","a.info.name="+a.info.name);
- android.util.Log.e("hqb","a.info.parentActivityName="+a.info.parentActivityName);
- if(a.info.name.equals("类名")){
- intent.addCategory("android.intent.category.HOME");
- intent.addCategory("android.intent.category.DEFAULT");
- intent.setPriority(1000);
- }
- //add
- if (intent.countActions() == 0) {
- Slog.w(TAG, "No actions in intent filter at "
- + mArchiveSourcePath + " "
- + parser.getPositionDescription());
- } else {
- a.intents.add(intent);
- }
- } else if (parser.getName().equals("meta-data")) {
- if ((a.metaData=parseMetaData(res, parser, attrs, a.metaData,
- outError)) == null) {
- return null;
- }
- }
- ...
- ...
- }
复制代码
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。 |