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 + +
+
+ + +

Dependencies and prerequisites

+ + +
+
+ + +

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}.

+ + +

Lessons

+ +
+
Sending Content to Other Apps
+
Learn how to set up your application to be able to send text and binary data to other +applications with intents.
+ +
Receiving Content from Other Apps
+
Learn how to set up your application to receive text and binary data from intents.
+ +
Adding an Easy Share Action
+
Learn how to add a "share" action item to your action bar.
+
diff --git a/docs/html/training/sharing/receive.jd b/docs/html/training/sharing/receive.jd new file mode 100644 index 0000000000000..b2cac304325d0 --- /dev/null +++ b/docs/html/training/sharing/receive.jd @@ -0,0 +1,149 @@ +page.title=Receiving Content from Other Apps +parent.title=Sharing Content +parent.link=index.html + +trainingnavtop=true +previous.title=Sending Content to Other Apps +previous.link=send.html +next.title=Adding an Easy Share Action +next.link=shareaction.html + +@jd:body + +
+
+ + +

This lesson teaches you to

+
    +
  1. Update Your Manifest
  2. +
  3. Handle the Incoming Content
  4. +
+ + +

You should also read

+ + +
+
+ +

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.

+ + +

Update Your Manifest

+ +

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.

+ + +

Handle the Incoming Content

+ +

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 + +
+
+ + +

This lesson teaches you to

+
    +
  1. Send Text Content
  2. +
  3. Send Binary Content
  4. +
  5. Send Multiple Pieces of Content
  6. +
+ + +

You should also read

+ + +
+
+ +

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.

+ + +

Send Text Content

+ +
+ +

+ 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.

+ + +

Send Binary Content

+ +

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:

+ + + +

Send Multiple Pieces of Content

+ +

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 + +
+
+ + +

This lesson teaches you to

+
    +
  1. Update Menu Declarations
  2. +
  3. Set the Share Intent
  4. +
+ + +

You should also read

+ + +
+
+ + +

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. +

+
+ +

Update Menu Declarations

+ +

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.

+ + +

Set the Share Intent

+ +

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.

+ +