app_links 3.3.0 icon indicating copy to clipboard operation
app_links: ^3.3.0 copied to clipboard

Android App Links, Deep Links, iOs Universal Links and Custom URL schemes handler for Flutter (desktop included).

example/lib/main.dart

// ignore_for_file: avoid_print

import 'dart:async';
import 'dart:io';

import 'package:app_links/app_links.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'web_url_protocol.dart'
    if (dart.library.io) 'package:url_protocol/url_protocol.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 \
//     -c android.intent.category.BROWSABLE \
//     -d "https://www.example.com/#/book/hello-world"
///
/// On windows & macOS:
///   The simpliest way to test it is by
///   opening your browser and type: sample://foo/#/book/hello-world2
///////////////////////////////////////////////////////////////////////////////

const kWindowsScheme = 'sample';

void main() {
  // Register our protocol only on Windows platform
  _registerWindowsProtocol();

  runApp(const MyApp());
}

class MyApp extends StatefulWidget {
  const MyApp({Key? key}) : super(key: key);

  @override
  _MyAppState 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();

    // Check initial link if app was in cold state (terminated)
    final appLink = await _appLinks.getInitialAppLink();
    if (appLink != null) {
      print('getInitialAppLink: $appLink');
      openAppLink(appLink);
    }

    // Handle link when app is in warm state (front or background)
    _linkSubscription = _appLinks.uriLinkStream.listen((uri) {
      print('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 (!kIsWeb) {
      if (Platform.isWindows) {
        return TextButton(
            onPressed: () => unregisterProtocolHandler(kWindowsScheme),
            child: const Text('Remove Windows protocol registration'));
      }
    }

    return const SizedBox.shrink();
  }
}

void _registerWindowsProtocol() {
  // Register our protocol only on Windows platform
  if (!kIsWeb) {
    if (Platform.isWindows) {
      registerProtocolHandler(kWindowsScheme);
    }
  }
}
150
likes
140
pub points
97%
popularity

Publisher

verified publisher iconopenapi4j.org

Android App Links, Deep Links, iOs Universal Links and Custom URL schemes handler for Flutter (desktop included).

Repository (GitHub)

Documentation

API reference

License

Icon for licenses.Apache-2.0 (LICENSE)

Dependencies

app_links_macos, app_links_platform_interface, app_links_web, app_links_windows, flutter

More

Packages that depend on app_links