本文へジャンプ
トップページ
開発実績
会社概要
お問い合わせ
プライバシーポリシー
 
こんな研究もしています
Yii Framework
Ethna
EC-CUBE
Android
 
便利なツール
ツール・ア・ラ・カルト
資料・ア・ラ・カルト
素材・ア・ラ・カルト

Android研究

Androidを使ったシステム構築

まえおき
1.開発環境
2.実例
 2-1.貯金箱を作ってみました
 2-2.システムの概要
 2-3.SQLiteの構造
 2-4.画像と音
3.いろいろ
4.日本語ビューア
5.マンガビューア
6.Titaniumを使ってみる



2.実例

2-1.貯金箱を作ってみました

コインを指先で選び、それをブタの貯金箱に引いていくと、「チャリン」と鳴って下部のカウンターに、ブタの貯金箱に投入されたコインの額の合計を表示します。
合計額は、マシン内部にSQLiteで保存されますので、ご破算にするまで消えません。
ハンマーをタッチすると、「ご破算にしますか?」ダイアログが表示され、「はい」をタッチすると、「ガシャン」とブタの貯金箱が泣き(ご愛嬌)、カウンターがゼロに初期化されます。
これだけの内容です。

2-2.システムの構造
JavaでmainにあたるonCreateで、描画部分(MyView)をインスタンス化、セット(setContentView)します。
起動に必要なimportクラスは以下のとおりです。

import android.app.Activity;
import android.os.Bundle;
import android.content.Context;
import android.view.View;

/**
 *  起動クラス
 */
public class PiggyDemo extends Activity {
   /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle icicle) {
         super.onCreate(icicle);

         /* 描画クラスのインスタンスを生成 */
         MyView mView = new MyView(getApplication());

         /* 現在のViewに設定 */
         setContentView(mView);
    }
}

描画の構造は、次のとおりです。スケルトン的なものなので、だいたいこんな構造だと覚えてしまうしかありません。

/**
 * 描画用のクラス
 */
class MyView extends View {

ここに、描画に使う変数などを宣言します。

    /**
     * コンストラクタ
     * @param c
     */
    public MyView(Context c) {
        super(c);

ここで、描画に使う変数などの初期化を行います。
    }

    /**
     * 描画処理
     */
    @Override
	protected void onDraw(Canvas canvas) {

ここで、実際の描画が実行されます。いわゆる心臓部分になります。

    }

    /**
     * タッチイベント
     */
    @Override
	public boolean onTouchEvent(MotionEvent event) {

この例の場合は、画面タッチなので、タッチイベントを判断するクラスMotionEventを引数とするonTouchEventメソッドをオーバーライドさせます。 画面がタッチされると、ここにそのイベントが報告され、その結果をonDrawします。

        return true;
    }
必要なimportクラスは、

import android.graphics.Canvas;
import android.view.MotionEvent;
となります。

2-3.SQLiteの構造

先に保存のためのSQLiteの説明をしておきます。これもスケルトン的なものなので、形がほぼ決まっているからです(参考:データベースの読み書き)。
    //レコード群の読み込み
    private String[][] readRecords(String[][] records) {
        Cursor c=db.query(DB_TABLE,new String[]{"id","info"},
            null,null,null,null,"id");
        records=new String[c.getCount()][2];
        if (c.moveToFirst()) {
            int j=0;
            do {
                records[j][0]=c.getString(0);
                records[j][1]=c.getString(1);
                j++;
           } while(c.moveToNext());
        }
        c.close();

        return records;
    }

    //レコードの追加
    private void addRecord(String id,String info) {
        ContentValues values=new ContentValues();
        values.put("id",id);
        values.put("info",info);
        int colNum=db.update(DB_TABLE,values,"id='"+id+"'",null);
        if (colNum==0) db.insert(DB_TABLE,"",values);
    }

    //データベースヘルパーの定義
    private static class DBHelper extends SQLiteOpenHelper {
        //コンストラクタ
        public DBHelper(Context context) {
            super(context,DB_NAME,null,DB_VERSION);
        }

        //データベースの生成
        @Override
        public void onCreate(SQLiteDatabase db) {
            db.execSQL("create table if not exists "+
                DB_TABLE+"(id text primary key,info text)");
        }

