 |
BOOK: Beginning Android Application Development
 | This is the forum to discuss the Wrox book Beginning Android Application Development by Wei-Meng Lee; ISBN: 978-1-1180-1711-1 |
Welcome to the p2p.wrox.com Forums.
You are currently viewing the BOOK: Beginning Android Application Development section of the Wrox Programmer to Programmer discussions. This is a community of software programmers and website developers including Wrox book authors and readers. New member registration was closed in 2019. New posts were shut off and the site was archived into this static format as of October 1, 2020. If you require technical support for a Wrox book please contact http://hub.wiley.com
|
|
|
|

November 19th, 2011, 09:32 PM
|
|
Authorized User
|
|
Join Date: Nov 2011
Posts: 15
Thanks: 4
Thanked 0 Times in 0 Posts
|
|
Chapter 6 - Data Persistance
Excellent Chapter, however on page 225 the code uses Toast to display a 'getAllContacts' list.
I would like to use a list view to display the data instead.
When I refer to the list views in Chapter 4 there is no example for this. There is only the reference, "While this example shows that....., in a real-life application it is recommended that you retrieve them from a database.", with no example of how this is done.
Can someone provide the example for this with a list view instead of the toast please? Here are the 2 files used in Chapter 6:
MainActivity.java
Code:
package net.learn2develop.Databases;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import android.app.Activity;
import android.os.Bundle;
import android.widget.SimpleCursorAdapter;
import android.widget.Toast;
import android.widget.ListAdapter;
import android.database.Cursor;
public class MainActivity extends Activity {
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
try {
String destPath = "/data/data/" + getPackageName() + "/databases/MyDB";
File f = new File(destPath);
if (!f.exists()) {
CopyDB( getBaseContext().getAssets().open("mydb"),
new FileOutputStream(destPath));
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
DBAdapter db = new DBAdapter(this);
/*
//---add a contact---
db.open();
long id = db.insertContact("Wei-Meng Lee", "[email protected]");
id = db.insertContact("Mary Jackson", "[email protected]");
db.close();
*/
//---get all contacts---
db.open();
Cursor c = db.getAllContacts();
if (c.moveToFirst())
{
do {
DisplayContact(c);
} while (c.moveToNext());
}
db.close();
/*
//---get a contact---
db.open();
Cursor c = db.getContact(2);
if (c.moveToFirst())
DisplayContact(c);
else
Toast.makeText(this, "No contact found", Toast.LENGTH_LONG).show();
db.close();
*/
/*
//---update contact---
db.open();
if (db.updateContact(1, "Wei-Meng Lee", "[email protected]"))
Toast.makeText(this, "Update successful.", Toast.LENGTH_LONG).show();
else
Toast.makeText(this, "Update failed.", Toast.LENGTH_LONG).show();
db.close();
*/
/*
//---delete a contact---
db.open();
if (db.deleteContact(1))
Toast.makeText(this, "Delete successful.", Toast.LENGTH_LONG).show();
else
Toast.makeText(this, "Delete failed.", Toast.LENGTH_LONG).show();
db.close();
*/
}
public void CopyDB(InputStream inputStream, OutputStream outputStream)
throws IOException {
//---copy 1K bytes at a time---
byte[] buffer = new byte[1024];
int length;
while ((length = inputStream.read(buffer)) > 0) {
outputStream.write(buffer, 0, length);
}
inputStream.close();
outputStream.close();
}
public void DisplayContact(Cursor c)
{
Toast.makeText(this,
"id: " + c.getString(0) + "\n" +
"Name: " + c.getString(1) + "\n" +
"Email: " + c.getString(2),
Toast.LENGTH_LONG).show();
}
}
DBAdapter.java
Code:
package net.learn2develop.Databases;
import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.database.SQLException;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
import android.util.Log;
public class DBAdapter {
public static final String KEY_ROWID = "_id";
public static final String KEY_NAME = "name";
public static final String KEY_EMAIL = "email";
private static final String TAG = "DBAdapter";
private static final String DATABASE_NAME = "MyDB";
private static final String DATABASE_TABLE = "contacts";
private static final int DATABASE_VERSION = 2;
private static final String DATABASE_CREATE =
"create table contacts (_id integer primary key autoincrement, "
+ "name text not null, email text not null);";
private final Context context;
private DatabaseHelper DBHelper;
private SQLiteDatabase db;
public DBAdapter(Context ctx)
{
this.context = ctx;
DBHelper = new DatabaseHelper(context);
}
private static class DatabaseHelper extends SQLiteOpenHelper
{
DatabaseHelper(Context context)
{
super(context, DATABASE_NAME, null, DATABASE_VERSION);
}
@Override
public void onCreate(SQLiteDatabase db)
{
try {
db.execSQL(DATABASE_CREATE);
} catch (SQLException e) {
e.printStackTrace();
}
}
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion)
{
Log.w(TAG, "Upgrading database from version " + oldVersion + " to "
+ newVersion + ", which will destroy all old data");
db.execSQL("DROP TABLE IF EXISTS contacts");
onCreate(db);
}
}
//---opens the database---
public DBAdapter open() throws SQLException
{
db = DBHelper.getWritableDatabase();
return this;
}
//---closes the database---
public void close()
{
DBHelper.close();
}
//---insert a contact into the database---
public long insertContact(String name, String email)
{
ContentValues initialValues = new ContentValues();
initialValues.put(KEY_NAME, name);
initialValues.put(KEY_EMAIL, email);
return db.insert(DATABASE_TABLE, null, initialValues);
}
//---deletes a particular contact---
public boolean deleteContact(long rowId)
{
return db.delete(DATABASE_TABLE, KEY_ROWID + "=" + rowId, null) > 0;
}
//---retrieves all the contacts---
public Cursor getAllContacts()
{
return db.query(DATABASE_TABLE, new String[] {KEY_ROWID, KEY_NAME,
KEY_EMAIL}, null, null, null, null, null);
}
//---retrieves a particular contact---
public Cursor getContact(long rowId) throws SQLException
{
Cursor mCursor =
db.query(true, DATABASE_TABLE, new String[] {KEY_ROWID,
KEY_NAME, KEY_EMAIL}, KEY_ROWID + "=" + rowId, null,
null, null, null, null);
if (mCursor != null) {
mCursor.moveToFirst();
}
return mCursor;
}
//---updates a contact---
public boolean updateContact(long rowId, String name, String email)
{
ContentValues args = new ContentValues();
args.put(KEY_NAME, name);
args.put(KEY_EMAIL, email);
return db.update(DATABASE_TABLE, args, KEY_ROWID + "=" + rowId, null) > 0;
}
}
|
|

