2011年1月15日土曜日

Android:JSON表示クライアントアプリ

こないだGoogle App Engine + slim3 + JSONICで作ったサンプルをAndroidで表示するアプリを作ってみたのでメモ。

とりあえず実現したい事は、JSONをHTTPのgetで受け取ってListViewで表示までを目標に。
で、下記のように実装。
(URIベタ書きですが...、とりあえず動かしたいので。)

  1. import java.io.IOException;  
  2. import java.util.ArrayList;  
  3. import java.util.List;  
  4. import org.apache.http.HttpEntity;  
  5. import org.apache.http.HttpResponse;  
  6. import org.apache.http.HttpStatus;  
  7. import org.apache.http.ParseException;  
  8. import org.apache.http.client.ClientProtocolException;  
  9. import org.apache.http.client.methods.HttpGet;  
  10. import org.apache.http.impl.client.DefaultHttpClient;  
  11. import org.apache.http.params.HttpConnectionParams;  
  12. import org.apache.http.params.HttpParams;  
  13. import org.apache.http.util.EntityUtils;  
  14. import org.json.JSONArray;  
  15. import org.json.JSONException;  
  16. import org.json.JSONObject;  
  17. import android.app.Activity;  
  18. import android.os.Bundle;  
  19. import android.widget.ArrayAdapter;  
  20. import android.widget.ListView;  
  21.   
  22. public class JsonListActivity extends Activity {  
  23.   
  24.  private String strUri = "http://1.latest.slim3demo001.appspot.com/AjaxTweet.json";  
  25.   
  26.  private String json = null;  
  27.   
  28.     /** Called when the activity is first created. */  
  29.     @Override  
  30.     public void onCreate(Bundle savedInstanceState) {  
  31.         super.onCreate(savedInstanceState);  
  32.         setContentView(R.layout.main);  
  33.   
  34.         DefaultHttpClient httpClient = new DefaultHttpClient();  
  35.         HttpParams params = httpClient.getParams();  
  36.         HttpConnectionParams.setConnectionTimeout(params, 1000);  
  37.         HttpConnectionParams.setSoTimeout(params, 1000);  
  38.         HttpGet httpRequest = new HttpGet(strUri);  
  39.         HttpResponse httpResponse = null;  
  40.   
  41.         try {  
  42.    httpResponse = httpClient.execute(httpRequest);  
  43.   } catch (ClientProtocolException e) {  
  44.    e.printStackTrace();  
  45.   } catch (IOException e) {  
  46.    e.printStackTrace();  
  47.   }  
  48.   if (httpResponse != null && httpResponse.getStatusLine().getStatusCode() == HttpStatus.SC_OK) {  
  49.    HttpEntity httpEntity = httpResponse.getEntity();  
  50.   
  51.    try {  
  52.     json = EntityUtils.toString(httpEntity);  
  53.    } catch (ParseException e) {  
  54.     e.printStackTrace();  
  55.    } catch (IOException e) {  
  56.     e.printStackTrace();  
  57.    } finally {  
  58.     try {  
  59.      httpEntity.consumeContent();  
  60.     } catch (IOException e) {  
  61.      e.printStackTrace();  
  62.     }  
  63.    }  
  64.   }  
  65.   
  66.   httpClient.getConnectionManager().shutdown();  
  67.   ArrayAdapter<string> adapter = new ArrayAdapter<string>(this, android.R.layout.simple_list_item_1);  
  68.   
  69.   try {  
  70.    JSONArray jsonArray = new JSONArray(json);  
  71.    int cnt = jsonArray.length();  
  72.    List<jsonobject> jlist = new ArrayList<jsonobject>();  
  73.    for (int i = 0; i < cnt; i++) {  
  74.     jlist.add(jsonArray.getJSONObject(i));  
  75.    }  
  76.    for (JSONObject obj : jlist) {  
  77.     String item = obj.getString("content");  
  78.     adapter.add(item);  
  79.    }  
  80.   } catch (JSONException e) {  
  81.    e.printStackTrace();  
  82.   }  
  83.   ListView listView = (ListView)findViewById(R.id.jsonlistview);  
  84.   listView.setAdapter(adapter);  
  85.     }  
  86. }  
  87. </jsonobject></jsonobject></string></string>  
main.xmlは下記のように
  1. <?xml version="1.0" encoding="utf-8"?>  
  2. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"  
  3.     android:orientation="vertical"  
  4.     android:layout_width="fill_parent"  
  5.     android:layout_height="fill_parent"  
  6.     >  
  7.     <ListView  
  8.      android:id="@+id/jsonlistview"  
  9.      android:layout_width="fill_parent"  
  10.      android:layout_height="wrap_content"/>  
  11. </LinearLayout>  
ネットにつなげるので、Manifestファイルにも"android.permission.INTERNET"を追加
  1. <uses-permission android:name="android.permission.INTERNET"/>  
一応無事に動きました。
参考サイト: Android で JSON を使おう ~ 前編~CommentsAdd Star Android で JSON を使おう ~ 後編 ~CommentsAdd Star

2011年1月12日水曜日

Androidメモ:Android で証明書が期限切れ

久しぶりに以前作ったサンプルプログラムを参考にしようとEclipseでプロジェクトを開いたら、
「Error generating final archive: Debug Certificate expired ...」
とか言われてビルドできませんでした。

検索してみると、Android SDK の debug 用キーストアの有効期限がすぎているみたい。

C:\Documents and Settings\USER_NAME\.android以下のdebug.keystoreを削除したら正常にビルドしてくれました。

参考サイト:Android で証明書が期限切れというエラーがでて apk が作成できない

2011年1月7日金曜日

JavaのList内容をソートする

