ハンズオンセミナーに参加した

本日、第2回ハンズオンセミナーin大阪に参加してきました。

初めて参加しましたが、色々な人がいて刺激を受けました。
一番後ろの席で態度がでかくてすみません。。。orz
とりあえず、感想。

OpenGL事始め

エミュレータと実機での動作の差が非常にありました。
その理由も説明して頂きましたが、現状のAndroidでは3Dはきついな
っていうのが感想。
まだまだこれからってことで。

PIAX(P2P Interactive Agent eXtensions) on Androidの挑戦

え〜と、Androidに関することは5分くらし話したか話してないかって感じw
でも、現在のWebの状況とかIP枯渇とか、P2Pが救うぞとか
マルチレイヤーとか興味深い話ではありました。
P2Pに興味が湧いたというか、吉田さんSUGEEEEEEEって感じですw

もっとServiceしよう

使い所がいまいち分からなかったけど、おそらく既にネットワーク接続確立とかって
常駐なんで、Service使われているんだろうな〜って感じです。
Android内でHTTPサーバたてるとか面白かったです。

GPSはじめの一歩

結構、簡単にできるもんだな〜って驚きました。
ただ、数学?物理?が出来ない私は、数式を見て頭いたくなったw
でも、一度実装してみようと思います。

動画再生アプリ

これほど簡単に動画再生できるとは・・
VideoViewってあるな〜とは思ってたけど、一度も使ってなかったので
面白かったです。
AndroidでiTuneみたいなの誰か作りそうだなってのが感想。
簡易なのであれば、そんなに難しくないんじゃないかと思う。



やはり、実機がない分日本ではAndroid開発者は不利なのかなと。
G1 Devも5万くらいするしね(持ってるけどw)

次回も参加したいです。そして・・・いつか発表側で何かやりたいなと思いました。

壁紙設定をしてみる

じゃらんWebサービスを使ったアプリは進んでません。。。
とりあえず、色々触ってはいるんですが。

今日は、Androidで壁紙設定を組み込んでみました。

壁紙を設定するのは非常に簡単です。

ContextWrapper.setWallpaper(Bitmap bitmap)

上記メソッドを使うだけです。
ActivityはContextを継承しているので、直接setWallpaperメソッドを呼べます。
壁紙に設定したいイメージを、Bitmapクラスに設定し
引数として渡せば、設定されます。
あと、AndroidManifest.xmlに追記が必要です。
壁紙設定しますという下記記述を追記しなければ、
Security違反のExceptionが発生するので気をつけなければなりません。

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

以上で、壁紙設定する実装です。

ProgressDialogを使う

Rssを取得するアプリは、以前から完成してたが
本を色々と読んでいると、やはり呼応性がかなり重要だなと・・・
今までもちょくちょく目にしてた「Application Not Responding」(以降ANR)ので
直さないと思っていたので、ProgressDialogを実装することにしました。

ProgressDialogの実装を参考にさせて頂いたのは、
今回も、id:minghaiさんのアプリです。

すでに、id:minghaiさんのエントリーでHandlerを使用しないと
いけないのは知っていました。

一応、APIDemoのソースを見て、組み込んでみましたが
やはり無理でした。

とりあえず、下記が実装したソースの一部
まずHandlerを作成しておきます。

    	final Handler h = new Handler();

次に、ダイアログを生成
今回は、進捗を表示しないのでデフォルトのクルクルでOK。

    	pd = new ProgressDialog(Transition3d.this);
    	pd.setMessage("Now Processing...");
    	pd.setTitle("Loading ....");
    	pd.show();

次に、RSSを取得する少し時間のかかる部分をスレッドで呼び出します。

    	new Thread() {
    		public void run() {
		        try{
	    			holder = kfc.getRssData();
		            if(holder.getTitle().size() < 1) {
		            	isData = false;
		            }
		        } catch(Exception e) {
		        	isData = false;
		        }
		        h.post(new Runnable() {
		        	public void run() {
		        		loadData();
		        	}
		        });
			}
    	}.start();

