masterfabric_flutter_quick_actions

A Flutter plugin for iOS Quick Actions (3D Touch/Haptic Touch) and Android App Shortcuts. This plugin provides a unified API to create and handle quick actions on both platforms.

Repository: https://github.com/gurkanfikretgunak/masterfabric_flutter_quick_actions

Screenshots

Quick Actions Demo

Usage Example

Platform Comparison

Features

  • Cross-platform support: Unified API for iOS and Android
  • Dynamic shortcuts: Update shortcuts at runtime
  • Easy integration: Simple API to set up quick actions in your app
  • Platform-specific features:
    • iOS: System icon types support
    • Android: Pinned shortcuts support (Android 8.0+)
  • Action handling: Stream-based and callback-based handling

Platform Support

  • iOS: 12.0+ (Quick Actions require iOS 9+, but plugin supports iOS 12.0+)
  • Android: API level 21+ (App Shortcuts require API 25+, but app can run on lower versions)

Getting Started

Installation

Add this to your package's pubspec.yaml file:

dependencies:
  masterfabric_flutter_quick_actions: ^0.0.4

For local development, you can use the package from your local path:

dependencies:
  masterfabric_flutter_quick_actions:
    path: ../path/to/masterfabric_flutter_quick_actions

Or from GitHub:

dependencies:
  masterfabric_flutter_quick_actions:
    git:
      url: https://github.com/gurkanfikretgunak/masterfabric_flutter_quick_actions.git

iOS Setup

No additional setup required. The plugin automatically registers with Flutter.

Android Setup

No additional setup required. The plugin automatically registers with Flutter.

Note: For Android shortcuts to work, ensure your app's main activity can handle intents. The plugin uses Intent.ACTION_VIEW with a package-specific intent.

Usage

Basic Usage

Initialize quick actions in your main() function:

import 'package:flutter/material.dart';
import 'package:masterfabric_flutter_quick_actions/masterfabric_flutter_quick_actions.dart';

void main() async {
  WidgetsFlutterBinding.ensureInitialized();
  
  await QuickActionsManager.initialize(
    actions: [
      QuickAction(
        type: 'search',
        title: 'Search',
        subtitle: 'Find items quickly',
        iconType: 'UIApplicationShortcutIconTypeSearch', // iOS
        iconName: 'ic_search', // Android drawable resource
      ),
      QuickAction(
        type: 'compose',
        title: 'New Message',
        subtitle: 'Start a conversation',
        iconType: 'UIApplicationShortcutIconTypeCompose', // iOS
        iconName: 'ic_compose', // Android drawable resource
      ),
    ],
    onAction: (action) {
      debugPrint('Quick action triggered: ${action.type}');
      // Handle the action
      switch (action.type) {
        case 'search':
          // Navigate to search screen
          break;
        case 'compose':
          // Navigate to compose screen
          break;
      }
    },
  );

  runApp(const MyApp());
}

Dynamic Updates

Update shortcuts dynamically based on app state:

await QuickActionsManager.setActions([
  QuickAction(
    type: 'recent_chat_${chatId}',
    title: contact.name,
    subtitle: 'Continue conversation',
    iconType: 'UIApplicationShortcutIconTypeMessage',
    iconName: 'ic_chat',
    userInfo: {'chatId': chatId},
  ),
]);

Clear Actions

Remove all dynamic shortcuts:

await QuickActionsManager.clearActions();

Pinned Shortcuts (Android Only)

Request to pin a shortcut on Android 8.0+:

import 'dart:io';

if (Platform.isAndroid) {
  final pinned = await QuickActionsManager.requestPinShortcut(
    QuickAction(
      type: 'pinned_feature',
      title: 'Quick Access',
      iconName: 'ic_pin',
    ),
  );
  
  if (pinned) {
    debugPrint('Shortcut pinned successfully');
  }
}

Handling Launch Actions

Check if the app was launched via a quick action (useful for restoring state):

// In your app's initState or main()
final launchAction = await QuickActionsManager.getLaunchAction();
if (launchAction != null) {
  debugPrint('App launched via quick action: ${launchAction.type}');
  // Navigate to the appropriate screen or restore state
  switch (launchAction.type) {
    case 'search':
      // Navigate to search screen
      break;
    case 'compose':
      // Navigate to compose screen
      break;
  }
}

