Working with SQLite database in Android
Trying to work with SQlite and Android. But inspite of the build success I am not getting any output on the Android emulator. Below is the code I have used.
DatabaseManager.java
package com.exampl开发者_如何学编程e.AndroidDatabase;
import java.util.ArrayList;
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 DatabaseManager
{
// the Activity or Application that is creating an object from this class.
Context context;
// a reference to the database used by this application/object
private SQLiteDatabase db;
// These constants are specific to the database. They should be
// changed to suit your needs.
private final String DB_NAME = "database_name";
private final int DB_VERSION = 1;
// These constants are specific to the database table. They should be
// changed to suit your needs.
private final String TABLE_NAME = "database_table";
private final String TABLE_ROW_ID = "id";
private final String TABLE_ROW_ONE = "table_row_one";
private final String TABLE_ROW_TWO = "table_row_two";
public DatabaseManager(Context context)
{
this.context = context;
// create or open the database
CustomSQLiteOpenHelper helper = new CustomSQLiteOpenHelper(context);
this.db = helper.getWritableDatabase();
}
/**********************************************************************
* ADDING A ROW TO THE DATABASE TABLE
*
* This is an example of how to add a row to a database table
* using this class. You should edit this method to suit your
* needs.
*
* the key is automatically assigned by the database
* @param rowStringOne the value for the row's first column
* @param rowStringTwo the value for the row's second column
*/
public void addRow(String rowStringOne, String rowStringTwo)
{
// this is a key value pair holder used by android's SQLite functions
ContentValues values = new ContentValues();
values.put(TABLE_ROW_ONE, rowStringOne);
values.put(TABLE_ROW_TWO, rowStringTwo);
// ask the database object to insert the new data
try{db.insert(TABLE_NAME, null, values);}
catch(Exception e)
{
Log.e("DB ERROR", e.toString());
e.printStackTrace();
}
}
/**********************************************************************
* DELETING A ROW FROM THE DATABASE TABLE
*
* This is an example of how to delete a row from a database table
* using this class. In most cases, this method probably does
* not need to be rewritten.
*
* @param rowID the SQLite database identifier for the row to delete.
*/
public void deleteRow(long rowID)
{
// ask the database manager to delete the row of given id
try {db.delete(TABLE_NAME, TABLE_ROW_ID + "=" + rowID, null);}
catch (Exception e)
{
Log.e("DB ERROR", e.toString());
e.printStackTrace();
}
}
/**********************************************************************
* UPDATING A ROW IN THE DATABASE TABLE
*
* This is an example of how to update a row in the database table
* using this class. You should edit this method to suit your needs.
*
* @param rowID the SQLite database identifier for the row to update.
* @param rowStringOne the new value for the row's first column
* @param rowStringTwo the new value for the row's second column
*/
public void updateRow(long rowID, String rowStringOne, String rowStringTwo)
{
// this is a key value pair holder used by android's SQLite functions
ContentValues values = new ContentValues();
values.put(TABLE_ROW_ONE, rowStringOne);
values.put(TABLE_ROW_TWO, rowStringTwo);
// ask the database object to update the database row of given rowID
try {db.update(TABLE_NAME, values, TABLE_ROW_ID + "=" + rowID, null);}
catch (Exception e)
{
Log.e("DB Error", e.toString());
e.printStackTrace();
}
}
/**********************************************************************
* RETRIEVING A ROW FROM THE DATABASE TABLE
*
* This is an example of how to retrieve a row from a database table
* using this class. You should edit this method to suit your needs.
*
* @param rowID the id of the row to retrieve
* @return an array containing the data from the row
*/
public ArrayList<Object> getRowAsArray(long rowID)
{
// create an array list to store data from the database row.
// I would recommend creating a JavaBean compliant object
// to store this data instead. That way you can ensure
// data types are correct.
ArrayList<Object> rowArray = new ArrayList<Object>();
Cursor cursor;
try
{
// this is a database call that creates a "cursor" object.
// the cursor object store the information collected from the
// database and is used to iterate through the data.
cursor = db.query
(
TABLE_NAME,
new String[] { TABLE_ROW_ID, TABLE_ROW_ONE, TABLE_ROW_TWO },
TABLE_ROW_ID + "=" + rowID,
null, null, null, null, null
);
// move the pointer to position zero in the cursor.
cursor.moveToFirst();
// if there is data available after the cursor's pointer, add
// it to the ArrayList that will be returned by the method.
if (!cursor.isAfterLast())
{
do
{
rowArray.add(cursor.getLong(0));
rowArray.add(cursor.getString(1));
rowArray.add(cursor.getString(2));
}
while (cursor.moveToNext());
}
// let java know that you are through with the cursor.
cursor.close();
}
catch (SQLException e)
{
Log.e("DB ERROR", e.toString());
e.printStackTrace();
}
// return the ArrayList containing the given row from the database.
return rowArray;
}
/**********************************************************************
* RETRIEVING ALL ROWS FROM THE DATABASE TABLE
*
* This is an example of how to retrieve all data from a database
* table using this class. You should edit this method to suit your
* needs.
*
* the key is automatically assigned by the database
*/
public ArrayList<ArrayList<Object>> getAllRowsAsArrays()
{
// create an ArrayList that will hold all of the data collected from
// the database.
ArrayList<ArrayList<Object>> dataArrays = new ArrayList<ArrayList<Object>>();
// this is a database call that creates a "cursor" object.
// the cursor object store the information collected from the
// database and is used to iterate through the data.
Cursor cursor;
try
{
// ask the database object to create the cursor.
cursor = db.query(
TABLE_NAME,
new String[]{TABLE_ROW_ID, TABLE_ROW_ONE, TABLE_ROW_TWO},
null, null, null, null, null
);
// move the cursor's pointer to position zero.
cursor.moveToFirst();
// if there is data after the current cursor position, add it
// to the ArrayList.
if (!cursor.isAfterLast())
{
do
{
ArrayList<Object> dataList = new ArrayList<Object>();
dataList.add(cursor.getLong(0));
dataList.add(cursor.getString(1));
dataList.add(cursor.getString(2));
dataArrays.add(dataList);
}
// move the cursor's pointer up one position.
while (cursor.moveToNext());
}
}
catch (SQLException e)
{
Log.e("DB Error", e.toString());
e.printStackTrace();
}
// return the ArrayList that holds the data collected from
// the database.
return dataArrays;
}
/**********************************************************************
* THIS IS THE BEGINNING OF THE INTERNAL SQLiteOpenHelper SUBCLASS.
*
* I MADE THIS CLASS INTERNAL SO I CAN COPY A SINGLE FILE TO NEW APPS
* AND MODIFYING IT - ACHIEVING DATABASE FUNCTIONALITY. ALSO, THIS WAY
* I DO NOT HAVE TO SHARE CONSTANTS BETWEEN TWO FILES AND CAN
* INSTEAD MAKE THEM PRIVATE AND/OR NON-STATIC. HOWEVER, I THINK THE
* INDUSTRY STANDARD IS TO KEEP THIS CLASS IN A SEPARATE FILE.
*********************************************************************/
/**
* This class is designed to check if there is a database that currently
* exists for the given program. If the database does not exist, it creates
* one. After the class ensures that the database exists, this class
* will open the database for use. Most of this functionality will be
* handled by the SQLiteOpenHelper parent class. The purpose of extending
* this class is to tell the class how to create (or update) the database.
*
*
*
*/
private class CustomSQLiteOpenHelper extends SQLiteOpenHelper
{
public CustomSQLiteOpenHelper(Context context)
{
super(context, DB_NAME, null, DB_VERSION);
}
@Override
public void onCreate(SQLiteDatabase db)
{
// This string is used to create the database. It should
// be changed to suit your needs.
String newTableQueryString = "create table " +
TABLE_NAME +
" (" +
TABLE_ROW_ID + " integer primary key autoincrement not null," +
TABLE_ROW_ONE + " text," +
TABLE_ROW_TWO + " text" +
");";
// execute the query string to the database.
db.execSQL(newTableQueryString);
}
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion)
{
// NOTHING TO DO HERE. THIS IS THE ORIGINAL DATABASE VERSION.
// OTHERWISE, YOU WOULD SPECIFIY HOW TO UPGRADE THE DATABASE.
}
}
AndroidDatabaseActivity.java
package com.example.AndroidDatabase;
import java.util.ArrayList;
import android.app.Activity;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TableLayout;
import android.widget.TableRow;
import android.widget.TextView;
public class AndroidDatabaseActivity extends Activity
{
// the text fields that users input new data into
EditText textFieldOne, textFieldTwo,
idField, updateIDField, updateTextFieldOne, updateTextFieldTwo;
// the buttons that listen for the user to select an action
Button addButton, deleteButton, retrieveButton, updateButton;
// the table that displays the data
TableLayout dataTable;
// the class that opens or creates the database and makes sql calls to it
DatabaseManager db;
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState)
{
// this try catch block returns better error reporting to the log
try
{
// Android specific calls
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
// create the database manager object
db = new DatabaseManager(this);
// create references and listeners for the GUI interface
setupViews();
// make the buttons clicks perform actions
addButtonListeners();
// load the data table
updateTable();
}
catch (Exception e)
{
Log.e("ERROR", e.toString());
e.printStackTrace();
}
}
/**
* creates references and listeners for the GUI interface
*/
private void setupViews()
{
// THE DATA TABLE
dataTable= (TableLayout)findViewById(R.id.data_table);
// THE DATA FORM FIELDS
textFieldOne= (EditText)findViewById(R.id.text_field_one);
textFieldTwo= (EditText)findViewById(R.id.text_field_two);
idField= (EditText)findViewById(R.id.id_field);
updateIDField= (EditText)findViewById(R.id.update_id_field);
updateTextFieldOne= (EditText)findViewById(R.id.update_text_field_one);
updateTextFieldTwo= (EditText)findViewById(R.id.update_text_field_two);
// THE BUTTONS
addButton = (Button)findViewById(R.id.add_button);
deleteButton = (Button)findViewById(R.id.delete_button);
retrieveButton = (Button)findViewById(R.id.retrieve_button);
updateButton = (Button)findViewById(R.id.update_button);
}
/**
* adds listeners to each of the buttons and sets them to call relevant methods
*/
private void addButtonListeners()
{
addButton.setOnClickListener
(
new View.OnClickListener()
{
@Override public void onClick(View v) {addRow();}
}
);
deleteButton.setOnClickListener
(
new View.OnClickListener()
{
@Override public void onClick(View v) {deleteRow();}
}
);
updateButton.setOnClickListener
(
new View.OnClickListener()
{
@Override public void onClick(View v) {updateRow();}
}
);
retrieveButton.setOnClickListener
(
new View.OnClickListener()
{
@Override public void onClick(View v) {retrieveRow();}
}
);
}
/**
* adds a row to the database based on information contained in the
* add row fields.
*/
private void addRow()
{
try
{
// ask the database manager to add a row given the two strings
db.addRow
(
textFieldOne.getText().toString(),
textFieldTwo.getText().toString()
);
// request the table be updated
updateTable();
// remove all user input from the Activity
emptyFormFields();
}
catch (Exception e)
{
Log.e("Add Error", e.toString());
e.printStackTrace();
}
}
/**
* deletes a row from the database with the id number in the corresponding
* user entry field
*/
private void deleteRow()
{
try
{
// ask the database manager to delete the row with the give rowID.
db.deleteRow(Long.parseLong(idField.getText().toString()));
// request the table be updated
updateTable();
// remove all user input from the Activity
emptyFormFields();
}
catch (Exception e)
{
Log.e("Delete Error", e.toString());
e.printStackTrace();
}
}
/**
* retrieves a row from the database with the id number in the corresponding
* user entry field
*/
private void retrieveRow()
{
try
{
// The ArrayList that holds the row data
ArrayList<Object> row;
// ask the database manager to retrieve the row with the given rowID
row = db.getRowAsArray(Long.parseLong(updateIDField.getText().toString()));
// update the form fields to hold the retrieved data
updateTextFieldOne.setText((String)row.get(1));
updateTextFieldTwo.setText((String)row.get(2));
}
catch (Exception e)
{
Log.e("Retrieve Error", e.toString());
e.printStackTrace();
}
}
/**
* updates a row with the given information in the corresponding user entry
* fields
*/
private void updateRow()
{
try
{
// ask the database manager to update the row based on the information
// found in the corresponding user entry fields
db.updateRow
(
Long.parseLong(updateIDField.getText().toString()),
updateTextFieldOne.getText().toString(),
updateTextFieldTwo.getText().toString()
);
// request the table be updated
updateTable();
// remove all user input from the Activity
emptyFormFields();
}
catch (Exception e)
{
Log.e("Update Error", e.toString());
e.printStackTrace();
}
}
/**
* helper method to empty all the fields in all the forms.
*/
private void emptyFormFields()
{
textFieldOne.setText("");
textFieldTwo.setText("");
idField.setText("");
updateIDField.setText("");
updateTextFieldOne.setText("");
updateTextFieldTwo.setText("");
}
/**
* updates the table from the database.
*/
private void updateTable()
{
// delete all but the first row. remember that the count
// starts at one and the index starts at zero
while (dataTable.getChildCount() > 1)
{
// while there are at least two rows in the table widget, delete
// the second row.
dataTable.removeViewAt(1);
}
// collect the current row information from the database and
// store it in a two dimensional ArrayList
ArrayList<ArrayList<Object>> data = db.getAllRowsAsArrays();
// iterate the ArrayList, create new rows each time and add them
// to the table widget.
for (int position=0; position < data.size(); position++)
{
TableRow tableRow= new TableRow(this);
ArrayList<Object> row = data.get(position);
TextView idText = new TextView(this);
idText.setText(row.get(0).toString());
tableRow.addView(idText);
TextView textOne = new TextView(this);
textOne.setText(row.get(1).toString());
tableRow.addView(textOne);
TextView textTwo = new TextView(this);
textTwo.setText(row.get(2).toString());
tableRow.addView(textTwo);
dataTable.addView(tableRow);
}
}
Main.xml
<!-- ADD A DATA ENTRY FORM -->
<TextView
android:text="@string/add_directions"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
/>
<LinearLayout
android:orientation="horizontal"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
>
<EditText
android:id="@+id/text_field_one"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:minWidth="100px"
/>
<EditText
android:id="@+id/text_field_two"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:minWidth="100px"
/>
<Button
android:id="@+id/add_button"
android:text="@string/add"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
/>
</LinearLayout>
<!-- DELETE A DATA ENTRY FORM -->
<TextView
android:text="@string/delete_directions"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
/>
<LinearLayout
android:orientation="horizontal"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
>
<EditText
android:id="@+id/id_field"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:minWidth="100px"
/>
<Button
android:id="@+id/delete_button"
android:text="@string/delete"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
/>
</LinearLayout>
<!-- UPDATE A DATA ENTRY FORM -->
<TextView
android:text="@string/update_directions"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
/>
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="wrap_content"
>
<EditText
android:id="@+id/update_id_field"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:minWidth="45px"
/>
<Button
android:id="@+id/retrieve_button"
android:text="@string/retrieve"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
/>
<EditText
android:id="@+id/update_text_field_one"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:minWidth="70px"
/>
<EditText
android:id="@+id/update_text_field_two"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:minWidth="70px"
/>
<Button
android:id="@+id/update_button"
android:text="@string/update"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
/>
</LinearLayout>
<!-- THE DATA TABLE -->
<TableLayout
android:id="@+id/data_table"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
>
<TableRow>
<TextView
android:text="@string/th_id"
android:minWidth="50px"
/>
<TextView
android:text="@string/th_text_one"
android:minWidth="125px"
/>
<TextView
android:text="@string/th_text_two"
android:minWidth="125px"
/>
</TableRow>
</TableLayout>
String.xml
Database Application
<string name="add_directions">Fill in both fields with text and click the "add" button.</string>
<string name="add">add</string>
<string name="delete_directions">To delete a row, type the "id" of the row in the field provided and press the "delete" button.</string>
<string name="delete">delete</string>
<string name="update_directions">To update a row, type the "id" of the row in the first field and type the new information into the next two fields.</string>
<string name="retrieve">get</string>
<string name="update">update</string>
<string name="th_id">ID</string>
<string name="th_text_one">Text Field One</string>
<string name="th_text_two">Text Field Two</string>
AndroidManifest.xml
<application android:icon="@drawable/icon" android:label="@string/app_name">
<activity android:name=".DatabaseManager"
android:label="@string/app_name">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
Everytime I try to launch this app, it gives me a warning " The application has stopped unexpectedly. Please try again." Can someone guide me as to what is going wrong ?
Error:
[2011-04-25 16:07:57 - AndroidDatabaseManager] ------------------------------
[2011-04-25 16:07:57 - AndroidDatabaseManager] Android Launch!
[2011-04-25 16:07:57 - AndroidDatabaseManager] adb is running normally.
[2011-04-25 16:07:57 - AndroidDatabaseManager] Performi com.example.AndroidDatabase.DatabaseManager activity launch
[2011-04-25 16:07:57 - AndroidDatabaseManager] Automatic Target Mode: launching new emulator with compatible AVD 'my_avd'
[2011-04-25 16:07:57 - AndroidDatabaseManager] Launching a new emulator with Virtual Device 'my_avd'
[2011-04-25 16:08:05 - AndroidDatabaseManager] New emulator found: emulator-5554
[2011-04-25 16:08:05 - AndroidDatabaseManager] Waiting for HOME ('android.process.acore') to be launched...
[2011-04-25 16:08:49 - AndroidDatabaseManager] HOME is up on device 'emulator-5554'
[2011-04-25 16:08:49 - AndroidDatabaseManager] Uploading AndroidDatabaseManager.apk onto device 'emulator-5554'
[2011-04-25 16:08:49 - AndroidDatabaseManager] Installing AndroidDatabaseManager.apk...
[2011-04-25 16:12:01 - AndroidDatabaseManager] Failed to install AndroidDatabaseManager.apk on device 'emulator-5554!
[2011-04-25 16:12:01 - AndroidDatabaseManager] (null)
[2011-04-25 16:12:06 - AndroidDatabaseManager] Launch canceled!
Your manifest is wrong, DatabaseManager isn't an activity, it's a class. Replace it with
<activity android:name=".AndroidDatabaseActivity"
Also you don't have a proper root element in your main.xml, you need to change it to something like:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:background="#ffffff">
---------
YOUR EXISTING XML
---------
</LinearLayout>
.
精彩评论