第7回 C#で自作Android アプリを作ろう:簡易アンケートを作ろう

技術顧問の増田です。
前回までは、Web API を使ってサーバーからデータを取得する機能を使ってアプリを作ってきました。今回は、その逆で、Web API を使ってサーバーにデータを送信する機能を使ってアプリを作ります。
Android アプリでアンケートを入力して、サーバーに送信する「簡易アンケート」アプリを作ってみましょう。

サンプルコードは https://github.com/moonmile/sg-xamarin-sample にあります。

 

バックナンバー

 

POSTとは何か?

アンケートツールでは、サーバーにWebサーバーを使います。Webサーバーには、HTTP プロトコルでデータを送信するのですが、これは一般的にブラウザで閲覧をしているときと同じ「プロトコル」です。プロトコルというのは「約束事」ですから、世の中にはいろいろなプロトコルがあります。場合によっては自作プロトコルを作ることもできます。が、まあ、一般的な Web サーバーでは「HTTP プロトコル」が使われているので、この使い方を覚えると、大抵のWebサーバーアクセスができるというということになります。

フォーム入力を送信する

HTTP プロトコルの詳細は、別に探して貰うということで、ここではサンプルに必要なところだけ解説しましょう。

  • HTTPプロトコルのPOSTメソッドを使う
  • Content-Typeを「application/x-www-form-urlencoded」で送る。
  • 戻り値は、HTML形式などで返ってくる。

ことだけ覚えておけばokです。

Content-Typeが「application/x-www-form-urlencoded」ってのは、ブラウザのフォーム(formタグやinputタグなど)を使ってサーバーと送受信する、いわゆるCGIな古くからある方式ですが、いまでも十分現役です。一方で、ajax など非同期で JSON や XML 形式のデータを送る方法もあります。こっちの方式のほうが、Android アプリで作るときは楽なのですが(Web APIと同じ作り方ができますからね)、一般的な Web サーバーの応答をそのまま使う場合は、Android アプリから「application/x-www-form-urlencoded」で送信できるようになったほうが、応用の幅が広がります。

図のように、

  • ブラウザ
  • コンソールアプリ
  • Android アプリ

の3種類で同じ HTTP サーバーを相手にすることができるからです。

PHPでサーバーを作る

Web APIの解説では、駅データ.jp を使いましたが、今回は自前で Web サーバーを用意してみましょう。既に Linux などで LAMP 環境がある場合は、それを使ってもいいでしょう。

xampp を使う

Windows 上で、LAMP 環境を作るときは xampp を使うと便利です。Apache + MySQL/MariaDB + PHP の環境がさっくり作れます。

index.php

Windows 環境に /xampp/htdocs/svQuest フォルダを作って、index.php を置きます。単純なアンケートツールですね。

sgQuestion sample page

 

 

名前:

 

参加: 参加 不参加 どちらともいえない

 

星座:

 

メモ:

form の method 属性に「post」を指定して、送信先を「post.php」にしておきます。

post.php

もうひとつ、post.php を作ります。

sgQuestion post check

ポストされた内容を確認する

name:

 

join:

 

horoscope:

 

memo:

本来ならば、MySQL に保存するところですが、面倒…いや、ここでは実験なので値を返すだけにします。

ブラウザから呼び出し

ブラウザを使って動作確認をしておきましょう。

アンケート画面

確認画面

要求ヘッダ

HTTP プロトコルがどういう動きをしているのかを見るために F12 キーを押して、ネットワークの状態を確認しておきます。

要求本文

POST メソッドで送信するデータはこんな感じですね。

ブラウザから、送信するときはサーバーから送られてきた画面に対してぽちぽちやれば大丈夫ですが、これを自動化するにはどうしたらいいでしょうか?
という訳で、Android で実装するまえに、コンソールアプリを作って詳細を確認してみましょう。

コンソールから呼び出し

コンソールアプリから HTTP プロトコルを使って Web サーバーにアクセスするときは HttpClient クラスを使います。フォーム入力のような POST メソッドも手軽にできるようになっています。

コード

  1. HttpClient のオブジェクトを生成
  2. 送信するパラメータは、Dictionary で作ります。
  3. キーと値のペアができたら、FormUrlEncodedContent でフォーム用にエンコードします。
  4. 送信先は post.php ですね。
  5. POST は、PostAsync メソッドを呼び出して実行します。
  6. 応答は ReadAsStringAsync を使って一括で取得すればokです。

結果

うまくいくと、こんな風に登録した結果が帰って来ます。

Android から呼び出し

コンソールアプリでの動作が確認できたところで、Android に実装していきましょう。

画面デザイン

