Twitter Kit for Androidを使って画像付きツイート

TwitterAPIを使うのに、今までは非公式ライブラリであるTwitter4Jなどを利用しておりましたが、公式ライブラリであるTwitter Kit for Androidがリリースされましたので、このライブラリを使用して画像付きツイートを実現してみます。

環境は下記のとおりです。

課題

Twitter Kitで画像付きTweetをするには下記課題があります。

  1. まだライブラリがmedia/uploadに対応していない
  2. その上、statuses/updateにmedia_idsを渡すためのIFも用意されていない

解決策

1. まだライブラリがmedia/uploadを対応していない

自前で対応します。

Twitter KitでREST APIを使用するにはTwitterApiClientを使用しますので、それにちなんで、media/upload対応したクライアントをTwitterUploadClientとします。

2. その上、statuses/updateにmedia_idsを渡すためのIFも用意されていない

自前で用意します。

TwitterApiClientを継承したClassを作成して対応します。

実装

  1. media/upload対応したTwitterUploadClientを実装する
  2. media/uploadのレスポンスをマッピングするMediaEntityを実装する
  3. TwitterApiClientを継承して、statuses/updateのmedia_idsに対応したIFを備えるMyTWitterApiClientを実装する

使用例

TwitterUploadClient twitterApiClient = new TwitterUploadClient(Twitter.getSessionManager().getActiveSession());
TwitterUploadClient.MediaService mediaService = twitterApiClient.getMediaService();
String imageData = "/9j/4AAQSkZJRgABAQEAAQABAAD/2wBDAAcFBgYGBQcGBgYICAcJCxIMCwoKCxcQEQ0SGxccHBoXGhkdISokHR8oIBkaJTIlKCwtLzAvHSM0ODQuNyouLy7/2wBDAQgICAsKCxYMDBYuHhoeLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi7/wAARCAAgACADASIAAhEBAxEB/8QAGQABAQADAQAAAAAAAAAAAAAABgcAAwQF/8QALRAAAQMDAwIEBQUAAAAAAAAAAQIDBAAFEQYSIUFhEzEyUQcUgZGhNHLB0fD/xAAXAQEBAQEAAAAAAAAAAAAAAAAFBgME/8QAJBEAAQMDBAIDAQAAAAAAAAAAAQIDBAARIQUTMXFBkRQjgaH/2gAMAwEAAhEDEQA/AL7f73CsUAzJi/M7W20+pxXsKnErXt0lOEtLRGb6IQkE/Ums+Ja13K6OxAf0qQGv3EZP3yBRuxxYDMNiVcGfmHpAKkNLUQhtAUU5IGCSSD2AHeuL7pD2014pXTpOnNxlvP5Uk2tz1Ye/VIY+vrtEcCnVtym+qHEgH6EeVUnT18g3+AJkJR4O1xtXqbV7H++tTSBAsFzW40Lc00+2nfhClbVpzg8E8EZFKNKQoVquOITAaD42LwTzjkdf9mj3tSVBmphSAbqtY+M4B91s+uDMj7sZJBHX9zXha8iri6hW8oHw5SAtJ7gYI/A+9HJbAmR2Q0+2xIZBSPEB2OJJJ5IBwQSemDmrNfLREvUFUSUCOdyHE+ptXuKms7R2oYjpSw03MZzw42sJOO6T/GaRG9He3majZMVYWVIFwa1aQgmMZMl2Ql95SfCy2DsQMgkAkAqPA6YHemdibL1zQU+loFSj+BXHbbDcg03HSwI7aRgrcIyfc4FL7bAZgMeE3lSjytZ81GgUw5mpal86WLJTwOuMd5qgZCIsUMpyTz+81//Z";
mediaService.upload(imageData, new Callback<MediaEntity>() {
    @Override
    public void success(Result<MediaEntity> result) {
        MyTwitterApiClient twitterApiClient = new MyTwitterApiClient(Twitter.getSessionManager().getActiveSession());
        MyTwitterApiClient.MyStatusesService statusesService = twitterApiClient.getMyStatusesService();
        statusesService.update("upload test", null, result.data.mediaIdString, new Callback<Tweet>(){

            @Override
            public void success(Result<Tweet> result) {

            }

            @Override
            public void failure(TwitterException e) {

            }
        });


    }

    @Override
    public void failure(TwitterException e) {

    }

});

