I want to open my Android app for a specific link not for the specific host so that whenever user types the url in browser my app should be shown in Open With options.
I have already got success in opening my app from browser link.
For e.g:
If user types: www.abc.com app must not be shown in Open with options. But if user types or clicks www.abc.com/video app must be shown.
I have tried diffrent combination of following but none of them works.
<data android:pathPrefix="www.abc.com"
android:pathPattern=".*"
android:pathPrefix="/video/" android:scheme="http" />
It shows me my app even if I have typed abc.com in web browser. But what i want is that my application should only be visible if the user typed exact url i.e. www.abc.com/video
From Android docs:
Each of these attributes is optional, but they are not independent of each other: For an authority to be meaningful, a scheme must also be specified. For a path to be meaningful, both a scheme and an authority must be specified.
Then you should use:
android:scheme="http" android:host="www.abc.com" android:path="/video"
What i Understands after applying all the combinations of
<data android:pathPrefix="www.abc.com" android:pathPattern=".*" android:pathPrefix="/video/" android:scheme="http" />
is that:
1.) Browser throws intent for the url part before the /(slash) operator. For e.g:
If I write www.abc.com/terms, Browser will throw intent for www.abc.com. similary It will also check for www.abc.com/videos, www.abc.com/xyz, abc.com/, abc.com/videos and throws intent.
Now, Its our responsiblity to check other params in the incoming url and provide checks for the url we want to handle.
In my case, I have added check for second parameter videos if it contains, else show the home screen for the app.
Related
I need to know if there is a way to override deepLinking mechanism to take url based action. I actually need a way to figure out whether url has query parameter or not. (Assume url doesn't have prefix) If url has query parameter i'll run app if not will redirect user to the browser)
As quoted in the Android Developer Documentation,
<data>
Add one or more tags, each of which represents a URI format that resolves to the activity. At minimum, the tag must include
the android:scheme attribute.
You can add more attributes to further refine the type of URI that the activity accepts.
android:pathPrefix
This attribute can be used to differentiate between different URL's
For example the intent filter for the URL
http://www.example.com/endpoint1
would be
<intent-filter>
<data
android:host="www.example.com"
android:pathPrefix="/endpoint1"
android:scheme="http" />
</intent-filter>
android:pathPattern
This attribute can be used to specify a regular expression for the path pattern making it suitable for path with parameters.
For example for the URL
https://www.example.com/endpoint1?param=1
android:pathPattern=".param=."
I want to register an intent-filter exclusively for the share in the Youtube app.
So far I'm able to receive the intent from Youtube successfully. The problem is my intent filer is not specific enough. My app is displayed as available for other share features in other apps (not only for Youtube).
This is what I'm using right now:
<intent-filter>
<action android:name="android.intent.action.SEND" />
<category android:name="android.intent.category.DEFAULT" />
<data android:mimeType="text/plain" />
</intent-filter>
I have reviewed several questions (most are much like this one) the problem is there is an inaccuracy in those types of answers:
<data android:host="www.youtube.com" ... />
According to the data documentation the scheme most be provided in order for the host to be valid. So in those answers simply adding the host, doesn't make the intent-filter specific for Youtube, because there is no scheme, therefore, the host is ignored.
So I have been trying to figure this out by using the available methods of the intent when the Activity is started:
Intent intent = getIntent();
Bundle bundle = intent.getExtras();
for (String key : bundle.keySet()) {
Log.d("KEY", key);
}
//The above loop will log
//... D/KEY: android.intent.extra.SUBJECT
//... D/KEY: android.intent.extra.TEXT
//This is are the same keys than above, but using the available constants
String subject = getIntent().getStringExtra(Intent.EXTRA_SUBJECT);
String text = getIntent().getStringExtra(Intent.EXTRA_TEXT);
//The subject is the video title
Log.d("SUBJECT", subject);
//The text is the video url, example: https://youtu.be/p6qX_lg4wTc
Log.d("TEXT", text);
//Action is consistent with the intent-filter android.intent.action.SEND
Log.d("ACTION", intent.getAction());
//This is consistent with the intent-filter data mime type text/plain
Log.d("TYPE", intent.getType());
/*
This is the problem.
The scheme is null (that is why I'm using String value of).
*/
Log.d("scheme", String.valueOf(intent.getScheme()));
So, when the available information in the intent is checked, everything seems to be in order, but not the scheme. So, based on what is gotten, I have done some blind attempts to figure it out:
<data android:scheme="http" android:mimeType="text/plain"/>
//I'm adding youtu.be here because is the url format in the text extra
<data android:scheme="http" android:host="youtu.be" android:mimeType="text/plain"/>
Adding http or https won't work, it makes the app is no longer available in the chooser. This means it will neither work the other attempt adding the host.
Doe's anybody knows how to create an intent-filter exclusively for Youtube share?
PS: I know I could validate the url to see if it match a Youtube url, but having my app in every chooser matching SEND doesn't seem user friendly
tldr: You can't make an intent-filter exclusively for Youtube app, the intent for sharing a video doesn't have anything to narrow it down.
So I got really obsessed about this, the only way to find out seems to check the Youtube app code. I found the apk here and then decompile with this. I think I found the code in this file (the text error seems to confirm my finding).
So, if my deductions are correct, then what is going on is Youtube app make an intent with no scheme or nothing else to make it specific. It only uses SEND.
This not answer your specific question, but I think achieves the same you want.
You can use the youtube android player api library and the YouTubeIntents
Like this:
Intent youtubeIntent =
YouTubeIntents.createPlayVideoIntent(getApplicationContext(), VIDEO_ID);
startActivity(youtubeIntent);
I want to create a custom url scheme and the url should look like:
zf-moments://p1234567890
I define it in manifest as:
<data
android:host="*"
android:scheme="zf-moments" />
The problem is my activity is started on every link click. I guess the problem is with host but I want the host to be any. Probably the host is checked 1st, then the scheme. How to define the manifest so that only above links clicks open my app?
Thanks
On my application I am trying to make it so that it opens a activity when someone clicks a link on the browser. I am using this data block but it wont work.
<data android:scheme="http"
android:host="www.test.com"
android:pathPrefix="/get/"
android:pathPattern="/.*\\" />
For example when I click on www.test.com it opens the app when it should only open it when the pathPrefix is /get/. How can I fix this?
API: http://developer.android.com/guide/topics/manifest/data-element.html#path
So you have the prefix as /get but from my understanding of the documentation this is checked against the beginning of the string so it's irrelevant here.
Why it's catching all is this because your regex catches all?
Try something like:
android:pathPattern="[get]"
Say I want to define that an URI such as:
myapp://path/to/what/i/want?d=This%20is%20a%20test
must be handled by my own application, or service. Notice that the scheme is "myapp" and not "http", or "ftp". That is precisely what I intend: to define my own URI schema globally for the Android OS. Is this possible?
This is somewhat analogous to what some programs already do on, e.g., Windows systems, such as Skype (skype://) or any torrent downloader program (torrent://).
This is very possible; you define the URI scheme in your AndroidManifest.xml, using the <data> element. You setup an intent filter with the <data> element filled out, and you'll be able to create your own scheme. (More on intent filters and intent resolution here.)
Here's a short example:
<activity android:name=".MyUriActivity">
<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="path" />
</intent-filter>
</activity>
As per how implicit intents work, you need to define at least one action and one category as well; here I picked VIEW as the action (though it could be anything), and made sure to add the DEFAULT category (as this is required for all implicit intents). Also notice how I added the category BROWSABLE - this is not necessary, but it will allow your URIs to be openable from the browser (a nifty feature).
Complementing the #DanielLew answer, to get the values of the parameteres you have to do this:
URI example: myapp://path/to/what/i/want?keyOne=valueOne&keyTwo=valueTwo
in your activity:
Intent intent = getIntent();
if (Intent.ACTION_VIEW.equals(intent.getAction())) {
Uri uri = intent.getData();
String valueOne = uri.getQueryParameter("keyOne");
String valueTwo = uri.getQueryParameter("keyTwo");
}
I strongly recommend that you not define your own scheme. This goes against the web standards for URI schemes, which attempts to rigidly control those names for good reason -- to avoid name conflicts between different entities. Once you put a link to your scheme on a web site, you have put that little name into entire the entire Internet's namespace, and should be following those standards.
If you just want to be able to have a link to your own app, I recommend you follow the approach I described here:
How to register some URL namespace (myapp://app.start/) for accessing your program by calling a URL in browser in Android OS?
Another alternate approach to Diego's is to use a library:
https://github.com/airbnb/DeepLinkDispatch
You can easily declare the URIs you'd like to handle and the parameters you'd like to extract through annotations on the Activity, like:
#DeepLink("path/to/what/i/want")
public class SomeActivity extends Activity {
...
}
As a plus, the query parameters will also be passed along to the Activity as well.
As the question is asked years ago, and Android is evolved a lot on this URI scheme.
From original URI scheme, to deep link, and now Android App Links.
Android now recommends to use HTTP URLs, not define your own URI scheme. Because Android App Links use HTTP URLs that link to a website domain you own, so no other app can use your links. You can check the comparison of deep link and Android App links from here
Now you can easily add a URI scheme by using Android Studio option: Tools > App Links Assistant.
Please refer the detail to Android document: https://developer.android.com/studio/write/app-link-indexing.html