h.postメソッドの引数Runnable#runで実行しているloadDataメソッドは
読み込み完了しているかをチェックしてます。
チェックしてるといっても、インスタンスが生成されているかどうかを
見てるだけですが・・・
結果インスタンスを存在する場合、画面表示を更新します。

    private void loadData() {
    	new FeedLoader().load();
    }
    
    private class FeedLoader {
        private Handler mHandler = new Handler();
        private Runnable mRun = new Runnable() {
            public void run() {
                    check();
            }
        };

        void load() {
            mHandler.post(mRun);
        }
        
        void check() {
            if (holder != null) {
                // Only last time changes mRun to exit
                mRun = new Runnable() {
                    public void run() {
                            updateUI();
                    }
                };
            }
            load();
        }
    }

これでなんとかなりました。
実は、Javaもそれほどしっかりと理解してないので
ここらへん(Threadとか)が凄く苦手だったりします。
勉強しないと駄目だな。。。

じゃらんWebサービスを使ってみる1

今日から、じゃらんWebサービスを利用して宿泊ホテル検索アプリを
作ってみようと思ってます。

まず、じゃらんWebサービスは、APIキーが必要です。
ってことで、じゃらんWebサービスに登録。

これで、じゃらんWebサービスを利用することができるようになりました。
じゃらんWebサービスでは、色々と検索できるようです。

  • じゃらん宿表示API
    • Advance
    • Light
  • 空室検索API
  • エリア検索API
  • 温泉検索API

他のAPIは基本的にはエリア指定が必要なので、
エリア検索は、組み合わせて使う感じでしょうか。

【メイン画面構成】
1.都道府県選択
2.地域を絞ったエリア選択

エリア検索で全データを保持しておいて、都道府県が選択された段階で
地域選択を更新してあげるように実装してみます。

main.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    >
    <ImageView
    	android:id="@+id/jaranImg"
    	android:layout_width="88px"
    	android:layout_height="50px"
    	android:layout_gravity="top"
    	/>
    <LinearLayout
    	android:id="@+id/inner_layout1"
    	android:layout_width="wrap_content"
    	android:layout_height="wrap_content">
    	
    	<TextView
			android:id="@+id/prefTxt"
			android:layout_width="wrap_content"
			android:layout_height="wrap_content"
			android:text="都道府県を選択してください"
			/>
		<Spinner
			android:id="@+id/prefSpn"
			android:layout_width="wrap_content"
			android:layout_height="wrap_content"
			/>
	</LinearLayout>
    <LinearLayout
    	android:id="@+id/inner_layout2"
    	android:layout_width="wrap_content"
    	android:layout_height="wrap_content">
    	<TextView
			android:id="@+id/areaTxt"
			android:layout_width="wrap_content"
			android:layout_height="wrap_content"
			android:text="地域を選択してください"
			/>
		<Spinner
			android:id="@+id/areaSpn"
			android:layout_width="wrap_content"
			android:layout_height="wrap_content"
			/>
	</LinearLayout>	
   	<Button
 		android:id="@+id/btnSearch"
 		android:layout_width="wrap_content"
 		android:layout_height="wrap_content"
 		android:text="宿検索" />
	
</LinearLayout>

さて、メイン画面いったんこれで。
では実装ですが、
まず都道府県なですが、じゃらんのエリア検索を使用して取得します。
っとここで、用事ができたので続きは明日か・・・仕事早く帰れるかな・・・

はてなPhoto一覧を表示してみる

Androidのアプリを触り始めたのだが、サンプルが充実している。
ただ、ネット経由ってのがよくわからない。

とりあえず、以前にRSSを取得するコードを再利用し、はてなPhoto一覧を
取得し表示してみる。

