I am trying to add deep linking to my app. I have added 2 intent filters to one of my activities, one filter for the "http" scheme, and another for my custom scheme (I'm using "example"). I have added one intent filter per scheme, based on the info in this SO (Deep-linking intent does not work), so that I can handle both example://test and http://www.example.com/test type of links.
Here is my XML:
<activity
android:name="com.myapp.myapp.SplashActivity"
android:screenOrientation="portrait"
android:theme="#android:style/Theme.Holo.Light.NoActionBar.Fullscreen" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
<intent-filter android:label="Intent Filter label">
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<category android:name="android.intent.category.LAUNCHER" />
<!-- Accepts URIs that begin with "http://www.example.com/test2” -->
<data android:scheme="http"
android:host="www.example.com"
android:pathPrefix="/test2" />
</intent-filter>
<intent-filter android:label="Intent Filter label">
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<category android:name="android.intent.category.LAUNCHER" />
<!-- Accepts URIs that begin with "example://test2” -->
<data android:scheme="example"
android:host="test2" />
</intent-filter>
</activity>
They are loading correctly when I test in ADB:
adb shell am start -W -a android.intent.action.MAIN -d "example://test2" com.myapp.myapp
returns
Starting: Intent { act=android.intent.action.MAIN dat=example://test2 pkg=com.myapp.myapp }
Status: ok
Activity: com.myapp.myapp/com.app.myapp.SplashActivity
ThisTime: 357
TotalTime: 357
Complete
However, I get absolutely nothing in a browser. When I try this in a browser:
"example://test2" in FF I get "couldn't find an app to open this link" and in Chrome and the Native Browser, it opens up new Google search for "example://test2".
When I try the other style: "http://www.example.com/test2" it just tries to navigate to that web page in all 3 browsers.
I am deploying the app to my phone from Android Studio. I have also tried by generating a debug APK, sending it to my phone, and installing. Same result for both.
What am I doing wrong? I've followed the guide (https://developer.android.com/training/app-indexing/deep-linking.html) to the letter as far as I can tell. Does my app need to be in the store for the deep linking to work?
Ughh, my action was MAIN when it should have been VIEW...
<intent-filter>
<action android:name="android.intent.action.MAIN" />
...
<intent-filter>
<action android:name="android.intent.action.VIEW" />
Your implementation seems to be correct and also, if you're testing your app in your device, it does not need to be available on Playstore.
Have you tried testing through a QR code? As is demonstrated in Google documents - https://developers.google.com/app-indexing/android/test
Hope this helps.
The scheme (and probably host) have to be in all lower case.
From the uni_link package i copied the deep link intent filter:
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<!-- Accepts URIs that begin with YOUR_SCHEME://YOUR_HOST -->
<data
<!-- THIS HAS TO BE IN ALL LOWER CASE -->
android:scheme="[YOUR_SCHEME]"
<!-- android:scheme="[your_scheme]" -->
android:host="[YOUR_HOST]" />
</intent-filter>
and pasted in my package name com.myPackage.app as the scheme. For the host I put localhost.
Changing the scheme to all lower case com.mypackage.app allowed the deep link to work.
You can use this site to test the deep link without using adb.
PS: This is not true for iOS where the CFBundleURLName and CFBundleURLSchemes can contain uppercase letters.
Related
I made changes in Android manifes as suggested here:
https://docs.flutter.dev/development/ui/navigation/deep-linking
So, new metadata and config has been added to MainActivity:
<!-- Deep linking -->
<meta-data android:name="flutter_deeplinking_enabled" android:value="true" />
<intent-filter android:autoVerify="true">
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<data android:scheme="http" android:host="flutterbooksample.com" />
<data android:scheme="https" />
</intent-filter>
As a result, when I use adb for testing as they said to do:
adb shell am start -a android.intent.action.VIEW \
-c android.intent.category.BROWSABLE \
-d "http://flutterbooksample.com/book/1"
I am getting what I want:
But if I try to open url http://flutterbooksample.com/book/1 directly in browser on my emulator, nothing happens, browser opens page and theres no prompt to open url in my app.
Do I need to do anything else to make it working?
Short Answer
You can't call the deep link URL from the web browser's search bar. First, you need to create an HTML page. Then you can click the link. It will work.
More details
In my case, I created an HTML file with a deep link and send it to my email.
HTML file
Open my app
AndroidManifest.xml
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<data
android:host="test"
android:scheme="myapp" />
</intent-filter>
Imagine following AndroidManifest.xml ready to support app links:
<activity ...>
<!-- Intent filter specifying that this activity is a launcher activity -->
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
<!-- Intent filter for an app link: https://www.example.com/books -->
<intent-filter android:autoVerify="true">
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<data
android:scheme="https"
android:host="www.example.com"
android:pathPrefix="/books" />
</intent-filter>
</activity>
So at this point app links are working: assetlinks.json is uploaded on the server, and when the user clicks in the browser on a link like: https://www.example.com/books, then the user is automatically taken into the app (without showing the app chooser dialog).
Now, at some point later we added support for deeplinks via push notifications: you get a notification via Firebase, tap on it, and start an Intent with the uri https://com.application.package/books. Some activity handles this intent and redirects the user to an appropriate screen.
Now the manifest looks like this:
<activity ...>
<!-- New intent filter to support
deeplinks of type: https://com.application.package/books -->
<intent-filter android:autoVerify="false">
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<data
android:host="com.application.package"
android:pathPrefix="/books"
android:scheme="https" />
</intent-filter>
<!-- // the other 2 intent filters follow bellow.. -->
</activity>
As a result of this addition, we noticed that the app links stopped working (app chooser dialog was showing to the user), so after some trial and error investigation we found out that in fact, having these three declarations in the deeplink intent-filter, is what breaks the app links:
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
If the above <action /> and <category ../> tags are removed from the deep link intent-filter, then the app links start working again.
But, as a result, now the deep links no longer work, which in this case is expected, because we are using an SDK, and that SDK is specifically looking .action.VIEW.
Why adding this new intent-filter would cause the app links to stop working? Would appreciate any suggestions from your side.
I want my app to be launched when a link with a specific, custom scheme is clicked on.
But it only works from adb with:
./adb shell a start -a Android.Intent.Action.VIEW -d "ghd://whateversite.com"
It doesn't work when a link is clicked, or the URL is written directly in the browser.
I'm using:
<activity
android:name=".link.LaunchActivity"
android:theme="#android:style/Theme.NoDisplay">
<intent-filter>
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<data android:scheme="ghd" />
</intent-filter>
</activity>
Set android:host too in the Intent filter
<activity
android:name=".link.LaunchActivity"
android:noHistory="true"
android:theme="#android:style/Theme.NoDisplay">
<intent-filter android:autoVerify="true">
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<data android:scheme="ghd" android:host="whateversite.com" />
</intent-filter>
</activity>
Try to remove the autoVerify=true from your <intent-filter/>. As said in the documentation :
When the android:autoVerify attribute is present, installing your app causes the system to attempt to verify all hosts associated with the web URIs in all of your app's intent filters. The system treats your app as the default handler for the specified URI pattern only if it successfully verifies all app link patterns declared in your manifest.
Since you didn't add any host, this might be why it is not working.
I am unable to get the app I have written to launch when a certain url is passed back to the browser.
When the user launches the default browser and goes to the where my server is running for example: www.test.com, a list of films and books are displayed on the remote server. When the user selects one of these items i.e. a film or book - the server sends back a url that starts with bb:// and contains the uri link.fil?data=1. So the url looks like this when sent back from the server:
bb://link.fil?data=1
Currently I have the manifest which declares the following filter intent:
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<data
android:scheme="bb"
android:host="test.com"
android:path="/.*"
android:pathPattern="/.*\\.*"/>
/>
<data
android:scheme="bb"
android:host="www.test.com"
android:path="/.*"
android:pathPattern="/.*\\.*"
/>
</intent-filter>
<intent-filter>
<action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.LAUNCHER"/>
</intent-filter>
What I am trying to make happen is when the user selects a book of film the returning url launches my app.
After following many of the examples on line I still don't seem to be able to get this to work, and would appreciate any help you can provide.
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<data
android:host="link.fil"
android:scheme="bb" />
</intent-filter>
The issue lay with chrome and mozilla they were rejecting the invocation - when using the default browser on android the app was called from the browser as was required. So I am marking the previous answer as correct but the problem lies with iframe which chrome and mozzila are now using- Maybe some one has the answer for fixing these exceptions?
I know this question may appear duplicated with some other similar questions. I've reviewed all of them and still can't fix this issue.
I want to launch my android app when clicking a link on a webpage. It works as desired when I use a custom Scheme:
<!-- In the deployed webpage: -->
Launch application
<!-- The Intent filter: -->
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.BROWSABLE" />
<category android:name="android.intent.category.DEFAULT" />
<data android:scheme="test" android:host="test.com" />
</intent-filter>
But when changing the scheme to "https":
<!-- In the deployed webpage: -->
Launch application
<!-- The Intent filter: -->
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.BROWSABLE" />
<category android:name="android.intent.category.DEFAULT" />
<data android:scheme="https" android:host="test.com"/>
</intent-filter>
the browser attempts to open the (nonexistent) page and ignores the intent filter.
It does not work for http, https, ftp, etc.
I'm running the app on Android 6.0, compiling: Minimum 11, target 23.
It seems like some mechanism is not allowing me to use the "reserved" schemes to launch an app, but I've not seen anything related to this in the posts.
Do you have any clue on what could it be?
Beginning with Android Marshmallow there's a new android:autoVerify flag you can use to request Android to verify that a certain domain belongs to you and that you want links to open in your app and not the browser.
"Android 6.0 (API level 23) and higher allow an app to designate
itself as the default handler of a given type of link"
See: https://developer.android.com/training/app-links/index.html#intent-handler
Try joining the two data tags like so and removing the first android.intent.category.DEFAULT category as its not needed on the first intent-filter at all, but necessary on the 2nd so that "the activity should be an option for the default action to perform on a piece of data"
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.BROWSABLE" />
<category android:name="android.intent.category.DEFAULT" />
<data android:scheme="https" android:host="test.com" />
</intent-filter>
</activity>