Skip to content

[quick_actions_android] initialize() throws quick_action_getlaunchaction_no_activity when the engine has no attached Activity #190348

Closed
flutter/packages
#12331

Description

@Sembauke

Steps to reproduce

QuickActionsAndroid.initialize() throws PlatformException(quick_action_getlaunchaction_no_activity) whenever main() runs in a FlutterEngine that has no Activity attached. Apps cannot prevent this, because initialize() calls getLaunchAction() unconditionally.

The easiest real-world trigger is a cached engine shared with a background service. audio_service is a common example: its AudioServiceActivity supplies a cached engine via AudioServicePlugin.getFlutterEngine(), and AudioService.onCreate() warms up that same engine. So the process, and main() with it, starts with no Activity at all when the service is started headlessly by a media button, a Bluetooth device, or Android Auto binding the MediaBrowserService.

Minimal reproduction using the app in this repo's quick_actions example plus audio_service:

  1. Set the launcher activity to com.ryanheise.audioservice.AudioServiceActivity in AndroidManifest.xml.
  2. Call QuickActions().initialize(...) in main().
  3. Start the audio service without any UI:
    adb shell am start-foreground-service -n <package>/com.ryanheise.audioservice.AudioService
    
    (on API < 26, adb shell am startservice)

I reproduced this on Android 12 (API 31), Android 8.0 (API 26) and Android 16 (API 36) emulators. API 24 is unaffected, since isVersionAllowed() returns null before the activity check.

A second trigger exists without any background service: because a cached engine outlives its activity, the Dart isolate keeps running after the activity detaches, so getLaunchAction() can be reached with activity == null if the activity is destroyed while main() is still awaiting.

Expected results

initialize() completes and reports no launch action. "There is no Activity, therefore nothing launched this app via a shortcut" is a legitimate state with an obvious correct answer: null.

Actual results

initialize() throws:

PlatformException(quick_action_getlaunchaction_no_activity, There is no activity available when launching action, null, null)
#0  AndroidQuickActionsApi.getLaunchAction (package:quick_actions_android/src/messages.g.dart:123:7)
#1  QuickActionsAndroid.initialize (package:quick_actions_android/quick_actions_android.dart:34:28)

Why I think this should return null rather than throw

QuickActions.java#L104-L109 (still present at main, unchanged since before the Pigeon conversion in #5099):

if (activity == null) {
  throw new FlutterError(
      "quick_action_getlaunchaction_no_activity",
      "There is no activity available when launching action",
      null);
}
  1. The throw provides no recovery value. When an Activity later attaches, QuickActionsPlugin.onAttachedToActivity() calls onNewIntent(activity.getIntent()), which reports the shortcut through AndroidQuickActionsFlutterApi.launchAction(). And initialize() registers the Dart handler before it calls getLaunchAction(), so the handler is already installed when the exception is thrown. I verified on-device that swallowing the exception loses nothing: the shortcut is still delivered correctly. The throw only converts a recoverable state into an app-visible error.

  2. null is already the established idiom in this method for "cannot answer": if (!isVersionAllowed()) { return null; } on the line above.

  3. Callers have no way to check first. There is no hasActivity-style API, so the only remedy available to apps is a try/catch on a magic error-code string around initialize(), in every app that could ever run engine-first.

  4. This is not app misuse. Cached and pre-warmed engines are a supported Flutter pattern (FlutterEngineCache, FlutterEngineGroup), and [quick_actions] start event is reported twice with pre-warmed FlutterEngine #89615 is another known quick_actions issue in the same pre-warmed-engine area.

I'd suggest logging a warning and returning null, so a genuinely misconfigured launcher activity (per the README note about #152883) stays diagnosable in logcat without being fatal to the caller. Happy to open a PR along those lines.

Code sample

Code sample
// Runs when the engine is warmed up by a background service, with no Activity attached.
Future<void> main() async {
  WidgetsFlutterBinding.ensureInitialized();
  runApp(const MyApp());

  // Throws PlatformException(quick_action_getlaunchaction_no_activity).
  await const QuickActions().initialize((type) => debugPrint(type));
}

Logs

Logs
E flutter : [ERROR:flutter/runtime/dart_vm_initializer.cc(40)] Unhandled Exception: PlatformException(quick_action_getlaunchaction_no_activity, There is no activity available when launching action, null, null)
E flutter : #0      AndroidQuickActionsApi.getLaunchAction (package:quick_actions_android/src/messages.g.dart:123:7)
E flutter : <asynchronous suspension>
E flutter : #1      QuickActionsAndroid.initialize (package:quick_actions_android/quick_actions_android.dart:34:28)
E flutter : <asynchronous suspension>

Flutter Doctor output

Doctor output
[✓] Flutter (Channel stable, 3.44.2, on Ubuntu 26.04 LTS 7.0.0-28-generic, locale en_US.UTF-8)
[✓] Android toolchain - develop for Android devices (Android SDK version 36.1.0)

Reproduced with quick_actions 1.1.0 / quick_actions_android 1.0.21 and again on
quick_actions_android 1.0.32 (latest).

Activity

  1. mbcorona commented on Jul 31, 2026

    @mbcorona
    Member

    Hi @Sembauke , thanks for the detailed report and the proposed fix.
    Routing to the Android team for evaluation.

  2. added
    c: crashStack traces logged to the console
    team-androidOwned by Android platform team
    on Jul 31, 2026
  3. added
    P2Important issues not at the top of the work list
    triaged-androidTriaged by Android platform team
    on Aug 4, 2026
  4. added a commit that references this issue on Oct 6, 2026
    c840e38
  5. github-actions commented on Oct 20, 2026

    @github-actions

    This thread has been automatically locked since there has not been any recent activity after it was closed. If you are still experiencing a similar issue, please open a new bug, including the output of flutter doctor -v and a minimal reproduction of the issue.

  6. locked as resolved and limited conversation to collaborators on Oct 20, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    P2Important issues not at the top of the work listc: crashStack traces logged to the consolefound in release: 3.44Found to occur in 3.44p: quick_actionsQuickActions pluginpackageflutter/packages repository. See also p: labels.platform-androidAndroid applications specificallyteam-androidOwned by Android platform teamtriaged-androidTriaged by Android platform team

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions