目录
一.多个launcher 启动设置默认launcher的核心类
1.通过ResolverActivity.java设置为默认Launcher
2.通过ActivityManagerService.java设置为默认Launcher主要修改getHomeIntent(),将其替换成需要默认的Launcher即可。
在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;
}
}
...
...
}