Android(Java)を始める – Wonderfl APIからデータを取ってきて表示

Filed under Android, Java

絶賛Androidの勉強中。

Wonderfl APIから情報を取ってきて表示しています。

今回は、

  • JSONの扱い方
  • ListViewのカスタマイズ
  • ProgressDialogを使う
  • AsyncTaskでバックグラウンド処理

の4つの勉強。

ちゃんとJSONパーサーがあるのでデータの解析は楽ですね。

各アイテムをクリックするとWonderflのサイトへ飛ぶようになってます。

以下、今回のソースです。

Main.java。

package jp.sakef;

import java.io.BufferedInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;
import org.apache.http.HttpResponse;
import org.apache.http.HttpStatus;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.util.EntityUtils;
import org.json.JSONArray;
import org.json.JSONObject;
import android.app.Activity;
import android.app.ProgressDialog;
import android.content.Context;
import android.content.Intent;
import android.content.pm.ActivityInfo;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.net.Uri;
import android.os.AsyncTask;
import android.os.Bundle;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.ImageView;
import android.widget.ListView;
import android.widget.TextView;

public class Main extends Activity
{
	private int count;
	private int numCode;
	private ProgressDialog dialog;
	private List<CodeData> list;
	private ListView view;

	// Activity作成時に実行
	protected void onCreate(Bundle savedInstanceState)
	{
		super.onCreate(savedInstanceState);
		setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
		setContentView(R.layout.main);

		// ListViewを取得
		view = (ListView)findViewById(R.id.listView);

		// ProgressDialogを作成
		dialog = new ProgressDialog(this);
		dialog.setTitle("Wonderflに接続中");
		dialog.setMessage("Wonderflからsakefのデータを取得しています。");
		dialog.setProgressStyle(ProgressDialog.STYLE_SPINNER);
		dialog.setCancelable(true);
		dialog.show();

		try
		{
			// Wonderflに接続
			String key = "ここにAPI Keyを入れるのよー。";
			String user = "sakef";
			String url = "http://api.wonderfl.net/user/"+user+"/codes?api_key="+key;
			HttpGet get = new HttpGet( url );
			HttpClient client = new DefaultHttpClient();
			HttpResponse response = client.execute(get);

			// 接続が成功しているか確認
			int status = response.getStatusLine().getStatusCode();
			if (status != HttpStatus.SC_OK) throw new Exception("Error!");

			// 結果を取得
			String source =  EntityUtils.toString( response.getEntity());
			JSONObject json = new JSONObject(source);

			// statがokなら続行
			count = 0;
			list = new ArrayList<CodeData>();
			String stat = json.getString("stat");
			if(stat.equals("ok"))
			{
				JSONArray codes = json.getJSONArray("codes");
				numCode = codes.length();
				for(int i = 0; i < numCode; i++)
				{
					JSONObject code = codes.getJSONObject(i);
					String title = code.getString("title");
					String thm = code.getString("thumbnail");
					String id = code.getString("id");

					new ImageLoadTask(this, title, id).execute(thm);
				}
			}
			else dialog.dismiss();

			// 接続を解除
			client.getConnectionManager().shutdown();
		}
		catch (ClientProtocolException e){Log.d("ClientProtocolException", e.getMessage());}
		catch (IOException e){Log.d("IOException", e.getMessage());}
		catch(Exception e){Log.d("Exception", e.getMessage());}
	}

	// 画像をロードするクラス
	public class ImageLoadTask extends AsyncTask<String, Integer, Bitmap>
	{
		private Main parent;
		private String title;
		private String id;

		// コンストラクタ
		public ImageLoadTask(Activity activity, String title, String id)
		{
			parent = (Main)activity;
			this.title = title;
			this.id = id;
		}

		// 画像のロード
		protected Bitmap doInBackground(String... args)
		{
			Bitmap bitmap = null;

			try
			{
				URL url = new URL(args[0]);
				HttpURLConnection conn = (HttpURLConnection) url.openConnection();
				conn.setDoInput(true);
				conn.connect();
				InputStream in = new BufferedInputStream(conn.getInputStream());

				ByteArrayOutputStream bos  = new ByteArrayOutputStream();
				byte[] w=new byte[1024];
				while (true)
				{
					int ss=in.read(w);
					if (ss<=0) break;
					bos.write(w,0,ss);
				};
				bitmap = BitmapFactory.decodeByteArray(bos.toByteArray(), 0, bos.size());
				in.close();
				bos.close();
				conn.disconnect();
			}
			catch (Exception e){Log.d("Exception", e.getMessage());}

			return bitmap;
		}

		// ロード終了後に実行
		protected void onPostExecute(Bitmap result)
		{
			synchronized (parent)
			{
				count ++;
				list.add(new CodeData(result, title, id));
				if(count == numCode)
				{
					dialog.dismiss();
					DataAdapter adapter = new DataAdapter(parent, R.layout.list_item, list);
					view.setAdapter(adapter);

					view.setOnItemClickListener(new AdapterView.OnItemClickListener()
					{
						public void onItemClick(AdapterView<?> parent, View view, int position, long id)
						{
							String url = "http://wonderfl.net/c/"+list.get(position).id;

							Uri uri=Uri.parse(url);
							Intent intent=new Intent(Intent.ACTION_VIEW, uri);
							startActivity(intent);
						}
					});
				}
			}
		}
	}

	// リスト用のデータを保持するクラス
	public class CodeData
	{
		public Bitmap bitmap;
		public String title;
		public String id;

		public CodeData(Bitmap bitmap, String title, String id)
		{
			this.bitmap = bitmap;
			this.title = title;
			this.id = id;
		}
	}

	// データをリストの表示させるためのアダプター
	public class DataAdapter extends ArrayAdapter<CodeData>
	{
		private LayoutInflater inflater;
		private List<CodeData> items;  

		public DataAdapter(Context context, int textViewResourceId, List<CodeData> objects)
		{
			super(context, textViewResourceId, objects);
			items = objects;
			inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
		}

		public View getView(int position, View convertView, ViewGroup parent)
		{
			CodeData item = items.get(position);

			View v = convertView;
			if(v == null)  v = inflater.inflate(R.layout.list_item, null);

			ImageView iv = (ImageView)v.findViewById(R.id.img);
			iv.setImageBitmap(item.bitmap);

			TextView tv = (TextView)v.findViewById(R.id.text);
			tv.setText(item.title);

			return v;
		}
	}
}

main.xml。

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:id = "@+id/mainLayout"
android:orientation="horizontal"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
    <ListView
    android:id="@+id/listView"
   	android:layout_width="fill_parent"
   	android:layout_height="wrap_content"
   	android:fadeScrollbars="false"/>
</LinearLayout>

list_item.xml。

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:id = "@+id/listLayout"
android:orientation="horizontal"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:padding = "10px"
android:background = "#000000">
    <ImageView
    android:id = "@+id/img"
    android:width = "140px"
    android:height = "140px"
    android:paddingRight = "20px"
    android:layout_width = "wrap_content"
    android:layout_height = "wrap_content"
    android:scaleType = "fitXY" />
    <TextView
    android:id = "@+id/text"
    android:layout_width = "fill_parent"
    android:layout_height = "wrap_content"
    android:layout_marginTop = "20px"
    android:textSize = "15px"
    android:width = "200px"
    android:textColor = "#FFFFFF" />
</LinearLayout>

Post a Comment

Your email is never published nor shared.