---
slug: "flutter-android-applinks-app-start-with-keystore-codesign"
title: "Building an Android App with Flutter and Enabling App Launch from https:// URLs Using AppLinks"
description: "Make AppLinks (launching the app from an https:// URL) work for a Flutter Android build — keystore signing, getting the SHA256 fingerprint, and Digital Asset Links setup."
url: "https://www.ytyng.com/en/blog/flutter-android-applinks-app-start-with-keystore-codesign"
publish_date: "2021-12-26T13:14:51Z"
created: "2021-12-26T13:14:51Z"
updated: "2026-05-11T13:06:14.337Z"
categories: ["Android", "Flutter"]
keywords: ""
featured_image_url: "https://media.ytyng.com/resize/20230812/dc02bb3dc04a4ba7a4494c66e5869f64.png.webp?width=768"
has_video: false
has_music: false
video_urls: []
music_urls: []
lang: "en"
---

# Building an Android App with Flutter and Enabling App Launch from https:// URLs Using AppLinks

<p>Android's AppLinks is a feature that launches an app when transitioning to an https:// URL in Android's Chrome, provided the URL matches a specified pattern. Unlike traditional Deep Links, AppLinks uses app signatures to determine the app, allowing you to securely pass information only to specific apps that are controlled within the domain.</p>
<p>This blog post will guide you through enabling this feature.</p>
<pre>% flutter doctor<br />Doctor summary (to see all details, run flutter doctor -v):<br />[✓] Flutter (Channel stable, 2.8.1, on macOS 12.0.1 21A559 darwin-arm, locale ja-JP)<br />[✓] Android toolchain - develop for Android devices (Android SDK version 32.0.0)<br />[✓] Xcode - develop for iOS and macOS (Xcode 13.1)<br />[✓] Chrome - develop for the web<br />[✓] Android Studio (version 2020.3)<br />[✓] IntelliJ IDEA Ultimate Edition (version 2021.3)<br />[✓] VS Code (version 1.62.3)<br />[✓] Connected device (2 available)</pre>
<p>(Note: The editor used here is Android Studio, not VS Code)</p>
<h1>Creating a New App</h1>
<p>In Android Studio: File menu &rarr; New &rarr; New Flutter Project</p>
<p><img src="https://www.ytyng.com/media/uploads/applink/applink_01.png" alt="" width="677" height="637" /></p>
<p>Flutter &rarr; Next</p>
<p>Project name: my_link_app (you can choose any name)</p>
<p>Organization: com.ytyng (you can choose any name)</p>
<p><img src="https://www.ytyng.com/media/uploads/applink/applink_02.png" alt="" width="719" height="635" /></p>
<p>Run the app once to see the demo counter app launch.</p>
<p><img src="https://www.ytyng.com/media/uploads/applink/applink_03.png" alt="" width="419" height="864" /></p>
<h2>Creating a Keystore</h2>
<p>Reference: https://developer.android.com/studio/publish/app-signing?hl=en</p>
<p>Open the android directory in Android Studio by selecting File -> Open...</p>
<p>Create a keystore. If you already have a keystore, you can skip this step.</p>
<p>Select Build menu -> Generate Signed Bundle / APK...</p>
<p><img src="https://www.ytyng.com/media/uploads/applink/applink_04.png" alt="" width="540" height="506" /></p>
<p>Select APK and then Next (Android App Bundle is also fine)</p>
<p>Click Create new... under Key store path</p>
<p><img src="https://www.ytyng.com/media/uploads/applink/applink_05.png" alt="" width="556" height="425" /></p>
<p>Specify a key store path. For this example, we created keystore.jks under the android folder. Fill in the password and other fields.</p>
<p><img src="https://www.ytyng.com/media/uploads/applink/applink_06.png" alt="" width="952" height="530" /></p>
<p>After creating the keystore, click Next</p>
<p>In the Build Variants settings, select debug, profile, and release while holding Shift, then click Finish.</p>
<p>In Android Studio, open the File -> Project Structure</p>
<p>Under Modules, go to Signing Config and fill in the details for the debug configuration. Use the keystore file created earlier, the key alias (key0), and the password. Close with OK.</p>
<p><img src="https://www.ytyng.com/media/uploads/applink/applink_06.png" alt="" width="952" height="530" /></p>
<p>In Project Structure, under Modules -> Default Config, add the debug signing configuration.</p>
<p><img src="https://www.ytyng.com/media/uploads/applink/applink_07.png" alt="" width="948" height="530" /></p>
<p>In Project Structure, add the debug signing configuration to each build variant in Build Variants.</p>
<p>Stop and re-run the app in the emulator. If the app fails to launch, you may encounter this error:</p>
<pre>FAILURE: Build failed with an exception.<br /><br />* What went wrong:<br />Execution failed for task ':app:packageDebug'.<br />&gt; A failure occurred while executing com.android.build.gradle.tasks.PackageAndroidArtifact$IncrementalSplitterRunnable<br />   &gt; Entry name 'assets/flutter_assets/AssetManifest.json' collided<br /><br />* Try:<br />Run with --stacktrace option to get the stack trace. Run with --info or --debug option to get more log output. Run with --scan to get full insights.<br /><br />* Get more help at https://help.gradle.org<br /><br />BUILD FAILED in 11s<br />Exception: Gradle task assembleDebug failed with exit code 1</pre>
<p>This error occurs because the signature has changed, preventing reinstallation. Uninstall the app from the emulator and try running it again.</p>
<h2>Verifying the Signature</h2>
<p>Verify the fingerprint of the keystore you created.</p>
<pre>% keytool -J-Duser.language=en -list -v -keystore android/keystore.jks<br />Enter keystore password: <br />Keystore type: PKCS12<br />Keystore provider: SUN<br /><br />Your keystore contains 1 entry<br /><br />Alias name: key0<br />Creation date: Dec 26, 2021<br />Entry type: PrivateKeyEntry<br />Certificate chain length: 1<br />Certificate[1]:<br />Owner: O=ytyng<br />Issuer: O=ytyng<br />Serial number: 4b0bf92f<br />Valid from: Sun Dec 26 21:16:44 JST 2021 until: Thu Dec 20 21:16:44 JST 2046<br />Certificate fingerprints:<br />    SHA1: 9D:CB:5B:FC:DE:30:94:5B:8B:AC:AC:B3:89:69:CE:3C:E8:6C:5A:2A<br />    SHA256: B3:A2:05:04:F6:75:A7:27:A3:77:96:E2:E1:CF:1B:9A:4B:90:3D:25:E6:67:D0:78:A5:C9:72:1C:D8:93:77:52<br />Signature algorithm name: SHA256withRSA<br />Subject Public Key Algorithm: 2048-bit RSA key</pre>
<p>If the output is in Japanese, you may encounter issues with the SHA256 section. Use <code>-J-Duser.language=en</code> to force English output.</p>
<p>Note down the SHA256 fingerprint.</p>
<p>Also, verify the signature of the app installed in the Android emulator.</p>
<pre>% keytool -J-Duser.language=en -list -printcert -jarfile build/app/outputs/flutter-apk/app-debug.apk<br />Signer #1:<br /><br />Signature:<br /><br />Owner: O=ytyng<br />Issuer: O=ytyng<br />Serial number: 4b0bf92f<br />Valid from: Sun Dec 26 21:16:44 JST 2021 until: Thu Dec 20 21:16:44 JST 2046<br />Certificate fingerprints:<br />    SHA1: 9D:CB:5B:FC:DE:30:94:5B:8B:AC:AC:B3:89:69:CE:3C:E8:6C:5A:2A<br />    SHA256: B3:A2:05:04:F6:75:A7:27:A3:77:96:E2:E1:CF:1B:9A:4B:90:3D:25:E6:67:D0:78:A5:C9:72:1C:D8:93:77:52<br />Signature algorithm name: SHA256withRSA<br />Subject Public Key Algorithm: 2048-bit RSA key<br />Version: 3<br /><br />Extensions: </pre>
<p>Since the signatures match, you can confirm that the app is signed with the keystore created earlier.</p>
<h2>Writing the Intent Filter</h2>
<p>References:</p>
<p><a href="https://developer.android.com/studio/write/app-link-indexing?hl=en">https://developer.android.com/studio/write/app-link-indexing?hl=en</a></p>
<p><a href="https://qiita.com/noboru_i/items/fd4634ecb326b3749ac0">https://qiita.com/noboru_i/items/fd4634ecb326b3749ac0</a></p>
<p>Open android/app/src/main/AndroidManifest.xml and add the following &lt;intent-filter&gt; inside the activity tag.</p>
<pre>&lt;intent-filter android:autoVerify="true"&gt;<br /> &lt;action android:name="android.intent.action.VIEW"/&gt;<br /><br /> &lt;category android:name="android.intent.category.DEFAULT"/&gt;<br /> &lt;category android:name="android.intent.category.BROWSABLE"/&gt;<br /><br /> &lt;data<br /> android:host="www.ytyng.com"<br /> android:pathPrefix="/my-app-link"<br /> android:scheme="https"/&gt;<br />&lt;/intent-filter&gt;</pre>
<p>In this example, the app will launch when https://www.ytyng.com/my-app-link/xxxx is specified.</p>
<h2>Setting the Minimum API Level</h2>
<p>After setting the above intent filter, if you open AndroidManifest.xml in Android Studio, you may see a warning for the <code>autoVerify="true"</code> attribute indicating "API level 23 and higher (current min is 16)".</p>
<p><img src="https://www.ytyng.com/media/uploads/applink/applink_09.png" alt="" width="959" height="476" /></p>
<p>To set the Min API Level, open <code>local.properties</code> in the android directory and add:</p>
<pre>flutter.minSdkVersion=23</pre>
<p></p>
<h2><img src="https://www.ytyng.com/media/uploads/applink/applink_10.png" alt="" width="574" height="250" /><br /><br />Introducing uni_links</h2>
<p>Install the uni_links package from Pub.</p>
<p><a href="https://pub.dev/packages/uni_links">https://pub.dev/packages/uni_links</a></p>
<p>Add the following line to the <code>dependencies</code> section of <code>pubspeck.yaml</code>:</p>
<pre>uni_links: ^0.5.1</pre>
<p>Run Pub get to fetch the package.</p>
<h2>Modifying the Widget</h2>
<p>For verification, display the launch URL in the app.</p>
<p>Modify main.dart in the demo app to display the result of getInitialLink() from the uni_links package, as shown on the pub page.</p>
<p>This completes the app-side setup.</p>
<p><img src="https://www.ytyng.com/media/uploads/applink/applink_11.png" alt="" width="525" height="504" /></p>
<p><img src="https://www.ytyng.com/media/uploads/applink/applink_12.png" alt="" width="747" height="317" /></p>
<h1><br />Server-Side Configuration</h1>
<p>On the server, place the following content in <code>/.well-known/assetlinks.json</code>.</p>
<pre>[<br />  {<br />    "relation": ["delegate_permission/common.handle_all_urls"],<br />    "target": {<br />      "namespace": "android_app",<br />      "package_name": "com.ytyng.my_link_app",<br />      "sha256_cert_fingerprints":<br />      ["B3:A2:05:04:F6:75:A7:27:A3:77:96:E2:E1:CF:1B:9A:4B:90:3D:25:E6:67:D0:78:A5:C9:72:1C:D8:93:77:52"]<br />    }<br />  }<br />]</pre>
<p>Ensure the sha256_cert_fingerprints matches the signature verified earlier using keytool.</p>
<p>After deploying assetlinks.json, verify it using this tool:</p>
<p><a href="https://developers.google.com/digital-asset-links/tools/generator?hl=en">https://developers.google.com/digital-asset-links/tools/generator?hl=en</a></p>
<p><img src="https://www.ytyng.com/media/uploads/applink/applink_13.png" alt="" width="867" height="520" /></p>
<p></p>
<p>For verification, deploy a page with a link to launch the App Link.</p>
<pre>&lt;a href="https://www.ytyng.com/auth?token=xxxxxx"&gt;Login with app&lt;/a&gt;</pre>
<p>Create a link like the one above and display the page in Android's Chrome browser.</p>
<p>Ensure the app is closed.</p>
<p>Click the link to verify that the app launches.</p>
