[Android]簡単なTwitter Client Applicationを開発する

Androidで、自分のTwitterアカウントと連携し、リツイートした一覧を表示するだけの簡単なアプリケーションを開発してみようと思います。

事前準備

まず事前準備としてTwitterアカウントとTwitter Deceloperアカウントの2つが必要です。Twitterアカウントに関してはほとんどの人が持っていると思うので割愛します。

Twitter Developerアカウントを作成する

Twitter DeveloperのページからDeveloperアカウントの登録を行います。長いので読み飛ばしてもらっても大丈夫です。

Twitter Developerにアクセス

https://developer.twitter.com/en

メニューからApplyを選択

Apply for developer accountを押す

用途を選択する

ここでは自分自身についてのことと、Twitter Developerアカウントをどのように使用するかといったことを選択します。

Hobbyist(趣味でやっている)、Build Tooles for Twitter users(Twitterユーザー向けのビルドツール)、を選択しました。

ユーザーの基本情報を入力する

Twitter APIの使用用途を明確に記載する

ここではどのようにAPIを使用するかを、英字(200文字以上)で記述します。

簡単なアプリケーションを開発する旨を、Google先生に翻訳してもらい設定しました。

アプリケーションに関する質問

アプリケーションに関していくつか質問されます。今回は分析する予定はなし、ReadOnlyのアプリケーションなのですべてNoを選択しました。

  • Twitterデータを分析する予定があるかどうか
  • アプリケーションからツイート、リツイート、DM送信などを実装するかどうか
  • Twitter以外のコンテンツを表示するかどうか
  • 政府機関が利用できるようにするかどうか

入力内容の確認

開発者契約、ポリシーの確認

登録用のEメールが届く

Eメールの完了ボタンを押して登録完了

Developer portalのダッシュボードが開くのでここをブックマークしておくと良いです。

API KeyとAPI Key Secretを発行

つぎにクライアントアプリケーションからTwitter APIを使用するために必要な、API KeyAPI Key Secretを発行します。

+ Create APP

Developer Portalから、Project & Apps > Overview > + Create App

アプリケーション名を入力

ここは何でも良いので分かりやすいアプリケーション名を入力してNext

アプリケーション登録

ここで発行されたAPI Key、API Key Secret、Bearer Tokenを控えておく。

認証設定

次に作成するアプリケーションから認証を可能にするための設定を行います。

Authentication settings

Developer Portalから、Project & Apps > 作成したアプリケーション > Authentication settings > Edit

Enable 3-legged OAuth にチェックを入れ、以下の必須項目を入力しSaveします。

  • Callback URLs (required)
    Webアプリケーションの場合は認証後に遷移する画面のURLを設定しますが、アプリケーションの場合は「twittersdk://」を固定で入力します。
  • Website URL (required)
    アプリケーション開発者のWebサイトURLを入力します。ここではこのブログのURLを入力しました。あとから変更できます。

実装

ライブラリと権限の設定

app/build.gradle

まずはdependenciesに以下の行を追加して、「Sync Now」を押せばライブラリがダウンロードされます。

implementation 'com.twitter.sdk.android:twitter-core:3.1.1'

AndroidManifest.xml

INTERNET通信の権限を設定します。

<uses-permission android:name="android.permission.INTERNET" />

アプリケーション起動時の処理

MainActivity.onCreate

アプリケーション起動時の処理ですが、Twitterライブラリの初期化処理を行います。TwitterAuthConfigのコンストラクタに渡しているAPI_KEYとAPI_SECRETは事前準備で発行したKEYをセットします。この処理はアプリケーションの起動時に1回だけ行えば良いです。

次にActiveSessionを確認し、ログイン済みであれば画面初期化処理を、未ログインであればログイン画面へ遷移するようにしています。

super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);

TwitterConfig config = new TwitterConfig.Builder(this)
        .logger(new DefaultLogger(Log.DEBUG))
        .twitterAuthConfig(new TwitterAuthConfig(API_KEY, API_SECRET))
        .debug(true)
        .build();
Twitter.initialize(config);

if (TwitterCore.getInstance().getSessionManager().getActiveSession() == null) {
    Intent intent = new Intent(this, LoginActivity.class);
    startActivity(intent);
    finish();
} else {
    init();
}

ログイン画面の処理

LoginActivity.onCreate

ログイン画面ではTwitterLoginButtonを設置し、Callbackクラスでログインの結果を受け取ります。

loginButton = findViewById(R.id.twitterLoginButton);
loginButton.setCallback(new Callback<TwitterSession>() {
    @Override
    public void success(Result<TwitterSession> result) {
        Toast.makeText(LoginActivity.this, "ログイン成功", Toast.LENGTH_LONG).show();
        Intent intent = new Intent(LoginActivity.this, MainActivity.class);
        startActivity(intent);
        finish();
    }

    @Override
    public void failure(TwitterException exception) {
        Toast.makeText(LoginActivity.this, exception.getMessage(), Toast.LENGTH_LONG).show();
    }
});

layout_login.xml

View側は以下のボタンが設置してあればOKです。

<com.twitter.sdk.android.core.identity.TwitterLoginButton
    android:id="@+id/twitterLoginButton"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content" />

