diff --git a/docs/html/images/training/sharing/share-text-screenshot.png b/docs/html/images/training/sharing/share-text-screenshot.png new file mode 100644 index 0000000000000..089221ccace64 Binary files /dev/null and b/docs/html/images/training/sharing/share-text-screenshot.png differ diff --git a/docs/html/training/sharing/index.jd b/docs/html/training/sharing/index.jd new file mode 100644 index 0000000000000..cb133c393c419 --- /dev/null +++ b/docs/html/training/sharing/index.jd @@ -0,0 +1,46 @@ +page.title=Sharing Content + +trainingnavtop=true +startpage=true +next.title=Sending Content to Other Apps +next.link=send.html + +@jd:body + +
One of the great things about Android applications is their ability to communicate and +integrate with each other. Why reinvent functionality that isn't core to your application when it +already exists in another application?
+ +This class shows some common ways you can send and receive content between +applications using {@link android.content.Intent} APIs and the {@link +android.view.ActionProvider}.
+ + +Just as your application can send data to other applications, so too can it easily receive data +from applications. Think about how users interact with your application, and what data types you +want to receive from other applications. For example, a social networking application would likely +be interested in receiving text content, like an interesting web URL, from another app. The +Google+ Android +application +accepts both text and single or multiple images. With this app, a user can easily start a +new Google+ post with photos from the Android Gallery app.
+ + +Intent filters inform the system what intents an application component is willing to accept.
+Just as you constructed an intent with action {@link android.content.Intent#ACTION_SEND} in the
+Send Content to Other Apps Using Intents
+lesson, you create intent filters in order to be able to receive intents with this action. You
+define an intent filter in your manifest, using the
+<intent-filter>
+element. For example, if your application handles receiving text content, a single image of any
+type, or multiple images of any type, your manifest would look like:
+<activity android:name=".ui.MyActivity" > + <intent-filter> + <action android:name="android.intent.action.SEND" /> + <category android:name="android.intent.category.DEFAULT" /> + <data android:mimeType="image/*" /> + </intent-filter> + <intent-filter> + <action android:name="android.intent.action.SEND" /> + <category android:name="android.intent.category.DEFAULT" /> + <data android:mimeType="text/plain" /> + </intent-filter> + <intent-filter> + <action android:name="android.intent.action.SEND_MULTIPLE" /> + <category android:name="android.intent.category.DEFAULT" /> + <data android:mimeType="image/*" /> + </intent-filter> +</activity> ++ +
Note: For more information on intent filters and intent resolution +please read Intents and Intent +Filters
+ +When another application tries to share any of these things by constructing an intent and passing
+it to {@link android.content.Context#startActivity(android.content.Intent) startActivity()}, your
+application will be listed as an option in the intent chooser (see figure 1). If the user selects
+your application, the corresponding activity (.ui.MyActivity in the example above) will
+be started. It is then up to you to handle the content appropriately within your code and UI.
To handle the content delivered by an {@link android.content.Intent}, start by calling {@link +android.content.Intent#getIntent(String) getIntent()} +to get {@link android.content.Intent} object. Once you have the object, you can examine its +contents to determine what to do next. Keep in mind that if this activity can be started from other +parts of the system, such as the launcher, then you will need to take this into consideration when +examining the intent.
+ +
+void onCreate (Bundle savedInstanceState) {
+ ...
+ // Get intent, action and MIME type
+ Intent intent = getIntent();
+ String action = intent.getAction();
+ String type = intent.getType();
+
+ if (Intent.ACTION_SEND.equals(action) && type != null) {
+ if ("text/plain".equals(type)) {
+ handleSendText(intent); // Handle text being sent
+ } else if (type.startsWith("image/")) {
+ handleSendImage(intent); // Handle single image being sent
+ }
+ } else if (Intent.ACTION_SEND_MULTIPLE.equals(action) && type != null) {
+ if (type.startsWith("image/")) {
+ handleSendMultipleImages(intent); // Handle multiple images being sent
+ }
+ } else {
+ // Handle other intents, such as being started from the home screen
+ }
+ ...
+}
+
+void handleSendText(Intent intent) {
+ String sharedText = intent.getStringExtra(Intent.EXTRA_TEXT);
+ if (sharedText != null) {
+ // Update UI to reflect text being shared
+ }
+}
+
+void handleSendImage(Intent intent) {
+ Uri imageUri = (Uri) intent.getParcelableExtra(Intent.EXTRA_STREAM);
+ if (imageUri != null) {
+ // Update UI to reflect image being shared
+ }
+}
+
+void handleSendMultipleImages(Intent intent) {
+ ArrayList<Uri> imageUris = intent.getParcelableArrayListExtra(Intent.EXTRA_STREAM);
+ if (imageUris != null) {
+ // Update UI to reflect multiple images being shared
+ }
+}
+
+
+Caution: Take extra care to check the incoming data, you never +know what some other application may send you. For example, the wrong MIME type might be set, or the +image being sent might be extremely large. Also, remember to process binary data in a separate +thread rather than the main ("UI") thread.
+ +Updating the UI can be as simple as populating an {@link android.widget.EditText}, or it can +be more complicated like applying an interesting photo filter to an image. It's really specific +to your application what happens next.
+ diff --git a/docs/html/training/sharing/send.jd b/docs/html/training/sharing/send.jd new file mode 100644 index 0000000000000..d151ed03c7dbe --- /dev/null +++ b/docs/html/training/sharing/send.jd @@ -0,0 +1,194 @@ +page.title=Sending Content to Other Apps +parent.title=Sharing Content +parent.link=index.html + +trainingnavtop=true +next.title=Receiving Content from Other Apps +next.link=receive.html + +@jd:body + +When you construct an intent, you must specify the action you want the intent to "trigger." +Android defines several actions, including {@link android.content.Intent#ACTION_SEND} which, as +you can probably guess, indicates that the intent is sending data from one activity to another, +even across process boundaries. To send data to another activity, all you need to do is speicify +the data and its type, the system will identify compatible receiving activities and display them +to the user (if there are multiple options) or immediately start the activity (if there is only +one option). Similarly, you can advertise the data types that your activities support receiving +from other applications by specifying them in your manifest.
+ +Sending and receiving data between applications with intents is most commonly used for social +sharing of content. Intents allow users to share information quickly and easily, using their +favorite social applications.
+ +Note: The best way to add a share action item to an +{@link android.app.ActionBar} is to use {@link android.widget.ShareActionProvider}, which became +available in API level 14. {@link android.widget.ShareActionProvider} is discussed in the lesson +about Adding an Easy Share Action.
+ + +
++ Figure 1. Screenshot of {@link android.content.Intent#ACTION_SEND} intent chooser +on a handset. +
+The most straightforward and common use of the {@link android.content.Intent#ACTION_SEND} +action is sending text content from one activity to another. For example, the built-in Browser +app can share the URL of the currently-displayed page as text with any application. This is useful +for sharing an article or website with friends via email or social networking. Here is the code to +implement this type of sharing:
+ +
+Intent sendIntent = new Intent();
+sendIntent.setAction(Intent.ACTION_SEND);
+sendIntent.putExtra(Intent.EXTRA_TEXT, "This is my text to send.");
+sendIntent.setType("text/plain");
+startActivity(sendIntent);
+
+
+If there's an installed application with a filter that matches +{@link android.content.Intent#ACTION_SEND} and MIME type text/plain, the Android system will run +it; if more than one application matches, the system displays a disambiguation dialog (a "chooser") +that allows the user to choose an app. If you call +{@link android.content.Intent#createChooser(android.content.Intent, CharSequence) +Intent.createChooser()} +for the intent, Android will always display the chooser. This has some +advantages:
+ +Here's the updated code:
+ +
+Intent sendIntent = new Intent();
+sendIntent.setAction(Intent.ACTION_SEND);
+sendIntent.putExtra(Intent.EXTRA_TEXT, "This is my text to send.");
+sendIntent.setType("text/plain");
+startActivity(Intent.createChooser(sendIntent, getResources().getText(R.string.send_to));
+
+
+The resulting dialog is shown in figure 1.
+ +Optionally, you can set some standard extras for the intent: +{@link android.content.Intent#EXTRA_EMAIL}, {@link android.content.Intent#EXTRA_CC}, +{@link android.content.Intent#EXTRA_BCC}, {@link android.content.Intent#EXTRA_SUBJECT}. However, +if the receiving application is not designed to use them, nothing will happen. You can use +custom extras as well, but there's no effect unless the receiving application understands them. +Typically, you'd use custom extras defined by the receiving application itself.
+ +Note: Some e-mail applications, such as Gmail, expect a +{@link java.lang.String String[]} for extras like {@link android.content.Intent#EXTRA_EMAIL} and +{@link android.content.Intent#EXTRA_CC}, use +{@link android.content.Intent#putExtra(String,String[]) putExtra(String, String[])} to add these +to your intent.
+ + +Binary data is shared using the {@link android.content.Intent#ACTION_SEND} action combined with +setting the appropriate MIME type and placing the URI to the data in an extra named {@link +android.content.Intent#EXTRA_STREAM}. This is commonly used to share an image but can be used to +share any type of binary content:
+ +
+Intent shareIntent = new Intent();
+shareIntent.setAction(Intent.ACTION_SEND);
+shareIntent.putExtra(Intent.EXTRA_STREAM, uriToImage);
+shareIntent.setType("image/jpeg");
+startActivity(Intent.createChooser(shareIntent, getResources().getText(R.string.send_to)));
+
+
+Note the following:
+To share multiple pieces of content, use the {@link android.content.Intent#ACTION_SEND_MULTIPLE} +action together with a list of URIs pointing to the content. The MIME type varies according to the +mix of content you're sharing. For example, if you share 3 JPEG images, the type is still {@code +"image/jpeg"}. For a mixture of image types, it should be {@code "image/*"} to match an activity +that handles any type of image. You should only use {@code "*/*"} if you're sharing out a wide +variety of types. As previously stated, it's up to the receiving application to parse and process +your data. Here's an example:
+ +
+ArrayList<Uri> imageUris = new ArrayList<Uri>();
+imageUris.add(imageUri1); // Add your image URIs here
+imageUris.add(imageUri2);
+
+Intent shareIntent = new Intent();
+shareIntent.setAction(Intent.ACTION_SEND_MULTIPLE);
+shareIntent.putParcelableArrayListExtra(Intent.EXTRA_STREAM, imageUris);
+shareIntent.setType("image/*");
+startActivity(Intent.createChooser(shareIntent, "Share images to.."));
+
+
+As before, make sure the provided {@link android.net.Uri URIs} point to data that a receiving +application can access.
+ diff --git a/docs/html/training/sharing/shareaction.jd b/docs/html/training/sharing/shareaction.jd new file mode 100644 index 0000000000000..f6be745b93b84 --- /dev/null +++ b/docs/html/training/sharing/shareaction.jd @@ -0,0 +1,115 @@ +page.title=Adding an Easy Share Action +parent.title=Sharing Content +parent.link=index.html + +trainingnavtop=true +previous.title=Receiving Content from Other Apps +previous.link=receive.html + +@jd:body + +Implementing an effective and user friendly share action in your {@link android.app.ActionBar} +is made even easier with the introduction of {@link android.view.ActionProvider} in Android 4.0 +(API Level 14). An {@link android.view.ActionProvider}, once attached to a menu item in the action +bar, handles both the appearance and behavior of that item. In the case of {@link +android.widget.ShareActionProvider}, you provide a share intent and it does the rest.
+ +Note: {@link android.widget.ShareActionProvider} is available +starting with API Level 14 and higher.
+ + +
++ Figure 1. The {@link android.widget.ShareActionProvider} in the Gallery app. +
+To get started with {@link android.widget.ShareActionProvider ShareActionProviders}, define the android:actionProviderClass attribute for the corresponding <item> in your menu resource file:
+<menu xmlns:android="http://schemas.android.com/apk/res/android"> + <item android:id="@+id/menu_item_share" + android:showAsAction="ifRoom" + android:title="Share" + android:actionProviderClass="android.widget.ShareActionProvider" /> + ... +</menu> ++ +
This delegates responsibility for the item's appearance and function to +{@link android.widget.ShareActionProvider}. However, you will need to tell the provider what you +would like to share.
+ + +In order for {@link android.widget.ShareActionProvider} to function, you must provide it a share +intent. This share intent should be the same as described in the Sending Content to Other Apps +lesson, with action {@link android.content.Intent#ACTION_SEND} and additional data set via extras +like {@link android.content.Intent#EXTRA_TEXT} and {@link android.content.Intent#EXTRA_STREAM}. To +assign a share intent, first find the corresponding {@link android.view.MenuItem} while inflating +your menu resource in your {@link android.app.Activity} or {@link android.app.Fragment}. Next, call +{@link android.view.MenuItem#getActionProvider() MenuItem.getActionProvider()} to retreive an +instance of {@link android.widget.ShareActionProvider}. Use {@link +android.widget.ShareActionProvider#setShareIntent(android.content.Intent) setShareIntent()} to +update the share intent associated with that action item. Here's an example:
+ +
+private ShareActionProvider mShareActionProvider;
+...
+
+@Override
+public boolean onCreateOptionsMenu(Menu menu) {
+ // Inflate menu resource file.
+ getMenuInflater().inflate(R.menu.share_menu, menu);
+
+ // Locate MenuItem with ShareActionProvider
+ MenuItem item = menu.findItem(R.id.menu_item_share);
+
+ // Fetch and store ShareActionProvider
+ mShareActionProvider = (ShareActionProvider) item.getActionProvider();
+
+ // Return true to display menu
+ return true;
+}
+
+// Call to update the share intent
+private void setShareIntent(Intent shareIntent) {
+ if (mShareActionProvider != null) {
+ mShareActionProvider.setShareIntent(shareIntent);
+ }
+}
+
+
+You may only need to set the share intent once during the creation of your menus, or you may +want to set it and then update it as the UI changes. For example, when you view photos full screen +in the Gallery app, the sharing intent changes as you flip between photos.
+ +For further discussion about the {@link android.widget.ShareActionProvider}, see the Action Bar guide.
+ +