Azure Mobile Apps を利用して Androidアプリ開発　その2


[その１](http://qiita.com/maehara08/items/4c04e3cbfce41735f381)でAzure Mobile Apps のインスタンスを作り、使用するための下準備をしました。

今回は、実際にフロントサイドで掲示板風アプリを作ります。
エラー処理などもかなーり適当なので、通信方法の参考程度にどうぞ。

## MySQLのテーブルを作成
その前にデータベースのテーブルを作成しましょう。
Azureポータルから
リソースグループ -> 作ったMobile App -> Setting -> Mobile 
の中の Easy tables -> Add 

![s](https://qiita-image-store.s3.amazonaws.com/0/93802/c9ff2696-4542-afa1-1a50-5f5e12873e64.png )

テーブル名を覚えておきましょう
アプリ側でテーブル名に対応したクラスを後で作成します。

また、テキストを保存するためスキーマを追加します。
![aa](https://qiita-image-store.s3.amazonaws.com/0/93802/500331e7-0dbc-1af2-e1df-ec93e1a2af39.png)



## プロジェクト作成

Android Priject を作成しましょう。
Empty Activity で作ってます
![a](https://qiita-image-store.s3.amazonaws.com/0/93802/022f166d-5507-0958-0373-00e4e9bc8cd4.png)

# アプリ開発
##準備

### ライブラリ入れる
その1でダウンロードした、Mobile Apps 向け Android クライアント SDK を使用して実装していきます。libsに入れましょう。
![b](https://qiita-image-store.s3.amazonaws.com/0/93802/347c7f33-97c5-02a4-9d9c-c21158753ca0.png)

### gradleに記述
先ほど入れたライブラリの他にも、必要なライブラリがあります。
まとめて記述しましょう。

```
dependencies {
 	compile files('libs/azure-mobile-android-3.1.0.jar')
    compile 'com.google.guava:guava:18.0'
    compile 'com.google.code.gson:gson:2.4'
    compile 'com.squareup.okhttp:okhttp:2.5.0'
}
```

書いたらSyncしときましょう

### インターネットアクセス許可
インターネットアクセス許可が必要です。

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

## コードを書いていく
### クライアントデータクラスを定義

先ほど作成したテーブルに対応するようにエンティティクラスを作成します。

ゲッター、セッターも準備しておきましょう。

```Java:BBSItem.java
public class BBSItem {
    private String id;
    private String text;

    public String getId() {
        return id;
    }

    public void setId(String s) {
        id = s;
    }

    public String getText() {
        return text;
    }

    public void setText(String s) {
        text = s;
    }
}

```

### テーブル参照を作成
リモートのテーブルを参照するための準備です。

```Java:MainActivity.java
public class MainActivity extends AppCompatActivity {

    MobileServiceClient mClient;
    MobileServiceTable<BBSItem> mBBSTable;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        try {
            mClient=new MobileServiceClient("ここにURL",this);
        } catch (MalformedURLException e) {
            e.printStackTrace();
        }
        mBBSTable=mClient.getTable(BBSItem.class);
    }
}
```

ポイントは

```Java:
mClient=new MobileServiceClient("ここにURL",this);
```

の部分ですね。
AzureポータルのMobileApp画面の要点のなかのURLをここに入れます。
http://アプリ名.azurewebsites.net
です。

### レイアウトを作成
今回はListViewを使います。

```xml:row_list_bbs
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical" android:layout_width="match_parent"
    android:layout_height="match_parent">
    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="bbs"
        android:id="@+id/textBBS"/>

</LinearLayout>

```

activity_main.xml　にも記述しましょう

![ass](https://qiita-image-store.s3.amazonaws.com/0/93802/e4ddb338-2e96-351d-9206-336d79b81b24.png )

```xml:activity_main.xml
 	<FrameLayout
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_weight="6">

        <ListView
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:id="@+id/list_view_BBS"
            tools:listitem="@layout/row_list_bbs"></ListView>
    </FrameLayout>

    <FrameLayout
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_weight="1">

        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:layout_gravity="center"
            android:orientation="horizontal">

            <EditText
                android:id="@+id/editText"
                android:layout_width="0dp"
                android:layout_height="match_parent"
                android:layout_weight="3" />

            <Button
                android:id="@+id/button2"
                android:layout_width="0dp"
                android:layout_height="wrap_content"
                android:layout_weight="1"
                android:text="add" />

            <Button
                android:id="@+id/button"
                android:layout_width="0dp"
                android:layout_height="wrap_content"
                android:layout_weight="1"
                android:text="refresh"
                android:textSize="12dp" />
        </LinearLayout>
    </FrameLayout>
```
  
### カスタムAdapter
続いてListViewのAdapter  

```Java:BBSItemAdapter.java
public class BBSItemAdapter extends ArrayAdapter<BBSItem> {
    private Context mContext;
    private int mLayoutResourceID;

    public BBSItemAdapter(Context context, int resource) {
        super(context, resource);
        mContext = context;
        mLayoutResourceID = resource;
    }

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        View row =convertView;
        final BBSItem currentItem=getItem(position);

        if (row==null){
            LayoutInflater inflater =((Activity)mContext).getLayoutInflater();
            row=inflater.inflate(R.layout.row_list_bbs,parent,false);
        }
        row.setTag(currentItem);
        final TextView textView=(TextView)row.findViewById(R.id.textBBS);
        textView.setText(currentItem.getText());
        return row;
    }
}
```
### 通信を書いていく
仕上げに、MainActivity.javaに、通信処理をAsyncTaskを使って書き上げましょう。

```java:MainActivity.java

public class MainActivity extends AppCompatActivity {

    MobileServiceClient mClient;
    MobileServiceTable<BBSItem> mBBSTable;

    EditText mEditText;
    BBSItemAdapter mAdapter;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        mEditText = (EditText) findViewById(R.id.editText);

        try {
            mClient = new MobileServiceClient("ここにURL", this);
        } catch (MalformedURLException e) {
            e.printStackTrace();
        }
        mBBSTable = mClient.getTable(BBSItem.class);

        mAdapter = new BBSItemAdapter(this, R.layout.row_list_bbs);
        ListView listViewBBS = (ListView) findViewById(R.id.list_view_BBS);
        listViewBBS.setAdapter(mAdapter);
        showAll();
    }

    public void refreshBtn(View v) {
        showAll();
    }

    public void addBtn(View v) {

        AsyncTask<Void, Void, Void> task = new AsyncTask<Void, Void, Void>() {
            String text = mEditText.getText().toString();

            @Override
            protected Void doInBackground(Void... params) {
                BBSItem item = new BBSItem();
                item.setText(text);
                try {
                    BBSItem entity = mBBSTable.insert(item).get();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                } catch (ExecutionException e) {
                    e.printStackTrace();
                }

                return null;
            }
        };
        runAsyncTask(task);
    }

    private void showAll() {
        AsyncTask<Void, Void, Void> task = new AsyncTask<Void, Void, Void>() {
            @Override
            protected Void doInBackground(Void... params) {
                try {
                    final List<BBSItem> results = mBBSTable.execute().get();
                    runOnUiThread(new Runnable() {

                        @Override
                        public void run() {
                            mAdapter.clear();
                            for (BBSItem item : results) {
                                mAdapter.add(item);
                            }
                        }
                    });
                } catch (Exception exception) {
                    e.printStackTrace();

                }
                return null;
            }
        };
        runAsyncTask(task);

    }

    private AsyncTask<Void, Void, Void> runAsyncTask(AsyncTask<Void, Void, Void> task) {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
            return task.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
        } else {
            return task.execute();
        }
    }
}
```

### 完成
実際に動かしてみましょう。まだテーブルに何もないはずなので、AddしRefreshしてみると、更新されていることがわかります。
今回は通信をやってみるという趣旨で書いたので、ちゃんと運用するときはエラー処理周りをもっと書いたほうが良いです。実際久しぶりに起動するときはサーバーの応答が遅くてタイムアウト？で拾ってこれません、、、汗
![adc](https://qiita-image-store.s3.amazonaws.com/0/93802/bb85754c-d0c5-c2df-6b66-9f4397bf2dcc.png)

以上です。