AndroidアプリでPHP連携。

目標発表会お疲れ様でした!!

 

4月から8月にかけて、個別目標でAndroidの家計簿アプリをつくる!という目標を立てて、しばらくAndroid Studioと遊んでいました。

 

初めてのJava、初めてのAndroidアプリだったわけなんですが…

独学で、調べながら迷走していた中で、何とか実現した、PHPとの連携を紹介しておこうと思います

 

PHP連携を実装するに至った経緯

 

目標でAndroidの家計簿アプリを作る!

…と設定した後、

まぁ、家計簿だし、もちろん登録はDBだよね~。

と、何も考えずに思って、とりあえず、方法を確認しようとしたところ、

 

Androidアプリから直接SQLをたたいてDBに接続する方法はないです。

 

という記事を見かけました…。(つんだ

 

データ登録をする = 2次元のアレ

……と思っていた私は、SQLiteの記事を見かけるもスルーし、PHPで取得することを決意しました……

 

 

 

コード

 

実際のコードはこんな感じ。

どうやら、PHPと連携するには非同期クラスが必須らしいんですけど、Javaって非同期クラス、複数あるんですね…。今回は、最初に目についたThreadクラス(非推奨らしいです。)を使用しています。

※ importは省略。

 

Get

public class MainActivity extends AppCompatActivity {
    public static String data;

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

        // (略)

        // 非同期処理の呼び出し
        GetValues action = new GetValues("接続先URL");
        action.start();


        try {
            // 非同期終了を感知
            action.join();
        } catch (InterruptedException e) {
            // 例外処理
            e.printStackTrace();
        }

        // (略)
        
        return view;
    }

    public void writeResult (String result) {
        data = result;
    }

    public class GetValues extends Thread {

        private URL url;
        private String urlText;
        public StringBuilder result;
        public String data;

        public GetValues(String text) { 
           // 接続先のURLをテキスト形式で受信
           urlText = text;
        }

        // 取得
        public void run () {
            super.run();

            try {

                URL url = new URL(urlText);

                // connection を定義
                HttpURLConnection connection = (HttpURLConnection) url.openConnection();


                connection.setReadTimeout(3000);
                connection.setConnectTimeout(3000);
                connection.setRequestMethod("GET");
                connection.setDoInput(true);      // true : データを受信する
                connection.setRequestProperty("Accept-Language", "jp");
                connection.connect();

                result = new StringBuilder();

                Map headers = connection.getHeaderFields();
                Iterator headerIt = headers.keySet().iterator();
                String header = null;
                while(headerIt.hasNext()){
                    String headerKey = (String)headerIt.next();
                    header += headerKey + ":" + headers.get(headerKey) + "\r\n";
                }

                int getStatus = connection.getResponseCode();
                if (getStatus == HttpURLConnection.HTTP_OK) {
                    InputStream in = connection.getInputStream();
                    InputStreamReader inReader = new InputStreamReader(in);
                    BufferedReader bufferedReader = new BufferedReader(inReader);
                    String line = null;
                    while((line = bufferedReader.readLine())!=null) {
                        result.append(line);
                    }
                    bufferedReader.close();
                    inReader.close();
                    in.close();

                    writeResult(result.toString());

                }

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

}

 

POSTは呼び出し、POST完了の確認方法はほぼ同じで、非同期クラスの内容が少し変わっただけ。

    class PostData extends Thread {
        private String data;
        private String urlText;

        /* text: 接続先URL
           query:
                Uri.Builder uriBuilder = new Uri.Builder();

                uriBuilder.appendQueryParameter("ポストする値の名前", "値");  // postする値をセット

                String query = uriBuilder.build().getEncodedQuery();*/

        public  PostData (String text, String query) {
            urlText = (String) text;
            data = query;
        }

        public void run () {
            super.run();

            try {
                URL url = new URL(textUrl);
                try {
                    HttpURLConnection connection = (HttpURLConnection) url.openConnection();
                    connection.setRequestMethod("POST");
                    connection.setDoOutput(true);
                    connection.setDoInput(true);
                    connection.connect();
                    OutputStream os = connection.getOutputStream();
                    os.write(data.getBytes());
                    int resCode = connection.getResponseCode();
                } catch (IOException e) {
                    e.printStackTrace();
                }

                Intent intent = new Intent(getActivity(), MainActivity.class);
                startActivity(intent);

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

 

 

課題

  • Threadクラス以外の非同期クラスを調べる。
  • エラーメッセージを表示する
  • 今回は、入力フォームごとに一つ一つ手入力で取得を書いたけれど(↓)、入力値の取得方法を考える。
// テキスト要素

EditText date = (EditText) view.findViewById(R.id.date);
String dataValue = date.getText().toString();

// selectbox (Spinner)

Spinner category = (Spinner) view.findViewById(R.id.select_kbn);
Integer categoryString = category.getSelectedItemPosition();

// RadioGroup
RadioGroup group = (RadioGroup) view.findViewById(R.id.tax_kbn);
int radioId = group.getCheckedRadioButtonId();
String radioValue = new String("");
if (radioId != -1) {
    RadioButton radio = (RadioButton) view.findViewById(radioId);
    radioValue = radio.getText().toString();
}

 

 

Androidアプリ、レイアウトもかなり難しかったんですが、HttpConnectionなどなど、使用できるクラスが、設定するSDKバージョンによって全く違うようで、SDKを最新の29に設定すると、PHP連携を調べてよくみつかる方法、HttpClientを使った接続ができなくなる、「読み込み中…」などのメッセージのAleartDialogが使えない、など、難しいことが多かったですが、とても勉強になりました。

 

課題は山積みだし、家計簿しっかり作って使いたいなぁと思っています。