Launcher start App WINDOWING_MODE_FREEFORM
1.Android 11 -- 强制清理app后台,关于权限引发的问题2.Android 11 (MTK)状态栏图标反色-->跟随当前应用变化代码流程3.Android 11 --关于Toast的异常4.Android 11 -- 关于dialog和悬浮窗导致SystemUI状态栏下拉频繁闪烁(窗口焦点问题)5.Android 11 下拉菜单长按WiFi图标SystemUI ANR6.Android 11 sim卡来电不弹出悬浮通知,默认来电默认全屏7.Android Bluetooth 蓝牙开发/蓝牙协议 小结8.Android11 —— 自定义添加一个System Services9.Android系统——AOSP相关-->随记10.Android11 , Launcher3 切换阿拉伯语,最近应用(后台)不能滑动11.Android 底层问题日志记录12.Android 11 -- app 服务保活13.Android11 - 添加自定义服务注意事项14.Android 11 导航栏添加一个虚拟按钮--问题合集15.Android 11--设置第三方Launcher并默认 与 如何预置apk16.Android11 系统修改 AOSP输入法的默认输入键盘布局17.Settings里面切换不同Launcher的代码流程18.关于Android`系统默认屏保`19.关于Android 11 Settings添加新的选项界面的细节20.Android 11 自由窗口模式 || 全屏模式启动app21.强制app横屏显示或者竖屏显示(动态)22.Android 11 禁止从SD卡上安装第三方应用23.实体物理音量键替换为home键24.AMS- kill Launcher进程的代码流程25.Android 11 recovery恢复出厂设置保留某些文件26.Android 11 禁用 adb root (userdebug版本)27.Android11 应用默认获取通知使用权限(可以获取系统所有通知信息)28.Android 11 UsbDebug 关于adb RSA 认证29.Android 11 NavigationBar && Status Bar 如果改变背景颜色30.Anroid 11 关于NotificationManager && NotificationManagerService -- 衍生到权限管理31.Android13 控制设置界面 双栏显示或单栏显示32.Android 13 大屏显示时关于SystemUI和Launcher3问题33.Android 系统适配无源码app34.Android 11 关于app的权限重置35.Android 11.0 关于app进程保活36.Android 11 关于按键拦截/按键事件处理分享37.Android R Settings关于屏保/PowerManagerService欺骗系统不让其进入休眠状态38.Android13 关于SystemUI更新/Nav Bar add volume button&&other button39.Android 13 移植EthernetSettings/Ethernet更新40.Anrdoir 13 关于设置静态IP后,突然断电,在上电开机卡动画41.Android T(13) The app is granted permissions by default42.Android T 关于屏幕旋转 (一)43.Android T about screen rotation(二)44.Android 13 about launcher3 (1)45.Android T don't abort background activity starts46.Android T adout replace bootanimation
47.Launcher start App WINDOWING_MODE_FREEFORM
48.Android 11 About SleepToken / (Settings)Screen timeout49.Settings.System数据监听/prop&SystemProperties数据监听WINDOWING_MODE_FREEFORM start App
核心思路:
这个windowmode需要从FullScreen ---> Freeform,
需要在startActivity时候携带相关相关参数,把windowmode和launchBounds进行设置。
Android T
+++ b/frameworks/base/core/java/android/app/Instrumentation.java
@@ -1798,6 +1798,7 @@ public class Instrumentation {
public ActivityResult execStartActivity(
Context who, IBinder contextThread, IBinder token, Activity target,
Intent intent, int requestCode, Bundle options) {
+ android.util.Log.d("tag",Log.getStackTraceString(new Throwable()));
IApplicationThread whoThread = (IApplicationThread) contextThread;
Uri referrer = target != null ? target.onProvideReferrer() : null;
if (referrer != null) {
//打印堆栈,查看一下堆栈,清晰看见整个startActivity的过程
//清楚知道在哪里启动的onClick且一步步到对应的startActivity...,这里寻找最贴近context的startActivity...
java.lang.Throwable
at android.app.Instrumentation.execStartActivity(Instrumentation.java:1801)
at android.app.Activity.startActivityForResult(Activity.java:5522)
at com.android.launcher3.Launcher.startActivityForResult(Launcher.java:1895)
at com.android.launcher3.uioverrides.QuickstepLauncher.startActivityForResult(QuickstepLauncher.java:833)
at android.app.Activity.startActivity(Activity.java:5974)
at com.android.launcher3.views.ActivityContext.startActivitySafely(ActivityContext.java:356)
at com.android.launcher3.Launcher.startActivitySafely(Launcher.java:2259)
at com.android.launcher3.uioverrides.QuickstepLauncher.startActivitySafely(QuickstepLauncher.java:348)
at com.android.launcher3.touch.ItemClickHandler.startAppShortcutOrInfoActivity(ItemClickHandler.java:351)
at com.android.launcher3.touch.ItemClickHandler.onClickAppShortcut(ItemClickHandler.java:309)
at com.android.launcher3.touch.ItemClickHandler.onClick(ItemClickHandler.java:94)
at com.android.launcher3.touch.ItemClickHandler.$r8$lambda$c3IcSovkrXGdCZtXy0f_A5Sz5VA(Unknown Source:0)
at com.android.launcher3.touch.ItemClickHandler$$ExternalSyntheticLambda6.onClick(Unknown Source:0)
at com.android.launcher3.uioverrides.QuickstepLauncher.onItemClicked(QuickstepLauncher.java:387)
at com.android.launcher3.uioverrides.QuickstepLauncher$$ExternalSyntheticLambda9.onClick(Unknown Source:2)
at android.view.View.performClick(View.java:7542)
at android.view.View.performClickInternal(View.java:7519)
at android.view.View.-$$Nest$mperformClickInternal(Unknown Source:0)
at android.view.View$PerformClick.run(View.java:29476)
at android.os.Handler.handleCallback(Handler.java:942)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loopOnce(Looper.java:201)
at android.os.Looper.loop(Looper.java:288)
at android.app.ActivityThread.main(ActivityThread.java:7924)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:548)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:936)
+++ b/packages/apps/Launcher3/src/com/android/launcher3/views/ActivityContext.java
default boolean startActivitySafely(
View v, Intent intent, @Nullable ItemInfo item) {
Preconditions.assertUIThread();
Context context = (Context) this;
...
try {
boolean isShortcut = (item instanceof WorkspaceItemInfo)
&& (item.itemType == LauncherSettings.Favorites.ITEM_TYPE_SHORTCUT
|| item.itemType == LauncherSettings.Favorites.ITEM_TYPE_DEEP_SHORTCUT)
&& !((WorkspaceItemInfo) item).isPromise();
if (isShortcut) {
// Shortcuts need some special checks due to legacy reasons.
startShortcutIntentSafely(intent, optsBundle, item);
} else if (user == null || user.equals(Process.myUserHandle())) {
// Could be launching some bookkeeping activity
//add text
Log.e("tag", "WINDOWING_MODE_FREEFORM launcher");
ActivityOptions activityOptions = ActivityOptions.makeBasic();
activityOptions.setLaunchWindowingMode(WINDOWING_MODE_FREEFORM);
final Rect rect = new Rect(0, 0, 480, (int) (480 * 0.5f));
activityOptions.setLaunchBounds(rect);
context.startActivity(intent, activityOptions.toBundle());
//context.startActivity(intent, optsBundle);
//add text
} else {
context.getSystemService(LauncherApps.class).startMainActivity(
intent.getComponent(), user, intent.getSourceBounds(), optsBundle);
}
...
}
补充:
如果发现修改无效,检查是否打开系统的自由窗口模式
adb shell settings put global enable_freeform_support 1
adb shell settings put global force_resizable_activities 1
或者
开发者模式下开启小窗功能,开发者模式下打开如下两个开关,然后重启即可.
Android13深入了解 Android 小窗口模式和窗口类型
copy
参考
FLAG_ACTIVITY_RESET_TASK_IF_NEEDED
public static final int FLAG_ACTIVITY_RESET_TASK_IF_NEEDED = 0x00200000;
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED);
//如果没有新的,就会new 一个新的TASK,如果存在旧的TASK,使用旧的TASK(正在启动的Activity的Task已经在运行的话,那么新的Activity将不会启动)
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 一个费力不讨好的项目,让我损失了近一半的绩效!
· 实操Deepseek接入个人知识库
· CSnakes vs Python.NET:高效嵌入与灵活互通的跨语言方案对比
· 【.NET】调用本地 Deepseek 模型
· Plotly.NET 一个为 .NET 打造的强大开源交互式图表库