Professional Documents
Culture Documents
s12 AndroidCookbook Steele ch9 SQLite
s12 AndroidCookbook Steele ch9 SQLite
Then, any application can automatically have the EULA functionality by simply putting
the following line in the onCreate() method of the main activity of the application:
Eula.show(this);
SQLite Database
For more complex data structures, a database provides a quicker and more flexible access
method than flat files or shared preferences.Android provides a built-in database called
SQLite that provides full relational database capability utilizing SQL commands. Each
application that uses SQLite has its own instance of the database, which is by default
accessible only from the application itself.The database is stored in the /data/data/
<package_name>/databases folder of an Android device.A Content Provider can be
used to share the database information between applications.The different steps for utilizing SQLite are
1.
2.
3.
4.
5.
6.
Create a database.
Open the database.
Create a table.
Create an insert interface for datasets.
Create a query interface for datasets.
Close the database.
n
n
MyDB()Initializes
Download at www.wowebook.com
SQLite Database
233
getdiaries()Reads
Listing 9.9
src/com/cookbook/data/MyDB.java
package com.cookbook.data;
import
import
import
import
import
import
android.content.ContentValues;
android.content.Context;
android.database.Cursor;
android.database.sqlite.SQLiteDatabase;
android.database.sqlite.SQLiteException;
android.util.Log;
Download at www.wowebook.com
234
src/com/cookbook/data/MyDBhelper.java
package com.cookbook.data;
import
import
import
import
import
import
android.content.Context;
android.database.sqlite.SQLiteDatabase;
android.database.sqlite.SQLiteException;
android.database.sqlite.SQLiteOpenHelper;
android.database.sqlite.SQLiteDatabase.CursorFactory;
android.util.Log;
Download at www.wowebook.com
SQLite Database
235
The third file of the com.cookbook.data package is the Constants class shown in
Listing 9.11.This class is used to hold all the String constants because they are utilized in
both MyDB and MyDBhelper.
Listing 9.11
src/com/cookbook/data/Constants.java
package com.cookbook.data;
public class Constants {
public static final String DATABASE_NAME="datastorage";
public static final int DATABASE_VERSION=1;
public static final String TABLE_NAME="diaries";
public static final String TITLE_NAME="title";
public static final String CONTENT_NAME="content";
public static final String DATE_NAME="recorddate";
public static final String KEY_ID="_id";
}
Download at www.wowebook.com
236
res/layout/diary.xml
Download at www.wowebook.com
SQLite Database
Figure 9.3
237
src/com/cookbook/datastorage/Diary.java
package com.cookbook.datastorage;
import
import
import
import
import
import
import
android.app.Activity;
android.content.Intent;
android.os.Bundle;
android.view.View;
android.view.View.OnClickListener;
android.widget.Button;
android.widget.EditText;
import com.cookbook.data.MyDB;
public class Diary extends Activity {
EditText titleET, contentET;
Button submitBT;
MyDB dba;
@Override
public void onCreate(Bundle savedInstanceState) {
Download at www.wowebook.com
238
super.onCreate(savedInstanceState);
setContentView(R.layout.diary);
dba = new MyDB(this);
dba.open();
titleET = (EditText)findViewById(R.id.diarydescriptionText);
contentET = (EditText)findViewById(R.id.diarycontentText);
submitBT = (Button)findViewById(R.id.submitButton);
submitBT.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
try {
saveItToDB();
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
public void saveItToDB() {
dba.insertdiary(titleET.getText().toString(),
contentET.getText().toString());
dba.close();
titleET.setText("");
contentET.setText("");
Intent i = new Intent(Diary.this, DisplayDiaries.class);
startActivity(i);
}
}
The DataStorage.java class is the same as in Listing 9.6 with the MyPreferences.class
changed to launch the Diary.class when the login is successful:
Toast.makeText(DataStorage.this, "login passed!!",
Toast.LENGTH_SHORT).show();
Intent i = new Intent(DataStorage.this, Diary.class);
startActivity(i);
Finally, the AndroidManifest XML file must be updated to include the new activities, as
shown in Listing 9.14.
Listing 9.14
AndroidManifest.xml
Download at www.wowebook.com
SQLite Database
239
<activity android:name=".DataStorage"
android:label="@string/app_name">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity android:name=".MyPreferences" />
<activity android:name=".Diary"/>
</application>
<uses-sdk android:minSdkVersion="7" />
</manifest>
Now that a separate database has been integrated, the layout for the list of entries is discussed in the next recipe to complete the diary application.
res/layout/diaries.xml
Listing 9.16
res/layout/diaryrow.xml
Download at www.wowebook.com
240
android:padding="12dip">
<TextView android:layout_width="wrap_content"
android:layout_height="wrap_content" android:id="@+id/name"
android:layout_marginRight="4dp" android:text="Diary Title "
android:textStyle="bold" android:textSize="16dip" />
<TextView android:id="@+id/datetext"
android:layout_width="wrap_content"
android:layout_height="wrap_content" android:text="Date Recorded"
android:textSize="14dip" />
</RelativeLayout>
getCount()Returns
Note that ListView calls getView() to draw the view for each item.To improve the UI
rendering performance, the view returned by getView() should be recycled as much as
possible.This is done by creating a ViewHolder class to hold the views.
When getView() is called, the view currently displayed to the user is also passed in,
which is when it is saved in the ViewHolder and tagged. On subsequent calls to
getView() with the same view, the tag identifies the view as already in the ViewHolder. In
this case, the content can be changed on the existing view rather than create a new one.
The main activity is shown in Listing 9.17, and the resulting view of diary entries in a
ListView is shown in Figure 9.4.
Listing 9.17
src/com/cookbook/datastorage/DisplayDiaries.java
package com.cookbook.datastorage;
import java.text.DateFormat;
import java.util.ArrayList;
import java.util.Date;
import
import
import
import
import
import
android.app.ListActivity;
android.content.Context;
android.database.Cursor;
android.os.Bundle;
android.view.LayoutInflater;
android.view.View;
Download at www.wowebook.com
SQLite Database
241
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.TextView;
import com.cookbook.data.Constants;
import com.cookbook.data.MyDB;
public class DisplayDiaries extends ListActivity {
MyDB dba;
DiaryAdapter myAdapter;
private class MyDiary{
public MyDiary(String t, String c, String r){
title=t;
content=c;
recorddate=r;
}
public String title;
public String content;
public String recorddate;
}
@Override
protected void onCreate(Bundle savedInstanceState) {
dba = new MyDB(this);
dba.open();
setContentView(R.layout.diaries);
super.onCreate(savedInstanceState);
myAdapter = new DiaryAdapter(this);
this.setListAdapter(myAdapter);
}
private class DiaryAdapter extends BaseAdapter {
private LayoutInflater mInflater;
private ArrayList<MyDiary> diaries;
public DiaryAdapter(Context context) {
mInflater = LayoutInflater.from(context);
diaries = new ArrayList<MyDiary>();
getdata();
}
public void getdata(){
Cursor c = dba.getdiaries();
startManagingCursor(c);
if(c.moveToFirst()){
do{
String title =
c.getString(c.getColumnIndex(Constants.TITLE_NAME));
Download at www.wowebook.com
242
String content =
c.getString(c.getColumnIndex(Constants.CONTENT_NAME));
DateFormat dateFormat =
DateFormat.getDateTimeInstance();
String datedata = dateFormat.format(new
Date(c.getLong(c.getColumnIndex(
Constants.DATE_NAME))).getTime());
MyDiary temp = new MyDiary(title,content,datedata);
diaries.add(temp);
} while(c.moveToNext());
}
}
@Override
public int getCount() {return diaries.size();}
public MyDiary getItem(int i) {return diaries.get(i);}
public long getItemId(int i) {return i;}
public View getView(int arg0, View arg1, ViewGroup arg2) {
final ViewHolder holder;
View v = arg1;
if ((v == null) || (v.getTag() == null)) {
v = mInflater.inflate(R.layout.diaryrow, null);
holder = new ViewHolder();
holder.mTitle = (TextView)v.findViewById(R.id.name);
holder.mDate = (TextView)v.findViewById(R.id.datetext);
v.setTag(holder);
} else {
holder = (ViewHolder) v.getTag();
}
holder.mdiary = getItem(arg0);
holder.mTitle.setText(holder.mdiary.title);
holder.mDate.setText(holder.mdiary.recorddate);
v.setTag(holder);
return v;
}
public class ViewHolder {
MyDiary mdiary;
TextView mTitle;
TextView mDate;
}
}
}
Download at www.wowebook.com
Content Provider
Figure 9.4
243
Content Provider
Every application has its own sandbox and cannot access data from other applications. If
access to functions not provided by its own sandbox is required, the application must
explicitly declare permission upfront before installation.Android provides an interface
called ContentProvider to act as a bridge between applications, enabling them to share
and change each others data.A content provider allows a clean separation between the
application layer and data layer. It requires a permission setting in the AndroidManifest
XML file and can be accessed using a simple URI model.
Some native databases Android makes available as content providers are
n
n
n
ContactsContract.RawContactsContains
Download at www.wowebook.com