Eclipse ✕ Android ✕ MySQL その2

サーバ側とAndroid側の通信を行います \(^o^)/

前回JDBCを使った方法でやりましたが、実機に入れるとできませんでしたorz
頑張ったんだけどね(;´∀`)
自分の実機に対応してなかったみたいです(´・ω・`)


てことで、違う方法を考えいました。

MySQL】→【Json】 送る 【Json】→【Android

の方法でデータの読み込みをすることにしました。


まずはMySQLJsonファイルにすることから!
今回は PerlCGI 利用することにしました。

まずはサーバ側の設定から。
Webサーバー構築(Apache) - CentOSで自宅サーバー構築

次に確認。
http://homepage2.nifty.com/sak/w_sak3/doc/sysbrd/pe_kj01.htm

#!/usr/local/bin/perl
  print "Content-type: text/html\n\n";
  print "<HTML>\n";
  print "<P>はじめての CGI-Perl ですのん。</P>\n";
  print "</HTML>\n";

これで確認できたらおk( ´∀`)bグッ!

今回はGETメソッドを使います。
Twitterとかでよくあるあれですよ。。。
例:ATNDhttp://api.atnd.org/events/?keyword=android&format=json


MySQL
host :192.168.100.200
database :sample
table :first_mysql
user :root
password :




※iptableは切っています。

http://d.hatena.ne.jp/uriyuri/20080704/1215164085

/etc/rc.d/init.d/iptables stop


【参考】
[Perl] データベースから取得したレコードをJSON形式で出力する – 極上の人生
入力フォーム編(GETとPOSTデータを受け取るには) - futomi's CGI Cafe

#!/usr/local/bin/perl

use strict;
use warnings;

use CGI;
use DBI;
use JSON;

my $cgi = CGI->new();
my $where_string = $cgi->param('WHERE_STRING');
my %forminh = &get_arg();

#データベース接続情報
my $data_source = 'DBI:mysql:sample:192.168.100.200';
my $username  = 'root';
my $auth  = '';

my $dbh = DBI->connect($data_source, $username, $auth);
$dbh->do("SET NAMES utf8");

#SQL文:select * from first_mysql where RECORD_ID='rally024';
my $sql = "select * from first_mysql where RECORD_ID='".$forminh{id}."';";

my $sth = $dbh->prepare($sql);
$sth->execute();

my $JSON = '['; # JSONハッシュの配列にするので
while ( my $ref = $sth->fetchrow_hashref() ){# ハッシュ参照を順次取り出し
 $JSON .= (JSON->new->encode($ref).', ');# JSON文字列に変換して連結
      }
$JSON =~ s/,.$//s; # 最後のカンマを除去(正規表現を使用)
$JSON .=']';
print $cgi->header(-content_type => "application/json",-charset => "utf-8");
print $JSON;


#GETメソッド
sub get_arg{
    my %forminh;
    my ($formin,$name,$value,$tmp,@indata);

    $formin= $ENV{'QUERY_STRING'}; #データを受け取り変数へ

    @indata = split (/&/,$formin); #受け取ったデータを&で区切り、配列へ

    foreach $tmp (@indata) #フォームの要素分(配列分)以下の処理を繰り返す
    {
	($name,$value) = split (/=/,$tmp); # =記号で区切り、名前 と 値 に
	$forminh{$name} = $value; #区切った名前を付けた連想配列に
    }
    return (%forminh);
}

http://192.168.100.200/test/sample.cgi?id=skwaon077

のように?の後に情報を入力するとできますv( ̄Д ̄)v イエイ

【苦労したところ】
MIMEタイプ: text/html → application/json に変更。
print $cgi->header(-content_type => "application/json",-charset => "utf-8");



よーし!これでサーバ側は終わり。
次はAndroid側です!!

まずはNetwork通信ができるためにAndroidManifest.xmlを編集。
ソフトウェア雑記 ネットワークに接続する場合の定義

<uses-permission android:name="android.permission.INTERNET" />

【参考】
http://techbooster.jpn.org/andriod/application/1645/

public class Etc11 extends Activity {
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        setContentView(R.layout.main);

        String id = "skwaon077";
        HttpClient httpClient = new DefaultHttpClient();
        String url_string = "http://192.168.100.200/test/sample.cgi?id=" + id;
        StringBuilder uri = new StringBuilder(url_string);		
		
		HttpGet request = new HttpGet(uri.toString());
		HttpResponse httpResponse = null;
		
		try {
//AndroidManifest.xmlに<uses-permission android:name="android.permission.INTERNET" />が必要。
		    httpResponse = httpClient.execute(request);
		} catch (Exception e) {
		    Log.d("JSONSampleActivity", "Error Execute");
			Toast.makeText(getApplicationContext(), e.toString() , Toast.LENGTH_LONG).show();
		    return;
		}
			
		int status = httpResponse.getStatusLine().getStatusCode();
		
		String data = null;
		if (HttpStatus.SC_OK == status) {
			try{
				ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
				httpResponse.getEntity().writeTo(outputStream);			      
				data = outputStream.toString(); // JSONデータ
			} catch (Exception e) {
				Log.d("JSONSampleActivity", "Error");
				Toast.makeText(getApplicationContext(), e.getMessage() , Toast.LENGTH_LONG).show();
			}

		} else {
			Log.d("JSONSampleActivity", "Status" + status);
			Toast.makeText(getApplicationContext(),"失敗"+ status, Toast.LENGTH_LONG).show();
			return;
		}

		//JSONArray にJsonファイルを格納
		JSONArray coupon = null;
		Toast.makeText(getApplicationContext(),"成功"+data, Toast.LENGTH_LONG).show();
		try {
			coupon = new JSONArray(data);
		} catch (JSONException e2) {
			// TODO 自動生成された catch ブロック
			Toast.makeText(getApplicationContext(),"失敗", Toast.LENGTH_LONG).show();
			e2.printStackTrace();
		}
		
		//リスト表示するために必要
		ArrayList words = new ArrayList();
		
		for (int i = 0; i < coupon.length(); i++) {
			JSONObject o = null;
			try {
				o = coupon.getJSONObject(i);
			} catch (JSONException e1) {
				// TODO 自動生成された catch ブロック
				Toast.makeText(getApplicationContext(), e1.getMessage() , Toast.LENGTH_LONG).show();
				e1.printStackTrace();
			}

			String message=null;
			try {
				message = o.getString("RECORD_NAME");
			} catch (JSONException e) {
				// TODO 自動生成された catch ブロック
				Toast.makeText(getApplicationContext(), e.getMessage() , Toast.LENGTH_LONG).show();
				
			}
			//Toast.makeText(getApplicationContext(), message , Toast.LENGTH_LONG).show();			
			words.add(message);
		}
	

	//リスト表示
        ArrayAdapter<String> la = 
            	new ArrayAdapter<String>(this, 
            		android.R.layout.simple_list_item_1, words); 
            		
            // main.xmlのListViewにlaをセットします。
            ListView lv = (ListView)findViewById(R.id.twitter);
            lv.setAdapter(la);		
		
    }

データベースにあるデータを読み込み、リスト表示します。

【苦労したところ】
httpResponse = httpClient.execute(request);
でエラーになる。
AndroidManifest.xml
の書き忘れ /(^o^)\ナンテコッタイ


以上。
お疲れ様でした \(^o^)/

脆弱性が半端無いので、対策しましょう (。-`ω-)うん