app_links 6.3.3  app_links: ^6.3.3 copied to clipboard
app_links: ^6.3.3 copied to clipboard
Android App Links, Deep Links, iOs Universal Links and Custom URL schemes handler for Flutter (desktop included).
example/lib/main.dart
import 'dart:async';
import 'package:app_links/app_links.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'url_protocol/api.dart';
///////////////////////////////////////////////////////////////////////////////
/// Please make sure to follow the setup instructions below
///
/// Please take a look at:
/// - example/android/app/main/AndroidManifest.xml for Android.
///
/// - example/ios/Runner/Runner.entitlements for Universal Link sample.
/// - example/ios/Runner/Info.plist for Custom URL scheme sample.
///
/// You can launch an intent on an Android Emulator like this:
///    adb shell am start -a android.intent.action.VIEW \
///     -d "sample://open.my.app/#/book/hello-world"
///
///
/// On windows & macOS:
///   The simplest way to test it is by
///   opening your browser and type: sample://foo/#/book/hello-world2
///
/// On windows:
/// Outside of a browser, in a email for example, you can use:
/// https://example.com/#/book/hello-world2
///////////////////////////////////////////////////////////////////////////////
const kWindowsScheme = 'sample';
void main() {
  // Register our protocol only on Windows platform
  // registerProtocolHandler(kWindowsScheme);
  runApp(const MyApp());
}
class MyApp extends StatefulWidget {
  const MyApp({Key? key}) : super(key: key);
  @override
  State<MyApp> createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
  final _navigatorKey = GlobalKey<NavigatorState>();
  late AppLinks _appLinks;
  StreamSubscription<Uri>? _linkSubscription;
  @override
  void initState() {
    super.initState();
    initDeepLinks();
  }
  @override
  void dispose() {
    _linkSubscription?.cancel();
    super.dispose();
  }
  Future<void> initDeepLinks() async {
    _appLinks = AppLinks();
    // Handle links
    _linkSubscription = _appLinks.uriLinkStream.listen((uri) {
      debugPrint('onAppLink: $uri');
      openAppLink(uri);
    });
  }
  void openAppLink(Uri uri) {
    _navigatorKey.currentState?.pushNamed(uri.fragment);
  }
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      navigatorKey: _navigatorKey,
      initialRoute: "/",
      onGenerateRoute: (RouteSettings settings) {
        Widget routeWidget = defaultScreen();
        // Mimic web routing
        final routeName = settings.name;
        if (routeName != null) {
          if (routeName.startsWith('/book/')) {
            // Navigated to /book/:id
            routeWidget = customScreen(
              routeName.substring(routeName.indexOf('/book/')),
            );
          } else if (routeName == '/book') {
            // Navigated to /book without other parameters
            routeWidget = customScreen("None");
          }
        }
        return MaterialPageRoute(
          builder: (context) => routeWidget,
          settings: settings,
          fullscreenDialog: true,
        );
      },
    );
  }
  Widget defaultScreen() {
    return Scaffold(
      appBar: AppBar(title: const Text('Default Screen')),
      body: Center(
        child: Column(
          mainAxisSize: MainAxisSize.min,
          children: [
            const SelectableText('''
            Launch an intent to get to the second screen.
            On web:
            http://localhost:<port>/#/book/1 for example.
            On windows & macOS, open your browser:
            sample://foo/#/book/hello-deep-linking
            This example code triggers new page from URL fragment.
            '''),
            const SizedBox(height: 20),
            buildWindowsUnregisterBtn(),
          ],
        ),
      ),
    );
  }
  Widget customScreen(String bookId) {
    return Scaffold(
      appBar: AppBar(title: const Text('Second Screen')),
      body: Center(child: Text('Opened with parameter: $bookId')),
    );
  }
  Widget buildWindowsUnregisterBtn() {
    if (defaultTargetPlatform == TargetPlatform.windows) {
      return TextButton(
          onPressed: () => unregisterProtocolHandler(kWindowsScheme),
          child: const Text('Remove Windows protocol registration'));
    }
    return const SizedBox.shrink();
  }
}