なるようになるかも

力は多くの場合、その人の思いを超えない。

AndroidでSNS連携する方法

すごく今更な話題なんですけど、iOS8で「AndroidのIntentみたいに簡単に共有できるようになる!」っていう話をよく聞いたので。

OS標準で共有機能のあるiOSアプリをAndroidに移植を行う場合に、「TwitterFacebookに投稿するボタン作って。IntentのあるAndroidなら簡単でしょ?」みたいに言われるんですが、現実は割と甘くないです。

確かに、ACTION_SENDなどで暗黙のインテントを飛ばすだけで勝手に投稿可能なメーラーSNSクライアントが一覧表示されます。

ただし、ACTION_SENDによる共有の考え方では、受け取ったアプリが全てハンドリングしてくれる利点と引き換えに、「Twitterのみに投稿したい」という制約条件を付与できないのです。

加えてSNSごとの文字数制限や、後述するFacebookの独自仕様などがあるため、送る側が何も考えなくても、インテントを受け取ったアプリでどうにかしてくれる…というわけでもありません。

Twitterに投稿したい場合

公式アプリのパッケージ名を指定してACTION_SEND

公式アプリ以外を使ってるユーザーを完全無視してもいいならこの方法が使えます。

URI.parse()を使う

https://twitter.com/intent/tweet?text=に送信したいメッセージを付与してURI.parse()します。大抵のTwitterクライアントはこのURLをハンドリングしてくれるはずです。

http://スキーマなので、普通のブラウザも反応するのが難です。このためTwitterクライアントがインストールされていないことを検知することはできませんし、インストールされていたとしてもログイン状況がどうなっているのかは把握できません。

Twitter4Jを組み込む。

そのため、Intentを投げ捨ててTwitter4Jを使うの最も現実的な解となっているような気がします。

それぞれのアプリがWebViewでログインさせている現状って正直微妙だと思うんですよね。

Account ManagerからOAuth2トークンを引っ張ってくるとか、もうちょっとマシな方法がある気がするのですが…。

Facebookに投稿したい場合

公式アプリのパッケージ名を指定してACTION_SEND

Intent連携を否定しているのがFacebookです。やれることは以下の2点のみです。

  • ウェブサイトへのリンクをシェアする
  • 画像をシェアする

「リンクもしくは画像」以外のものをIntent.EXTRA_TEXTに付与した場合、 その内容は破棄されます

なぜなら、Facebookには「 ウォールに投稿する文章はユーザーが制御するべき 」というポリシーがあるため、アプリ側から文字列を事前にプリセットする行為そのものが非推奨なのです。

じゃあなんでiOSのSocial.Frameworkだとできるの…。

Facebook SDKを使う

Android用の公式SDKを使う場合も、上記制約は変わらないため、FacebookDialog.ShareDialogではテキストのプリセットはできません。

何らかの文字をプリセットしたい場合、投稿用のDialogFragmentを自作しなければなりません。

LINEに投稿したい場合

LINEもIntent連携を無視した独自ルールを採用しています。

具体的には、line://msg/text/URI.parse()以外の方法で連携する手段がありません。

それiOSのURLスキームだと思うんですけど…。