サンプルを流用。
まず、最初に呼ばれるクラス

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.rss_main);
        
        hatenaBtn = (Button)findViewById(R.id.btn_hatena);
        rssBtn = (Button)findViewById(R.id.btn_kronos);
        wikiBtn = (Button)findViewById(R.id.btn_wiki);
        
        hatenaBtn.setOnClickListener(this);
        rssBtn.setOnClickListener(this);
        wikiBtn.setOnClickListener(this);
    }

	public void onClick(View bundle) {
		if(bundle == hatenaBtn) {
	    	//CalledActivityの呼び出し
            Intent intent=new Intent(this,net.kronos.rss.act.GalleryActivity.class);            
            startActivityForResult(intent,RESULT_OK);
		} else if(bundle == rssBtn) {
			Intent intent = new Intent(this,net.kronos.rss.act.Transition3d.class);
			startActivityForResult(intent, RESULT_OK);
		} else if(bundle == wikiBtn) {
			
		}
	}

はてな以外にも色々いじってたので、会社のRSS取得とかも入ってますが・・・
そこは気にしないで。

さて、次にActivityを継承した実際に取得して画面へデータを仲介する所ですが、
全部乗せるとえらいことになるので、抜粋。

        holder = (HatenaPhotoResourceHolder)this.getPhotoList();
        
	List<String> imgUrlList = holder.getImageUri();
		
	ImageAdapter adapter = new ImageAdapter(this);
		
	adapter.setImage(imgUrlList.toArray(new String[0]));
		
	Gallery gallery = (Gallery)findViewById(R.id.Gallery01);
				
	imageSwitcher = (ImageSwitcher)findViewById(R.id.ImageSwitcher01);
	imageSwitcher.setFactory(this);
	imageSwitcher.setClickable(true);
	imageSwitcher.setInAnimation(AnimationUtils.loadAnimation(this, android.R.anim.fade_in));
	imageSwitcher.setOutAnimation(AnimationUtils.loadAnimation(this, android.R.anim.fade_out));
	imageSwitcher.setImageURI(holder.next().getImgUrl());
		
	gallery = (Gallery) findViewById(R.id.Gallery01);		
	gallery.setAdapter(adapter);
	gallery.setOnItemSelectedListener(this);

ImageAdapter

import java.io.BufferedInputStream;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.URL;

import android.app.Activity;
import android.content.Context;
import android.content.res.Resources;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.Gallery;
import android.widget.ImageView;

public class ImageAdapter extends BaseAdapter {

	private Context myContext;
	
	private String[] imageUris = {};
	
	public ImageAdapter(Context c) {
		this.myContext = c;
	}
	
	public int getCount() {
		return this.imageUris.length;
	}

	public Object getItem(int position) {
		return position;
	}

	public long getItemId(int position) {
		return position;
	}

	public View getView(int position, View convertView, ViewGroup parent) {
		ImageView i = new ImageView(this.myContext);
        HttpURLConnection http = null;
        InputStream in = null;
        URL url = null;
        BufferedInputStream bis = null;
        Bitmap bm = null;
        try {
             // 指定した URL の作成
             url = new URL(imageUris[position]);
             // HTTP通信の初期化
             http = (HttpURLConnection) url.openConnection();
             // HTTP通信のメソッド指定(今回はダウンロードのみなので GET を指定)
             http.setRequestMethod("GET");
             // HTTP通信開始
             http.connect();
             // HTTP通信でデータを取得
             in = http.getInputStream();
             bis = new BufferedInputStream(in);
             // 取得したデータを Bitmap へ変換
             bm = BitmapFactory.decodeStream(bis);
             i.setImageBitmap(bm);
        } catch (Exception e) {
             e.printStackTrace();
        } finally{
             // HTTP 通信の後始末
             try{
                 in.close();
             } catch (Exception e) {}
             try {
                 http.disconnect();
		     } catch (Exception e) {}
        }
        // スケールタイプを設定
        i.setScaleType(ImageView.ScaleType.FIT_CENTER);
        i.setLayoutParams(new Gallery.LayoutParams(150, 200));
        
        return i;
 		
	}

	public float getScale(boolean focused,int offset) {
		return Math.max(0, 1.0f / (float)Math.pow(2, Math.abs(offset)));
	}
	
