Address Book App 1 Define styles res/values/address_book_styles.xml <item name="android:background">@drawable/textview_border </item> Specify a background for a TextView – – 2 res/drawable/textview_border.xml The textview_border is defined as a shape element Create menu resources res/menu – 2 Define the MenuItems The menu will be inflated by Activity’s MenuInflater getMenuInflater().inflate(R.menu.add ressbook_menu, menu); Extend ListActivity A ListActivity’s default GUI consists of a ListView (we do not need to define a separate layout) – Specify the format that’s applied to each list item shown in the ListView (contact_list_item.xml) Create an Activity extends from ListActivity lv = getListView(); //get the built-in ListView lv.setOnItemClickListener(oicl); 5 ListView 5 ListView is a subclass of AdapterView, a GUI component is bound to a data source via an Adapter. We use CursorAdapter to display the results of a database query in the ListView. CursorAdapter SimpleCursorAdapter is a subclass of CursorAdapter that’s designed to mapping Cursor columns directly to TextView or ImageView To create a SimpleCursonAdapter, you must first define arrays containing the column names to map to GUI components (contact_list_item.xml) and the resource IDs (R.id.contactTV) of the GUI components that will display the data from the named columns. String[] columns = {"name"}; int[] components = {R.id.contactTV}; contactAdapter = new SimpleCursorAdapter(this, R.layout.contact_list_item, null, columns, components, 0); lv.setAdapter(contactAdapter); 5 CursorAdapter SimpleCursorAdapter requires 6 arguments: 5 – Context in which the ListView is running – Resource ID of the layout – The Cursor that provides access to the data – String array containing the column names to display – int array containing the corresponding GUI resource ID – Flag AsyncTask Perform action in one thread and receive the results in GUI thread Three parameters: – – – 6 Type of the parameter for doInBackground method, which is performed in separate thread Type of the parameter for onProgressUpdate method, which is executed in the GUI thread and is used to receive intermediate updates of the specified type from a longrunning task Type of the parameter for onPostExecute method, which is executed in the GUI thread and enables the Activity to use the AsyncTask’s results. AsyncTask example GetContactTask extends AsyncTask<Object, Object, Cursor> private DatabaseConnector dbc; protected Cursor doInBackground(Object... params) { dbc = new DatabaseConnector(AddressBook.this); dbc.open(); return dbc.getAllContacts();} protected void onPostExecute(Cursor result) { contactAdapter.changeCursor(result); dbc.close(); super.onPostExecute(result);} 6 OnResume Get the complete list of contacts from the database and make CursorAdpater works 5 – (new GetContactTask()).execute((Object[ ]) null); – execute do not receive any argument in this case OnStop 5 CursorAdpater Cursor is not needed contactAdapter.changeCursor(null); //adapter now has no cursor SQLite Database DatabaseConnector – – 7 Database names must be unique within a specific app but need not be unique across apps. A SQLiteDatabase object provides read/write access to a SQLite database DatabaseOpenHelper extends SQLiteOpenHelper is used to manage creating, opening and upgrading databases DatabaseOpenHelper Extends from SQLiteOpenHelper – Constructor requires 4 arguments – – – – 7 Helps apps create databases and manage version changes Context Database name CursorFactory = null indicates use default SQLite CursorFactory Database version number DatabaseOpenHelper OnCreate – Create the “contacts” table contains an integer primary key field (_id) that us auto-incremented, and 5 other text fields – String cmd = "create table contacts " +"(" + "_id integer primary key autoincrement, " + "name text, " + "email text, " + "phone text, " + "street text, " + "city text " + ")"; db.execSQL(cmd); //execute the query – – – – – 7 Database Operations 7 open close insertContacts – ContentValue: key-value pairs – insert(db name, nullColumnHack, data) updateContact – db.update("contacts", cv, "_id=?", new String[]{id+""}); deleteContact(long id) – db.delete("contacts", "_id=?", new String[]{id+””}); Query method database.query(7 arguments) – – – – – – – getAllContacts – db.query("contacts", columns, null, null, null, null, null); getOneContact(long id) – 7 Database name A String array of the column names to return A SQL WHERE clause A argument for WHERE clause A SQL GROUP BY clause A SQL HAVING clause A SQL ORDER BY clause db.query("contacts", columns, "_id=?", new String[]{id+””}, null, null, null); ViewContact LoadContactTask extends AsyncTask<Long, Object, Cursor> doInBaground – – onPostExecute – – – – – – – – 7 Open database getOneContact(params[0]) result.moveToFirst(); //move to the first item nameTV.setText(result.getString(0)); phoneTV.setText(result.getString(1)); emailTV.setText(result.getString(2)); streetTV.setText(result.getString(3)); cityTV.setText(result.getString(4)); result.close(); dbc.close(); DeleteContact Show alert dialog DeleteAsync extends AsyncTask<Long, Object, Object> doInBaground – – Open database deleteContact(params[0]) onPostExecute – finish(); //return to the AddressBook Activity 1. 2. 3. 7 Dismiss any dialogs the activity was managing. Close any cursors the activity was managing. Close any open search dialog EditContact SaveContactTask extends AsyncTask<Object, Object, Object> doInBaground – – onPostExecute – 7 Open database updateContact finish() AddContact SaveContactTask extends AsyncTask<Object, Object, Object> doInBaground – – onPostExecute – 7 Open database insertContact finish() Show alert dialog if name field is null