/* * 今回はAndroidで使用できるSQLiteという * 機能を使ってみました。 * * これは一般で使うSQLデータベースの簡易 * 版みたいな感じだと思うのですが、結構 * 色々できちゃうので問題なくデータベース * プラグラミングができると思います。 * 簡易版てよりandroid版java版みたいな感じ * でしょうか。 * * それでですが、説明はメンド・・いや説明より * 慣れろ!てことで簡単なアプリを作ってみま * した。 * とはいえ、結構完成度は高く、一通りの機能 * は詰め込みました。 * テーブルのカラム(列)を増やせばなんでも * できます。 * * ・最初からデータを設定しておく * ・データの昇順、降順の切り替え * ・データ保存 * ・データ更新 * ・データ削除 * ・ListViewの子リスト(row)へのアクセス * * こんな感じです。 * それぞれのメソッドや、データベース説明は * ソースに直接書いてありますが、そこでは説明 * できないことを書いておきます。 * * このプログラムでは、本当に基本的なことしか * やっていません。おおきなレコードを扱うと、 * それを分解して、プログラム上でつなぎ合わせ * などやるのですが、それはandroidプログラミング * のみでの話しではないのでやっていません。 * * しかしこのデータベースは勉強するとおもしろいし * SQLを勉強したものが結構そのまま使えたりするので * 勉強してみるのもいいかもしれません。 */
|
ファイル名「MainActivityjava」 package com.example.dbrensyu5; import android.os.Bundle; import android.app.Activity; import android.graphics.PixelFormat; import android.view.Display; import android.view.Menu; import android.view.MenuItem; import android.view.Window; import android.view.WindowManager; import android.widget.Toast; public class MainActivity extends Activity { private static final int MENU_ITEM0=0; float disp_w; float disp_h; MainLoop ml; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); requestWindowFeature(Window.FEATURE_NO_TITLE); getWindow().setFormat(PixelFormat.TRANSLUCENT); Window window = getWindow(); window.addFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN); WindowManager manager = window.getWindowManager(); Display disp = manager.getDefaultDisplay(); disp_w = disp.getWidth(); disp_h = disp.getHeight(); ml = new MainLoop(this,disp_w,disp_h); //setContentView(R.layout.edit_listview); } //オプションメニューに表示させるアイテム登録 @Override public boolean onCreateOptionsMenu(Menu menu) { super.onCreateOptionsMenu(menu); MenuItem item0 = menu.add(0,MENU_ITEM0,0,"終了"); return true; } //オプションメニューを選択した時の処理 public boolean onOptionsItemSelected(MenuItem item){ switch (item.getItemId()){ case MENU_ITEM0: finish(); return true; } return true; } /* * エラーなど確認用などに便利。おまけ */ public void makeTost(String str,int id){ int tost = Toast.LENGTH_LONG; if(id==1) tost = Toast.LENGTH_SHORT; Toast toast = Toast.makeText(this.getApplicationContext(), str, tost); toast.show(); } } ファイル名「DBAdapter.java」 /* * SqLiteの心臓部です。ほぼこのまま使えます * それぞれのカラム値など変えればいいだけです。 */ package com.example.dbrensyu5; /* * 条件に合った指定行だけ取り出す方法-------------------------------------------- * FROM テーブル名 * SELECT * かSELECT A,B,C...と全列名 * WHERE 取り出したい列名 * * 必要な列だけ取り出す方法------------------------------------------------------- * FROM テーブル名 * SELECT 必要列名 * * 複数のテーブルを1つのテーブルとして抽出する方法------------------------------- * FROM テーブルA,テーブルB * SELECT A1列,A2列,B1列,B2列 * WHERE A2列=B1列 * * LIKE 先頭がxxで始まる = xx% 最後がxxで終わる = %xx xxを含む = %xx%------------ * * AND OR NOT---------------------------------------------------------------------- * FROM テーブル名A * SELECT * * WHERE A1列='条件名' AND A2='条件名 * * 数値を範囲で指定するやり方------------------------------------------------------- * FROM テーブル名A * SELECT * * WHERE A1列 >=最小値 AND A1列 <= 最大値 * * FROM テーブル名A * SELECT * * WHERE A1列 IN(19,20,21) * * ORDER_BY 抽出結果を昇順または降順に並べ替える------------------------------------- * ASC 昇順(小→大)DESC 降順(大→小) * FROM テーブル名 * SEECT * * WHERE どの列を * ORDER_BY 列名+ASC(DESC) * * DISTINCT 重複下行をまとめる-------------------------------------------------------- * FROM テーブル名 * SELECT DISTINCT 重複をさせない列名 * * 計算 ------------------------------------------------------------------------------ * SUM 合計を求める SUM(列名または、計算式) * AVG 平均を求める AVG(列名または、計算式) * MAX 最大値を求める MAX(列名または、計算式) * MIN 最小値を求める MIN(列名または、計算式) * COUNT 行数を求める COUNT(列名),COUNT(*) * * GROUP BY グループ化---------------------------------------------------------------- * FROM テーブル名A,テーブル名B * SELECT 列名,SUM(列名) * GROUP BY グループ化する列名 * * HAVING GROUP グループ化されたデータから条件にあったグループを抽出------------------ * SELECT 列名1,列名2, 〜列名n * FROM 表名1,表名2,〜表名n * WHERE 抽出条件 ← 表の結合条件を記述する * GROUP BY 列名1,列名2 ← 指定された列の値でグループ化 * HAVING 抽出条件 ← 抽出条件 */ import android.content.ContentValues; import android.content.Context; import android.database.Cursor; import android.database.sqlite.SQLiteDatabase; import android.database.sqlite.SQLiteOpenHelper; import android.widget.Toast; public class DBAdapter { static MainActivity ma; static final int DATABASE_VERSION = 1; static final String DATABASE_TEST_DB = "db_rensyu.db"; public static final String TABLE_NAME_TESTDB = "test_db"; public static final String COL_ID = "_id"; public static final String COL_TEXT = "text"; protected final Context context; protected DatabaseHelper dbHelper; protected SQLiteDatabase db; public DBAdapter(Context context){ ma = (MainActivity)context; this.context = context; dbHelper = new DatabaseHelper(this.context,DATABASE_TEST_DB); } private static class DatabaseHelper extends SQLiteOpenHelper { public DatabaseHelper(Context context,String DATABASE_NAME){ super(context, DATABASE_NAME, null, DATABASE_VERSION); } /* * newされた時に呼ばれます * データベースを用意するって感じです。 * なければonCreateで作成されます。 * あればあるデータベースを呼び出します。 */ @Override public void onCreate(SQLiteDatabase db) { String db_exe = "CREATE TABLE " + TABLE_NAME_TESTDB + " (" + COL_ID + " INTEGER PRIMARY KEY AUTOINCREMENT," + COL_TEXT + " TEXT NOT NULL);"; db.execSQL(db_exe); /* * insert "insert into テーブルネーム (カラム) values(追加データ)" * これでデータを挿入することができます。 * 今回これを紹介したのは、データを最初から * セットしておくやり方を紹介したかったからです。 */ db.execSQL("insert into " + TABLE_NAME_TESTDB + "( " + COL_TEXT + " ) values ( " +"'オブリビオン'" +" );"); } /* * データベースがアップデートされた時に呼び出されるとかなんとか。 * 今のところ使用せずに色々できているので勉強していませぬ;; */ @Override public void onUpgrade(SQLiteDatabase db,int oldVersion,int newVersion) { db.execSQL("DROP TABLE IF EXISTS " + TABLE_NAME_TESTDB); onCreate(db); } } /* * DBを使用するにあたって必ず呼び出さなければいけないメソッドです。 * getWritableDatabase()は読み書きできるようにするメソッドです。 */ public DBAdapter open() { db = dbHelper.getWritableDatabase(); return this; } public void close(){ dbHelper.close(); } /* * レコードを消去するメソッド * 引数でカラムを指定します。カラムのみだと指定カラム全部 * カラム=xx などの指定でピンポイントで消去できます。 */ public boolean DB_Delete(String where_str){ return db.delete(TABLE_NAME_TESTDB, where_str ,null) > 0; } /* * どのようにDBを表示させるかのメソッド * ここが一番大事なので、詳しくはSQLを勉強するのが手っ取り早いかも * といってもどのテーブルのどの部分をどうやって表示 * みたいな感じなので簡単です */ public Cursor DB_Sort(String set_query){ return db.rawQuery(set_query,null); } /* * いまのDBテーブルを更新させるメソッド * ここでカラムをobj.getId()のCOL_IDを更新としています。 * 今回の場合 * 実はタイトルだろうがなんだろうがいいのですがなるべく個別に * 設定されている唯一無比のものがよく、それがCOL_IDなので * これにしています。 */ public void DB_update(Object obj){ ContentValues values = new ContentValues(); String UPDATE_WHERE = COL_ID + " = "+ obj.getId(); values.put(COL_TEXT, obj.getText()); db.update(TABLE_NAME_TESTDB, values, UPDATE_WHERE, null); } /* * 新しいレコードをDBテーブルに追加するメソッド */ public void DB_save(Object obj){ ContentValues values = new ContentValues(); values.put(COL_TEXT, obj.getText()); db.insertOrThrow(TABLE_NAME_TESTDB, null, values); } /* * オマケ */ public static void makeTost(String str,int id){ int tost = Toast.LENGTH_LONG; if(id==1) tost = Toast.LENGTH_SHORT; Toast toast = Toast.makeText(ma.getApplicationContext(), str, tost); toast.show(); } } ファイル名「ListAdapterjava」 package com.example.dbrensyu5; import java.util.List; import android.content.Context; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.BaseAdapter; import android.widget.TextView; public class ListAdapter extends BaseAdapter{ private Context context; public List<Object> list; public ListAdapter(Context context,List obj) { super(); this.context = context; list = obj; } public int getCount() {return list.size();} public Object getItem(int position) {return list.get(position);} public long getItemId(int position) {return position;} public View getView(int position, View convertView, ViewGroup parent) { ViewHolder holder; Object ob = (Object) getItem(position); if (convertView == null) { LayoutInflater inflater = LayoutInflater.from(context); holder = new ViewHolder(); convertView = inflater.inflate(R.layout.edei_listview_row, null); holder.tv1 = (TextView) convertView.findViewById(R.id.textView1_row_id); holder.tv2 = (TextView) convertView.findViewById(R.id.textView2_row_text); convertView.setTag(holder); } else { holder = (ViewHolder) convertView.getTag(); } holder.tv1.setText(Integer.toString(ob.getId())); holder.tv2.setText(ob.getText()); return convertView; } } class ViewHolder { TextView tv1; TextView tv2; } ファイル名「MainLoop.java」 package com.example.dbrensyu5; import java.util.ArrayList; import java.util.List; import android.content.Context; import android.database.Cursor; import android.util.Log; import android.view.View; import android.view.View.OnClickListener; import android.view.inputmethod.InputMethodManager; import android.widget.AdapterView; import android.widget.AdapterView.OnItemClickListener; import android.widget.AdapterView.OnItemSelectedListener; import android.widget.Button; import android.widget.EditText; import android.widget.ListView; import android.widget.TextView; import android.widget.Toast; public class MainLoop implements OnClickListener,OnItemClickListener{ static final int SAVE_MODE = 1; static final int EDIT_DELETE_MODE = 2; int mode =1; MainActivity mk; float disp_w,disp_h; public int sort_id = 0; public String[] sort_id_str = {" ASC"," DESC"}; public int sort_text = 0; public String[] sort_text_str = {" ASC"," DESC"}; ListView objlistview; static ListAdapter objlistadapter; static List<Object> objList = new ArrayList<Object>(); static DBAdapter dbAdapter; Object obj; Object nise_obj=new Object(); public String db_str; String btn_1 = ""; String btn_2 = ""; EditText et; String et_str=""; MainLoop(Context context,float disp_w,float disp_h){ mk = (MainActivity)context; this.disp_w = disp_w; this.disp_h = disp_h; dbAdapter = new DBAdapter(mk); db_str = "SELECT *" + " FROM " + DBAdapter.TABLE_NAME_TESTDB; obj = new Object(); setMode(SAVE_MODE); findView(); } //-------------------------------------画面部品いぢくれるように準備&ListViewセット public void findView(){ mk.setContentView(R.layout.edit_listview); et = (EditText)mk.findViewById(R.id.editText1); et.setOnClickListener(this); et.setText(et_str); deleteKey(); Button id_sort_btn = (Button)mk.findViewById(R.id.button_id_sort); id_sort_btn.setOnClickListener(this); Button text_sort_btn = (Button)mk.findViewById(R.id.button_text_sort); text_sort_btn.setOnClickListener(this); Button mode_btn = (Button)mk.findViewById(R.id.button_mode); mode_btn.setOnClickListener(this); Button bottom_left_btn = (Button)mk.findViewById(R.id.button1); bottom_left_btn.setText(btn_1); bottom_left_btn.setOnClickListener(this); Button bottom_right_btn = (Button)mk.findViewById(R.id.button2); bottom_right_btn.setText(btn_2); bottom_right_btn.setOnClickListener(this); dbAdapter = new DBAdapter(mk); objlistview = (ListView)mk.findViewById(R.id.listView1); objlistview.setOnItemClickListener(this); objlistadapter = new ListAdapter(mk,objList); objlistview.setAdapter(objlistadapter); setDB(db_str); } /* * EditTextに書き込みをしてキーボードでエンターボタンを * 押すと、キーボードが出たままボタンにフォーカスがいき * ます。そのまま保存などのボタンを押すと * なぜかエラーが出てしまう状態になっています。原因など * 調べるのがメンドーなので、テキスト入力完了でエンターなど * でフォーカスから離れるとキーボードを非表示にするように * しました。そのメソッドです。 */ public void deleteKey(){ et.setOnFocusChangeListener(new View.OnFocusChangeListener() { public void onFocusChange(View v, boolean hasFocus) { InputMethodManager imm = (InputMethodManager)mk.getSystemService(Context.INPUT_METHOD_SERVICE); imm.hideSoftInputFromWindow(v.getWindowToken(), InputMethodManager.HIDE_NOT_ALWAYS); }}); } //-------------------------------------データベースいぢり /* * ここがこのファイルのキモです。 * Sqliteを使用するには、別ファイルで作成している * DBAdapterにアクセスして色々するのですが、使用感 * はちょっとややこしくなっています。 * 簡単にいうと、 * 仮想データベースを作成して、そこからデータを拾う * こんな感じです。 * ここでの流れは大事なところだけ抜き出すと * (1)でCursor(カーソル)を設定。 * その名の通りカーソルをイメージしましょう。 * (2)ここがなによりも大事なところです。 * どんなことをしているかですが、 * 仮想データベースに表示させるレコードを、どんな感じ * で表示させるか。 * です。 * (3)ここからカーソル(→)をイメージしてください。 * moveToFirstで仮想データベースの一番最初のレコードに * カーソルを持って行っているイメージです。 * moveToNextでカーソルを次のレコードに持っていきます * 次のレコードが無い、というところまでこれを繰り返します。 * これにより、仮想データベースに表示されているレコード * がすべてobjListに入るわけです。 * データベースを何かする場合はopen(),close()でそれを囲います * CursorもstartManagingCursor、stopManagingCursorで囲います * * こんな感じでデータベースに登録されたレコードをいぢくれます。 * ここはコピペできるくらいこのまま使用しています。 * 引数は色々なレコードの表示ができるようにするためです。 */ public void setDB(String where_str){ objList.clear(); dbAdapter.open(); Cursor c = null;//(1) c = dbAdapter.DB_Sort(where_str);//(2) mk.startManagingCursor(c);//(3) if(c.moveToFirst()){ do{ obj = new Object( c.getInt(c.getColumnIndex(DBAdapter.COL_ID)), c.getString(c.getColumnIndex(DBAdapter.COL_TEXT)) ); objList.add(obj); }while(c.moveToNext()); } mk.stopManagingCursor(c); dbAdapter.close(); } /* * 今回保存、更新、削除など使用するにあたり、 * すべてアダプター内にメソッドを作り、それを * 呼び出すようにしました。 * 理由としてはコチラのほうがメソッドとして * カックイイカラデス。 */ //-------------------------------------データ保存 public void DB_save(Object obj){ if(obj.text.length()==0){makeTost("空欄では保存されません",1);}else{ dbAdapter.open(); dbAdapter.DB_save(obj); dbAdapter.close(); } } //-------------------------------------データ更新 public void DB_update(Object obj){ if(obj.text.length()==0){makeTost("空欄では更新されません",1);}else{ if(obj.id == 1){makeTost("このデータは更新できません",1);}else{ dbAdapter.open(); dbAdapter.DB_update(obj); dbAdapter.close(); } } et_str=""; } //-------------------------------------データ削除 public void DB_delete(Object obj){ if(obj.id == 1){makeTost("このデータは削除できません",1);}else{ String str = dbAdapter.COL_ID+" = "+ obj.getId(); dbAdapter.open(); if(dbAdapter.DB_Delete(str) == true){makeTost(obj.id+" "+obj.text+" を消去しました ",1);} dbAdapter.close(); } et_str=""; } //-------------------------------------クリック処理 public void onClick(View v) { switch(v.getId()) { //-------------------------------------idでソート case R.id.button_id_sort: if(sort_id == 0){ sort_id = 1; db_str = "SELECT * FROM " + DBAdapter.TABLE_NAME_TESTDB + " ORDER BY " + DBAdapter.COL_ID + sort_id_str[sort_id]; et_str=""; findView(); break; }else if(sort_id == 1){ sort_id = 0; db_str = "SELECT * FROM " + DBAdapter.TABLE_NAME_TESTDB + " ORDER BY " + DBAdapter.COL_ID + sort_id_str[sort_id]; et_str=""; findView(); break; } break; //-------------------------------------textでソート case R.id.button_text_sort: if(sort_text == 0){ sort_text = 1; db_str = "SELECT * FROM " + DBAdapter.TABLE_NAME_TESTDB + " ORDER BY " + DBAdapter.COL_TEXT + sort_text_str[sort_text]; et_str=""; findView(); break; }else if(sort_text == 1){ sort_text = 0; db_str = "SELECT * FROM " + DBAdapter.TABLE_NAME_TESTDB + " ORDER BY " + DBAdapter.COL_TEXT + sort_text_str[sort_text]; et_str=""; findView(); break;} break; //-------------------------------------保存モードへ case R.id.button_mode: setMode(SAVE_MODE); et_str=""; findView(); break; //-------------------------------------下部ボタン左 case R.id.button1: switch(mode){ //-------------------------------------保存モード case SAVE_MODE: nise_obj.setText(et.getText().toString()); DB_save(nise_obj); et_str=""; findView(); break; //-------------------------------------エディットモード case EDIT_DELETE_MODE: nise_obj.setText(et.getText().toString()); DB_update(nise_obj); et_str = ""; setMode(SAVE_MODE); et_str=""; findView(); break; } break; //-------------------------------------下部ボタン右 case R.id.button2: switch(mode){ //-------------------------------------保存モード case SAVE_MODE: //使わない break; //-------------------------------------エディットモード case EDIT_DELETE_MODE: nise_obj.setId(nise_obj.getId()); DB_delete(nise_obj); et_str = ""; findView(); break; } break; } } //-------------------------------------ListViewをタップしたら public void onItemClick(AdapterView<?> arg0, View view, int position, long id) { // TODO 自動生成されたメソッド・スタブ TextView tv_id = (TextView)objlistview.getChildAt(position). findViewById(R.id.textView1_row_id); TextView tv_text = (TextView)objlistview.getChildAt(position). findViewById(R.id.textView2_row_text); et.setText(""); nise_obj = objList.get(position); et_str = nise_obj.text; setMode(EDIT_DELETE_MODE); findView(); } //-------------------------------------モード変更時 public void setMode(int mo){ mode = mo; switch(mo){ case SAVE_MODE: btn_1 = "保存"; btn_2 = ""; break; case EDIT_DELETE_MODE: btn_1 = "更新"; btn_2 = "消去"; break; } } //-------------------------------------トースト表示 public void makeTost(String str,int id){ int tost = Toast.LENGTH_LONG; if(id==1) tost = Toast.LENGTH_SHORT; Toast toast = Toast.makeText(mk.getApplicationContext(), str, tost); toast.show(); } //Log.i("MultipleChoiceListActivity", "---------------------------------------------------"); } ファイル名「Object.java」 package com.example.dbrensyu5; /* * レコードの部品 */ public class Object{ protected int id; protected String text; Object(){} Object(int id,String text){ this.id = id; this.text = text; } public int getId(){ return id; } public String getText(){ return text; } public void setId(int id){ this.id = id; } public void setText(String text){ this.text = text; } } ファイル名「listview.xml」 <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="fill_parent" android:layout_height="fill_parent" tools:context=".MainActivity" > <ListView android:id="@+id/listView1" android:layout_width="fill_parent" android:layout_height="wrap_content" android:layout_above="@+id/button1" android:layout_alignParentLeft="true" android:layout_below="@+id/button_id_sort" > </ListView> <EditText android:id="@+id/editText1" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentBottom="true" android:layout_alignParentLeft="true" android:layout_toLeftOf="@+id/button1" android:ems="10" android:inputType="textPersonName" > </EditText> <Button android:id="@+id/button2" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentBottom="true" android:layout_alignParentRight="true" android:focusableInTouchMode="true" android:text=""> <requestFocus /> </Button> <Button android:id="@+id/button1" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentBottom="true" android:layout_toLeftOf="@+id/button2" android:text="save" /> <Button android:id="@+id/button_id_sort" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentLeft="true" android:layout_alignParentTop="true" android:text=" ID " /> <Button android:id="@+id/button_text_sort" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignLeft="@+id/button1" android:layout_alignParentRight="true" android:layout_alignParentTop="true" android:text="TEXT" /> <Button android:id="@+id/button_mode" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentTop="true" android:layout_toLeftOf="@+id/button_text_sort" android:layout_toRightOf="@+id/button_id_sort" android:text="保存MODEへ" /> </RelativeLayout> ファイル名「listview_row.xml」 <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="fill_parent" android:layout_height="fill_parent" tools:context=".MainActivity" > <TextView android:id="@+id/textView1_row_id" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentLeft="true" android:layout_alignParentTop="true" android:gravity="center" android:text="TextView" android:textSize="20sp" /> <TextView android:id="@+id/textView2_row_text" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentRight="true" android:layout_alignParentTop="true" android:layout_toRightOf="@+id/textView1_row_id" android:gravity="center" android:text="TextView" android:textSize="20sp" /> </RelativeLayout>
|
どういう動作をするかなどは直接いぢって確かめてみてください。 最初から入っているデータは削除、更新ができないようになっています。 |