Using the Action Stream

Listen to quick action events (for actions triggered while app is running):

QuickActionsManager.actionStream.listen((action) {
  debugPrint('Quick action triggered: ${action.type}');
  // Handle the action
});

Note: The initialize() callback handles launch actions automatically, but you can also use getLaunchAction() for more control over state restoration.

Icon Configuration

iOS Icons

iOS uses system icon types. Available icon types include:

  • UIApplicationShortcutIconTypeCompose
  • UIApplicationShortcutIconTypePlay
  • UIApplicationShortcutIconTypePause
  • UIApplicationShortcutIconTypeAdd
  • UIApplicationShortcutIconTypeLocation
  • UIApplicationShortcutIconTypeSearch
  • UIApplicationShortcutIconTypeShare
  • UIApplicationShortcutIconTypeContact
  • UIApplicationShortcutIconTypeHome
  • UIApplicationShortcutIconTypeFavorite
  • UIApplicationShortcutIconTypeLove
  • UIApplicationShortcutIconTypeMail
  • UIApplicationShortcutIconTypeMessage
  • UIApplicationShortcutIconTypeDate
  • UIApplicationShortcutIconTypeTime
  • UIApplicationShortcutIconTypeCapturePhoto
  • UIApplicationShortcutIconTypeCaptureVideo
  • UIApplicationShortcutIconTypeTask
  • UIApplicationShortcutIconTypeTaskCompleted
  • UIApplicationShortcutIconTypeAlarm
  • UIApplicationShortcutIconTypeBookmark
  • UIApplicationShortcutIconTypeShuffle
  • UIApplicationShortcutIconTypeAudio
  • UIApplicationShortcutIconTypeUpdate

And more. See the iOS documentation for the complete list.

Android Icons

Android uses drawable resources. Place your icon files in android/app/src/main/res/drawable/ and reference them by name (without extension):

QuickAction(
  type: 'search',
  title: 'Search',
  iconName: 'ic_search', // References res/drawable/ic_search.xml or ic_search.png
)

Note: For Android 8.0+, use adaptive icons for best results.

Platform Differences

Feature iOS Android
Max shortcuts 4 4 static + 4 dynamic (varies by launcher)
Icon source System types Drawable resources
Static definition Info.plist res/xml/shortcuts.xml
API level iOS 9+ Android 7.1+ (API 25)
Pinned shortcuts ❌ Not available ✅ Supported (Android 8.0+)
Shortcut categories ❌ Not available ✅ Supported
Disabled message ❌ Not available ✅ Supported

Limitations

  • Maximum shortcuts: Both platforms support up to 4 shortcuts, though Android may vary by launcher
  • Testing: Quick actions can only be tested on real devices (not simulators/emulators)
  • Launcher support: Not all Android launchers support shortcuts equally
  • iOS: Requires a device with 3D Touch or Haptic Touch support

API Reference

QuickAction

Model class representing a quick action.

const QuickAction({
  required String type,           // Unique identifier
  required String title,          // Display title
  String? subtitle,               // Optional subtitle
  String? iconName,               // Android drawable resource name
  String? iconType,               // iOS system icon type
  Map<String, dynamic>? userInfo, // Additional data
})

QuickActionsManager

High-level API for managing quick actions.

Methods

  • initialize({required List<QuickAction> actions, required void Function(QuickAction) onAction}): Initialize quick actions
  • getLaunchAction(): Get the quick action that launched the app (returns null if not launched via quick action)
  • setActions(List<QuickAction> actions): Update dynamic shortcuts
  • clearActions(): Clear all dynamic shortcuts
  • requestPinShortcut(QuickAction action): Request to pin a shortcut (Android only)
  • dispose(): Clean up resources

Properties

  • actionStream: Stream of quick action events

Contributing

Contributions are welcome! Please feel free to submit a Pull Request.

GitHub Repository: https://github.com/gurkanfikretgunak/masterfabric_flutter_quick_actions

License

See the LICENSE file for details.

Additional Resources