November 28th, 2011, 06:41 PM
|
|
Registered User
|
|
Join Date: Nov 2011
Posts: 3
Thanks: 0
Thanked 1 Time in 1 Post
|
|
Okay, here's how I did it:
As you'll probably gather, I've included phone number too. The important part of the code is the CursorAdapter and SimpleCursorAdapter which is exactly what it appears to be, a database analogue of an ArrayAdapter. I've put the drawing of the ListView in onStart rather than onCreate because when the user clicks on an entry they're taking to an activity which displays the record and allows them to edit or delete the record. If the drawing was left in onCreate it wouldn't be updated on return from the record view activity. I've created an array of ids so that I can pass the id of the clicked record to the viewer. Check out what I've done with the row.xml
Main code
Code:
package uk.co.minminzemi.MyContactsDatabase;
import android.app.ListActivity;
import android.content.Intent;
import android.database.Cursor;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.CursorAdapter;
import android.widget.ListView;
import android.widget.SimpleCursorAdapter;
public class MyContactsDatabaseActivity extends ListActivity {
/** Called when the activity is first created. */
private String[] ids;
private CursorAdapter datasource;
private static final String[] fields = {"name", "email", "telNo"};
private DBAdapter db;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
@Override
public void onStart() {
super.onStart();
// open database and read record IDs into the array
db = new DBAdapter(this);
db.open();
Cursor cursor = db.getAllContacts();
ids = new String[cursor.getCount()];
if (cursor.moveToFirst()) {
int i=0;
do {
ids[i++] = cursor.getString(0);
} while(cursor.moveToNext());
}
// we now have the ids array populated
datasource = new SimpleCursorAdapter(this, R.layout.row, cursor,
fields, new int[] { R.id.nameLine, R.id.emailLine,
R.id.phoneLine });
setListAdapter(datasource);
}
@Override
public void onStop() {
super.onStop();
db.close();
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
super.onCreateOptionsMenu(menu);
menu.add(0,0,0, "New Contact");
menu.add(0,1,1, "Exit");
return true;
}
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case 0:
Intent i = new Intent("uk.co.minminzemi.AddContact");
Bundle extras = new Bundle();
extras.putString("Name", "");
extras.putString("Email", "");
extras.putString("TelNo", "");
extras.putInt("Id", 0);
i.putExtras(extras);
db.close();
startActivity(i);
return true;
case 1:
db.close();
finish();
}
return false;
}
public void onListItemClick(ListView parent, View v, int pos, long id) {
Intent i = new Intent("uk.co.minminzemi.ViewContact");
Bundle extras = new Bundle();
extras.putString("Id", ids[pos]);
i.putExtras(extras);
db.close();
startActivity(i);
}
}
What I've done here is simply specify that I want the name to be large and at the top of the row, and that I want the two other fields to be small, and vertically arranged. This was passed to the SimpleCursorAdapter, and the miracle occurred.
row.xml
Code:
<?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/nameLine"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:textSize="20sp"
android:text="Name will go here" />
<TextView
android:id="@+id/emailLine"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:textSize="10sp"
android:text="Email will go here" />
<TextView
android:id="@+id/phoneLine"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:textSize="10sp"
android:text="Phone number will go here" />
</LinearLayout>
Hope this gives you some ideas so that you can achieve what you're after.
Tony
Last edited by mudskipper; December 1st, 2011 at 04:10 PM..
|
|
The Following User Says Thank You to mudskipper For This Useful Post:
|
|
|
 |
|