I want to launch my app from a custom URL scheme. I checked the deep links section on dev android and here is a snippet of my code. This doesnt seem to fire though with a URL that looks like : myApp://?host=myhost.com
Manifest :
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
<category android:name="android.intent.category.BROWSABLE" />
<data android:scheme="myApp" />
</intent-filter>
In the activity which is my main activity, i have :
Intent intent = getIntent();
Uri uri = intent.getData();
if (uri != null) {
String host = uri.getQueryParameter("host");
}
The app does not launch when i have email that has the url as a hyperlink.
Also, what would be a good way to test this ?
Try this, edit your IntentFilter
<intent-filter>
<action android:name="android.intent.action.VIEW"></action>
<category android:name="android.intent.category.DEFAULT"></category>
<category android:name="android.intent.category.BROWSABLE"></category>
<data android:host="www.youtube.com" android:scheme="http"></data>
</intent-filter>
EDIT
<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"></action>
<category android:name="android.intent.category.DEFAULT"></category>
<category android:name="android.intent.category.BROWSABLE"></category>
<data android:host="www.youtube.com" android:scheme="http"></data>
</intent-filter>
The browser converts the scheme to lowercase, so you need to change the data tag to
<data android:scheme="myapp"/>
k it looks like ACTION_VIEW is a must to support custom URI schemes. I can add VIEW and MAIN though which gets it to work.
Related
I am trying to configure a deep link intent-filter to open an Android app from a QR Code scanned by the Camera.
The data value of the QR Code is "tagname:datavalue", presumably a "text/plain" mime type, but I don't know this for sure.
In my AndroidManifest.xml I have the following intent within an activity:
<activity
android:name="a.b.activity.DeepLinkActivity"
android:exported="true"
android:theme="#style/FullscreenTheme">
<intent-filter>
<data android:mimeType="text/plain" />
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
</intent-filter>
</activity>
It wants me include a scheme of which there is none; it's just plain text data.
When the QR Code is scanned by the Camera, I can launch Chrome, but I want to add the option of opening my app. Is this possible?
When I add a mimetype without a scheme, Android Studio wants to add a scheme value android:scheme="<some-scheme>" tools:ignore="AppLinkUrlError" to the intent-filter.
<intent-filter android:scheme="<some-scheme>"
tools:ignore="AppLinkUrlError">
<data android:mimeType="text/plain" />
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
</intent-filter>
But there is no scheme.
Bonus question: Can I filter on specific values of tagname, for example launch the app if tagname is "apple", but not "orange"?
Add the scheme as the content and it won't show the error again.
<intent-filter>
<action android:name="android.intent.action.VIEW"/>
<category android:name="android.intent.category.DEFAULT"/>
<data android:mimeType="text/plain" android:scheme="content"/>
</intent-filter>
Well, I was breaking the hell of my brain cells with this and no solution came up...
Usually, in Android, to open the Web Browser in a specified Website, we do this:
Intent browserIntent = new Intent(Intent.ACTION_VIEW, Uri.parse("http://www.google.com"));
startActivity(browserIntent);
So, I got a Data URI Scheme (dunno if it is written this way, i'm not an expert on this kind of stuff) like this:
data:text/html;charset=utf8;base64,<base64 html code>
If I copy and paste this in a web browser, it will handle it the way I want it.
But how can I do it programatically in Android?
Intent browserIntent = new Intent(Intent.ACTION_VIEW, Uri.parse(dataHTMLBase64));
startActivity(browserIntent);
dataHTMLBase64 stores the Data URI Scheme I mentioned before.
The code above won't work. It won't even launch chrome.
What can I do?
PS: I'm not good with English. Please warn me if I didn't express myself the right way...
Actually, it appears that one can launch a Data URI in an Android browser quite easily.
String url = "data:text/html;charset=utf8,<b>Hee-haw!</b>";
startActivity(Intent.makeMainSelectorActivity(
Intent.ACTION_MAIN, Intent.CATEGORY_APP_BROWSER)
.setData(Uri.parse(url.toString())));
Using apktool I reviewed the AndroidManifest.xml of the Google Chrome .apk file.
(apktool is quite easy to install, and then the command is simply apktool d example.apk)
I found the relevant intent filters (listed below) so there are many possible ways to launch the browser. Of course other browsers may have different intent filters, but it seems that APP_BROWSER is a good choice.
<activity-alias android:exported="true" android:name="com.google.android.apps.chrome.Main" android:targetActivity="org.chromium.chrome.browser.document.ChromeLauncherActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.DEFAULT"/>
<category android:name="android.intent.category.LAUNCHER"/>
<category android:name="android.intent.category.BROWSABLE"/>
<category android:name="android.intent.category.APP_BROWSER"/>
<category android:name="android.intent.category.NOTIFICATION_PREFERENCES"/>
</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="googlechrome"/>
<data android:scheme="http"/>
<data android:scheme="https"/>
<data android:scheme="about"/>
<data android:scheme="javascript"/>
</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="googlechrome"/>
<data android:scheme="http"/>
<data android:scheme="https"/>
<data android:scheme="about"/>
<data android:scheme="content"/>
<data android:scheme="javascript"/>
<data android:mimeType="text/html"/>
<data android:mimeType="text/plain"/>
<data android:mimeType="application/xhtml+xml"/>
</intent-filter>
<intent-filter>
<action android:name="android.intent.action.VIEW"/>
<category android:name="android.intent.category.DEFAULT"/>
<data android:mimeType="multipart/related" android:scheme="file"/>
</intent-filter>
<intent-filter>
<action android:name="android.intent.action.MEDIA_SEARCH"/>
<category android:name="android.intent.category.DEFAULT"/>
</intent-filter>
<intent-filter>
<action android:name="android.speech.action.VOICE_SEARCH_RESULTS"/>
<category android:name="android.intent.category.DEFAULT"/>
</intent-filter>
<intent-filter>
<action android:name="android.nfc.action.NDEF_DISCOVERED"/>
<category android:name="android.intent.category.DEFAULT"/>
<data android:scheme="http"/>
<data android:scheme="https"/>
</intent-filter>
<intent-filter>
<action android:name="android.intent.action.SEARCH"/>
</intent-filter>
<intent-filter>
<action android:name="com.sec.android.airview.HOVER"/>
</intent-filter>
<meta-data android:name="android.app.searchable" android:resource="#xml/searchable"/>
</activity-alias>
If you get these data URIs from somewhere you could do two things:
Parse the data content out of it and use it in some WebViewand call loadData(...) on it to display the contents
Save the data content of the URIs to some file, use FileProvider to make this file accessible outside of your app and use the URI returned by that to fire up a browser / view intent
I am trying to enable deeplinking in my app. Here is the code I am running in AndroidManifest to achieve it:
<activity
android:name=".ui.WalletActivity"
android:label="#string/title_activity_wallet">
<intent-filter android:label="#string/title_activity_link_wallet" >
<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"
android:host="wallet"
/>
</intent-filter>
</activity>
Is there anything else I need to do in order to make tapping on myapp://wallet to open WalletActivity of my app?
In my app, this works fine:
<activity
android:name=".ui.WalletActivity"
android:label="#string/title_activity_wallet">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
<intent-filter>
<data android:scheme="myapp" android:host="wallet" />
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
</intent-filter>
</activity>
I also have extra parameters (myapp://wallet?id=42), which I parse like this:
Intent intent = getIntent();
String providerUrl = intent.getData().toString();
UrlQuerySanitizer sanitizer = new UrlQuerySanitizer();
sanitizer.setAllowUnregisteredParamaters(true);
sanitizer.parseUrl(providerUrl);
String id = sanitizer.getValue("id");
(You can read about UrlQuerySanitizer here)
To test, I'd suggest to send the myapp://wallet link to yourself via email, for example :-) (or adb, as mentioned in the comments)
To test and make sure that your intent is working, you can use adb command as suggested in the deep linking docs
To pass parameters in your uri, simply add them as a normal query parameter (i.e. example://gizmos/path?key=value, then retrieve them by parsing the intent data like this:
Uri uri = getIntent().getData();
String value = uri.getQueryParameter("key");
Make sure you check for nulls etc.
I need my application opens when clicking on a link. for this I read that I must use a URL scheme. The link must have the form myapp://parameters.
I read every post on this subject, but when I send an email with "myapp://addUser/?id=22" and I open from chrome (on my phone), it is not clickable.
My manifest:
<activity
android:name="com.example.SplashActivity"
android:label="#string/app_name"
android:screenOrientation="portrait" >
<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" android:host="com.example"/>
</intent-filter>
</activity>
My class:
public class SplashActivity extends FragmentActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_splash);
Intent intent = getIntent();
if (Intent.ACTION_VIEW.equals(intent.getAction())) {
Uri uri = intent.getData();
String id = uri.getQueryParameter("id");
}
}
Content of the mail to test the code:
myapp://addUser/?id=22
Reference Links:
Make a link in the Android browser start up my app?
How to register some URL namespace (myapp://app.start/) for accessing your program by calling a URL in browser in Android OS?
https://legacy.madewithmarmalade.com/devnet/forum/custom-url-scheme-primarily-android-3
UPDATE
I think the problem is the mail body, but I don't know how I can test this.
In your manifest
<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" android:host="com.example"/>
</intent-filter>
you define android:host="com.example", so you should modify link URL :
myapp://addUser/?id=22 //error
myapp://com.example/?id=22 //correct
then it can work!!
I made a test here and in the manifest file I just removed the "android:host" parameter, leaving this:
<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>
and it opened an URL myapp://testing here that I put on a simple HTML file just for trying.
I am trying to figure out how to start an app from a URL, and how I should write that URL.
I have the following code in my AndroidManifest:
<activity android:name=".MyActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN"></action>
<action android:name="android.intent.action.VIEW"></action>
<category android:name="android.intent.category.LAUNCHER"></category>
<category android:name="android.intent.category.DEFAULT"></category>
<category android:name="android.intent.category.BROWSABLE"></category>
<data android:host="my.app" android:scheme="http"></data>
</intent-filter>
</activity>
I used a URL as explained in this answer, but nothing happens.
Please let me know if my intent is well written, and how I should write the URL that calls that app, and note that I need to call my "Main" Activity.
You need to have two <intent-filter> elements for this <activity>. One will be for MAIN and LAUNCHER. The other will be for VIEW, BROWSABLE/DEFAULT, and your <data> element:
<activity android:name=".MyActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN"></action>
<category android:name="android.intent.category.LAUNCHER"></category>
</intent-filter>
<intent-filter>
<action android:name="android.intent.action.VIEW"></action>
<category android:name="android.intent.category.DEFAULT"></category>
<category android:name="android.intent.category.BROWSABLE"></category>
<data android:host="my.app" android:scheme="http"></data>
</intent-filter>
</activity>
Then, http://my.app should launch your activity.