1
Android Programming
and
Database
2
Android とデータベースの連結
① データベースオープンヘルパー SQLite は、データベースを1つのファイルで扱うので、指定のデータベースがないときは 作成し、あるときは、既存のファイルを開く、という処理が必要です。そういう一連の処 理をしてくれるのが、SQLiteOpenHelper クラスです。これを継承して、テーブル作成、 初期うデータ挿入まで定義しておきます package jp.ac.neec.kmt.is04.takata; import android.content.Context; import android.database.sqlite.SQLiteDatabase; import android.database.sqlite.SQLiteDatabase.CursorFactory; import android.database.sqlite.SQLiteOpenHelper;public class DBHelper extends SQLiteOpenHelper {
public DBHelper(Context context, String name, CursorFactory factory, int version) {
super(context, name, factory, version); // TODO Auto-generated constructor stub }
@Override
public void onCreate(SQLiteDatabase db) { // TODO Auto-generated method stub
String sql = "create table planet_table (" + "id integer primary key autoincrement," + "name text,"
+ "image text" + ")";
db.execSQL(sql); //テーブル作成
sql="insert into planet_table (name,image) values('水星','mercury.jpg')"; db.execSQL(sql);
sql="insert into planet_table (name,image) values('金星','venus.jpg')"; db.execSQL(sql);
sql="insert into planet_table (name,image) values('地球','earth.jpg')"; db.execSQL(sql);
sql="insert into planet_table (name,image) values('火星','mars.jpg')"; db.execSQL(sql);
sql="insert into planet_table (name,image) values('木星','jupiter.jpg')"; db.execSQL(sql);
3
sql="insert into planet_table (name,image) values('土星','saturn.jpg')"; db.execSQL(sql);
}
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { // TODO Auto-generated method stub
} }
② 主プログラムからオープンヘルパーを呼び出してデータベースを使えるようにする Activity.java
SQLiteDatabase db;
public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState);
setContentView(R.layout.main);
DBHelper dbHelper = new DBHelper(this , "planet_db" , null , 1); db = dbHelper.getWritableDatabase();
}
new DBHelper(this , "planet_db" , null , 1);
このクラス , データベース名 , 特別なカーソルを使うか? , DB 番号 SQLiteOpenHelper 戻り値 メソッド SQLiteDatabase getReadableDatabase() 読み込み専用でデータベースを開く SQLiteDatabase getWritableDatabase() 書き込みもできるデータベースを開く ③ SQL を発行する
Select 文のようにデータを読み出す SQL と、delete 文や insert 文のようにデータベー スに影響を与える SQL とで扱いが違います
データの挿入や削除の場合
sql="insert into photo_table (name,title) values('mercury.jpg','水星')"; db.execSQL(sql);
4 データの読み出しの場合
Cursor cursor = null;
sql = "select * from photo_table"; cursor = db.rawQuery(sql, null);
④ データの読み出し データを読み出した瞬間は、先頭のデータの前を指しています。 カーソル→ データ1 データ2 まず、先頭のデータを指すようにカーソルを移動します cursor.moveToFirst(); カーソル→ データ1 データ2 カーソル移動のメソッド(Cursor クラス) 戻り値 メソッド
boolean move(into offset)
現在のカーソル位置から相対値で移動する boolean moveToFirst() 先頭位置に移動する boolean moveToLast() 最後の位置に移動する boolean moveToNext() 次の行に移動する
boolean moveToPosition(int position) 絶対値に移動する
boolean moveToPrevious() 前の行に移動する いずれも移動できなかったとき false となる
5
カーソル位置のデータを読み込む。データの種類によってメソッドが異なります。引数に カラム位置を指定する(最初のカラムは 0)
String name=cursor.getString(1);
戻り値 メソッド
double getDouble(int columnIndex) int getInt(int columnIndex) long getLong(int columnIndex) String getString(int columnIndex)
その他のメソッド
戻り値 メソッド
int getColumnCount() カラム数を得る
int getColumnIndex(String columnName)
カラム名からカラム番号を得る、指定の名前がないときは-1 が 返る
int getColumnIndexOrThrow(String columnName)
カラム名からカラム番号を得る。指定の名前がないときは例外を
投げる
String getColumnName(int columnIndex) カラム番号からカラム名を得る int getCount() 総行数を返す int getPosition() 現在カーソルがある位置を求める boolean isAfterLast() 最後の行より後にカーソルがあるか? boolean isBeforFirst() 最初の行より前にカーソルがあるか? boolean isFirst() 先頭行にカーソルがあるか? boolean isLast() 最終行にカーソルがあるか? boolean isNull(int columnIndex)
6 プログラム例 データベースの最初のレコードを表示する Activity package jp.ac.neec.kmt.is04.takata; import java.io.File; import android.app.Activity; import android.database.Cursor; import android.database.sqlite.SQLiteDatabase; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.os.Bundle; import android.os.Environment; import android.widget.ImageView; import android.widget.TextView;
public class HelloDBActivity extends Activity { SQLiteDatabase db;
7
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState);
setContentView(R.layout.main);
DBHelper dbHelper = new DBHelper(this , "planet_db" , null , 1); db = dbHelper.getWritableDatabase();
String sql = "select * from planet_table"; cursor = db.rawQuery(sql, null);
cursor.moveToFirst();
String name=cursor.getString(1); String image=cursor.getString(2); System.out.println("name="+name);
File dir = Environment.getExternalStorageDirectory(); dir = new File(dir , "Pictures");
String path = dir.getAbsolutePath();
Bitmap bitmap = BitmapFactory.decodeFile(path+"/"+image);
TextView textView = (TextView) this.findViewById(R.id.planet_name); ImageView imageView = (ImageView) this.findViewById(R.id.planet_image); textView.setText(name); imageView.setImageBitmap(bitmap); } } データベースの場所:data/data/(パッケージ名)/database/ この中のファイルを削除すると、データベースは削除されます。
8
データベースからリストを表示する
SDカード上の画像ファイルをすべて表示するのではなく、データベースの情報をもとに、 SDカード上の画像を選んで表示するプロジェクトです ① レイアウトの作成 プログラミング編 p43 を参考に、メインのレイアウトと 1 行分のレ イアウトを設計してください(画像を載せる場合には、画像のサイズが大きくなりすぎ ないように、最初からサイズを指定しておくとよい) android:layout_width="85dp" android:layout_height="85dp" ② データベースヘルパークラスの作成 データベースを作成し、初期データをインサート しておく。そのとき、コマンドで SQL が正しいことを確認しておく ③ Activity からでデータベースヘルパーのインスタンス作成し、データベースとの連携に 問題がないことを実験しておく。(データベースプログラミング編 p3)これはあとでア ダプタに移動します Activity.java SQLiteDatabase db;public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState);
setContentView(R.layout.main);
DBHelper dbHelper = new DBHelper(this , "planet_db" , null , 1); db = dbHelper.getWritableDatabase(); } ④ 1 行分のデータを格納するクラスの作成 プログラミング編 p44 を参考に。ただし、 画像がある場合でも、データベースに格納されているのはファイル名なので、String にしておくのがおすすめ。ビットマップ化は、表示のときに行う ⑤ アダプタの作成 プログラミング編 p45 を参考に。ただし、読み込むのはSDカードで はなく、データベースになります。 Adapter //コンストラクタ public DataListAdapter(Context c) { // レイアウトとデータを統合させるおまじない
9
layoutInflater = (LayoutInflater) c.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
//袋をインスタンス化
list = new ArrayList<LineData>();
//ここからデータベースから情報を取得する
DBHelper dbHelper = new DBHelper(c , "planet_db" , null , 1); db = dbHelper.getWritableDatabase();
String sql = "select * from planet_table"; cursor = db.rawQuery(sql, null);
cursor.moveToFirst();
while(cursor.moveToNext()){ //DBから全部読む int id = cursor.getInt(0);
String name=cursor.getString(1); String image=cursor.getString(2);
System.out.println(id + " " + name + " " + image); LineData one = new LineData(id , name , image); list.add(one); } } getView で画像のファイル名からビットマップに変換します。そのために、コンス トラクタで Path を取得しておくとよいでしょう。 getCount でデータの個数を返してください。プログラミング編 p46 参照 ⑥ Activity で表示します プログラミング編 p47 参照
10
リストをタップして、次の画面に進む
リストをタップして、詳細情報を表示するようにします。 ① リストにイベントをつけます プログラム編 p49 ② 第 2 画面を設計します。プログラム編 p51~ ③ 第 2 画面をマニフェストに登録します プログラム編 p55~ ④ Intent を使って第 2 画面を呼び出します プログラム編 p55 ⑤ 第 2 画面から戻るボタンでメイン画面に戻ります プログラム編 p58 ⑥ リスト中の選ばれたデータを第 2 画面に送ります ここでは、データベース 1 行分のデータをまるごと第 2 画面に送ります。そのためには、 オブジェクトがシリアライズ化できなければなりません。文字や数値だけからなるデー タはシリアライズ化できます。public class LineData implements Serializable {
private static final long serialVersionUID = 1L; private int id; //ID
private String name; //名前
11 Activity
public void onItemClick(AdapterView<?> parent, View view, int position, long id) { // TODO Auto-generated method stub
LineData data = adapter.getItem(position);
Intent intent = new Intent(this , SecondActivity.class); intent.putExtra("data", adapter.getItem(position)); startActivityForResult(intent , 1);
}
⑦ 第 2 画面でデータをうけとり、表示します 第 2Activity
protected void onCreate(Bundle savedInstanceState) { // TODO Auto-generated method stub
super.onCreate(savedInstanceState); setContentView(R.layout.second);
subText = (TextView) this.findViewById(R.id.textSub); subImage = (ImageView) this.findViewById(R.id.imageSub);
Intent intent = this.getIntent();
LineData data = (LineData) intent.getSerializableExtra("data"); subText.setText(subText.getText() + data.getName());
File dir = Environment.getExternalStorageDirectory(); dir = new File(dir , "Pictures");
String path = dir.getAbsolutePath();
Bitmap bitmap = BitmapFactory.decodeFile(path+"/"+ data.getImage()); subImage.setImageBitmap(bitmap);
}
12 main.xml <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:layout_height="fill_parent" android:orientation="vertical" > <TextView android:layout_width="fill_parent" android:layout_height="wrap_content" android:text="@string/hello" /> <ListView android:id="@+id/listMain" android:layout_height="match_parent" android:layout_width="match_parent" > </ListView> </LinearLayout> list_item.xml <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="horizontal" > <TextView android:id="@+id/idArea" android:layout_width="wrap_content" android:layout_height="wrap_content" /> <ImageView android:id="@+id/imageArea" android:layout_width="85dp"
13 android:layout_height="85dp" android:layout_gravity="center_vertical" /> <TextView android:id="@+id/nameArea" android:layout_width="wrap_content" android:layout_height="wrap_content" android:padding="10dp" android:text="test" android:textSize="16sp" /> </LinearLayout> DBHelper package jp.ac.neec.kmt.is04.takata; import android.content.Context; import android.database.sqlite.SQLiteDatabase; import android.database.sqlite.SQLiteDatabase.CursorFactory; import android.database.sqlite.SQLiteOpenHelper;
public class DBHelper extends SQLiteOpenHelper {
public DBHelper(Context context, String name, CursorFactory factory, int version) {
super(context, name, factory, version); // TODO Auto-generated constructor stub }
@Override
public void onCreate(SQLiteDatabase db) { // TODO Auto-generated method stub
String sql = "create table planet_table (" + "id integer primary key autoincrement," + "name text,"
14 + ")";
db.execSQL(sql); //テーブル作成
sql="insert into planet_table (name,image) values('水星','mercury.jpg')"; db.execSQL(sql);
sql="insert into planet_table (name,image) values('金星','venus.jpg')"; db.execSQL(sql);
sql="insert into planet_table (name,image) values('地球','earth.jpg')"; db.execSQL(sql);
sql="insert into planet_table (name,image) values('火星','mars.jpg')"; db.execSQL(sql);
sql="insert into planet_table (name,image) values('木星','jupiter.jpg')"; db.execSQL(sql);
sql="insert into planet_table (name,image) values('土星','saturn.jpg')"; db.execSQL(sql);
}
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { // TODO Auto-generated method stub
} }
LineData
package jp.ac.neec.kmt.is04.takata;
public class LineData implements Serializable {
private static final long serialVersionUID = 1L; private int id; //ID
private String name; //名前
private String image; //画像ファイル名
//コンストラクタ
15 this.id = id; this.name = name; this.image = image; } //セッタ・ゲッタ public int getId() {
return id; }
public void setId(int id) { this.id = id;
}
public String getName() { return name;
}
public void setName(String name) { this.name = name;
}
public String getImage() { return image;
}
public void setImage(String image) { this.image = image;
} }
16 DataListAdapter package jp.ac.neec.kmt.is04.takata; import java.io.File; import java.util.ArrayList; import android.content.Context; import android.database.Cursor; import android.database.sqlite.SQLiteDatabase; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.os.Environment; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.BaseAdapter; import android.widget.ImageView; import android.widget.TextView;
public class DataListAdapter extends BaseAdapter { private ArrayList<LineData> list;
private LayoutInflater layoutInflater = null; private SQLiteDatabase db;
private Cursor cursor = null; private String path;
//コンストラクタ
public DataListAdapter(Context c) {
// レイアウトとデータを統合させるおまじない
layoutInflater = (LayoutInflater) c.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
//袋をインスタンス化
list = new ArrayList<LineData>();
17
DBHelper dbHelper = new DBHelper(c , "planet_db" , null , 1); db = dbHelper.getWritableDatabase();
String sql = "select * from planet_table"; cursor = db.rawQuery(sql, null);
cursor.moveToFirst(); while(cursor.moveToNext()){ int id = cursor.getInt(0);
String name=cursor.getString(1); String image=cursor.getString(2);
System.out.println(id + " " + name + " " + image); LineData one = new LineData(id , name , image);
list.add(one);
}
File dir = Environment.getExternalStorageDirectory(); dir = new File(dir , "Pictures");
path = dir.getAbsolutePath(); System.out.println("path="+path);
}
//データの個数 @Override
public int getCount() {
// TODO Auto-generated method stub return list.size();
}
@Override
public Object getItem(int arg0) { // TODO Auto-generated method stub return null;
18 @Override
public long getItemId(int arg0) { // TODO Auto-generated method stub return 0;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) { // TODO Auto-generated method stub
convertView = layoutInflater.inflate(R.layout.list_item, null); TextView idView = (TextView) convertView.findViewById(R.id.idArea);
ImageView imageView = (ImageView) convertView.findViewById(R.id.imageArea); TextView nameView = (TextView)convertView.findViewById(R.id.nameArea); idView.setText("" + list.get(position).getId());
Bitmap bitmap = BitmapFactory.decodeFile(path+"/"+list.get(position).getImage()); imageView.setImageBitmap(bitmap); imageView.setScaleType(ImageView.ScaleType.CENTER_CROP); nameView.setText(list.get(position).getName()); System.out.println("name="+list.get(position).getName()); return convertView; }
public ArrayList<LineData> getList(){ return list;
}
19 Activity package jp.ac.neec.kmt.is04.takata; import android.app.Activity; import android.database.sqlite.SQLiteDatabase; import android.os.Bundle; import android.widget.ListView;
public class HelloDBListActivity extends Activity {
/** Called when the activity is first created. */ @Override
public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState);
setContentView(R.layout.main);
DataListAdapter adapter = new DataListAdapter(this);
ListView listView = (ListView) this.findViewById(R.id.listMain); listView.setAdapter(adapter);
listView.setTextFilterEnabled(true); }
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) { // TODO Auto-generated method stub
LineData data = adapter.getItem(position); testText.setText(data.getName());
Intent intent = new Intent(this , SecondActivity.class); intent.putExtra("position", position); intent.putExtra("data", adapter.getItem(position)); //intent.setAction(Intent.ACTION_VIEW); startActivityForResult(intent , 1); } }
20
データベースの検索
データベースは、必要なデータを必要なときに必要なだけ取り出せなければなりません。 そのための機能が検索です。検索して得られるのは 1 件だけとは限りません。いろいろな ケースを想定してアプリを設計しましょう ① オープンヘルパーの作成 テーブルを作成、初期データをインサート あらかじめコマンドを実行してSQL文が正しいことを検証しておく public void onCreate(SQLiteDatabase db) {// TODO Auto-generated method stub String sql = "create table town_table("
+ "id integer primary key autoincrement ," + "ken char(20) not null,"
+ "town char(20)" +")";
db.execSQL(sql); //テーブル作成
sql = "insert into town_table (ken , town) values('東京' , '蒲田')"; db.execSQL(sql);
sql = "insert into town_table (ken , town) values('東京' , '渋谷')"; db.execSQL(sql);
21 db.execSQL(sql);
sql = "insert into town_table (ken , town) values('東京' , '四谷')"; db.execSQL(sql);
sql = "insert into town_table (ken , town) values('神奈川' , '横浜')"; db.execSQL(sql);
sql = "insert into town_table (ken , town) values('神奈川' , '川崎')"; db.execSQL(sql);
sql = "insert into town_table (ken , town) values('神奈川' , '相模原')"; db.execSQL(sql);
sql = "insert into town_table (ken , town) values('埼玉' , '越谷')"; db.execSQL(sql);
sql = "insert into town_table (ken , town) values('埼玉' , '熊谷')"; db.execSQL(sql);
sql = "insert into town_table (ken , town) values('千葉' , '浦安')"; db.execSQL(sql); } ② ヘルパーの呼び出し Activity からヘルパーを呼び出して、データベースを作成。 DDMS でデータベースができていることを確認する data/data/<パッケージ名>/<データベース名> Activity
public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState);
setContentView(R.layout.main);
DBHelper dbHelper = new DBHelper(this , "town_db" , null ,1); db = dbHelper.getWritableDatabase();
//テスト
TextView test1 = (TextView) this.findViewById(R.id.test_id); String sql = "select * from town_table";
Cursor cursor = db.rawQuery(sql, null); test1.setText("" + cursor.getCount()); }
22 ③ データベース読み出しテスト
データベースが入力されていることを確認するため、件数を調べて表示してみましょう。 TextView に ID をつけておきます。
public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState);
setContentView(R.layout.main);
DBHelper dbHelper = new DBHelper(c , "town_db" , null ,1); db = dbHelper.getWritableDatabase();
String sql = "select * from town_table"; Cursor cursor = db.rawQuery(sql, null);
TextView textView = (TextView) this.findViewById(R.id.test_id); textView.setText("" + cursor.getCount()); } ④ 画面レイアウト 検索を行うためのテキストエディタとボタン、それに結果を表示するリストを作成して おきます。 main.xml <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:layout_height="fill_parent" android:orientation="vertical" > <TextView android:id = "@+id/test_id" android:layout_width="fill_parent" android:layout_height="wrap_content" android:text="@string/hello" /> <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" > <EditText
23 android:id="@+id/key_ed" android:layout_height="wrap_content" android:layout_width="0dp" android:layout_weight="3" android:text="@string/key_label" /> <Button android:id="@+id/go_bt" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/go_label" android:onClick="onClickGo" /> </LinearLayout> <ListView android:layout_height="match_parent" android:layout_width="match_parent" android:id="@+id/result_id" > </ListView> </LinearLayout> リストの 1 行分の定義 list_item.xml <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="horizontal" > <TextView android:id="@+id/text_ken" android:layout_width="0dp" android:layout_height="wrap_content" android:layout_weight="1" /> <TextView android:id="@+id/text_town" android:layout_width="0dp"
24 android:layout_height="wrap_content" android:layout_weight="1" /> </LinearLayout> ⑤ データを受け取るクラス データベースの 1 件分を受け取るクラスを作成 LineData.java ⑥ アダプタ データベースから読み込んでリストを作成 public DataListAdapter(Context c) { layoutflater = (LayoutInflater) c.getSystemService(Context.LAYOUT_INFLATER_SERVICE); list = new ArrayList<LineData>();
DBHelper dbHelper = new DBHelper(c , "town_db" , null ,1); db = dbHelper.getWritableDatabase();
String sql = "select * from town_table"; Cursor cursor = db.rawQuery(sql, null); while(cursor.moveToNext()){
int id = cursor.getInt(0);
String ken = cursor.getString(1); String town = cursor.getString(2);
System.out.println(id + " " + ken + " " + town); LineData one = new LineData(id ,ken , town); list.add(one);
} }
25 ⑦ ためしに全データ表示
Activity
public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState);
setContentView(R.layout.main);
DataListAdapter adapter = new DataListAdapter(this);
ListView listView = (ListView) this.findViewById(R.id.result_id); listView.setAdapter(adapter);
26 ⑧ ボタンのイベントハンドラを記述
EditText からテキストを読み込んでおく。これがキーワードになる Activity
public void onClickGo(View view){
EditText ev = (EditText) this.findViewById(R.id.key_ed); String key = ev.getText().toString();
}
⑨ アダプタにもう一つのコンストラクタ
public DataListAdapter(Context c , String key) { layoutflater =
(LayoutInflater) c.getSystemService(Context.LAYOUT_INFLATER_SERVICE); list = new ArrayList<LineData>();
DBHelper dbHelper = new DBHelper(c , "town_db" , null ,1); db = dbHelper.getWritableDatabase();
String sql = "select * from town_table where ken='" + key + "'"; Cursor cursor = db.rawQuery(sql, null);
while(cursor.moveToNext()){ int id = cursor.getInt(0);
String ken = cursor.getString(1); String town = cursor.getString(2);
System.out.println(id + " " + ken + " " + town); LineData one = new LineData(id ,ken , town); list.add(one);
} }
⑩ アダプタの呼び出し Activity
public void onClickGo(View view){
EditText ev = (EditText) this.findViewById(R.id.key_ed); String key = ev.getText().toString();
DataListAdapter adapter = new DataListAdapter(this , key);
ListView listView = (ListView) this.findViewById(R.id.result_id); listView.setAdapter(adapter);
27
データベースの登録
データベースにデータを新規に登録します。 ① まず、入力画面を作ります main.xml <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:layout_height="fill_parent" android:orientation="vertical" > <TextView android:id="@+id/test_tx" android:layout_width="fill_parent" android:layout_height="wrap_content" android:text="@string/hello" /> <LinearLayout android:layout_width="fill_parent" android:layout_height="wrap_content" android:orientation="horizontal" > <EditText android:id="@+id/ken_ed"28 android:layout_height="wrap_content" android:layout_width="0dp" android:layout_weight="1" /> <EditText android:id="@+id/town_ed" android:layout_height="wrap_content" android:layout_width="0dp" android:layout_weight="1" /> <Button android:id="@+id/go_bt" android:layout_height="wrap_content" android:layout_width="wrap_content" android:text="@string/go_label" android:onClick="OnClickReg" /> </LinearLayout> </LinearLayout> ② データベースヘルパーを作ります すでにできているデータベースを使うときは、どうせ onCreate は動かないので、何も 書かなくてOK ③ データベースと連結します Activity @Override
public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState);
setContentView(R.layout.main);
DBHelper dbHelper = new DBHelper(this , "town_db" , null , 1); db = dbHelper.getWritableDatabase();
29 ④ ボタンのイベント
Activity
public void OnClickReg(View view){
EditText kenArea = (EditText) this.findViewById(R.id.ken_ed); EditText townArea = (EditText) this.findViewById(R.id.town_ed); String ken = kenArea.getText().toString();
String town = townArea.getText().toString();
String sql = "insert into town_table (ken , town) values('" + ken + "','" + town + "')"; System.out.println(sql); // db.execSQL(sql); } SQL を発行するまえに、正しいかどうか、チェックしてください sql 文が log に表示されるので、これを選んでファイルに保存する ファイルを開いて、コマンドプロンプトで実行してみる。
sqlite> insert into town_table (ken , town) values('東京','銀座'); sqlite> select * from town_table;
1|東京|蒲田 2|東京|渋谷 3|東京|新宿 4|東京|四谷 5|神奈川|横浜 6|神奈川|川崎 7|神奈川|相模原 8|埼玉|越谷 9|埼玉|熊谷 10|千葉|浦安 11|東京|銀座 sqlite> 挿入されることを確認してから、コメント文をはずして実行する 検索用アプリで確認する
30 銀座が追加されており、成功した
31
リストから個別へ
リスト表示から1つ選んで個別詳細データを表示します セカンドアクティビティ側で、あらためてデータベースを読み直します。 ID を指定して読み込みができるようにアダプタのコンストラクタを追加。 //コンストラクタ public DataListAdapter(Context c) {String sql = "select * from planet_table"; dataSet(c , sql);
}
public DataListAdapter(Context c,int id) {
String sql = "select * from planet_table where id="+id; dataSet(c , sql);
}
public void dataSet(Context c , String sql){ // レイアウトとデータを統合させるおまじない layoutInflater =
(LayoutInflater) c.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
//袋をインスタンス化
list = new ArrayList<LineData>();
//ここからデータベースから情報を取得する
32 db = dbHelper.getWritableDatabase();
cursor = db.rawQuery(sql, null); //cursor.moveToFirst();
while(cursor.moveToNext()){ int id = cursor.getInt(0);
String name=cursor.getString(1); String image=cursor.getString(2);
System.out.println(id + " " + name + " " + image); LineData one = new LineData(id , name , image); list.add(one);
}
File dir = Environment.getExternalStorageDirectory(); dir = new File(dir , "Pictures");
path = dir.getAbsolutePath(); System.out.println("path="+path); }
セカンドアクティビティでアダプタを作り直して表示
protected void onCreate(Bundle savedInstanceState) { // TODO Auto-generated method stub
super.onCreate(savedInstanceState); setContentView(R.layout.second);
subText = (TextView) this.findViewById(R.id.textSub); subImage = (ImageView) this.findViewById(R.id.imageSub);
Intent intent = this.getIntent(); int id = intent.getIntExtra("id", 0); subText.setText("" + id);
adapter = new DataListAdapter(this , id); int size = adapter.getCount();
33
subText.setText(subText.getText() + data.getName());
dir = new File(dir , "Pictures"); String path = dir.getAbsolutePath();
Bitmap bitmap = BitmapFactory.decodeFile(path+"/"+ data.getImage()); subImage.setImageBitmap(bitmap);
}
詳しい説明をファイルから読んでみよう(とりあえずファイル固定) セカンドアクティビティ
File dir = Environment.getExternalStorageDirectory(); String description = readFromFile("earth.txt");
TextView desArea = (TextView) this.findViewById(R.id.desriptionSub); desArea.setText(description);
private String readFromFile(String fileName){ String readString = "";
String SDFile = android.os.Environment.getExternalStorageDirectory().getPath() + "/Text/earth.txt";
File file = new File(SDFile); try{
FileInputStream fis = new FileInputStream(file);
InputStreamReader isr = new InputStreamReader(fis,"UTF-8"); BufferedReader br= new BufferedReader(isr);
String s;
while ((s = br.readLine() ) != null){ readString = readString+s+"¥r¥n"; } br.close(); isr.close(); fis.close(); } catch(FileNotFoundException e){ e.printStackTrace();
34 } catch(UnsupportedEncodingException e){ e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } return readString; }
35
CSV からデータベースに読み込み
Excel で作成したデータを CSV で書き出して、それを使ってデータベースに読み込みを行 うと、データベースのデータ作成が楽にできます
Helper を作成します。データベースがまだない場合には、 public void onCreate(SQLiteDatabase db) {
// TODO Auto-generated method stub ここでデータベースをCreateする
}
Activity
public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState);
setContentView(R.layout.main);
//データベースに接続する
DBHelper dbHelper = new DBHelper(this , "town_db" , null ,1); db = dbHelper.getWritableDatabase();
//ファイルに接続する String readString="";
String SDFile = Environment.getExternalStorageDirectory().getPath() + "/Text/city.csv";
File file = new File(SDFile);
try {
//ストリームを確立する
FileInputStream fis = new FileInputStream(file);
InputStreamReader isr = new InputStreamReader(fis,"UTF-8"); BufferedReader br= new BufferedReader(isr);
String s;
while ((s = br.readLine() ) != null){ //1行分の処理
36 //insert文を組み立てる
String sql = "insert into town_table (ken , town) values('"+part[0]+"' , '"+part[1]+"')"; System.out.println(sql);
readString += sql + "¥r¥n";
//sql = "select * from town_table"; //db.rawQuery(sql, null); db.execSQL(sql); } br.close(); isr.close(); fis.close(); } catch (FileNotFoundException e) { // TODO Auto-generated catch block e.printStackTrace();
} catch (UnsupportedEncodingException e) { // TODO Auto-generated catch block e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block e.printStackTrace();
}
//確認用にSQLを表示
TextView tv = (TextView) this.findViewById(R.id.text_id); tv.setText(readString);
37
ファイル名を入力するエディットテキストを用意し、データ取り込みボタンでデータベー スに追加するアプリなども考えられます。
38
正規表現
入力データに制限をかけ、不正なデータがデータベースに登録されないようにしましょう そういうときには、文字列のマッチングを調べる正規表現が便利です あいう 通常の文字リテラル . 任意の 1 文字 [あいう] ここに含まれる任意の 1 文字 [^あいう] ここに含まれる任意の 1 文字以外 ^あ 先頭の文字を指定 あ$ 最後の文字を指定 あ? 0 回または 1 回 あ+ 1 回以上の繰り返し あ* 0 回以上の繰り返し あ{n , m} n 回以上 m 回以下の繰り返し あ{n,} n 回以上の繰り返し あ{n} n 回の繰り返し (あ|い) 選択 どちらでもよい { } グループ(繰り返しの単位指定) プログラム例 AlertDialog.Builder dlg; dlg = new AlertDialog.Builder(this); dlg.setTitle("TEST"); dlg.setPositiveButton("閉じる", null);EditText et = (EditText) this.findViewById(R.id.input_et); Pattern pattern = Pattern.compile("^あ.*$");
Matcher matcher = pattern.matcher(et.getText()); if(matcher.matches()){ dlg.setMessage("OK"); System.out.println("OK"); } else{ dlg.setMessage("NG"); System.out.println("NG"); } dlg.show();
39
アプリケーション作品制作について
設計項目 1.画面遷移図 2.データベース仕様書 フィールド名 内容 型 備考(内容説明と属性 primary key など)id 主キー Integer primary Key autoincrement
3.画像やテキストファイルがある場合には、保存場所(フォルダ階層) 4.データベースと画面との関係