        //データベースのアップグレード
        @Override
        public void onUpgrade(SQLiteDatabase db,
            int oldVersion,int newVersion) {
            db.execSQL("drop talbe if exists "+DB_TABLE);
            onCreate(db);
        }
    }
SQLiteというデータベースを使うことになりますから、描画用クラス(ここではMyView)の最初のうちに、
private final static String DB_NAME ="piggy.db";//DB名
private final static String DB_TABLE="piggy";   //テーブル名
private final static int    DB_VERSION=1;       //バージョン

private SQLiteDatabase db;
のように、データベース名、テーブル名などを設定しておきます。
そのコンストラクタで、データベース使用の初期化を以下のように行います。
//データベースオブジェクトの生成
DBHelper dbHelper=new DBHelper(c);
db=dbHelper.getWritableDatabase();
この初期化までの時点で、
import android.content.ContentValues;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
以上のクラスが必要になります。
レコードの削除のメソッドがありませんが、これは、ハンマーによる初期化、すなわち既存レコードを書き直す処理で済ませるからです。
データベース起動時には、
data/data/パッケージ名/database
に、DB_NAME名のデータベースが作られますが、中身はありません。データベースの器はできたけれど、実際のテーブルはまだ、というわけで、初期の段階で初期値を入れてあげることになります。
data内容は、いったんデバッグモードで実行することで、DDMSのファイル・エクスプローラで見ることができます。
ちなみにデータベースを消すときは、そのデータベースをカーソルでクリック(選択)し、画面右上かにある「-(選択範囲を削除します)」をクリックすれば消せます。
ここで言う初期の段階というのは、データベースのテーブルを読みに行ったところが、中身がないと返された場合の意味なので、コンストラクタに初期値を入れれば済むのとはちょっと違います。
レコードは、内部レコードキー(いわゆるauto increment key)のほかには、保存用のキー(この例でid)と内容(この例でinfo)の2つなので、配列を使っています。
1次に内部レコードキー、2次に、キーと内容を取得して、返します。
レコードの読み込みは、onDrawでカウンターを描画する前に、
String[][] records=new String[6][2];
records=readRecords(records);
宣言することになります。
このときに、返されたレコード(records)の中身がない(null)というときに、中身を与えてあげます。つまり、初期の段階で初期値を入れてあげることになります。
あれば、その内容を使えるようにしなければなりませんので、こんな感じでプログラムを追加しておきます。
int[] coin_num=new int[6];
if(records.length>0){
	coin_num[0]=Integer.parseInt(records[0][1]);
	coin_num[1]=Integer.parseInt(records[3][1]);
	coin_num[2]=Integer.parseInt(records[1][1]);
	coin_num[3]=Integer.parseInt(records[4][1]);
	coin_num[4]=Integer.parseInt(records[2][1]);
	coin_num[5]=Integer.parseInt(records[5][1]);
}else{
	/* 最初だけ */
	addRecord("coin1","0");
	addRecord("coin5","0");
	addRecord("coin10","0");
	addRecord("coin50","0");
	addRecord("coin100","0");
	addRecord("coin500","0");
}
何かしらの結果を持たないとあとの処理ができませんので、coin_num配列を用意しておきます。
わざわざ「最初だけ」と断ってありますが、なければないでどうしようもない処理なので、入れておくしかありません。そういう意味では、importクラスで済まされていますが、データベースを用意するのも、テーブルを作るのも、最初の1回でいいわけで、常にimport(クラスの中身はそれだけではありませんが)する必要はない、プログラミングのちょっとしたジレンマでしょうね。
addRecordはレコードの追加という処理ですが、1度めはそうでも、2度めからは更新でしょ、と。レコード追加のメソッドで、あれば更新、なければ挿入としていますね。
レコードがあったとき、読み込んだ内容を数値に変換していますが、これも、文字列でテーブルに保存されるようにしているからです。取り出して以後はめんどうですが、データは文字列で扱った方が楽だというのが、プログラミング全体に言える筆者の感想です。

2-4.画像と音

最近、商用でもないのにフリーが少なくて、探すのに苦労します。
コインは、うちのプリンタで実物をスキャンしました。探してもフリーでちょうどいいのはありませんでした。トンカチ(とんかち-日用品-アイコン素材)とブタの貯金箱(ソザイング)はフリーのものです。瞬間ですがブタが流す涙は、フリー(素材:涙 素材 - を無料ダウンロードするなら!)のものを加工させていただきました。背景を透過するのに、PhotoShopがあると便利です。「Webおよびデバイス用に保存」だとPNG形式でも透過が可能になります。
音は、こだま標準効果音ライブラリで、いろいろな効果音がダウンロードできます。もちろん商用だと有料になります。

 2    



Copyright c 2010 by キーウェブコーポレーション