WebAPIからJSON形式のデータを取得する|Android開発
AndroidアプリでWebAPIを使ってJSON形式のデータを取得する方法です。
今回、サーバー側はCakePHP 3.6.11、WebAPIはGET通信でアクセスするものを作成しました。
また、テスト用のサーバーはXAMPPを使っています。
サーバー側
JSON の有効化
config/routes.php
に以下(★の箇所)を追記します
Router::defaultRouteClass(DashedRoute::class);
Router::extensions(['json']); // ★
Controller の作成
WebAPIを実装するController
を作成します。
WebApiController.php
<?php
namespace App\Controller;
use App\Controller\AppController;
use Cake\Event\Event;
class WebApiController extends AppController
{
public function beforeFilter(Event $event)
{
parent::beforeFilter($event);
$this->Auth->allow(['myFunction']);
}
public function myFunction()
{
$this->viewBuilder()->setClassName('Json');
$arrays = array();
$arrays[] = [
'id' => 1,
'name' => "User 001",
'color' => "Red",
];
$arrays[] = [
'id' => 2,
'name' => "User 002",
'color' => "Blue",
];
$arrays[] = [
'id' => 3,
'name' => "ユーザ 003",
'color' => "Green",
];
$this->set([
'root' => $arrays,
'_serialize' => ['root']
]);
return ;
}
}
ブラウザでの表示確認
ブラウザでhttp://サーバー名/cakePHPフォルダ/webapi/myFunction.json
にアクセスします。
WebApiController.phpで17行目を有効にしている場合、
でもアクセス可能になります。
http://サーバー名/cakePHPフォルダ/webapi/myFunction
でもアクセス可能になります。
取得結果
{
"root": [
{
"id": 1,
"name": "User 001",
"color": "Red"
},
{
"id": 2,
"name": "User 002",
"color": "Blue"
},
{
"id": 3,
"name": "\u30e6\u30fc\u30b6 003",
"color": "Green"
}
]
}
Androidアプリ側
AsyncTask を使ってHTTPアクセスを行う
非同期でデータを取得するため、AsyncTask
を継承したクラスでHTTPアクセスを行います。
AsyncTask
についてはこちら。
AsyncTaskを使った非同期処理|Android開発
受信データはJSONの文字列です。
取得が終わったら呼び出し元(ResponseListener
)へコールバックで通知します。(onPostExecute()
の処理)
import android.os.AsyncTask;
import android.util.Log;
import org.apache.commons.lang3.StringUtils;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.Locale;
public class GetContentsAsyncTask extends AsyncTask<URL, Void, String> {
private static final String TAG = "GetContentsAsyncTask";
public interface ResponseListener {
void onResponseDataReceived(String responseData);
}
private ResponseListener mListener;
public GetContentsAsyncTask(ResponseListener listener) {
if (listener == null) {
listener = new ResponseListener() {
@Override
public void onResponseDataReceived(String responseData) {
}
};
}
mListener = listener;
}
@Override
protected String doInBackground(URL... urls) {
HttpURLConnection connection = null;
try {
connection = (HttpURLConnection) urls[0].openConnection();
connection.setRequestMethod("GET");
connection.addRequestProperty("User-agent", "Android");
connection.addRequestProperty("Accept-Language", Locale.getDefault().toString());
// リダイレクトなし.
connection.setInstanceFollowRedirects(false);
// データ入力用.
connection.setDoInput(true);
connection.setDoOutput(false);
// 接続タイムアウト. 20sec.
connection.setConnectTimeout(20000);
// 読み取りタイムアウト. 30sec.
connection.setReadTimeout(30000);
connection.connect();
// get Response.
StringBuilder responseBuilder = new StringBuilder();
InputStream iStream = null;
BufferedReader reader = null;
try {
iStream = connection.getInputStream();
String line;
reader = new BufferedReader(new InputStreamReader(iStream, "UTF-8"));
while ((line = reader.readLine()) != null) {
responseBuilder.append(line);
}
} catch (IOException e) {
e.printStackTrace();
} finally {
if (!closeBufferedReader(reader)) {
closeInputStream(iStream);
}
}
int statusCode = connection.getResponseCode();
Log.i(TAG, urls[0] + " > statusCode=" + statusCode);
return responseBuilder.toString();
} catch (IOException e) {
e.printStackTrace();
Log.e(TAG, "HttpURLConnection method is error.");
return StringUtils.EMPTY;
} finally {
if (connection != null) {
connection.disconnect();
}
}
}
@Override
protected void onPostExecute(String responseData) {
mListener.onResponseDataReceived(responseData);
}
private static boolean closeBufferedReader(BufferedReader reader) {
if (reader == null) {
return false;
}
try {
reader.close();
return true;
} catch (IOException e) {
e.printStackTrace();
return false;
}
}
private static void closeInputStream(InputStream stream) {
if (stream == null) {
return;
}
try {
stream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
呼び出し側Activity
JSONObjectクラスを使うことで、簡単にデータを参照できます。
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import org.apache.commons.lang3.StringUtils;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import java.net.MalformedURLException;
import java.net.URL;
public class GetWebApiActivity extends AppCompatActivity
implements GetContentsAsyncTask.ResponseListener {
private static final String TAG = "GetWebApiActivity";
private GetContentsAsyncTask mHttpTask;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_get_web_api);
getServerData();
}
public void getServerData() {
try {
URL url = new URL("http://サーバー名/cakePHPフォルダ/webapi/myFunction.json");
mHttpTask = new GetContentsAsyncTask(this);
mHttpTask.execute(url);
} catch (MalformedURLException e) {
e.printStackTrace();
onResponseDataReceived(StringUtils.EMPTY);
}
}
@Override
public void onResponseDataReceived(String responseData) {
if (StringUtils.isEmpty(responseData)) {
finish();
return;
}
try {
JSONObject json = new JSONObject(responseData);
JSONArray lines = json.getJSONArray("root");
for (int i = 0; i < lines.length(); i++) {
JSONObject item = lines.getJSONObject(i);
Log.i(TAG, item.getString("id") + ", " + item.getString("name") + ", " + item.getString("color"));
}
} catch (JSONException e) {
e.printStackTrace();
finish();
}
}
}
実行時の出力ログ
I/GetWebApiActivity: 1, User 001, Red
I/GetWebApiActivity: 2, User 002, Blue
I/GetWebApiActivity: 3, ユーザ 003, Green