セッションに貯めたレコードのリストをソートする必要があったのでメモ

  1. /** 
  2.  * Listソート処理(Key昇順) 
  3.  * @param list 
  4.  */  
  5. public void sortKeyAsc(List<DataModel> list) {  
  6.  Collections.sort(list, new Comparator<DataModel>() {  
  7.   public int compare(DataModel t1, DataModel t2) {  
  8.    // Key昇順  
  9.    return t1.getKey().compareTo(t2.getKey());  
  10.   }  
  11.  });  
  12. }  
降順はreturnしてる箇所を下記のように逆にする。
  1. return t2.getKey().compareTo(t1.getKey());  

2011年1月6日木曜日

slim3 + JSONICメモ




slim3のtutorialをJSONICを使ってajaxでTweetするようにと、RESTfulに変えてみたのでメモ
できたのはこんなかんじ


JSONICの使い方メモ

準備

 最新のjsonic.jarをダウンロードしてプロジェクトに配置・ライブラリに追加

※追記 2011/02/01 jsonic.jarの配置場所が、war/WEB-INF/lib以下に置かないとローカルで動きませんでした。

エンコード・デコード

 JSON.decode(String json, XXX.class)でjson→javaオブジェクト
 JSON.encode(XXX)でjavaオブジェクト→json

WebサービスAPIを使う

RESTサーブレットを使用する場合

web.xmlへ追加

  1. <servlet>  
  2.      <servlet-name>restServlet</servlet-name>  
  3.      <servlet-class>net.arnx.jsonic.web.RESTServlet</servlet-class>  
  4.      <init-param>  
  5.       <param-name>config</param-name><param-value>{  
  6.        "mappings":{  
  7.         "/{class}.json":"tutorial.controller.twitter.${class}Controller"  
  8.        }  
  9.       }  
  10.       </param-value></init-param>  
  11.     </servlet>  
  12.     ・  
  13.     ・  
  14.     ・  
  15.     <servlet-mapping>  
  16.      <servlet-name>restServlet</servlet-name>  
  17.      <url-pattern>*.json</url-pattern>  
  18.     </servlet-mapping>  

コントローラは下記のように実装。

RESTfullな操作はJSONICのRESTサーブレットがやってくれるので、

HTTP MethodのGETでfind()メソッド、POSTでcreate()メソッドを呼出すように実装します。


  1. import java.util.List;  
  2.   
  3. import tutorial.model.Tweet;  
  4. import tutorial.service.TwitterService;  
  5.   
  6. public class AjaxTweetController {  
  7.   
  8.     private TwitterService service;  
  9.   
  10.     public List<tweet> find() {  
  11.   
  12.         this.service = new TwitterService();  
  13.   
  14.         List<tweet> tweetList = service.getTweetList();  
  15.   
  16.         return tweetList;  
  17.     }  
  18.   
  19.     public void create(Tweet tweet) {  
  20.   
  21.         this.service = new TwitterService();  
  22.   
  23.         this.service.tweet(tweet);  
  24.     }  
  25. }  
  26. </tweet></tweet>  

TwitterServiceにメソッド追加

  1. /** 
  2.      * JSON形式でもらってDataStoreへ追加 
  3.      * @param jsonTweet 
  4.      * @return String 
  5.      */  
  6.     public String jsonTweet(String jsonTweet) {  
  7.   
  8.         Tweet tweet = JSON.decode(jsonTweet, Tweet.class);  
  9.         tweet = this.tweet(tweet);  
  10.         String retJsonTweet = JSON.encode(tweet);  
  11.         return retJsonTweet;  
  12.     }  

viewは下記

  1. <p>What are you doing?</p>  
  2. <form id="tweetForm" action="tweet" method="post" name="tweetForm">  
  3. <textarea id="content" name="content"></textarea>  
  4.   
  5. <input type="button" value="tweet" onclick="sendTweetJSON()"/>  
  6. </form>  
  7.   
  8. <div id="ajaxTweetList"></div>  
  9.   
  10. </body>  
  11. <script type="text/javascript">  
  12.   
  13. function sendTweetJSON() {  
  14.  var form = $("#tweetForm");  
  15.  var param = {};  
  16.  $(form.serializeArray()).each(function(i,v){  
  17.   param[v.name] = v.value;  
  18.  });  
  19.  var jsonval = $.toJSON(param);  
  20.   
  21.  $.ajax({  
  22.   type:"POST",  
  23.   url:"/AjaxTweet.json",  
  24.   contentType:"application/json",  
  25.   data:jsonval,  
  26.   cache:false,  
  27.   success:function(data){getAjaxList();}  
  28.   });  
  29. }  
  30.   
  31. function displayList(jsonData) {  
  32.  var list = jsonData;  
  33.  var resultData = "<table><tr><th>TweetList</th></tr>";  
  34.   
  35.  for (var i in list) {  
  36.   var content = list[i].content;  
  37.   resultData += "<tr><td>" + content + "</td></tr>";  
  38.  }  
  39.  resultData += "</table>";  
  40.  return resultData;  
  41. }  
  42.   
  43. function getAjaxList() {  
  44.  var list;  
  45.  $.get("/AjaxTweet.json", function(data){  
  46.   $('#ajaxTweetList').html(displayList(data));  
  47.  });  
  48. }  
  49.   
  50. $(function() {  
  51.  getAjaxList();  
  52. });  
  53. </script>  

jqueryを使用しているのでheadでライブラリを読込み

  1. <script type="text/javascript" src="/js/jquery-1.4.2.min.js"></script>  
  2. <script type="text/javascript" src="/js/jquery.json-2.2.min.js"></script>  
  3. <script type="text/javascript" src="/js/deserialize.js"></script>  



参考サイト:
jQueryでフォームの内容をJSONで投げ、受け取ったJSONをフォームに戻す方法

JSONIC