2011/12/31

Java の 自作クラス を 配列 化する時の注意点

例えば、Dataという自作クラスがあったとします
そのクラスの配列を使いたい場合

private int NUM=5;
private Data[] datas = new Data[NUM];
    for(int i=0;i<NUM;i++)
        datas[i]=new Data();

と、このようにするとよいです

配列の要素一つ一つにインスタンス化しないとダメみたいですね
ビルドでエラーが出ないので気が付きにくいエラーです

Activity の動作について



アプリを作っていてSurfaceViewの上から別の画面(スコアなど)を表示したくなった
その際に何で画面を切り替えるか、どうやって処理を中断させるか、悩んだので書いて置きます

まあ、タイトルの通り、別画面への以降は別Activity呼び出しを使いました
SurfaceView上のから以下のコードを実行するといい

Intent i = new Intent(getContext(),ClearActivity.class);
i.putExtra("DataKeyWord",Data);
getContext().startActivity(i); 


ViewのgetContextを使っての呼び出し
 ここで、別画面での処理の後、もう一度呼び出し元のSurfaceViewに戻りたいと考えました
しかし、getContextだとstartActivityForResultメソッドは使えないようです

どうにかならんかなあ、とLogCatでトレースし、SurfaceViewとActivityの動きを観察してみた


SurfaceViewのオーバーライドメソッドは以下の3つ

Viewが生成されるとき呼び出し
surfaceCreated(SurfaceHolder holder)

Viewが変更されたとき呼び出し
surfaceChanged(SurfaceHolder holder,int format,int w,int h)

Viewが破棄されるとき呼び出し
surfaceDestroyed(SurfaceHolder holder)


Activityのオーバーライドメソッドは多いから省略!

図はめんどいので字で


メインのActivityをA
呼び出される側のActivityをB
SurfaceViewはSとする


A:onCreate 
A:onStart
A:onResume  //ここでSurfaceViewを生成
S:SurfaceCreated
S:SurfaceChanged 
//ここで一定条件を満たした時,Intentを投げる
A:onPause 
B:onCreate
S:SurfaceDestroyed
A:onPause
B:finish /呼び出された側の処理が終了
A:onRestart
二行目へ戻る

と、こんな感じになりました
結構不可解なとこもありますね
一番下の参照ページを見てもらったほうが早いと思います・・・
あと、logを挟む場所でも変わるし、一概には言えないとこもある


画面がOFFになった時や別Activity呼び出し時にonPauseが呼ばれるようなので
そこでSurfaceViewの停止処理を入れることです
SurfaceViewのインスタンスにnullを入れると surfaceDestroyedが呼ばれるようです

そうすることでonResumeでもう一度インスタンス化し、SurfaceViewでの処理をできます

参照ページ
Activityのライフサイクル


しっかし、文が汚い
もう少しうまく書けないものだろうか ・・・

2011/12/30

Android セミナー 2012 in Aizu 第2回 で作ったもの

一応置いておきます


Avoidroid
http://dl.dropbox.com/u/25808411/AndRocket.apk



傾きセンサを使って操作します
10秒間UFOから逃げてください 。
加えて、バグがあって直してないので、自己責任でお願いします

Xperia x10とかだと重いです・・・
Surface Viewでぬるぬる動かすのってどうやるんだろう?


追記:12/30
一応バグ直しました

2011/12/24

Android で MIME Type 判別

ちょっとアプリを作っていてかなり悩んだのでメモとして残しておく

MIME Typeというのは見たことはあるが、きちんと知らないので調べて見ました

MIME 【Multipurpose Internet Mail Extension】
"マイム"と読むらしい
直訳してみれば、"多目的インターネットメール拡張機能"かな?

ネットワーク上で動画、音声、画像などのファイルを扱うための規格
RFC2045~2049で規定されている。
 拡張子とファイルのデータを関連付けているものらしい
" タイプ名/サブタイプ名"のように区切られて表現される

例としては、
text/html
text/plain
image/jpg
application/pdf
などなど


さて、例えば、AndroidでSDカードにアクセスし適当なファイルを開いた際
どんなファイルか判別したいとする

この時にMIMEを読み取り画像か音声かテキストか判別し
他のアプリにIntentを投げようと思います


※12/25追記:以下の方法だと動作しない場合があるので更に下に追記しました。
Android Developerのここを参考に
//ファイル名からMIMEタイプ取得
public String GetMIMEType(String Path){
 //拡張子を取得
 String ext=MimeTypeMap.getFileExtensionFromUrl(Path);
 //小文字に変換
 ext=ext.toLowerCase();
 //MIME Typeを返す
 return MimeTypeMap.getSingleton().getMimeTypeFromExtension(ext);
}


引数のパスは"/sdcard/Music/xxx.mp3"のように渡しています。
そこからgetFileExtensionFromUrlメソッドを使って、拡張子(mp3)を取得
それをgetMimeTypeFromExtensionメソッドに入れてMIME Typeを呼び出し元に返す
getFileExtensionFromUrlとgetMimeTypeFromExtensionはエラーだとnullを返すので注意
加えて、他のサイトで見た時、端末によってMIME Typeにばらつきがあるとかなんとか…


最終的に取得したMIME Typeをintent.setType(MIME type)などに渡せば
対応したアプリが起動するはず



※12/25追記
動作する場合としない場合が多くあったのでより調べてみたところ
MimeTypeMapは全角文字に対応していないらしい…
実際空白や漢字がファイル名に含まれた場合に動作しませんでした
具体的にはgetFileExtensionFromUrl()で""が返ってくるようです

getMimeTypeFromExtension()の方は拡張子に対応したMIME Typeを返すので
自分でファイル名の"."以下を読み取って与えるようにしました
ついでにインテントの部分も載せておきます。


private void CreateIntent(String Path){
  //ファイルから拡張子取得
  File file = new File(Path); 
  String fn = file.getName(); 
  int ch = fn.lastIndexOf('.'); 
  String ext = (ch>=0)?fn.substring(ch + 1):null;
  
//拡張子からMIMEType取得
  String MIME = MimeTypeMap.getSingleton().getMimeTypeFromExtension(ext.toLowerCase()); 
  
  if(MIME != null && !MIME.equals("")){
   //Intent生成
   Intent intent = new Intent(Intent.ACTION_VIEW); 
   intent.setDataAndType(Uri.fromFile(file),MIME); 
   startActivity(intent); 
  }else
   Log.e("CreateIntent","MIME is Error");
 }


多分今度こそ動くはず…(;´Д`)

2011/12/18

Compiling Avrdude

AVRマイコンで遊ぶ下準備として自分で適当にコンパイルしてみた

AVRDUDE - AVR Downloader/UploaDEr
>AVRDUDE is an utility to download/upload/manipulate the ROM and EEPROM contents of AVR microcontrollers using the in-system programming technique (ISP).

AvrdudeはAVRマイコンにライタで書き込んだりする際に使うツールらしい

MinGWを使って、"avrdude-5.11.tar.gz"でUSB込でビルドしました(USB使う予定はないけど・・・)

と言っても、コマンドラインだけでの書き込みも面倒なので
eclipseのプラグインなどを使って開発環境を構築する予定

なんか、まとまりも無いし、後日改めてまとめ直すことにしよう

追記

現物が届いたのでいろいろとやってみたが肝心のeclipseだとどうも上手く動かないので
仕方なく公式の"AVR Studio"を使いました('A`)

とりあえず、超小さい蛍光管で、マイコン時計を作ってみようと思います
部品がまだ足りない・・・

概要

メモも兼ねて何でも書きますよ