素人のアンドロイドアプリ開発日記

通信のコンテンツ

GSONでJSONをパースする

2015.07.31

gsonを使うと、jsonを簡単にパースできる。というのを聞いたので使ってみました。

コツというか簡単な使い方の説明をします。

まずクラスを用意したりもしますが、

エラーのかどうかの判定は自分で判別をします。(ここはJsonObject jo = new JsonObject(str)で自分でstatusとかそういうのを取得して判別します。)

で、例えば、

result:{id:1,name:hello}

みたいに入れ子構造になっている場合には、面倒なので、resultの中のみを取り出します・

resultJsonObjectみたいなものをがあった場合

クラスで帰ってくる値と同じものを用意します。

ResultData.java

みたいのを作って、

public int id;
public String name;

を用意します。

で、

Gson gson = new Gson();
ResultData resultData = gson.fromJson(resultJsonObject.toString(), ResultData.class);

をすると該当のクラスの変数内に、対応する値がそのまま入ってくれます。

 

で、更に入れ子になる場合には、JsonObjectはそれ用のクラスを作って(innerData)として、配列の場合には、ArrayListを配置しておくと、jsonのキーと同じ名前の変数に該当のものが含まれます。

 

難点としては、値が存在しなくても、エラーも出ないので、サーバーの方の返り値がおかしくなっても気づけない事かと思います。

カテゴリー:通信

URLEncodeとPOSTメソッドのEncode

2015.06.10

ブラウザとかで、サーバー再度のプログラムを書いてもらった時とかに、Androidから投稿をすると、日本語が文字化けする時がある。

AndroidにURLEncodeがあるので

URLEncode.encode("てきすと");

でencodeできるのだけど、うまくいかない時がある。

で、UTF-8に指定してあげないからか。と思って、

URLEncode.encode("てきすと","UTF-8");

にしたのだけど、うまく変換できない場合がある。

で、???っUTF-8じゃないのかとSHIFT-JISとかしたりしてもうまくプログラムが通らない。

で、ちょっと部分になってしまうのですが、

httppost.setEntity(new UrlEncodedFormEntity(nameValuePair));

 みたいにしていた部分を

httppost.setEntity(new UrlEncodedFormEntity(nameValuePair,"UTF-8"));

 にしたら、うまくエンコードできていた。

URLEncodeが2種類あるようでjavaのが少し違う。とかそういう問題があるようなのですが、

これで解決できました。

 

カテゴリー:通信

通信でUserAgentを偽装する方法

2013.06.05

通信のユーザーエージェントの中を変更する事でセキュリティを担保する事などがあったので、通信のuseragentの変更をしてみました

続きを読む…

カテゴリー:通信

非同期でのファイルの読み込みはtxt,json,xmlで同じ

2012.06.06

通信をいくつか行なっていたのですが、テキスト以外のjson,xmlでも一度文字列に並べて、そこからパースをして利用をする形だったので、同じクラスで使い回せたら便利だと思い、以前作成したJsonLoaderをFileLoaderに改めて再度、公開させていただきます。

以前は別ファイルを作成して2つのファイルでしたが、面倒だったのでひとつのファイルにまとめております。

使い方は通常の読み込みは(このブログのフィードの読み込み)

FileLoader task = new FileLoader();
task.setOnCallBack(new FileLoader.CallBackFile() {
	@Override
	public void CallBack(String Result) {
		Log.e("result", Result);

	};
});
task.execute("http://andante.in/i/feed/");

でPOSTメソッドを用いた読み込みは

List<NameValuePair> nameValuePair = new ArrayList<NameValuePair>(0);
nameValuePair.add(new BasicNameValuePair("uid", "123456"));
FileLoader task = new FileLoader(nameValuePair);
task.setOnCallBack(new CallBackFile() {
	@Override
	public void CallBack(String Result) {

	};
});
task.execute("http://andante.in/i/feed/");

上記で、json,xml,txtまた、テキストにしてパースして利用するのであればテキストベースのcsvなども利用する事ができるとおもいます。

FileLoaderのファイルは下記です。

public class FileLoader extends AsyncTask<String, Integer, String> {