	public void setImage(String[] imgeurls) {
		this.imageUris = imgeurls;
	}
	
	private String getFilename(String url) {
		String filename = null;
		
		int pos = url.lastIndexOf("/");
		filename = url.substring(pos);
		
		return filename;
	}
}

ここで失敗。HttpCilentがあるのを後で気づいたw
後ほど、実装しなおすとして。
ここで、getViewメソッドだが、毎回呼ばれる?
いや、画像を取得する際には呼ばれるだろうが、
画像きりかえ(Gallery)の際もいってるのかな・・・
emulatorでも、実機でも画像がカクカクする。

とりあえず、id:minghaiさんのソースコード参考に
再度作り直しか。

ADP1のFirmwareを1.1にしてみる

Androidアプリの開発は、Firmware1.1で開発しています。
しかし、ADP1(Android Dev Phone 1)は、1.0なので
1.1に変更しました。
やはり、開発と同期とりたいので。

これも、先駆者のおかげですんなりできました。
一部、迷ったっていうかつまづいたのでそこを補填して記述します。

基本的には、ここの説明ですんなりいけます。
私が実施した時のつまづいたのは、


まず、上記画像の1.
最初、fastbootと表示されたのですが、ターミナルからfastbootが
認識されない(後述するが当たり前・・・)為、ADP1を再起動しました。
手順通り、いったん停止し、再起動しました。
そしたら、serial0となってしまい、しかもカメラボタン押しても変わらない・・・
焦りましたよ。
結局、カメラボタン押しながら起動で、serial0状態にして、backボタンでfastbootに
変わってくれました。

次に、上記画像の3.
fastbootを実行するところですが、fastboot-mac.zipを準備しわすれてました。
っていうか、気づきもしてませんでした(汗
下記手順で準備しました。

1.fastboot-mac.zipをダウンロード
2.解凍し、/bin にコピーする

sudo cp -p fastboot-mac /bin/fastboot

これで準備完了です。
ちなみに、ターミナルを立ち上げて手順通りに
実行すれば、問題なく実施できました。
※実際には

$ fastboot erase cache
$ fastboot update signed-dream_devphone-img-130444.zip 
archive does not contain 'boot.sig'
archive does not contain 'recovery.sig'
archive does not contain 'system.sig'
--------------------------------------------
Bootloader Version...: 0.95.3000
Baseband Version.....: 1.22.14.11
Serial Number........: xxxxxxxxxx
--------------------------------------------
checking product... OKAY
checking serialno... OKAY
checking version-baseband... OKAY
checking version-bootloader... OKAY
checking version-cpld... OKAY
sending 'boot' (1500 KB)... OKAY
writing 'boot'... OKAY
sending 'recovery' (1722 KB)... OKAY
writing 'recovery'... OKAY
sending 'system' (53645 KB)... OKAY
writing 'system'... OKAY
rebooting... 

setting→about phone→Firmware version で確認できます。

最後に、ADP1のSDカードが入れてある場所は、下記画像参考

AndroidでWIFI接続

さて、久しぶりの更新。
Androidの実機(Androdi Dev Phone 1)を手に入れて早速起動。

NO SIM CARD


そりゃそうですよね。だってSIMカード入れてないし。
っで、とりあえずGoogleで解除方法を検索。

ありましたよ。さすが、世の中先駆者はいるものです。

こちらを参考に実施。

Googleアカウントは持ってるので、認証をすます。
ここで、ネットワークエラー。
ネット接続できませんってことで、忘れていたWifi設定を行う。
ちなみに、自宅はバッファローの無線LAN環境なので、これに接続・・・



unsuccess・・



なんで。
とりあえず、調べてみるがこんなこと起こってる人がいないようです。
自宅はPS3やら、WiiやらがあるのでAOSSで行っているのを思い出すw

ってことで、AirStationにアクセス。
AOSSのMac制限でAndroidのMacアドレスを登録。

成功。

これで、自宅ではAndroidやりたい放題ってことで。