How to open a deep linking uri in Android? - android

For example, there is an uri example://activityone?foo=bar which can open up an application and launch one of the activity by this adb command
adb shell am start -W -a android.intent.action.VIEW -d "example://activityone?foo=bar" com.example.deeplinking
Are there any other ways to launch the android app through this uri (example://activityone?foo=bar)? How can I put this uri in an email, and when it is clicked, it will launch the app?

First, you should read the documentation for this: Intents and Intent Filters. Specifically the section "Receiving an Implicit Intent".
As others have stated, using a custom scheme for this has issues.
They aren't always treated as links
You don't own them like you own a domain name (host).
So you should define an activity in you Manifest with an intent filter for your host and use a real scheme. See the "Action Test", "Category Test" and "Data Test" sections of the Intent & Intent Filters documentation to see how to configure this for your specific use case.
<activity android:name="com.example.app.ActivityOne">
<intent-filter>
<data android:scheme="http"/>
<data android:host="example.com"/>
<data android:path="/activityone"/>
<action android:name="android.intent.action.VIEW"/>
<category android:name="android.intent.category.DEFAULT"/>
<category android:name="android.intent.category.BROWSABLE"/>
</intent-filter>
</activity>
Then you will be able to use a link like the following.
http://example.com/activityone?foo=bar
Since this is an http link the system will ask the user to choose which app to open it with (your app or their preferred browser). If they choose your app it will start ActivityOne which can get the query data like so.
public class ActivityOne extends Activity {
#Override
public void onResume() {
super.onResume();
Intent intent = getIntent();
Uri uri = intent.getData();
String foo = uri.getQueryParameter("foo");
}
}
If you use a custom scheme in the intent filter then you will (most likely) be the only app registered to handle that intent and the user will not have to select your app. However, it will be much harder for you to include a link with a custom scheme in an email. Most email clients will not recognize anything with a custom scheme as a link and it will not be clickable.

Non-standard URL schemes (which is what example:// is) aren't always treated as links. Your best option is to somehow wrap that URL inside a link that the app CAN recognize (http:// or https://), and then take care of opening your app later, usually by way of some sort of automatic redirect. This is how we handle things to make sure the app always launches no matter where the link is opened.

Related

How to confirm whether Android app is launched by DeepLink or normal launch?

I have an application where I need to do different task on different launch types. How to detect that app has been launched by deeplink, when my app was in background.
Assuming you already have an activity ready with the required intents what you'll to do is check your activity's if(getIntent().getAction() != null) which means it was launched via a deep-link. Normal intents used for navigation will return null.
Now the issue is if your activity was already running in background and you wrote this code in onCreate(), and the deep-linked activity was set to android:launchMode="singleTask" or launched with a FLAG_ACTIVITY_SINGLE_TOP it won't trigger again.
For this you will have to override onNewIntent(Intent intent) method of your activity, this way you can know each time your activity is started from an intent.
Again, here you can check if(intent.getAction() != null) and intent.getData() to retrieve the data.
One thing to note is to avoid running the same code twice in onCreate and onNewIntent
In case you haven't implemented deep-linking in your app yet you will first need to make use of <intent-filter> to make an activity be available to handle the intent when clicking on a link etc. as an example
<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="www.example.com"
android:pathPattern="/.*"
android:scheme="https" />
</intent-filter>
You can read more about on the official Docs here as someone already suggested.
Inside any activity you have specified the intent filter, you can get the URL via the Intent that launched the activity.
Activity:-
Intent appLinkIntent = getIntent();
Uri appLinkData = appLinkIntent.getData();
Fragment:-
Intent appLinkIntent = requireActivity().getIntent();
Uri appLinkData = appLinkIntent.getData();
in MainActivity i use this code
if(getIntent().getDataString()!=null &&
getIntent().getDataString().contains("specialWordInDeepLink")){
// confirm is run by deeplink
}
When a clicked link or programmatic request invokes a web URI intent, the Android system tries each of the following actions, in sequential order, until the request succeeds:
Open the user's preferred app that can handle the URI, if one is designated.
Open the only available app that can handle the URI.
Allow the user to select an app from a dialog.
To create a link to your app content, add an intent filter that contains these elements and attribute values in your manifest:
https://developer.android.com/training/app-links/deep-linking
Check out official android doc to know more about deeplinking

Starting application by file open

I created a music player and now I would like to implement a functionality that if I click a file (for example in Total Commander) it will open in my application. It already works on desktop but now I would like to also implement this feature in Android.
I know it must have been asked before but I couldn't find the answer.
I already found out that I need to define an intent-filter in 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:scheme="file"/>
<data android:mimeType="audio/*"/>
</intent-filter>
I did it and now my application opens (or I can choose it) if I click a music file. But now I need to do something in the java part (I do believe in the main activity onCreate function) too. How do I handle this?
Thank you.
The intent filter you specified, is already a step into the right direction.
Now other (Explorer-like-) Applications can start your app.
As a next step, you need to receive the data in the activities onCreate(...) function. This can be done like that:
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//setContentView(R.layout.main);
// Get the intent that started this activity
Intent intent = getIntent();
Uri data = intent.getData();
// Figure out what to do based on the intent type
if (intent.getType().equals("audio")) {
// Handle intents with audio ...
String filePath = data.toString();
// Do some handling here !
}
}
First you need to capture the Intent, that other apps use, to call your app. The intent contains the path of your file (as URI) structure. The only thing you need to do then is to get the URI String and get the path of your music file out of it.
Information about the intent filtering can be read here:
https://developer.android.com/training/basics/intents/filters

can i Broadcast custom intent through my HTML page link from browser?

I want to broadcast my custom intent when i click a link of my html page from browser. I know android system will broadcast "android.intent.action.VIEW" for this and i can receive this in my application but doing this will list my application for every clickable link so i want to broadcast my custom intent action.
I want to broadcast my custom intent when i click a link of my html
page from browser.
You can do that in two ways, the exact choice depend on your use case.
Create an <intent-filter> to open selected links (links of your website)
Change your link on the website to <a href="intent://...>
The first method gives you flexibility to leave the links on your website as it is and it will also helps in deeplinking and AppIndex. Where as the second method will make you change all the links in the website.
I know android system will broadcast "android.intent.action.VIEW" for
this and i can receive this in my application but doing this will list
my application for every clickable link so i want to broadcast my
custom intent action.
It will not list your application for every clickable link on the web, it will only open your app for your website links. If you don't want to do that and only open app for one specific link of your website, you should use method 2 above.
Just a note for the second mehtod
Make sure to implement a fallback url, as suggested by Google
When an intent could not be resolved, or an external application could
not be launched, then the user will be redirected to the fallback URL
if it was given.
The link should look like this
<a href="intent://scan/#Intent;scheme=zxing;package=com.google.zxing.client.android;S.browser_fallback_url=http%3A%2F%2Fzxing.org;end">
Notice the S.browser_fallback_url for fallback
I have solved this by following
create test.html file with this single line
Open Your Application Directly
Here "example.com/test?id=12345" can be any thing you want this will be passed as intent data in our in our onCreate() method so i have given id for example.
"scheme" can be any string we need to write same scheme in our menifest.xml for intent-filter
"package" is your app package name to differentiate it from other app with same scheme
Note : If app is not installed in device then it will open google playstore from given valid package name
in AndroidMenifest.xml file
<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:scheme="myapp" />
</intent-filter>
you can add intent filter for any activity i have given to launcher activity
note the <data android:scheme="myapp" /> scheme name must be same as given in HTML file before.
Done! open html file in any browser of your device & click on link it will directly open your app.
You can get intent data in your activity's onCreate() method like
Intent intent = getIntent();
if (intent != null && intent.getData() != null) {
Uri data = intent.getData();
String path = data.getPath();
String id = data.getQueryParameter("id");
Log.d("ID", ": " + id);
}

Extend browser functionality in Android

When I open the Android's default browser I want to add a button or a menu entry when it's clicked to open my Intent and pass me the current url parameter.
Is this possible in Android?
Only by means of the Share option, if the browser in question has one. The standard AOSP Browser app will have such a "Share" option in the action overflow. It triggers an ACTION_SEND Intent, with a MIME type of text/plain, so any activities claiming to support that in the manifest via an <intent-filter> will be able to respond:
<intent-filter android:label="#string/app_name">
<action android:name="android.intent.action.SEND"/>
<data android:mimeType="text/plain"/>
<category android:name="android.intent.category.DEFAULT"/>
</intent-filter>
Of course, you can get the current url:
URL url = new URL(mWebView.getUrl());
I don't know if I understood this right, but I think this what you want.
When the user clicks your button, you can redirect to a custom url, somesite://current_page_url. using javascript or the addon's capability.
That can be picked up by your intent filter with host set to "somesite", as done here.

Can't launch Android application from within an SMS - Android browser always take the task

I would like my application to launch when the user clicks on a link, for example, http://myapp.comwhich is embedded in an SMS message.
I have followed this [solution] but it doesn't work for me. The emulator keeps opening the browser each time.
Here's the intent filter:
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.catagory.DEFAULT"/>
<category android:name="android.intent.catagory.BROWSABLE"/>
<data android:host="myapp.com" android:scheme="http" />
</intent-filter>
I also tried to increase the priority of the intent filter in order to intercept the intent before the browser using the android:priority = 100 tag but it didn't change anything. So either this priority is not high enough or the intent filter didn't match from the beginning.
Here's the intent that the system broadcasts just after clicking on the link. It gave:
04-27 13:03:22.905: INFO/ActivityManager(59): Starting activity: Intent { act=android.intent.action.VIEW dat=http://myapp.com cmp=com.android.browser/.BrowserActivity}
My guess is that Android chooses the default browser each time this intent is sent out. I wonder if there is anything to do with the cmp attribute. Can we change it? Otherwise, how can we intercept the intent before the browser?
Any advices would be welcomed. Thank you in advance :)
I updated the emulator tool (actually I removed/re-installed the SDK) and rebuilt the application with exactly the same code. Now it works for all versions above 2.1! When the user clicks on the link in the SMS, a window pops up and proposes Browser and my app.
The broadcast intent is also different this time:
04-29 12:42:22.906: INFO/ActivityManager(63): Starting activity: Intent { act=android.intent.action.VIEW dat=http://www.my.com flg=0x80000 cmp=android/com.android.internal.app.ResolverActivity(has extras) }
The component attribute has changed! So I really think that it's something to do with the emulator's version.
Shouldn't your android:scheme link to your app instead of http?
<data android:scheme="myapp"/>
Have a look at these Stackoverflow questions for more information (I think you meant to link to one of these in your question where you say "[solution]"):
How to register some URL namespace (myapp://app.start/) for accessing your program by calling a URL in browser in Android OS?
How to implement my very own URI scheme on Android
Have you tried calling the setPackage method as described in one of those answers?
Update: I think you may be able to achieve this by using two schemes, perhaps something like this:
<data android:scheme="myapp" android:host="launch" android:pathPrefix="/" />
<data android:scheme="http" android:host="myapp" android:pathPrefix="/launch/" />

Categories

Resources