【Android】文字列+画像のシェアをfacebookでもそれ以外でも最低限何とかする方法

暗黙的IntentでAndroidアプリから文字列と画像をシェアしたい場合にfacebookがうまくいかなかったので、そのへんを探る。
他にいいやり方がありそうだけど、見つからなかったので書いておきます。


画像だけをシェアする場合は普通にやるだけです。
ただ、画像だけシェアしてもそこからアプリに結びつけることができないので、画像が拡散するだけになってしまいます。
やっぱりURLなどの情報も一緒にシェアしたい、と言われてしまいます。

文字列と画像をシェアする場合、Facebookの公式アプリで問題発生です。
「image/png」でIntentを送ると文字列が反映されません。
「text/plain」だと画像が反映されません。

ただ「text/plain」で文字列がURLになっていると「リンクのシェア」という形になります。
その場合リンクするHTMLのOGPの文字列、画像を表示できるので、これで良しとします。

良しとできない場合はreturn;。


というわけで、facebookの場合は「text/plain」でURLを渡す、他の場合は「image/png」で文字列と画像を渡す、ということができればいいけどそんなことができるのか。


Y.A.M の 雑記帳: Facebookとそれ以外でACTION_SENDで渡すテキストを変える

できるようです。

というわけでやってみたところうまくできました。
ソースこちら。

//OGPにシェアする画像と文字列を設定したhtmlのURL
//動的に生成する場合はシェアする時に画像アップロードしてHTMLも生成する
String link = "http://headlines.yahoo.co.jp/hl?a=20141120-00000011-jij_afp-int";

//シェアする画像のパス
//「/sdcard/Android/data/パッケージ名/files」に置く。
//パスには「file://」をつける。(Gmail対策)
String image = "file:///sdcard/Android/data/パッケージ名/files/share.png";


Intent intent = new Intent(Intent.ACTION_SEND);
//最初はimage/pngにしておく -> 画像を扱えるアプリたちが出てくる(facebookも出てくる)
intent.setType("image/png");

List<ResolveInfo> resInfo = getPackageManager().queryIntentActivities(intent, 0);  
if (resInfo.isEmpty()) {
    return;
}

List<Intent> shareIntentList = new ArrayList<Intent>();  

for (ResolveInfo info : resInfo) {  
    Intent shareIntent = (Intent) intent.clone();  

    if (info.activityInfo.packageName.toLowerCase().equals("com.facebook.katana")) {
        //facebook公式アプリの場合
        shareIntent.setType("text/plain");
        shareIntent.putExtra(Intent.EXTRA_TEXT, link);  
    } else {  
        //他のアプリの場合
        shareIntent.setType("image/png"); 
        shareIntent.putExtra(Intent.EXTRA_TEXT, "このポータルサイトすごい http://www.yahoo.co.jp #yahoo");
        shareIntent.putExtra(Intent.EXTRA_STREAM,  Uri.parse(image));
    }
    shareIntent.setPackage(info.activityInfo.packageName);  
    shareIntentList.add(shareIntent);  
}

Intent chooserIntent = Intent.createChooser(shareIntentList.remove(0), "select");
chooserIntent.putExtra(Intent.EXTRA_INITIAL_INTENTS, shareIntentList.toArray(new Parcelable[]{})); 
startActivity(chooserIntent);