内容
アプリからのツイートをtwitter-kit-androidライブラリを使って行っているが、最近TwitterアプリのDM送信画面が起動するようになったので調査する。
調査
TwitterアプリのIntentFilterを確認する
ツイートにはIntent.ACTION_SEND
を使用しているので、本来とは別なActivityが起動しているということはActionに対して別なActivityが起動している可能性が高い。そこでまずTwitterアプリのインテントアクションを確認する
$ adb shell $ pm list packages |grep twitter package:com.twitter.android $ pm dump com.twitter.android|head -n100 DUMP OF SERVICE package: Activity Resolver Table: Full MIME Types: text/plain: c4751b1 com.twitter.android/com.twitter.app.dm.DMActivity filter 527e696 Action: "android.intent.action.SEND" Category: "android.intent.category.DEFAULT" StaticType: "text/plain" 54ff165 com.twitter.android/com.twitter.composer.ComposerActivity filter 7b4be3a Action: "android.intent.action.SEND" Category: "android.intent.category.DEFAULT" StaticType: "text/plain" (dumpは関連箇所を抜粋)
上記はAndroidManifestを見た方がよかったかもしれないが、
ともかくACTION_SEND
に対して DMActivity
, ComposerActivity
が反応することが分かる。
実際にはもっとあるが、関係するのはこの2つ。そして、ツイートに使われるのはComposerActivity
の方だろう。
ツイートの仕組みを確認する
ツイートの際にはTweetComposer.Builder
を使ってテキストやイメージを渡している。
TweetComposer.Builder(context) .image(someImage) .text(someText) .show()
でもってTweetCompser内、createTwitterIntent
に含まれるコードを見ると
final PackageManager packManager = context.getPackageManager(); final List<ResolveInfo> resolvedInfoList = packManager.queryIntentActivities(intent, PackageManager.MATCH_DEFAULT_ONLY); for (ResolveInfo resolveInfo: resolvedInfoList){ if (resolveInfo.activityInfo.packageName.startsWith(TWITTER_PACKAGE_NAME)){ intent.setClassName(resolveInfo.activityInfo.packageName, resolveInfo.activityInfo.name); return intent; } }
というのがある。Activityの一覧を取得しているが、Twitterのパッケージかどうかしか確認しておらず、最初に見つかったものを使っている。なので最初にみつかるDMActivityが反応してしまう。
結論
Twitterアプリ側が修正される可能性もあるが、ComposerActivityを直接指定すれば対応はできそう。 ライブラリのメンテナンスが終了してしまっているため、 自前で実装するかフォークされたものでメンテナンスされてそうなのを 使うのが良いだろう。 TweetComposerはクラスとして独立しているので、 アプリ内で似たようなものを作ってしまうのが一番手っ取り早い気がする。