Google Android 文档笔记-Training-Getting started [5]

2013-7-15

Sharing Content

Sending Content to Other Apps

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.

Send Text Content

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 ACTION_SENDand MIME type text/plain, the Android system will run it;

 If you call Intent.createChooser() for the intent, Android will always display the chooser. This has some advantages:

· Even if the user has previously selected a default action for this intent, the chooser will still be displayed.

· If no applications match, Android displays a system message.

· You can specify a title for the chooser dialog.

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)) );

Send Binary Content

Binary data is shared using the ACTION_SEND action combined with setting the appropriate MIME type and placing the URI to the data in an extra named 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)));

· You can use a MIME type of "*/*", but this will only match activities that are able to handle generic data streams.

· The receiving application needs permission to access the data the Uri points to. There are a number of ways to handle this:

Write the data to a file on external/shared storage (such as the SD card), which all apps can read. Use Uri.fromFile() to create the Uri that can be passed to the share intent. However, keep in mind that not all applications process a file:// style Uri.

Write the data to a file in your own application directory using openFileOutput() with mode MODE_WORLD_READABLE after which getFileStreamPath() can be used to return a File. As with the previous option, Uri.fromFile() will create a file:// style Uri for your share intent.

Media files like images, videos and audio can be scanned and added to the system MediaStore using scanFile(). The onScanCompleted() callback returns a content:// style Uri suitable for including in your share intent.

Images can be inserted into the system MediaStore using insertImage() which will return a content:// style Uri suitable for including in a share intent.

Store the data in your own ContentProvider, make sure that other apps have the correct permission to access your provider (or use per-URI permissions).

To share multiple pieces of content, use the 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 "image/jpeg". For a mixture of image types, it should be "image/*" to match an activity that handles any type of image. You should only use "*/*" 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. 

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.."));

Receiving Content from Other Apps

Intent filters inform the system what intents an application component is willing to accept.

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>

To handle the content delivered by an Intent, start by calling getIntent() to get Intent object. 

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

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.

Adding an Easy Share Action

ActionProvider, once attached to a menu item in the action bar, handles both the appearance and behavior of that item. In the case of ShareActionProvider, you provide a share intent and it does the rest.

ShareActionProvider is available starting with API Level 14 and higher.

To get started with 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 ShareActionProvider. However, you will need to tell the provider what you would like to share.In order for ShareActionProvider to function, you must provide it a share intent. 

To assign a share intent, first find the corresponding MenuItem while inflating your menu resource in your Activity or Fragment. Next, call MenuItem.getActionProvider() to retrieve an instance of ShareActionProvider. Use 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);
    }
}

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值