While doing some R&D I found a code using the following statement
Uri uri = (Uri) getIntent().getExtras().get("android.intent.extra.STREAM");
I have scanned the whole project to find whether the activity was called from any other activity, but did'nt find any. Can any one tell me what will this statement return and what is the statement "android.intent.extra.STREAM" doing in the code, whether it is a constant, if yes what is its value?
Thanks in advance.
Happy Coding
This statement will return the extra named "android.intent.extra.STREAM". Whatever activity issued the intent set that value, and there's no easy way to tell what that data is without seeing how it is used, or where/how it was set. Don't forget that the intent could be issued by any activity or application.
Found your answer:
public static final String EXTRA_STREAM Since: API Level 1
A content: URI holding a stream of data associated with the Intent, used with
ACTION_SEND to supply the data being sent.
Constant Value: "android.intent.extra.STREAM"
So, I would posit that it's the result of poor coding (using the value rather than the defined static constant) for an intent designed to share images. The intent includes the Intent.EXTRA_STREAM extra as the data stream for the image (in this case) to be shared. IMO, the code should have been:
Uri uri = (Uri) getIntent().getExtras().get(Intent.EXTRA_STREAM);
But regardless, it appears to be the documented/standardized way of attaching a binary datastream to an intent.
Continued research seems to indicate that it adds Campyre (a Campfire client) as a "Share" option. So from Gallery, if you choose to Share an image, Campyre shows up as one of the options.
Google and the Android dev site are your friends. It took me all of about 2 minutes total to get all that information. Not as long as it took to type the replies and subsequent edits...
More elaboration:
Here is the relevant section from AndroidManifest.xml:
<activity android:name=".ShareImage"
android:theme="#android:style/Theme.Dialog"
android:label="#string/app_name">
<intent-filter>
<action android:name="android.intent.action.SEND" />
<category android:name="android.intent.category.DEFAULT" />
<data android:mimeType="image/*" />
</intent-filter>
</activity>
Which indicates that the Activity can handle Intents for sharing where the item being shared is an image.
Related
I added this code to my manifest, in order to handle sharing from Instagram to my application:
<activity android:name=".ActivityHandlingFragments">
<intent-filter>
<action android:name="android.intent.action.SEND" />
<category android:name="android.intent.category.DEFAULT" />
<data android:mimeType="text/plain" />
</intent-filter>
</activity>
And the following code is censed to handle the sharing (this function is called in onCreate(...) { ... }:
public void handleIntent() {
Intent intent = getIntent();
if(intent != null) {
Toast.makeText(getApplicationContext(), intent.getStringExtra("XYZ"), Toast.LENGTH_LONG).show();
}
}
By what could I replace XYZ in the above code? In other words: is there any list of all the data that Instagram passes into its implicit intent?
Note: https://www.instagram.com/developer/mobile-sharing/android-intents/ lists only intents from an application to Instagram (I want to contrary!).
Important edit:
Using getExtras() method, I discovered there is only one extra: android.intent.extra.TEXT, which contains the URL of the Instagram publication that is shared from Instagram to my app.
So, to get it, write: String url = intent.getStringExtra("android.intent.extra.TEXT");
Waiting for confirmations...! :) In particular: is there any legal mean to get the image (or video), the comments and the legend of the publication (the legend is the text the Instagramer write while posting the image or video and it appears just below the media, and above the comments)?
Using getExtras() method, I discovered there is only one extra: android.intent.extra.TEXT, which contains the URL of the Instagram publication that is shared from Instagram to my app.
So, to get it, write: String url = intent.getStringExtra("android.intent.extra.TEXT");
Waiting for confirmations...! :) In particular: is there any legal mean to get the image (or video), the comments and the legend of the publication (the legend is the text the Instagramer write while posting the image or video and it appears just below the media, and above the comments)?
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 would like to create an Intent-Filter, so that certain links will trigger the start of my application (see this stackoverflow-thread for example: How to register some URL namespace (myapp://app.start/) for accessing your program by calling a URL in browser in Android OS? )
While trying, I figured out, that I dont quite understand how Intents and Intent-Filters (defined in the Manifest.xml) actually work. What is the difference between the following:
<action android:name="android.intent.action.VIEW" />
<action android:name="android.intent.action.MAIN" />
or the following:
<category android:name="android.intent.category.LAUNCHER" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.MAIN" />
And what is actually the difference between category and action Intent-Filters. I read this page http://developer.android.com/reference/android/content/Intent.html but I still missing a basic understanding.
Instead of looking at it from your app's point of view, flip it around and look at it from the Intent side.
When an Intent is created, the creator has no idea what apps are on the system to handle that Intent. But the creator does know what it wants to do (e.g., an app might want to let the user pick out a contact from somewhere on the device), and needs to reach out to other apps on the system to ask for what's desired.
To do this, Intents have several pieces of information attached to them. Among them are actions and categories.
The actions define in a general way the action the Intent wants to do, like VIEW a contact, PICK an image from the Gallery, etc.
The category is an additional piece of information that gives the Intent another way to differentiate itself. For example, when a link in the browser is clicked, the Intent that is created has the BROWSABLE category attached to it.
So, when the OS resolves the Intent, it will look for registered Activities or BroadcastReceivers that have an intent filter that includes all of pieces of information. If the Intent specifies the PICK action, Activities that do not have an intent-filter with the PICK action will be discarded from the list of candidates to handle the Intent.
In this way, the combined set of action, categories, type, and (possibly) scheme associated with an Intent serve to pinpoint the set of Activities that can handle the Intent. When you set up your intent-filter in your manifest, you are telling the OS which class of Intents you can handle.
I had to examine the code of android.content.IntentFilter.matchCategories(Set<String> categories) to understand the matching of categories:
Successful match, if your IntentFilter has categories and the Intent doesn't provide Categories
Successful match, if your IntentFilter has all categories of the Intent. The filter also can have additional categories.
No match, if your IntentFilter has no categories and the Intent has categories
No match, if your IntentFilter has not the categories the Intent has
Especially #1 and #3 aren't obvious.
guys. I am trying to build a voip app for android. I want to make use of the built-in android phone dialer. Can you guys give me some reference to it. I have been googling with no luck. Thanks
What you need to do is setup an Intent filter on the Activity you want to make the call. You do this inside your AndroidManifest.xml file. Modify your activity definition to include this intent filter:
<intent-filter>
<action android:name="android.intent.action.CALL" />
<category android:name="android.intent.category.DEFAULT" />
<data android:scheme="tel" />
</intent-filter>
Note: there are some alternative ways to call people (which can be seeing in the AndroidManifest.xml of the source I linked bellow, however this is the main one
Adding this will give the user the option to use your app when making a call, and this can be set as the default app if the user wishes.
You can then get the phone number by adding something like this code to your onCreate() method of your activity:
final Intent i = getIntent();
final Uri phoneUri = i.getData();
phoneUri now contains tel:00000000000 and you can easily get the number out of the Uri object
If you have problems in to future take a look at the android source. I got these bits of code from the phone app source if you want to take a look.
This should open the dialer with new special permissions:
Intent i = new Intent(Intent.ACTION_DIAL, Uri.parse("tel:0000000000"));
startActivity(i);
That should open the dialer with the required telephone number already inserted.
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