page.title=Sending Simple Data to Other Apps parent.title=Sharing Simple Data parent.link=index.html trainingnavtop=true next.title=Receiving Simple Data from Other Apps next.link=receive.html @jd:body <div id="tb-wrapper"> <div id="tb"> <!-- table of contents --> <h2>This lesson teaches you to</h2> <ol> <li><a href="#send-text-content">Send Text Content</a></li> <li><a href="#send-binary-content">Send Binary Content</a></li> <li><a href="#send-multiple-content">Send Multiple Pieces of Content</a></li> </ol> <!-- other docs (NOT javadocs) --> <h2>You should also read</h2> <ul> <li><a href="{@docRoot}guide/components/intents-filters.html">Intents and Intent Filters</a></li> </ul> </div> </div> <p>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 specify 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.</p> <p>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 applications.</p> <p><strong>Note:</strong> 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 <a href="shareaction.html">Adding an Easy Share Action</a>.</p> <h2 id="send-text-content">Send Text Content</h2> <div class="figure" style="width:220px"> <img src="{@docRoot}images/training/sharing/share-text-screenshot.png" alt="" id="figure1" /> <p class="img-caption"> <strong>Figure 1.</strong> Screenshot of {@link android.content.Intent#ACTION_SEND} intent chooser on a handset. </p> </div> <p>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:</p> <pre> 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); </pre> <p>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.</p> <p>However, if you call {@link android.content.Intent#createChooser(android.content.Intent, CharSequence) Intent.createChooser()}, passing it your {@link android.content.Intent} object, it returns a version of your intent that will <strong>always display the chooser</strong>. This has some advantages:</p> <ul> <li>Even if the user has previously selected a default action for this intent, the chooser will still be displayed.</li> <li>If no applications match, Android displays a system message.</li> <li>You can specify a title for the chooser dialog.</li> </ul> <p>Here's the updated code:</p> <pre> 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(<strong>Intent.createChooser(sendIntent, getResources().getText(R.string.send_to))</strong>); </pre> <p>The resulting dialog is shown in figure 1.</p> <p>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}. If the receiving application is not designed to use them, it simply ignores them.</p> <p class="note"><strong>Note:</strong> 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.</p> <h2 id="send-binary-content">Send Binary Content</h2> <p>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:</p> <pre> 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))); </pre> <p>Note the following:</p> <ul> <li>You can use a MIME type of {@code "*/*"}, but this will only match activities that are able to handle generic data streams.</li> <li>The receiving application needs permission to access the data the {@link android.net.Uri} points to. The recommended ways to do this are: <ul> <li>Store the data in your own {@link android.content.ContentProvider}, making sure that other apps have the correct permission to access your provider. The preferred mechanism for providing access is to use <a href="{@docRoot}guide/topics/security/permissions.html#uri">per-URI permissions</a> which are temporary and only grant access to the receiving application. An easy way to create a {@link android.content.ContentProvider} like this is to use the {@link android.support.v4.content.FileProvider} helper class.</li> <li>Use the system {@link android.provider.MediaStore}. The {@link android.provider.MediaStore} is primarily aimed at video, audio and image MIME types, however beginning with Android 3.0 (API level 11) it can also store non-media types (see {@link android.provider.MediaStore.Files MediaStore.Files} for more info). Files can be inserted into the {@link android.provider.MediaStore} using {@link android.media.MediaScannerConnection#scanFile(android.content.Context, java.lang.String[], java.lang.String[], android.media.MediaScannerConnection.OnScanCompletedListener) scanFile()} after which a {@code content://} style {@link android.net.Uri} suitable for sharing is passed to the provided {@link android.media.MediaScannerConnection.OnScanCompletedListener#onScanCompleted( java.lang.String, android.net.Uri) onScanCompleted()} callback. Note that once added to the system {@link android.provider.MediaStore} the content is accessible to any app on the device.</li> </ul> </li> </ul> <h2 id="send-multiple-content">Send Multiple Pieces of Content</h2> <p>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:</p> <pre> 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..")); </pre> <p>As before, make sure the provided {@link android.net.Uri URIs} point to data that a receiving application can access.</p>