当前位置: 首页 > 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)因其在大规模数据处理和复杂问题求解中的卓越表现,迅速崛起为人工智能的最前沿技术。深度学习的核心是…...

Spark 之 入门讲解详细版(1)

1、简介 1.1 Spark简介 Spark是加州大学伯克利分校AMP实验室&#xff08;Algorithms, Machines, and People Lab&#xff09;开发通用内存并行计算框架。Spark在2013年6月进入Apache成为孵化项目&#xff0c;8个月后成为Apache顶级项目&#xff0c;速度之快足见过人之处&…...

React Native在HarmonyOS 5.0阅读类应用开发中的实践

一、技术选型背景 随着HarmonyOS 5.0对Web兼容层的增强&#xff0c;React Native作为跨平台框架可通过重新编译ArkTS组件实现85%以上的代码复用率。阅读类应用具有UI复杂度低、数据流清晰的特点。 二、核心实现方案 1. 环境配置 &#xff08;1&#xff09;使用React Native…...

Python爬虫(一):爬虫伪装

一、网站防爬机制概述 在当今互联网环境中&#xff0c;具有一定规模或盈利性质的网站几乎都实施了各种防爬措施。这些措施主要分为两大类&#xff1a; 身份验证机制&#xff1a;直接将未经授权的爬虫阻挡在外反爬技术体系&#xff1a;通过各种技术手段增加爬虫获取数据的难度…...

蓝桥杯3498 01串的熵

问题描述 对于一个长度为 23333333的 01 串, 如果其信息熵为 11625907.5798&#xff0c; 且 0 出现次数比 1 少, 那么这个 01 串中 0 出现了多少次? #include<iostream> #include<cmath> using namespace std;int n 23333333;int main() {//枚举 0 出现的次数//因…...

C# 表达式和运算符(求值顺序)

求值顺序 表达式可以由许多嵌套的子表达式构成。子表达式的求值顺序可以使表达式的最终值发生 变化。 例如&#xff0c;已知表达式3*52&#xff0c;依照子表达式的求值顺序&#xff0c;有两种可能的结果&#xff0c;如图9-3所示。 如果乘法先执行&#xff0c;结果是17。如果5…...

Cilium动手实验室: 精通之旅---13.Cilium LoadBalancer IPAM and L2 Service Announcement

Cilium动手实验室: 精通之旅---13.Cilium LoadBalancer IPAM and L2 Service Announcement 1. LAB环境2. L2公告策略2.1 部署Death Star2.2 访问服务2.3 部署L2公告策略2.4 服务宣告 3. 可视化 ARP 流量3.1 部署新服务3.2 准备可视化3.3 再次请求 4. 自动IPAM4.1 IPAM Pool4.2 …...

uniapp 集成腾讯云 IM 富媒体消息(地理位置/文件)

UniApp 集成腾讯云 IM 富媒体消息全攻略&#xff08;地理位置/文件&#xff09; 一、功能实现原理 腾讯云 IM 通过 消息扩展机制 支持富媒体类型&#xff0c;核心实现方式&#xff1a; 标准消息类型&#xff1a;直接使用 SDK 内置类型&#xff08;文件、图片等&#xff09;自…...

WEB3全栈开发——面试专业技能点P4数据库

一、mysql2 原生驱动及其连接机制 概念介绍 mysql2 是 Node.js 环境中广泛使用的 MySQL 客户端库&#xff0c;基于 mysql 库改进而来&#xff0c;具有更好的性能、Promise 支持、流式查询、二进制数据处理能力等。 主要特点&#xff1a; 支持 Promise / async-await&#xf…...

【2D与3D SLAM中的扫描匹配算法全面解析】

引言 扫描匹配(Scan Matching)是同步定位与地图构建(SLAM)系统中的核心组件&#xff0c;它通过对齐连续的传感器观测数据来估计机器人的运动。本文将深入探讨2D和3D SLAM中的各种扫描匹配算法&#xff0c;包括数学原理、实现细节以及实际应用中的性能对比&#xff0c;特别关注…...

RFID推动新能源汽车零部件生产系统管理应用案例

RFID推动新能源汽车零部件生产系统管理应用案例 一、项目背景 新能源汽车零部件场景 在新能源汽车零部件生产领域&#xff0c;电子冷却水泵等关键部件的装配溯源需求日益增长。传统 RFID 溯源方案采用 “网关 RFID 读写头” 模式&#xff0c;存在单点位单独头溯源、网关布线…...