    private CallBackFile callbackjson;
    private String mode = "none";
    private List<NameValuePair> _nameValuePair;

    // コンストラクタ
    public FileLoader() {
        mode = "none";
    }

    public FileLoader(List<NameValuePair> nameValuePair) {
        mode = "post";
        _nameValuePair = nameValuePair;
    }

    @Override
    protected void onPreExecute() {
    }

    @Override
    protected String doInBackground(String... params) {

        if (mode.equals("post")) {
            return getDataPost(params[0]);
        } else {
            return getData(params[0]);
        }
    }

    public void setOnCallBack(CallBackFile _cbj) {
        callbackjson = _cbj;
    }

    @Override
    protected void onPostExecute(String result) {
        callbackjson.CallBack(result);
        callbackjson =null;
    }

    public String getData(String _url) {
        DefaultHttpClient objHttp = new DefaultHttpClient();
        HttpParams params = objHttp.getParams();
        HttpConnectionParams.setConnectionTimeout(params, 3000);
        HttpConnectionParams.setSoTimeout(params, 3000);
        String _return = "";
        try {
            HttpGet objGet = new HttpGet(_url);
            HttpResponse objResponse = objHttp.execute(objGet);
            if (objResponse.getStatusLine().getStatusCode() < 400) {
                InputStream objStream = objResponse.getEntity().getContent();
                InputStreamReader objReader = new InputStreamReader(objStream);
                BufferedReader objBuf = new BufferedReader(objReader);
                StringBuilder objJson = new StringBuilder();
                String sLine;
                while ((sLine = objBuf.readLine()) != null) {
                    objJson.append(sLine);
                }
                _return = objJson.toString();
                objStream.close();
            }
        } catch (IOException e) {
            return "";
        }
        return _return;
    }

    public String getDataPost(String sUrl) {
        String sReturn = "";
        DefaultHttpClient httpclient = new DefaultHttpClient();
        HttpPost httppost = new HttpPost(sUrl);
        try {
            httppost.setEntity(new UrlEncodedFormEntity(_nameValuePair));
            HttpResponse response = httpclient.execute(httppost);
            ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
            response.getEntity().writeTo(byteArrayOutputStream);
            if (response.getStatusLine().getStatusCode() == HttpStatus.SC_OK) {
                sReturn = byteArrayOutputStream.toString();
            } else {
                return "";
            }
        } catch (UnsupportedEncodingException e) {
            return "";
        } catch (IOException e) {
            return "";
        }
        return sReturn;
    }

    public static class CallBackFile {
        public void CallBack(String Result) {

        }
    }
}

456

 

andante.in/i

カテゴリー:通信

前回作ったローダーをPOSTメソッド対応にしてみた。

2012.02.16

非同期での読み込みクラスを作りました。JSON,TEXTなど

で前回非同期の読み込みのクラスを作っていたのですが、PHPとの連携などで、POSTなどでデータを送る必要が出た場合に前回作成したものでは対応が出来きれないので、POSTメソッドを使えるように改変しました。

使い方は下記です。

List<NameValuePair> nameValuePair = new ArrayList<NameValuePair>(0);
 nameValuePair.add(new BasicNameValuePair("udid", UID));
 JsonLoader task = new JsonLoader(nameValuePair);
 task.setOnCallBack(new CallBackJson(){
 @Override
 public void CallBack(String Result) {
 Toast.makeText(TopActivity.this, Result, 800).show();
 };
 });
 task.execute(RSS_FEED_URL);

NameValuePairと言うのを作成する必要があります。ここはちょっと面倒だったので、クラス側ではなくこっちで対応させます。

CallBackJsonは前回のを使いまわせます。

package ***;

public class CallBackJson {
 
 public void CallBack(String Result){
 //ここにいろいろ関数をかけばいいと思う。
 }
}

次にJsonLoaderですが、

package ***;

import java.io.BufferedReader;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.UnsupportedEncodingException;
import java.util.List;
import org.apache.http.HttpResponse;
import org.apache.http.HttpStatus;
import org.apache.http.NameValuePair;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.params.HttpConnectionParams;
import org.apache.http.params.HttpParams;

import android.os.AsyncTask;