Parse Android SDK1.8+でPush通知を無視する

Push通知をON/OFFにしたい。それをParseでするのに以前はPushService.setDefaultPushCallbacknullを渡すことで実現していましたが、ひさしぶりにParseを使ってみるとPushService.setDefaultPushCallbackがdeprecatedになっていたので代替の方法を探しました。

環境は次のとおり。

  • Parse Android SDK1.8+
  • gradle 2.2.1

ググって見つかったsubscribe/unsubscribeを使ってchannel指定する方法だと、everyoneに配信したときに通知がでてしまう。ここのオペレーションは変えたくない。 そこで、Push通知を受け取るReceiverを継承してごにょごにょする方法を試したところ上手く行きました。

public class CustomReceiver extends ParsePushBroadcastReceiver {
    private static final String TAG = "CustomReceiver";

    @Override
    public void onReceive(Context context, Intent intent) {
        Setting setting = ((AnyApplication)context.getApplicationContext()).getSetting();
        if( setting.isEnabledReceiveNotification() ) {
            super.onReceive(context, intent);
        } else {
            abortBroadcast();
        }
    }
}
        <receiver
            android:name="${applicationId}.CustomReceiver"
            android:exported="false">
            <intent-filter>
                <action android:name="com.parse.push.intent.RECEIVE" />
                <action android:name="com.parse.push.intent.DELETE" />
                <action android:name="com.parse.push.intent.OPEN" />
            </intent-filter>
        </receiver>

参考

disabling-parse-notifications

parse-android-disable-push-notifications

MacでWifi共有で透過的にmitmproxy

mitmproxyをWifi共有を使って透過的proxyとして使うための手順メモです。 実施環境は下記の通り。

手順

  1. mitmproxyのインストール
  2. 証明書を端末(iPhone/Android)にインストール
  3. Wifi共有の設定
  4. Packet forwardingの設定

1.mitmproxyのインストール

$ pip install mitmproxy

2.証明書を端末(iPhone/Android)にインストール

下記に配置されているのでメールなどを使って端末に送る。 添付ファイルをタップすれば自動的にインストールのためのアプリ選択画面が表示される。

$ ~/.mitmproxy/mitmproxy-ca-cert.pem

f:id:bagpack:20140204225038p:plain

3.Wifi共有の設定

OS X側で、システム環境設定 -> 共有 -> インターネット共有からWifi共有の設定をする。 端末側はここで設定したWifiポイントにつなぐようにする。

4.Packet forwardingの設定

最後にport80/443に流れてくるパケットをmitmproxyにリダイレクトするようにする。 まずは、Wifi共有に使われているインターフェース名を調べる。

$ ifconfig

(たいてい、bridge0というような名前)

Packet forwardingを有効にする

$ sudo sysctl -w net.inet.ip.forwarding=1

Packet forwardingの設定を下記のような感じにする。

$ sudo vi /private/etc/pf.conf
scrub-anchor "com.apple/*"
nat-anchor "com.apple/*"
rdr-anchor "com.apple/*"
rdr pass on bridge0 inet proto tcp from 192.168.2.0/24 to any port http -> 127.0.0.1 port 8080
rdr pass on bridge0 inet proto tcp from 192.168.2.0/24 to any port https -> 127.0.0.1 port 8080
dummynet-anchor "com.apple/*"
anchor "com.apple/*"
load anchor "com.apple" from "/etc/pf.anchors/com.apple"

pfを有効にする。

$ sudo pfctl -f /private/etc/pf.conf
$ sudo pfctl -e

mitmproxyを透過的プロキシモードで起動する。

$ mitmproxy -T --host

おしまい。

 参考

mitmproxy公式

GradleでAndroidアプリを起動するタスクを追加する

GradleのAndroid Pluginはapkをビルドしてインストールするところまではやってくれますが、アプリの起動まではやってくれません。 ということで、アプリの起動をやってくれるタスクを追加しましょう。

実行環境は下記のとおりです。

タスクの追加

下記の記述をbuild.gradleに追加します。

使い方

次のようにして実行します。(実際にはbuildTypeの種類だけタスクが追加されます)

$ gradle runDebug 
$ gradle runRelease

参考

Custom Tasks hooking on to all flavors of a given buildtype

Thx

ichigotake様