【androidとPHP】Volleyを使ったHTTP通信

　超！初歩的なAndroidとPHPを使ってデータベースに保存する方法です。
android側とPHP側のサーバー通信はよく見かけますがそれぞれ別々に書かれていて理解しずらいのでここでは一つにまとめてみたいと思います。自分はド素人の自称アプリデベロッパーなので、いろいろ間違っているかもしれません。


##androidでVolleyを導入
　VolleyはGoogleが提供するオープンライブラリです。HTTP通信を手短ししてくれるライブラリでプログラムもバックグラウンドで動作してくれるみたいなのでとても扱いやすくおすすめです。

build.gradleファイルに以下のコマンドをコピーライブラリを追加してください。
[VolleyのGitHub－現在のVersionはここから確認して下さい](https://github.com/mcxiaoke/android-volley)

```build.gradle
dependencies {
   //Volleyのヴァージョンは随時変更されているので確認するようにお願いします。
    compile 'com.mcxiaoke.volley:library:1.0.19'
}
```

　次にAndroidManifestでインターネットに接続できるように設定します。
注意！！AndroidManifestで宣言しておかないとインターネット通信はできません。

```AndroidManifest.xml

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="myvolley.myvolley_test">

　　<!-- 下記の一行をAndroidManifestに追加 -->
    <uses-permission android:name="android.permission.INTERNET"/>
    
    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:supportsRtl="true"
        android:theme="@style/AppTheme">
        <activity android:name=".MainActivity">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
        <activity android:name=".WriteActivity"></activity>
    </application>

```

##androidでのサーバー通信
　android側ではデータベースを取得する**GET**クラスと書き込みをする**POST**クラス、二つのクラス使ってサーバー通信を行います。
　MainActivity.javaではActivityが生成されるたびにサーバーからデータを呼び出すようにしています。

```MainActivity.java

  private void rereadVolley() {

        //サーバーのアドレス任意
        String GET_URL="サーバーのURL.read.php";

        //queue
        RequestQueue getQueue=Volley.newRequestQueue(this);

 　　　 //Volleyによる通信開始　（GETかPOST、サーバーのURL、受信メゾット、エラーメゾット）
        JsonObjectRequest mRequest = new JsonObjectRequest(Request.Method.GET,GET_URL,

                // 通信成功
                new Response.Listener<JSONObject>() {
                    @Override
                    public void onResponse(JSONObject response) {
                        //リストを更新する
                        ChangeListView(response);
                    }
                },

                // 通信失敗
                new Response.ErrorListener() {
                    @Override
                    public void onErrorResponse(VolleyError error) {
                        Toast.makeText(MainActivity.this,"通信に失敗しました。",Toast.LENGTH_SHORT).show();
                    }
                }
        );

        getQueue.add(mRequest);
    }

```

　データの取得に成功した場合、今度は取得したデータをlistViewに反映させるためJsonデータを解析しアダプターに設定していきます。

```MainActivity.java

    private void ChangeListView(JSONObject response) {

        try {

            //Jsonデータを取得
            JSONArray count=  response.getJSONArray("SQL_TEST");
            adapter.clear();

            //Jsonデータからリストを作成
            for (int i=0;i<count.length();i++){
                JSONObject data=count.getJSONObject(i);
                adapter.add(data.getString("name")+"\n"+data.get("text"));
            }

            listView.setAdapter(adapter);
            adapter.notifyDataSetChanged();

        } catch (JSONException e) {
                e.printStackTrace();
        }
    }

```


　WriteActivity.javaでは入力したデータをサーバーに送信します。サーバにPOSTするデータを**　Map　＜String　,　String＞　getParams()　**に設定します。送信するデータはPHPと照合する部分にあたるのでタイプミスしないよに注意してください「**FastText**」に名前を、「**SecondText**」内容を設定しています。

```WriteActivity.java

  private void startVolley() {

        //queue
        RequestQueue postQueue = Volley.newRequestQueue(this);

        //サーバーのアドレス任意
        String POST_URL="サーバーのURL.edit.php";

        StringRequest stringReq=new StringRequest(Request.Method.POST,POST_URL,

                //通信成功
                new Response.Listener<String>() {
                    @Override
                    public void onResponse(String s) {
                        Toast.makeText(WriteActivity.this,"通信に成功しました。",Toast.LENGTH_SHORT).show();
                    }
                },

                //通信失敗
                new Response.ErrorListener(){
                    @Override
                    public void onErrorResponse(VolleyError error){
                        Toast.makeText(WriteActivity.this,"通信に失敗しました。",Toast.LENGTH_SHORT).show();
                    }
                }){

            //送信するデータを設定
            @Override
            protected Map<String,String> getParams(){

                //今回は[FastText：名前]と[SecondText：内容]を設定
                Map<String,String> params = new HashMap<String,String>();
                params.put("FastText",name.getText().toString());
                params.put("SecondText",text.getText().toString());
                return params;
            }
        };

       postQueue.add(stringReq);
    }

```



##PHPでのサーバー通信
 PHP側のプログラムはデータベース（SQL）に保存するedit.phpクラスとデータベース（SQL）から読み取るread.phpクラスの二つになります。read.phpではMYSQLから取得したデータをJsonデータ形式でAndroidにデータを送るようにしています。

```read.php

<?php

//SQLのデータandroidアプリに送信します。
try {
    $db =new PDO('データベース接続文字列','ユーザー名','パスワード');
　　//MYSQLの設定で一度に出力するデータの数を15に設定しています。
   $sqldata = $db->prepare('SELECT *FROM android_test ORDER BY id DESC LIMIT 15');
   $sqldata->execute();

   while ($row = $sqldata->fetch()) {
     
        $db_data[] = array(
　　　　　　　　　//idは特に必要ない
                'id'=>$row['id'],
                'name'=>$row['name']."(name)",
                'text'=>$row['text']."(text)"
                    );
      }

    //responseの準備
    $response['SQL_TEST'] = $db_data;

    //JSONデータ出力
    header("Content-type: application/json; charset=UTF-8");
    echo json_encode($response);
    $db=null;

  } catch (Exception $e) {
}
　?>
```

　edit.phpでは、WriteActivity.javaで入力されたデータデータベースに保存していく処理を行います。Androidの**Map　＜String　,　String＞　getParams()**メゾットで設定したパラメーター「FastText」と「SecondText」が入力済みで、PHPの引数と合致していればデータベースに文字列が挿入されます。

```edit.php

<?php

//ここでは送信されたデータをもとにSQLにデータを挿入してきます。
if(isset($_POST['FastText']) && isset($_POST['SecondText'])) {

　//データベースに書き込み
  try {
    $db =new PDO('データベース接続文字列','ユーザー名','パスワード');
    $write=$db->prepare('INSERT INTO android_test (name,text) VALUES(:name,:text)');
    $write->bindvalue(':name',$_POST['FastText']);
    $write->bindvalue(':text',$_POST['SecondText']);
    $write->execute();
    $db=null;

  } catch (Exception $e) {
  }
}
 ?>
```

　以上でサーバーのデータベースにデータを保存することができます。
正しく文字が入力されていたら下記の図のように表示されると思います。

![Screenshot_20161201-194838.png](https://qiita-image-store.s3.amazonaws.com/0/133775/282dc50a-9943-e0f1-02fe-05e55d333b75.png)
![Screenshot_20161201-194817.png](https://qiita-image-store.s3.amazonaws.com/0/133775/f2701183-2b56-e347-c63c-7eb0e1cba735.png)



##最後に

　今回はandroid側とサーバー側のプログラムを作成しましたが、URLは記入していませんサーバー側は個人のものを使用してください。また、今回のテストアプリはVolleyによるデータの送受信のつかみを目的にしているのでプログラミングに脆弱性があると思われます。くれぐれも、趣味の延長戦程度として参考にしていただければと思います。

以下が今回のテストアプリとなります。
[MyVolley_Test-GitHub](https://github.com/s-nobol/MyVolley_Test)