public class JsonLoader extends AsyncTask<String, Integer, String> {
 
 private CallBackJson callbackjson;
 private String mode = "none";
 private List<NameValuePair> _nameValuePair;
 
 // コンストラクタ  
 public JsonLoader() {
 mode = "none";
 }
 public JsonLoader(List<NameValuePair> nameValuePair) {
 mode = "post";
 _nameValuePair = nameValuePair;
 }
 
 
 @Override  
 protected void onPreExecute() {}

 @Override
 protected String doInBackground(String... params) {
 
 if(mode.equals("post")){
 return getDataPost(params[0]);
 }else{
 return getData(params[0]);
 }
 }
 
 public void setOnCallBack(CallBackJson _cbj){
 callbackjson = _cbj;
 }
 
 @Override  
 protected void onPostExecute(String result) {
 callbackjson.CallBack(result);
 }  
 
 public String getData(String _url) {
 DefaultHttpClient objHttp = new DefaultHttpClient();
 HttpParams params = objHttp.getParams();  
 HttpConnectionParams.setConnectionTimeout(params, 3000);
 HttpConnectionParams.setSoTimeout(params, 3000);
 String _return = "";  
 try {
 HttpGet objGet   = new HttpGet(_url);  
 HttpResponse objResponse = objHttp.execute(objGet);  
 if (objResponse.getStatusLine().getStatusCode() < 400){  
 InputStream objStream = objResponse.getEntity().getContent();  
 InputStreamReader objReader = new InputStreamReader(objStream);  
 BufferedReader objBuf = new BufferedReader(objReader);  
 StringBuilder objJson = new StringBuilder();  
 String sLine;
 while((sLine = objBuf.readLine()) != null){  
 objJson.append(sLine);  
 }  
 _return = objJson.toString();  
 objStream.close();  
 }  
 } catch (IOException e) { 
 return "";
 } 
 return _return;  
 }
 public String getDataPost(String sUrl) {  
 String sReturn = "";
 DefaultHttpClient httpclient = new DefaultHttpClient();
 HttpPost httppost = new HttpPost(sUrl);
 try{
 httppost.setEntity(new UrlEncodedFormEntity(_nameValuePair));
 HttpResponse response = httpclient.execute(httppost);
 ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
 response.getEntity().writeTo(byteArrayOutputStream);
 if(response.getStatusLine().getStatusCode() == HttpStatus.SC_OK){
 sReturn = byteArrayOutputStream.toString();
 }else{
 return "";
 }
 }catch (UnsupportedEncodingException e){
 return "";
 }catch (IOException e){
 return "";
 }
 return sReturn; 
 }
}

 

他の言語(actionscript)をやってた関係で、ちょっとJAVAは引数のタイプかえるだけで実行するコンストラクタを帰られるのがすごい便利だなーと思うのですが、こんな感じでPOSTに対応のJSONLoaderが完成しました。

POSTしたいものを増やすときには

nameValuePair.add(new BasicNameValuePair("udid1", UID1));
nameValuePair.add(new BasicNameValuePair("udid2", UID2));
nameValuePair.add(new BasicNameValuePair("udid3", UID3));

こんな感じで、addで増やしてください。

 

ずいぶん前に拾った方法でやっていたので参照元がわからなくなってしまいました。すいません。

ちょっと読み込み方が違うので、(両方とも同じ事なんですが)楽しいかもしれないので(基本違う必要があるのはheader部分のみなので)見比べるのも楽しいかもしれないです。

 

■追記

callbackjson = null;

をonPostExcuteの中に入れてメモリを解放してあげる必要がありました。

 

■追記

postもtimeoutに対応するには、

HttpParams params = httpclient.getParams();    
HttpConnectionParams.setConnectionTimeout(params, 5000);  
HttpConnectionParams.setSoTimeout(params, 5000);

を追加すればよいようです。

カテゴリー:通信

公開中のアプリ、是非ダウンロードしてみてください

2chまとめのたね

RSSを利用してさまざまなブログの情報をキュレーションしてくれるアプリ

インストールする

ひらがな戦記

OPENGL ES2 を利用したカルタのソーシャルゲーム

インストールする