当前位置: 首页 > news >正文

Android 源码多个Launcher设置默认Launcher

目录

第一部分、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的相关源码

 @UiThreadpublic class ResolverActivity extends Activity {  @Overrideprotected 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*/@UnsupportedAppUsageprotected 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() {@Overridepublic 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);
+        }
+    }@Overrideprotected 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() {@Overridepublic void onReceive(Context context, Intent intent) {Log.e(TAG,"action");//mHandler.postDelayed(mRunnable, 500);}};private Runnable mRunnable = new Runnable() {@Overridepublic 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);//addif(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() {
//addSettings.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;}}}
//addIntent 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("包名", "类名"));//addintent.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() {
//addSettings.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;}}}
//addIntent 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);
//addComponentName mHomecom = new ComponentName("包名", "类名"); mHomeIntent.setComponent(mHomecom);
//addmHomeIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK| Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED); @Overridepublic 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

 @NonNullprivate 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 startif ("类名".equals(activity.getName()))  {intent.addCategory("android.intent.category.HOME");intent.addCategory("android.intent.category.DEFAULT");intent.setPriority(1000);}
//add core endactivity.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;}
//addandroid.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);}
//addif (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;}} ...... }

相关文章:

Android 源码多个Launcher设置默认Launcher

目录 第一部分、android10之前 一.多个launcher 启动设置默认launcher的核心类 二 在自定义服务里面设置默认Launcher 第二部分、android10之后 一、Launcher应用内置并设置为默认Launcher 1.通过ResolverActivity.java设置为默认Launcher 改法一&#xff1a; 改法二&am…...

计算机毕业设计 网上体育商城系统 Java+SpringBoot+Vue 前后端分离 文档报告 代码讲解 安装调试

&#x1f34a;作者&#xff1a;计算机编程-吉哥 &#x1f34a;简介&#xff1a;专业从事JavaWeb程序开发&#xff0c;微信小程序开发&#xff0c;定制化项目、 源码、代码讲解、文档撰写、ppt制作。做自己喜欢的事&#xff0c;生活就是快乐的。 &#x1f34a;心愿&#xff1a;点…...

深度学习中实验、观察与思考的方法与技巧

在深度学习中&#xff0c;实验、观察与思考是理解和改进模型性能的关键环节。以下是一些有效的方法与技巧&#xff0c;可以帮助你在深度学习实践中系统性地开展实验、分析结果并进行深入思考&#xff1a; 1. 明确实验目标 在开始实验前&#xff0c;确保对实验的目标有清晰的定…...

记一次 FastDFS 存储节点迁移:基于 scp 的实践与经验分享

一、背景 某某项目&#xff0c;机房到期&#xff0c;需要迁移至其他机房&#xff1b; 此项目已经运行了3年多&#xff0c;fastdfs累计数据大概在250G 左右&#xff0c;现需要把旧的fastdfs数据迁移到新的fastdfs上&#xff1b; 采用scp物理迁移数据的方式&#xff0c;停机迁移…...

http连接github远程仓库密码问题解决办法

目录 一、问题&#xff1a;使用http连接失败 二、解决办法&#xff1a;使用个人访问令牌。 1、生成访问令牌&#xff1a; 步骤 1: 登录 GitHub 步骤 2: 进入设置页面 步骤 3: 生成新的访问令牌 步骤 4: 配置访问令牌 步骤 5: 复制令牌 2. 使用访问令牌 一、问题&#…...

LAMP环境下项目部署

目录 目录 1、创建一台虚拟机 centos 源的配置 备份源 修改源 重新加载缓存 安装软件 2、关闭防火墙和selinux 查看防火墙状态 关闭防火墙 查看SELinux的状态 临时关闭SELinux 永久关闭SELinux&#xff1a;编辑SELinux的配置文件 配置文件的修改内容 3、检查系统…...

Visual Studio 2022从外部引入dll导致的问题

这里以我学MapGIS二次开发的一个小demo为例 一、如何引入dll 1、在解决方案资源管理器中&#xff0c;有个引用的选项 2、然后右键点击添加引用 点击之后会出现如下&#xff1a; 3、点击浏览选项&#xff0c;选择想要引入dll的路径&#xff0c;这里我选择下载MapGIS 10的路径 …...

大模型从失败中学习 —— 微调大模型以提升Agent性能

人工智能咨询培训老师叶梓 转载标明出处 以往的研究在微调LLMs作为Agent时&#xff0c;通常只使用成功的交互轨迹&#xff0c;而丢弃了未完成任务的轨迹。这不仅造成了数据和资源的浪费&#xff0c;也可能限制了微调过程中可能的优化路径。论文《Learning From Failure: Integ…...

10.web应用体系以及windows网络常见操作应用

一、Dos命令 1.启动方式&#xff1a;winR&#xff0c;输入cmd 2.切换盘符/路径&#xff1a;盘符名称&#xff1a; &#xff08;C:) cd 目录 &#xff08;cd B111&#xff09;&#xff08;目录名按table键自动补全&#xff09; 3.查看目录&#xff1a;dir dir /p 分页展示目录及…...

【数据结构与算法 | 灵神题单 | 前后指针(链表)篇】力扣19, 61,1721

1. 力扣19&#xff1a;删除链表的倒数第N个节点 1.1 题目&#xff1a; 给你一个链表&#xff0c;删除链表的倒数第 n 个结点&#xff0c;并且返回链表的头结点。 示例 1&#xff1a; 输入&#xff1a;head [1,2,3,4,5], n 2 输出&#xff1a;[1,2,3,5]示例 2&#xff1a; …...

机器学习之实战篇——MNIST手写数字0~9识别(全连接神经网络模型)

机器学习之实战篇——Mnist手写数字0~9识别&#xff08;全连接神经网络模型&#xff09; 文章传送MNIST数据集介绍&#xff1a;实验过程实验环境导入模块导入MNIST数据集创建神经网络模型进行训练&#xff0c;测试&#xff0c;评估模型优化 文章传送 机器学习之监督学习&#…...

ICLR2024: 大视觉语言模型中对象幻觉的分析和缓解

https://arxiv.org/pdf/2310.00754 https://github.com/YiyangZhou/LURE 背景 对象幻觉&#xff1a;生成包含图像中实际不存在的对象的描述 早期的工作试图通过跨不同模式执行细粒度对齐&#xff08;Biten et al.&#xff0c;2022&#xff09;或通过数据增强减少对象共现模…...

数据库系统 第54节 数据库优化器

数据库优化器是数据库管理系统&#xff08;DBMS&#xff09;中的一个关键组件&#xff0c;它的作用是分析用户的查询请求&#xff0c;并生成一个高效的执行计划。这个执行计划定义了如何访问数据和执行操作&#xff0c;以最小化查询的执行时间和资源消耗。以下是数据库优化器的…...

微服务杂谈

几个概念 还是第一次听说Spring Cloud Alibaba &#xff0c;真是孤陋寡闻了&#xff0c;以前只知道 SpringCloud 是为了搭建微服务的&#xff0c;spring boot 则是快速创建一个项目&#xff0c;也可以是一个微服务 。那么SpringCloud 和 Spring boot 有什么区别呢&#xff1f;S…...

【Pandas操作2】groupby函数、pivot_table函数、数据运算(map和apply)、重复值清洗、异常值清洗、缺失值处理

1 数据清洗 #### 概述数据清洗是指对原始数据进行处理和转换&#xff0c;以去除无效、重复、缺失或错误的数据&#xff0c;使数据符合分析的要求。#### 作用和意义- 提高数据质量&#xff1a;- 通过数据清洗&#xff0c;数据质量得到提升&#xff0c;减少错误分析和错误决策。…...

如何分辨IP地址是否能够正常使用

在互联网的日常使用中&#xff0c;无论是进行网络测试、网站访问、数据抓取还是远程访问&#xff0c;一个正常工作的IP地址都是必不可少的。然而&#xff0c;由于各种原因&#xff0c;IP地址可能无法正常使用&#xff0c;如被封禁、网络连接问题或配置错误等。本文将详细介绍如…...

Sqoop 数据迁移

Sqoop 数据迁移 一、Sqoop 概述二、Sqoop 优势三、Sqoop 的架构与工作机制四、Sqoop Import 流程五、Sqoop Export 流程六、Sqoop 安装部署6.1 下载解压6.2 修改 Sqoop 配置文件6.3 配置 Sqoop 环境变量6.4 添加 MySQL 驱动包6.5 测试运行 Sqoop6.5.1 查看Sqoop命令语法6.5.2 测…...

【数据结构】排序算法系列——希尔排序(附源码+图解)

希尔排序 算法思想 希尔排序&#xff08;Shell Sort&#xff09;是一种改进的插入排序算法&#xff0c;希尔排序的创造者Donald Shell想出了这个极具创造力的改进。其时间复杂度取决于步长序列&#xff08;gap&#xff09;的选择。我们在插入排序中&#xff0c;会发现是对整体…...

c++(继承、模板进阶)

一、模板进阶 1、非类型模板参数 模板参数分类类型形参与非类型形参。 类型形参即&#xff1a;出现在模板参数列表中&#xff0c;跟在class或者typename之类的参数类型名称。 非类型形参&#xff0c;就是用一个常量作为类(函数)模板的一个参数&#xff0c;在类(函数)模板中…...

【机器学习】从零开始理解深度学习——揭开神经网络的神秘面纱

1. 引言 随着技术的飞速发展,人工智能(AI)已从学术研究的实验室走向现实应用的舞台,成为推动现代社会变革的核心动力之一。而在这一进程中,深度学习(Deep Learning)因其在大规模数据处理和复杂问题求解中的卓越表现,迅速崛起为人工智能的最前沿技术。深度学习的核心是…...

WebLogic 笔记汇总

WebLogic 笔记汇总 一、weblogic安装 1、创建用户和用户组 groupadd weblogicuseradd -g weblogic weblogic # 添加用户,并用-g参数来制定 web用户组passwd weblogic # passwd命令修改密码# 在文件末尾增加以下内容 cat >>/etc/security/limits.conf<<EOF web…...

leetcode:2710. 移除字符串中的尾随零(python3解法)

难度&#xff1a;简单 给你一个用字符串表示的正整数 num &#xff0c;请你以字符串形式返回不含尾随零的整数 num 。 示例 1&#xff1a; 输入&#xff1a;num "51230100" 输出&#xff1a;"512301" 解释&#xff1a;整数 "51230100" 有 2 个尾…...

Python GUI入门详解-学习篇

一、简介 GUI就是图形用户界面的意思&#xff0c;在Python中使用PyQt可以快速搭建自己的应用&#xff0c;自己的程序看上去就会更加高大上。 有时候使用 python 做自动化运维操作&#xff0c;开发一个简单的应用程序非常方便。程序写好&#xff0c;每次都要通过命令行运行 pyt…...

QT5实现https的post请求(QNetworkAccessManager、QNetworkRequest和QNetworkReply)

QT5实现https的post请求 前言一、一定要有sslErrors处理1、问题经过2、代码示例 二、要利用抓包工具1、问题经过2、wireshark的使用3、利用wireshark查看服务器地址4、利用wireshark查看自己构建的请求报文 三、返回数据只能读一次1、问题描述2、部分代码 总结 前言 QNetworkA…...

vscode 使用git bash,路径分隔符缺少问题

window使用bash --login -i 使用bash时候&#xff0c;在系统自带的terminal里面进入&#xff0c;测试conda可以正常输出&#xff0c;但是在vscode里面输入conda发现有问题 bash: C:\Users\marswennaconda3\Scripts: No such file or directory实际路径应该要为 C:\Users\mars…...

F12抓包10:UI自动化 - Elements(元素)定位页面元素

​课程大纲 1、前端基础 1.1 元素 元素是构成HTML文档的基本组成部分之一&#xff0c;定义了文档的结构和内容&#xff0c;比如段落、标题、链接等。 元素大致分为3种&#xff1a;基本结构、自闭合元素&#xff08;self-closing element&#xff09;、嵌套元素。 1、基本结构&…...

android 删除系统原有的debug.keystore,系统运行的时候,重新生成新的debug.keystore,来完成App的运行。

1、先上一个图&#xff1a;这个是keystore无效的原因 之前在安装这个旧版本android studio的时候呢&#xff0c;安装过一版最新的android studio&#xff0c;然后通过模拟器跑过测试的demo。 2、运行旧的项目到模拟器的时候&#xff0c;就报错了&#xff1a; Execution failed…...

SQL入门题

作者SQL入门小白&#xff0c;此栏仅是记录一些解题过程 1、题目 用户访问表users&#xff0c;记录了用户id&#xff08;usr_id&#xff09;和访问日期&#xff08;log_date&#xff09;,求出连续3天以上访问的用户id。 2、解答过程 2.1数据准备 通过navicat创建数据&#xf…...

Python实战:实战练习案例汇总

Python实战&#xff1a;实战练习案例汇总 **Python世界系列****Python实践系列****Python语音处理系列** 本文逆序更新&#xff0c;汇总实践练习案例。 Python世界系列 Python世界&#xff1a;力扣题43大数相乘算法实践Python世界&#xff1a;求解满足某完全平方关系的整数实…...

zabbix之钉钉告警

钉钉告警设置 我们可以将同一个运維组的人员加入到同一个钉钉工作群中&#xff0c;当有异常出现后&#xff0c;Zabbix 将告警信息发送到钉钉的群里面&#xff0c;此时&#xff0c;群内所有的运维人员都能在第一时间看到这则告警详细。 Zabbix 监控系统默认没有开箱即用…...