[MT]AndroidからDataAPIで、記事のカテゴリを指定する

DataAPIはAndroidで記事を投稿したい！というときにとても重要なAPIです。
今回は、その中からカテゴリの指定についてざっくり説明したいと思います。
※本記事は、ライフサイクルやAPIなど理解しているAndroid開発中級者以上を対象としています。
#記事のカテゴリを取得する
MainActivity.java

```Java
package com.example.mtapply01;

import java.util.ArrayList;

import android.os.Bundle;
import android.app.Activity;
import android.view.View;

import com.loopj.android.http.*;
import org.apache.http.Header;
import org.apache.http.message.BasicHeader;
import org.json.*;

import android.widget.Button;
import android.widget.TextView;
import android.widget.Toast;

public class MainActivity extends Activity  {
    MainActivity act;
    Button btnSend;
    TextView txtTitle, txtBody;

    String cgi_url  = "http://path/to/mt-data-api.cgi";
    String blog_id  = "id";
    String username = "username";
    String password = "password";
    String token;
    ArrayList<String>  categoryLabel;
    ArrayList<Integer> categoryId;
    AsyncHttpClient    client;


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        setContentView(R.layout.activity_main);
        act = this;
        btnSend = (Button) findViewById(R.id.btnSend);
        txtTitle = (TextView) findViewById(R.id.txtTitle);
        txtBody = (TextView) findViewById(R.id.txtBody);

        categoryLabel        = new ArrayList<String>();
        categoryId           = new ArrayList<Integer>();
        client               = new AsyncHttpClient();
        RequestParams params = new RequestParams();

        params.put("username", username);
        params.put("password", password);
        params.put("clientId", "test");

        String url = cgi_url.concat("/v2/authentication");
        client.post(url, params, new JsonHttpResponseHandler() {
            @Override
            public void onSuccess(JSONObject res) {
                try {
                    token = res.getString("accessToken");
                    Toast.makeText(act, "ログインしました", Toast.LENGTH_LONG).show();
                } catch (Exception e) {
                    Toast.makeText(act, "ログインエラー", Toast.LENGTH_LONG).show();
                }
            }

            @Override
            public void onFailure(Throwable e, JSONObject res) {
                Toast.makeText(act, "ログインエラー", Toast.LENGTH_LONG).show();
            }
        });

        url = cgi_url.concat("/v2/sites/2/categories");
        client.get(url, params, new JsonHttpResponseHandler() {
            @Override
            public void onSuccess(JSONObject json) {
                try {
                    // タイトルを取得する場合
                    JSONArray datas = json.getJSONArray("items");
                    for (int i = 0; i < datas.length(); i++) {
                        categoryLabel.add(datas.getJSONObject(i).getString("label"));
                        categoryId.add(Integer.parseInt(datas.getJSONObject(i).getString("id")));
                    }
                } catch (JSONException e) {
                    e.printStackTrace();
                }
            }

            @Override
            public void onFailure(Throwable e, JSONObject res) {
                Toast.makeText(act, "ログインエラー", Toast.LENGTH_LONG).show();
            }
        });



        btnSend.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                // Post entry
                try {
                    uploadText();
                } catch (JSONException e) {
                    e.printStackTrace();
                }
            }
        });

    }


    private void uploadText() throws JSONException {
        CharSequence  title  = "title";
        CharSequence  body   = "body";
        JSONObject    entry  = new JSONObject();
        RequestParams params = new RequestParams();
        JSONArray categories = new JSONArray();
        JSONObject category;
        for(int i=0; i<categoryLabel.size(); i++) {
            category = new JSONObject();
            category.put("id",categoryId.get(i));
            categories.put(category);
        }
        try {
            entry.put("title", title);
            entry.put("body", body);
            entry.put("categories",categories);
            entry.put("status", "Draft");
        } catch (JSONException e) {
            e.printStackTrace();
        }
        params.put("entry", entry.toString());
        String url = cgi_url.concat("/v2/sites/").concat(blog_id).concat("/entries");
        Header[] headers = new Header[1];
        headers[0] = new BasicHeader("X-MT-Authorization", "MTAuth accessToken=".concat(token));
        client.post(getBaseContext(), url, headers, params, "application/x-www-form-urlencoded", new JsonHttpResponseHandler() {
            @Override
            public void onSuccess(JSONObject res) {
                Toast.makeText(act, "送信完了", Toast.LENGTH_LONG).show();
            }
            public void onFailure(Throwable e, JSONObject res) {
                Toast.makeText(act, "送信エラー", Toast.LENGTH_LONG).show();
            }
        });

    }


    private void setButtonEnable(boolean flagEnable){
        btnSend.setEnabled(flagEnable);
    }

    public void onResume() {
        super.onResume();
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
    }

    @Override
    protected void onStop() {
        super.onStop();
    }
}
```
activity_main.xml

