以前にMySqlへデータを登録するプログラムを記述し、失敗していたので、
その原因を調べました。
以前のエラーの直接の原因は接続先のURLの間違いだったようです。
また、後付けになってしまいましたが、非同期処理で行わなければならないようです。
まとめるとこの2点に注意が必要です。
①非同期処理
②接続先のURL
それぞれ説明していきます。
①非同期処理について
非同期処理を行う理由は
UIスレッドでネットワーク通信が許可されてないから
のようです。
(AndroidでSocket通信より)
非同期処理を行うにはAsyncTaskクラス使います。
ソースを見るほうがわかりやすいかもしれませんので、載せておきます。
すごく雑な解説なので、下のほうに載せている参考URLからみていただければと思います。
画面側からAsyncTaskを呼び出してデータを登録します。
1 2 3 4 5 6 7 8 9 10 11 12 13 |
((Button) findViewById(R.id.btnSend)).setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { //メール本文取得 String message = ((EditText)findViewById(R.id.editTextMsg)).getText().toString(); //DB登録処理 executeNonQuery extNonQuery = new executeNonQuery(SendMessage.this, message); extNonQuery.execute(); } }); |
execute()で下に記述した処理が動きます。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 |
public class executeNonQueryextends AsyncTask { private String strUrl = "jdbc:mysql://10.0.2.2:3306/wgm"; //MySQL接続先 private String strUser = "root"; //MySQLユーザ private String strPassword = "TEST"; //MySQLパスワード String strQuery = ""; //SQL文格納用 private Activity threadActivity = null; //スレッド処理用のアクティビティ private String message = ""; //アクティビティからの送信メッセージ private Exception exception = null; //Exception格納用 // コンストラクタ publicexecuteNonQuery(Activity mainActivity, String strMessage) { threadActivity = mainActivity; message = strMessage; } /** * バックグランドで行う処理 * 第一引数(Params)で受け取った引数を実行する処理を記載する * 第三引数(Result)で使用する型をReturnする */ @Override protected Exception doInBackground(Void...params) { Connection conn = null; strQuery = "INSERT INTO ・・・以下省略" try { //JDBCドライバのロード Class.forName("com.mysql.jdbc.Driver"); //DB接続 conn = DriverManager.getConnection(strUrl, strUser, strPassword); Statement stmt = conn.createStatement(); conn.setAutoCommit(false); //DBへInsertクエリを実行 stmt.executeUpdate(strQuery); conn.commit(); stmt.close(); conn.close(); } catch (Exception e) { //エラー内容を書き込む System.out.println("MySQLに接続できませんでした。" + message.toString() + e.toString()); //Exceptionをセット exception = e; } return exception; } @Override protected void onProgressUpdate(Void...values) { super.onProgressUpdate(values); } /** *doInBackgroundで返した引数をMainActivity側へ反映させる */ protected void onPostExecute(Exception e) { //メッセージ表示用のインスタンス生成 AlertDialog.Builder builder = new AlertDialog.Builder(threadActivity); //Exception有無に応じてメッセージをセット if (exception != null) { builder.setMessage(exception.toString()); } else { builder.setMessage("メッセージが送信されました"); } //メッセージ表示 builder.show(); } } |
②接続先のURLについて
上に書いたソースにはすでに載っているのですが、ローカルホストのMySql接続を行う場合は、
接続URLはjdbc:mysql://10.0.2.2:3306/[DB名]と記述します。
某ブログなどで調べていると、こんな書き方になっていますが、ダメみたいです。(昔はできてたのか…?)
jdbc:mysql://localhost:3306/[DB名]
こちらの書き方でMySqlへ接続できない理由は
AVDから見たlocalhostはAVD自身になるそうです。
その代わりにローカルPCには、10.0.2.2 というIPが割り当てられているようです。
(androidエミュレータからlocalhostへの接続より)
なるほど。
AVDからAVDに接続してはおかしなことになってしまいますね。
SQL実行(メッセージ送信実行)
なにはともあれ、AndroidoからMySqlへデータの登録ができました!
以後はもっとアプリ作成に力を入れていきたいと思います。
2018/09/16追記
メールの送信相手は、ランダムに選んで送信しています。
以前、追々載せていくと記載しましたが、
ランダムにユーザにメール送信(登録)するSQLはこちらです。
AndroidSudio MySqlでランダムにデータを取得する
・AndroidでSocket通信
http://qiita.com/tomoima525/items/daa30505ad18e89641f9
・AsyncTaskを使った非同期処理のきほん
http://dev.classmethod.jp/smartphone/android/asynctask/
・AsyncTaskの使い方考察
http://d.hatena.ne.jp/Nagise/20120309/1331265123%E3%80%80
・Androidを使った備忘録を作ってみよう
http://web.sfc.wide.ad.jp/~tinaba/tutorials/AndroidCS/
・androidエミュレータからlocalhostへの接続
http://blog.ceed.jp/?p=298
・Android : How to send data to remote database without using PHP or any webservices?
http://stackoverflow.com/questions/15739407/android-how-to-send-data-to-remote-database-without-using-php-or-any-webservic