You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Android 13中TileService的startActivityAndCollapse无法收起快捷设置面板

解决方案

一、解决快捷设置面板无法收起的问题

方案1:通过原生中转Activity跳转

创建一个无界面的中转Activity,让快捷设置Tile先启动这个中转Activity(此时startActivityAndCollapse能正常触发面板收起逻辑),再由中转Activity启动FlutterActivity。

  1. 定义中转Activity(需设置透明主题)
class FlutterLauncherActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        // 获取Tile传递的启动参数
        val launchArgs = intent.getStringArrayListExtra("launch_args")
        // 启动目标FlutterActivity
        val flutterIntent = FlutterActivity.withNewEngine()
            .dartEntrypointArgs(launchArgs ?: emptyList())
            .build(this)
        startActivity(flutterIntent)
        finish() // 完成跳转后销毁中转Activity
    }
}
  1. 在AndroidManifest.xml中配置中转Activity
<activity
    android:name=".FlutterLauncherActivity"
    android:theme="@android:style/Theme.Translucent.NoTitleBar"
    android:exported="false"/>
  1. 修改Tile的onClick方法,启动中转Activity
override fun onClick() {
    super.onClick()
    try {
        val launcherIntent = Intent(this, FlutterLauncherActivity::class.java)
        launcherIntent.putStringArrayListExtra("launch_args", ArrayList(listOf("launchFromQuickTile")))
        launcherIntent.flags = Intent.FLAG_ACTIVITY_NEW_TASK
        startActivityAndCollapse(launcherIntent)
    } catch (e: Exception) {
        Log.d("debug", "Exception ${e.toString()}")
    }
}

方案2:手动触发快捷面板收起

在启动FlutterActivity后,调用系统API强制收起快捷设置面板,需适配不同Android版本:

override fun onClick() {
    super.onClick()
    try {
        val newIntent = FlutterActivity.withNewEngine()
            .dartEntrypointArgs(listOf("launchFromQuickTile"))
            .build(this)
        newIntent.flags = Intent.FLAG_ACTIVITY_NEW_TASK
        startActivityAndCollapse(newIntent)
        
        // 手动执行面板收起操作
        collapseQuickSettings()
    } catch (e: Exception) {
        Log.d("debug", "Exception ${e.toString()}")
    }
}

private fun collapseQuickSettings() {
    val statusBarManager = getSystemService(Context.STATUS_BAR_SERVICE) as StatusBarManager
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
        statusBarManager.collapsePanels()
    } else {
        // 低版本通过反射调用系统方法
        try {
            val method = statusBarManager.javaClass.getMethod("collapsePanels")
            method.invoke(statusBarManager)
        } catch (e: Exception) {
            Log.d("debug", "Failed to collapse panels: ${e.toString()}")
        }
    }
}

注:低版本反射调用存在一定兼容性风险,需针对目标设备范围测试验证。

二、带参数打开Flutter应用的其他方式

除了dartEntrypointArgs,还有以下两种常用实现方式:

  • 通过Intent Extra传递参数
    Android侧添加参数:

    val flutterIntent = FlutterActivity.withNewEngine().build(this)
    flutterIntent.putExtra("launch_source", "quick_tile")
    flutterIntent.putStringArrayListExtra("extra_args", ArrayList(listOf("param1", "param2")))
    

    Flutter侧通过MethodChannel获取参数:

    final MethodChannel channel = MethodChannel('com.your.pname/launch_args');
    Future<void> fetchLaunchParams() async {
      try {
        final Map<String, dynamic>? params = await channel.invokeMethod('getParams');
        if (params != null) {
          String source = params['launch_source'] ?? '';
          List<String>? args = params['extra_args']?.cast<String>();
          // 处理参数逻辑
        }
      } on PlatformException catch (e) {
        print("Params fetch failed: ${e.message}");
      }
    }
    

    需在Android的FlutterActivity子类中实现MethodChannel回调:

    class CustomFlutterActivity : FlutterActivity() {
        override fun configureFlutterEngine(flutterEngine: FlutterEngine) {
            super.configureFlutterEngine(flutterEngine)
            MethodChannel(flutterEngine.dartExecutor.binaryMessenger, "com.your.pname/launch_args")
                .setMethodCallHandler { call, result ->
                    if (call.method == "getParams") {
                        val params = hashMapOf<String, Any?>()
                        params["launch_source"] = intent.getStringExtra("launch_source")
                        params["extra_args"] = intent.getStringArrayListExtra("extra_args")
                        result.success(params)
                    } else {
                        result.notImplemented()
                    }
                }
        }
    }
    
  • 通过Deep Link传递参数
    配置Flutter的Deep Link,在AndroidManifest.xml中添加对应的intent-filter:

    <activity android:name=".CustomFlutterActivity">
        <intent-filter>
            <action android:name="android.intent.action.VIEW" />
            <category android:name="android.intent.category.DEFAULT" />
            <category android:name="android.intent.category.BROWSABLE" />
            <data android:scheme="your_app_scheme" />
        </intent-filter>
    </activity>
    

    Android侧通过带参数的Uri启动:

    val deepLinkIntent = Intent(Intent.ACTION_VIEW, Uri.parse("your_app_scheme://launch?source=quick_tile"))
    deepLinkIntent.flags = Intent.FLAG_ACTIVITY_NEW_TASK
    startActivityAndCollapse(deepLinkIntent)
    

    Flutter侧解析Uri获取参数:

    void initState() {
      super.initState();
      final uri = Uri.base;
      String? source = uri.queryParameters['source'];
      // 处理参数逻辑
    }
    

内容的提问来源于stack exchange,提问作者Pratik Butani

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.07 04:46:14