```XML
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="#eeeeee"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    tools:context=".MainActivity" >

    <TextView
        android:id="@+id/textView1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="タイトル" />

    <EditText
        android:id="@+id/txtTitle"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentLeft="true"
        android:layout_alignParentRight="true"
        android:layout_below="@+id/textView1"
        android:background="#ffffff"
        android:ems="10"
        android:inputType="text"
        android:padding="3dp" >

        <requestFocus />
    </EditText>

    <TextView
        android:id="@+id/textView2"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentLeft="true"
        android:layout_below="@+id/txtTitle"
        android:layout_marginTop="16dp"
        android:text="本文"
        android:textAppearance="?android:attr/textAppearanceSmall" />

    <EditText
        android:id="@+id/txtBody"
        android:layout_width="wrap_content"
        android:layout_height="match_parent"
        android:layout_alignParentLeft="true"
        android:layout_alignParentRight="true"
        android:layout_below="@+id/textView2"
        android:background="#ffffff"
        android:ems="10"
        android:gravity="center_vertical|top"
        android:inputType="textMultiLine"
        android:padding="3dp"
        android:layout_above="@+id/btnSend" />

    <Button
        android:id="@+id/btnSend"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentBottom="true"
        android:layout_centerHorizontal="true"
        android:text="送信"
        />


</RelativeLayout>
```

メンバ領域に、`cgi_url:DataAPIのエンドポイント`、`blog_id:ブログID`、`username     :ユーザー名`、`password:パスワード`を宣言します。

記事の取得は、`onCreate`内でやります。

ログインするために、メンバ変数の`username`と`password`を`RequestParams`に挿入し`AsyncHttpClient`で`cgi_url+/v2/authentication`に**post**します。

ログインに成功すると、`onSuccess`に入り`JSONObject`が返却されるので`accessToken`を保存しておきます。

記事のカテゴリを取得するのは、先ほど作成した`RequestParams`を`AsyncHttpClient`で`cgi_url+/v2/sites/2/categories`に**post**します。

カテゴリの取得に成功すると、`onSuccess`に入るので`JSONArray`に`items`の要素を挿入します。

```Java
JSONArray datas = json.getJSONArray("items");
```

取得してきた`items`から登録されているカテゴリの`label`と`id`を取得します。

```Java
for(int i=0; i<datas.length(); i++) {
    categoryLabel.add(datas.getJSONObject(i).getString("label"));
    categoryId.add(Integer.parseInt(datas.getJSONObject(i).getString("id")));
}
```

これで、記事のカテゴリを取得できます。

#記事を投稿する
ここまで出来れば、あとは投稿するだけです。

```Java
    private void uploadText() throws JSONException {
        CharSequence  title  = "title";
        CharSequence  body   = "body";
        JSONObject    entry  = new JSONObject();
        RequestParams params = new RequestParams();
        JSONArray categories = new JSONArray();
        JSONObject category;
        for(int i=0; i<categoryLabel.size(); i++) {           
            category = new JSONObject();
            category.put("id",categoryId.get(i));
            categories.put(category);
        }
        try {
            entry.put("title", title);
            entry.put("body", body);
            entry.put("categories",categories);
            entry.put("status", "Draft");
        } catch (JSONException e) {
            e.printStackTrace();
        }
        params.put("entry", entry.toString());
        String url = cgi_url.concat("/v2/sites/").concat(blog_id).concat("/entries");
        Header[] headers = new Header[1];
        headers[0] = new BasicHeader("X-MT-Authorization", "MTAuth accessToken=".concat(token));
        client.post(getBaseContext(), url, headers, params, "application/x-www-form-urlencoded", new JsonHttpResponseHandler() {
            @Override
            public void onSuccess(JSONObject res) {
                Toast.makeText(act, "送信完了", Toast.LENGTH_LONG).show();
            }
            public void onFailure(Throwable e, JSONObject res) {
                Toast.makeText(act, "送信エラー", Toast.LENGTH_LONG).show();
            }
        });

    }
```
まず、エントリとなる要素の`JSONObject`と記事リクエストを送信するための`RequestParams`を作成します。
あとは、複数のカテゴリを挿入するための`JSONArray`と個々のカテゴリを挿入する`JSONObject`を用意します。
カテゴリのエントリはidで、カテゴリ群のエントリはcategoriesになります。
**post**する時は、`categories`内に`category`を挿入する形で送信します。
あとは、`AsyncHttpClient`で`url`のエンドポイントと`params`と設定した`headers`を入れて送信すればカテゴリが登録された記事が出来ます。

#補足
インターネットを使用するので、AndroidManifest内に
`<uses-permission android:name="android.permission.INTERNET"/>`
`<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>`
を宣言する事はお忘れなく！

# 感想
上司から作ってみる？と聞かれて初めてQiitaに投稿しました！
ショボすぎる内容ですいません。。。
次書くときはもっと頑張ります！