画面初期化とRetweet取得

MainActivity.init()

ログインに成功すると今度は画面の初期化処理 (initメソッド) が呼ばれます。ここではスレッドの中でgetRetweets()メソッドを呼びます。

private void init() {
    progressDialog = new ProgressDialog(this);
    progressDialog.setMessage("Loading...");
    progressDialog.show();

    text = new StringBuilder();

    new Thread(new Runnable() {
        @Override
        public void run() {
            try {
                handler.post(new Runnable() {
                    @Override
                    public void run() {
                        getRetweets();
                    }
                });
            } catch (Exception e) {
                Log.d("ERROR", e.getMessage());
            }
        }
    }).start();
}

MainActivity.getRetweets()

getRetweets()内では、verifyCredentialsメソッドによりログイン中のユーザー情報を取得します。結果はCallback処理で受け取ります。

private void getRetweets() {
    Call<User> callUser = TwitterCore.getInstance().getApiClient().getAccountService().verifyCredentials(true, true, true);
    callUser.enqueue(new Callback<User>() {
        @Override
        public void success(Result<User> result) {
            user = result.data;
            Toast.makeText(MainActivity.this, result.data.screenName, Toast.LENGTH_LONG).show();

            text.append("id:" + user.id + "\n");
            text.append("screen_name:" + user.screenName + "\n\n");

            getRetweets(user.id, user.screenName);
        }

        @Override
        public void failure(TwitterException exception) {
            Toast.makeText(MainActivity.this, exception.getMessage(), Toast.LENGTH_LONG).show();
            progressDialog.dismiss();
        }
    });
}

MainActivity.getRetweets(long, String)

getRetweets(long, String)内で、ユーザーに紐づくツイート情報を取得し、更にリツイート情報を抜き出して画面に表示しています。

private void getRetweets(long id, String name) {
    StatusesService service = TwitterCore.getInstance().getApiClient().getStatusesService();

    Call<List<Tweet>> callTimeline = service.userTimeline(
            id, name, 100, null, null, false, false, false, true);

    callTimeline.enqueue(new Callback<List<Tweet>>() {
        @Override
        public void success(Result<List<Tweet>> result) {
            Toast.makeText(MainActivity.this, "timeline:" + result.data.toString(), Toast.LENGTH_LONG).show();

            for (Tweet tweet : result.data) {
                if (tweet.retweeted) {
                    text.append("tweet_id:" + tweet.id + "\n");
                    text.append("user:" + tweet.user.screenName + "\n");
                    text.append("text:" + tweet.text.substring(0, 30).replaceAll("[\n]+", " ") + "\n");
                    text.append("created_at:" + tweet.createdAt + "\n");
                    text.append("-----------------------------------\n");
                }
            }

            ((TextView) findViewById(R.id.textConsole)).setText(text.toString());
            progressDialog.dismiss();
        }

        @Override
        public void failure(TwitterException exception) {
            Toast.makeText(MainActivity.this, exception.getMessage(), Toast.LENGTH_LONG).show();
            progressDialog.dismiss();
        }
    });
}

userTimelineメソッドについて

twitter.comでユーザーのプロファイルを表示したときに表示されるものを返します。タイムラインを要求するときは、常にuser_idまたはscreen_nameのいずれかを指定します。includeRetweetsにTrueを指定するとユーザーがリツイートした内容を含みます。

userTimeline(Long userId,
    String screenName,
    Integer count,
    Long sinceId,
    Long maxId,
    Boolean trimUser,
    Boolean excludeReplies,
    Boolean contributeDetails,
    Boolean includeRetweets)

動作確認

アプリケーションのログイン画面

アプリケーションの初回起動時はセッション情報を持っていないのでログイン画面へ遷移します。

Twitterのログイン画面

「Twitterにログイン」ボタンを押すとTwitter-Core-SDKがログイン画面を出してくれます。ここに表示されるアプリケーションに関する情報が、事前準備の認証設定でセットした内容です。

メイン画面

ログインに成功するとリツイートを検索することができました。次回以降、起動したときはセッション情報が残っている限りログインの必要はなくなります。

エラーについて

「Twitterへログイン」ボタンを押してエラーが発生してfailureへ入る時

E/Twitter: Authorization completed with an error
com.twitter.sdk.android.core.TwitterAuthException: Failed to get request token

認証設定をしていないとこのエラーが発生します。

「Twitterログイン」ボタンがグレーアウトして押せない時

Twitter.initialize(Config) メソッドを呼び出していないか、失敗している時はログインボタンが押せなくなります。画面起動時の処理を確認し、問題ないようであればDeveloper portalでAPI_KEY、API_SECRETを確認してください。

サンプルソースコードについて

ここまでのソースコード以下にPUSHしました。

https://github.com/s-watanabe-apps/my-retweets/releases/tag/0.1.0

コメント

このブログの人気の投稿

docker-compose up で proxyconnect tcp: dial tcp: lookup proxy.example.com: no such host

docker-compose で起動したweb、MySQLに接続できない事象

【PHP】PHP_CodeSnifferを使う(コーディングルールのカスタマイズ)