共享簡單數據

向其餘app發送簡單的數據

   當你構造intents的時候,必須先定義你想要intent觸發的action。Android定義了若干action,包括ACTION_SEND,正如你猜到的,這個action被用來在activity之間傳遞數據,甚至在進程之間。爲了向其餘activity傳輸數據,你須要作的僅僅是定義數據和他的類型。系統將識別可接收的activity,而且展現選擇項(若是有多個符合要求的選擇項),或者馬上啓動接收activity(若是隻有一個符合要求的接收activity)。java

發送文本內容

activity之間傳遞數據的最簡單、直接的使用ACTION_SEND的方式是傳遞文本。例如,內置的瀏覽器應用將展現頁面的url做爲數據分享給其餘應用。對於經過email或社交軟件分享文章或網址這很是有用。
android

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

若是一個安裝的app帶了過濾器能夠匹配ACTION_SEND和MIME類型的text/plain,android系統將運行這個app,若是超過一個將會提供選擇。瀏覽器

然而,若是你調用Intent.createChooser(),將你的Intent做爲參數傳遞過去,這將老是返回可選項界面。網絡

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

可選地,你能夠爲intent設置一些標準參數,如:EXTRA_EMAIL, EXTRA_CC, EXTRA_BCC, EXTRA_SUBJECT.若是這個接收的app沒有設置接收這些參數,這個參數將被忽略。app

發送二進制內容

二進制數據也能夠經過ACTION_SEND分享,一般組合相適應的MIME類型以及將uri的數據放置在EXTRA_STREAM中。這種方法常常被用來分享圖片但也能夠被用來分享其餘二進制數據。
ide

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

有如下幾點須要注意:
ui

  1. 你能夠將MIME類型設置爲*/*,但這種類型將只配置能夠處理通常數據流的activity。google

  2. 接收app須要讀取uri指向的數據的權限,有以下推薦方式:url

  • 存儲數據在contentProvider中,保證別的應用程序對你的provider有正確的權限,  對於保護權限的優先方案是使用前綴URI權限,這個權限是臨時的或是僅向接收app開放權限。建立一個contentProvider的簡單方式是使用FileProvider幫助類。spa

  • 使用系統MediaStore。Mediastore最初被設計用於video、audio和圖片類型,可是3.0後也被用於存儲非媒體類型。適於分享的content://類型的Uri能夠做爲onScanCompleted()回調方法的參數,這以後文件能夠經過scanFile()方法被插入到MediaStore中。須要注意的是一旦被加入到系統MediaStore中,設備中的全部app均可以操做這個文件。

    發送多個內容模塊

    爲了分享多個內容,你須要指定action爲ACTION_SEND_MULTUPLE,同時傳遞指向具體內容URIs。例如發送一個JPEG圖片時,須要設置成「image/jpeg",可是不一樣的圖片類型時,須要設置成"image/*",若是你想要分享各類類型的內容,須要設置成「*/*」.如前面所述,這些都取決於接收app怎麼解析和處理數據。

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

 此外也要注意,你提供的URIs指向的數據能夠被接收的app操做。

    從別的apps接收簡單數據

       你的app不只能夠發送數據,也能夠接收數據。考慮下用戶怎樣和你的app交互,你想要接收怎樣的數據。例如,社交網絡app可能對接收文本內容,好比網址,感興趣。google+應用能夠接收文本和圖片。經過這個app用戶能夠輕鬆的向google+傳遞照片。

     更新manifest文件

       Intent過濾器通知系統應用程序想要接收怎樣的intents。和構造intent類似,須要建立intent過濾器以可以接收肯定action的intent。能夠在mainfest中使用<intent-filers>來建立過濾器。

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

  當另外一個app想要分享這些內容中的一些時,你的app將被列在可選項中。

  處理接收的內容

   爲了處理被intent傳輸的內容,能夠經過getIntent()方法獲取intent對象。一旦你持有這個對象,你能夠檢驗傳輸的內容來決定下一步作什麼,須要注意的是若是一個activity能夠被系統別的部分啓動,好比桌面,須要將檢查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
    }
}

當心 :  在當心檢查接收的數據時,因爲你不可能知作別的app發送給你什麼樣的數據,多是錯誤的MIME類型,也多是超大的圖片文件。因此須要記住要在工做線程中處理二進制數據而不是在UI線程。

  添加一個簡單的分享操做

          實現有效、用戶友好的分享操做因爲4.0裏actionProvider的引進變得相對簡單了。actionProvider曾經和菜單項相關聯,用來出來這項的外表和行爲。

   更新菜單聲明

爲了使用shareActionProviders,須要在menu資源文件的<item>子項裏定義android:acionProviderClass屬性。

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

ShareActionProvider負責這個項的外貌和做用。然而你須要告訴這個provider你想要分享什麼。

設置分享intent

爲了使ShareActionProvider起做用,你必須爲它提供一個分享intent。爲了指派分享intent,首先找到這個相應的菜單項,這能夠在activity或fragment加載菜單資源文件時操做,下一步,調用MenuItem.getActionProvider()方法獲取ShareActionProvider實例,使用setShareIntent()更新和操做項相關的分享intent。

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);
    }
}
相關文章
相關標籤/搜索