デザイナを使ってぽちぽちとデザインします。面倒…じゃなくて、わかりやすいように LinearLayout でペタペタ作っていきましたが、もうちょっとデザインしてもokです。名前さえ変えなければ、どのように変えても構いません。

axml

コード

MainActivity.cs は 100行ちょっとで済みます。

/// /// private async void BtnPost_Click(object sender, System.EventArgs e) { // 画面からデータを取得 string name = editName.Text; // ⑤ string memo = editMemo.Text; if ( spJoin.SelectedItemPosition == 0 ) { new AlertDialog.Builder(this) // ⑥ .SetMessage(“星座を選択してください”) .Show(); return; } string horo = Horos[spJoin.SelectedItemPosition].Id; string join = “1”; if (radioJoin1.Checked) join = “1”; if (radioJoin2.Checked) join = “2”; if (radioJoin3.Checked) join = “3”; var html = await Go(name, join, horo, memo); // ⑦ // 結果を表示 new AlertDialog.Builder(this) // ⑧ .SetMessage( html ) .Show(); return; } async Task Go(string name, string join, string horo, string memo) // ⑨ { var hc = new HttpClient(); var dic = new Dictionary<string, string>(); dic[“name”] = name; dic[“join”] = join; dic[“horoscope”] = horo; dic[“memo”] = memo; var cont = new FormUrlEncodedContent(dic); // 呼び出しのIPアドレスは変更すること var url = “http://172.16.0.11/svQuest/post.php”; var req = await hc.PostAsync(url, cont); var html = await req.Content.ReadAsStringAsync(); return html; } } public class Horo // ⑩ { public string Id { get; set; } public string Text { get; set; } public override string ToString() { return this.Text; } }

簡単にコードの解説をしておきましょう。

  1. FindViewById メソッドでコントロールを取ってきます。
  2. 選択用の Spinner に設定するリストを作ります。
  3. ArrayAdapter を作っておいて、
  4. Adapter プロパティに設定します。
  5. 「投稿」ボタンをタップしたときに、各コントロールから値を取得します。
  6. 入力時のエラーメッセージは「AlertDialog.Builder」を使うと便利です。
  7. 投稿時のメソッドはコンソールアプリからそのままコピーしています。投稿先の URL アドレスを記述しなおしてください。
  8. 結果を表示します。
  9. 投稿時の処理をコピペします。
  10. Spinner に設定する Horo クラスを作っておきます。

実行

コードができたらエミュレータで実行してみましょう。


ブラウザやコンソールアプリと同じようにアンケートが投稿できるようになりましたね。

サーバーを.NET Coreで作る

さて、LAMP サーバーの場合は、PHP を使ってサーバーサイドのコードを記述しましたが、ASP.NET Core MVC を使うこともできます。
この部分は、おまけなので、ざっとコードだけ示しておきます。詳細は https://github.com/moonmile/sg-xamarin-sample/tree/master/src/sgQuestionnaire/sqQuestSvCore にあります。

Model

MVC パターンの Model クラスです。

Controller

Controller クラスを作っておきます。登録時には Create メソッドが呼び出されます。

View

ブラウザから入力するための View を作っておきます。

Create

 

 

 

Person

 


 

 

 

 

 

 

参加 不参加 どちらともいえない

 

 

 

 

 

 

 

 

 

 

MainActivity.cs の書き替え

投稿時の URL が異なるので、書き替えて実行します。

実行

アンケートの入力と「投稿」ボタンまでは同じ動作になります。.net core のサーバーを「dotnet run」で動かして 5000 番ポートで待ち受けます。


戻り値が、ちょっとうまく表示できていない(HTMLデータが多すぎる)ので調節が必要ですが、ひとまず登録できていることがわかります。

まとめ

如何だったでしょうか? Android からサーバーにアクセスするときに HttpClient を使えば、結構いろいろなことができることが分かります。画面はチープですが、サーバーと組み合わせれば、サーバー側で独自で拡張することもできるので、同じアプリであっても後から機能をアップすることができます。また、逆にサーバーは同じであってもクライアントの UI を変更することで使いやすい画面を作ることも可能です。

次回は、Android 自身の機能を使ってアプリを作ります。カメラを使って、撮影の基本的な部分を作ってみます。

お楽しみに。

 

最新情報をチェックしよう!
>システム構築・保守に特化した会社です。

システム構築・保守に特化した会社です。

システムの構築・保守運用「システムガーディアン」 社内システム担当が欲しいが、専属で雇うほどの仕事量はない。 必要な時に必要なだけ頼りたいというお悩みを持つ企業様へ専門知識を持って対応を行っております。 サーバから各種システムまで自社・他社で構築されたシステムに対してサポートを行っております。

CTR IMG