Android SQLite Database and Content Provider - Tutorial
Android SQLite Database and Content Provider - Tutorial
2013
vogella.com
Tutorials
Training
Books
Shop
Contact us
TEXT REAL
INTEGER
android.database android.database.sqlite
SQLiteOpenHelper
super()
vogella.com
Tutorials
Training
Books
Shop
Contact us
onCreate() onUpgrade()
onCreate() SQLiteDatabase
SQLiteOpenHelper
getWriteableDatabase()
onCreate()
onUpgrade() SQLiteOpenHelper
SQLiteOpenHelper
SQLiteDatabase
insert() update()
delete()
key ContentValues
query()
SQLiteQueryBuilder
rawQuery()
Cursor cursor = getReadableDatabase(). rawQuery("select * from todo where _id = ?", new String[] { id });
query()
return database.query(DATABASE_TABLE, new String[] { KEY_ROWID, KEY_CATEGORY, KEY_SUMMARY, KEY_DESCRIPTION }, null, null, null, null, null);
query()
vogella.com
Tutorials
Training
Books
Shop
Contact us
null
Cursor
Cursor
getColumnIndexOrThrow(String)
Cursor
close()
ListViews
ListActivities
SimpleCursorAdapter
vogella.com
Tutorials
Training
Books
Shop
Contact us
ContentProvider
Loader
Cursor
de.vogella.android.sqlite.first
MySQLiteHelper
onUpgrade()
package de.vogella.android.sqlite.first; import import import import android.content.Context; android.database.sqlite.SQLiteDatabase; android.database.sqlite.SQLiteOpenHelper; android.util.Log;
public class MySQLiteHelper extends SQLiteOpenHelper { public static final String TABLE_COMMENTS = "comments"; public static final String COLUMN_ID = "_id"; public static final String COLUMN_COMMENT = "comment"; private static final String DATABASE_NAME = "commments.db"; private static final int DATABASE_VERSION = 1;
// Database creation sql statement private static final String DATABASE_CREATE = "create table " + TABLE_COMMENTS + "(" + COLUMN_ID + " integer primary key autoincrement, " + COLUMN_COMMENT + " text not null);";
public MySQLiteHelper(Context context) { super(context, DATABASE_NAME, null, DATABASE_VERSION);
vogella.com
Tutorials
Training
Books
Shop
Contact us
@Override public void onCreate(SQLiteDatabase database) { database.execSQL(DATABASE_CREATE); } @Override public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { Log.w(MySQLiteHelper.class.getName(), "Upgrading database from version " + oldVersion + " to " + newVersion + ", which will destroy all old data"); db.execSQL("DROP TABLE IF EXISTS " + TABLE_COMMENTS); onCreate(db); }
}
Comment
package de.vogella.android.sqlite.first; public class Comment { private long id; private String comment; public long getId() { return id; } public void setId(long id) { this.id = id; } public String getComment() { return comment; } public void setComment(String comment) { this.comment = comment; }
// Will be used by the ArrayAdapter in the ListView @Override public String toString() { return comment; }
}
CommentsDataSource
package de.vogella.android.sqlite.first; import java.util.ArrayList; import java.util.List; import import import import import android.content.ContentValues; android.content.Context; android.database.Cursor; android.database.SQLException; android.database.sqlite.SQLiteDatabase;
// Database fields private SQLiteDatabase database; private MySQLiteHelper dbHelper; private String[] allColumns = { MySQLiteHelper.COLUMN_ID, MySQLiteHelper.COLUMN_COMMENT };
public CommentsDataSource(Context context) { dbHelper = new MySQLiteHelper(context); } public void open() throws SQLException { database = dbHelper.getWritableDatabase(); } public void close() { dbHelper.close(); } public Comment createComment(String comment) { ContentValues values = new ContentValues(); values.put(MySQLiteHelper.COLUMN_COMMENT, comment); long insertId = database.insert(MySQLiteHelper.TABLE_COMMENTS, null, values); Cursor cursor = database.query(MySQLiteHelper.TABLE_COMMENTS, allColumns, MySQLiteHelper.COLUMN_ID + " = " + insertId, null, null, null, null); cursor.moveToFirst();
vogella.com
}
Books
Shop
Contact us
public void deleteComment(Comment comment) { long id = comment.getId(); System.out.println("Comment deleted with id: " + id); database.delete(MySQLiteHelper.TABLE_COMMENTS, MySQLiteHelper.COLUMN_ID + " = " + id, null); } public List<Comment> getAllComments() { List<Comment> comments = new ArrayList<Comment>(); Cursor cursor = database.query(MySQLiteHelper.TABLE_COMMENTS, allColumns, null, null, null, null, null); cursor.moveToFirst(); while (!cursor.isAfterLast()) { Comment comment = cursorToComment(cursor); comments.add(comment); cursor.moveToNext(); } // make sure to close the cursor cursor.close(); return comments; } private Comment cursorToComment(Cursor cursor) { Comment comment = new Comment(); comment.setId(cursor.getLong(0)); comment.setComment(cursor.getString(1)); return comment; } }
main.xml
res/layout ListView
<?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="vertical" > <LinearLayout android:id="@+id/group" android:layout_width="wrap_content" android:layout_height="wrap_content" > <Button android:id="@+id/add" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Add New" android:onClick="onClick"/> <Button android:id="@+id/delete" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Delete First" android:onClick="onClick"/> </LinearLayout> <ListView android:id="@android:id/list" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="@string/hello" /> </LinearLayout>
TestDatabaseActivity
package de.vogella.android.sqlite.first; import java.util.List; import java.util.Random; import import import import android.app.ListActivity; android.os.Bundle; android.view.View; android.widget.ArrayAdapter;
vogella.com
Tutorials
Training
Books
Shop
Contact us
// use the SimpleCursorAdapter to show the // elements in a ListView ArrayAdapter<Comment> adapter = new ArrayAdapter<Comment>(this, android.R.layout.simple_list_item_1, values); setListAdapter(adapter);
}
// Will be called via the onClick attribute // of the buttons in main.xml public void onClick(View view) { @SuppressWarnings("unchecked") ArrayAdapter<Comment> adapter = (ArrayAdapter<Comment>) getListAdapter(); Comment comment = null; switch (view.getId()) { case R.id.add: String[] comments = new String[] { "Cool", "Very nice", "Hate it" }; int nextInt = new Random().nextInt(3); // save the new comment to the database comment = datasource.createComment(comments[nextInt]); adapter.add(comment); break; case R.id.delete: if (getListAdapter().getCount() > 0) { comment = (Comment) getListAdapter().getItem(0); datasource.deleteComment(comment); adapter.remove(comment); } break; } adapter.notifyDataSetChanged(); } @Override protected void onResume() { datasource.open(); super.onResume(); } @Override protected void onPause() { datasource.close(); super.onPause(); }
}
AndroidManifest.xml
ContentProvider
AndroidManifest.xml
android:authorities
vogella.com
Tutorials
Training
Books
Shop
Contact us
content providers
content providers
UnsupportedOperationException()
android:exported=false|true AndroidManifest.xml
android:exported
ContentProvider
vogella.com
Tutorials
Training
Books
Shop
Contact us
vogella.com
Tutorials
Training
Books
Shop
Contact us
res/layout contactview
TextView
<?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="vertical" > <TextView android:id="@+id/contactview" android:layout_width="match_parent" android:layout_height="match_parent" /> </LinearLayout>
ContentProvider AndroidManifest.xml
android.permission.READ_CONTACTS
package de.vogella.android.contentprovider; import import import import import import android.app.Activity; android.database.Cursor; android.net.Uri; android.os.Bundle; android.provider.ContactsContract; android.widget.TextView;
public class ContactsActivity extends Activity { /** Called when the activity is first created. */
@Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_contacts); TextView contactView = (TextView) findViewById(R.id.contactview);
Cursor cursor = getContacts();
vogella.com
Tutorials Training Books Shop Contact us String displayName = cursor.getString(cursor .getColumnIndex(ContactsContract.Data.DISPLAY_NAME)); contactView.append("Name: "); contactView.append(displayName); contactView.append("\n");
} } private Cursor getContacts() { // Run query Uri uri = ContactsContract.Contacts.CONTENT_URI; String[] projection = new String[] { ContactsContract.Contacts._ID, ContactsContract.Contacts.DISPLAY_NAME }; String selection = ContactsContract.Contacts.IN_VISIBLE_GROUP + " = '" + ("1") + "'"; String[] selectionArgs = null; String sortOrder = ContactsContract.Contacts.DISPLAY_NAME + " COLLATE LOCALIZED ASC";
Loader
Loader
initLoader() LoaderManager.LoaderCallbacks
vogella.com
Tutorials
Training
Books
Shop
Contact us
managedQuery() Loader ContentProvider SimpleCursorAdapter Cursor CursorLoader Cursor ListViews onLoadFinished() swapCursor()
OptionMenu
ContentProvider
Cursor
Loader
vogella.com
Tutorials
Training
Books
Shop
Contact us
de.vogella.android.todos TodoDetailActivity
TodosOverviewActivity
de.vogella.android.todos.database
vogella.com
Tutorials
Training
Books
Shop
Contact us
// Database table public static final public static final public static final public static final public static final
TABLE_TODO = "todo"; COLUMN_ID = "_id"; COLUMN_CATEGORY = "category"; COLUMN_SUMMARY = "summary"; COLUMN_DESCRIPTION = "description";
// Database creation SQL statement private static final String DATABASE_CREATE = "create table " + TABLE_TODO + "(" + COLUMN_ID + " integer primary key autoincrement, " + COLUMN_CATEGORY + " text not null, " + COLUMN_SUMMARY + " text not null," + COLUMN_DESCRIPTION + " text not null" + ");";
public static void onCreate(SQLiteDatabase database) { database.execSQL(DATABASE_CREATE); } public static void onUpgrade(SQLiteDatabase database, int oldVersion, int newVersion) { Log.w(TodoTable.class.getName(), "Upgrading database from version " + oldVersion + " to " + newVersion + ", which will destroy all old data"); database.execSQL("DROP TABLE IF EXISTS " + TABLE_TODO); onCreate(database); } }
TodoDatabaseHelper TodoTable
SQLiteOpenHelper
package de.vogella.android.todos.database; import android.content.Context; import android.database.sqlite.SQLiteDatabase; import android.database.sqlite.SQLiteOpenHelper; public class TodoDatabaseHelper extends SQLiteOpenHelper { private static final String DATABASE_NAME = "todotable.db"; private static final int DATABASE_VERSION = 1; public TodoDatabaseHelper(Context context) { super(context, DATABASE_NAME, null, DATABASE_VERSION); }
// Method is called during creation of the database @Override public void onCreate(SQLiteDatabase database) { TodoTable.onCreate(database); } // Method is called during an upgrade of the database, // e.g. if you increase the database version @Override public void onUpgrade(SQLiteDatabase database, int oldVersion, int newVersion) { TodoTable.onUpgrade(database, oldVersion, newVersion); }
}
ContentProvider
package de.vogella.android.todos.contentprovider; import java.util.Arrays; import java.util.HashSet; import import import import import import import import android.content.ContentProvider; android.content.ContentResolver; android.content.ContentValues; android.content.UriMatcher; android.database.Cursor; android.database.sqlite.SQLiteDatabase; android.database.sqlite.SQLiteQueryBuilder; android.net.Uri;
vogella.com
// database private TodoDatabaseHelper database; // used for the UriMacher private static final int TODOS = 10; private static final int TODO_ID = 20;
private static final String AUTHORITY = "de.vogella.android.todos.contentprovider"; private static final String BASE_PATH = "todos"; public static final Uri CONTENT_URI = Uri.parse("content://" + AUTHORITY + "/" + BASE_PATH); public static final String CONTENT_TYPE = ContentResolver.CURSOR_DIR_BASE_TYPE + "/todos"; public static final String CONTENT_ITEM_TYPE = ContentResolver.CURSOR_ITEM_BASE_TYPE + "/todo"; private static final UriMatcher sURIMatcher = new UriMatcher(UriMatcher.NO_MATCH); static { sURIMatcher.addURI(AUTHORITY, BASE_PATH, TODOS); sURIMatcher.addURI(AUTHORITY, BASE_PATH + "/#", TODO_ID); }
@Override public boolean onCreate() { database = new TodoDatabaseHelper(getContext()); return false; } @Override public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder) { // Uisng SQLiteQueryBuilder instead of query() method SQLiteQueryBuilder queryBuilder = new SQLiteQueryBuilder(); // check if the caller has requested a column which does not exists checkColumns(projection); // Set the table queryBuilder.setTables(TodoTable.TABLE_TODO);
int uriType = sURIMatcher.match(uri); switch (uriType) { case TODOS: break; case TODO_ID: // adding the ID to the original query queryBuilder.appendWhere(TodoTable.COLUMN_ID + "=" + uri.getLastPathSegment()); break; default: throw new IllegalArgumentException("Unknown URI: " + uri); } SQLiteDatabase db = database.getWritableDatabase(); Cursor cursor = queryBuilder.query(db, projection, selection, selectionArgs, null, null, sortOrder); // make sure that potential listeners are getting notified cursor.setNotificationUri(getContext().getContentResolver(), uri); return cursor; }
@Override public String getType(Uri uri) { return null; } @Override public Uri insert(Uri uri, ContentValues values) { int uriType = sURIMatcher.match(uri); SQLiteDatabase sqlDB = database.getWritableDatabase(); int rowsDeleted = 0; long id = 0; switch (uriType) { case TODOS: id = sqlDB.insert(TodoTable.TABLE_TODO, null, values); break; default: throw new IllegalArgumentException("Unknown URI: " + uri); } getContext().getContentResolver().notifyChange(uri, null); return Uri.parse(BASE_PATH + "/" + id); } @Override public int delete(Uri uri, String selection, String[] selectionArgs) { int uriType = sURIMatcher.match(uri); SQLiteDatabase sqlDB = database.getWritableDatabase(); int rowsDeleted = 0;
vogella.com
Tutorials Training Books Shop Contact us rowsDeleted = sqlDB.delete(TodoTable.TABLE_TODO, selection, selectionArgs); break; case TODO_ID: String id = uri.getLastPathSegment(); if (TextUtils.isEmpty(selection)) { rowsDeleted = sqlDB.delete(TodoTable.TABLE_TODO, TodoTable.COLUMN_ID + "=" + id, null); } else { rowsDeleted = sqlDB.delete(TodoTable.TABLE_TODO, TodoTable.COLUMN_ID + "=" + id + " and " + selection, selectionArgs); } break; default: throw new IllegalArgumentException("Unknown URI: " + uri); } getContext().getContentResolver().notifyChange(uri, null); return rowsDeleted;
@Override public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) {
int uriType = sURIMatcher.match(uri); SQLiteDatabase sqlDB = database.getWritableDatabase(); int rowsUpdated = 0; switch (uriType) { case TODOS: rowsUpdated = sqlDB.update(TodoTable.TABLE_TODO, values, selection, selectionArgs); break; case TODO_ID: String id = uri.getLastPathSegment(); if (TextUtils.isEmpty(selection)) { rowsUpdated = sqlDB.update(TodoTable.TABLE_TODO, values, TodoTable.COLUMN_ID + "=" + id, null); } else { rowsUpdated = sqlDB.update(TodoTable.TABLE_TODO, values, TodoTable.COLUMN_ID + "=" + id + " and " + selection, selectionArgs); } break; default: throw new IllegalArgumentException("Unknown URI: " + uri); } getContext().getContentResolver().notifyChange(uri, null); return rowsUpdated; } private void checkColumns(String[] projection) { String[] available = { TodoTable.COLUMN_CATEGORY, TodoTable.COLUMN_SUMMARY, TodoTable.COLUMN_DESCRIPTION, TodoTable.COLUMN_ID }; if (projection != null) { HashSet<String> requestedColumns = new HashSet<String>(Arrays.asList(projection)); HashSet<String> availableColumns = new HashSet<String>(Arrays.asList(available)); // check if all columns which are requested are available if (!availableColumns.containsAll(requestedColumns)) { throw new IllegalArgumentException("Unknown columns in projection"); } } } }
MyTodoContentProvider
query()
checkColumns() ContentProvider
<application <!-- Place the following after the Activity Definition --> <provider android:name=".contentprovider.MyTodoContentProvider" android:authorities="de.vogella.android.todos.contentprovider" > </provider> </application>
vogella.com
Tutorials
Training
Books
Shop
Contact us
listmenu.xml
res/menu
android:showAsAction="always"
<?xml version="1.0" encoding="utf-8"?> <menu xmlns:android="http://schemas.android.com/apk/res/android" > <item android:id="@+id/insert" android:showAsAction="always" android:title="Insert"> </item> </menu>
priority.xml
res/values
<?xml version="1.0" encoding="utf-8"?> <resources> <string-array name="priorities"> <item>Urgent</item> <item>Reminder</item> </string-array> </resources>
strings.xml
res/values
<?xml version="1.0" encoding="utf-8"?> <resources> <string name="hello">Hello World, Todo!</string> <string name="app_name">Todo</string> <string name="no_todos">Currently there are no Todo items maintained</string> <string name="menu_insert">Add Item</string> <string name="menu_delete">Delete Todo</string> <string name="todo_summary">Summary</string> <string name="todo_description">Delete Todo</string> <string name="todo_edit_summary">Summary</string> <string name="todo_edit_description">Description</string> <string name="todo_edit_confirm">Confirm</string> </resources>
res/drawable
res/layout
<?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="wrap_content" > <ImageView android:id="@+id/icon" android:layout_width="30dp" android:layout_height="24dp" android:layout_marginLeft="4dp"
vogella.com
<TextView android:id="@+id/label" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginTop="6dp" android:lines="1" android:text="@+id/TextView01" android:textSize="24dp" > </TextView> </LinearLayout>
todo_list.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="vertical" > <ListView android:id="@android:id/list" android:layout_width="match_parent" android:layout_height="wrap_content" > </ListView> <TextView android:id="@android:id/empty" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/no_todos" /> </LinearLayout>
todo_edit.xml TodoDetailActivity
<?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="vertical" > <Spinner android:id="@+id/category" android:layout_width="wrap_content" android:layout_height="wrap_content" android:entries="@array/priorities" > </Spinner> <LinearLayout android:id="@+id/LinearLayout01" android:layout_width="match_parent" android:layout_height="wrap_content" > <EditText android:id="@+id/todo_edit_summary" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_weight="1" android:hint="@string/todo_edit_summary" android:imeOptions="actionNext" > </EditText> </LinearLayout> <EditText android:id="@+id/todo_edit_description" android:layout_width="match_parent" android:layout_height="match_parent" android:layout_weight="1" android:gravity="top" android:hint="@string/todo_edit_description" android:imeOptions="actionNext" > </EditText> <Button android:id="@+id/todo_edit_button" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/todo_edit_confirm" > </Button> </LinearLayout>
vogella.com
Tutorials
Training
Books
Shop
Contact us
TodosOverviewActivity.java
package de.vogella.android.todos; import import import import import import import import import import import import import import import import import import import android.app.ListActivity; android.app.LoaderManager; android.content.CursorLoader; android.content.Intent; android.content.Loader; android.database.Cursor; android.net.Uri; android.os.Bundle; android.view.ContextMenu; android.view.ContextMenu.ContextMenuInfo; android.view.Menu; android.view.MenuInflater; android.view.MenuItem; android.view.View; android.widget.AdapterView.AdapterContextMenuInfo; android.widget.ListView; android.widget.SimpleCursorAdapter; de.vogella.android.todos.contentprovider.MyTodoContentProvider; de.vogella.android.todos.database.TodoTable;
/* * TodosOverviewActivity displays the existing todo items * in a list * * You can create new ones via the ActionBar entry "Insert" * You can delete existing ones via a long press on the item */
public class TodosOverviewActivity extends ListActivity implements LoaderManager.LoaderCallbacks<Cursor> { private static final int ACTIVITY_CREATE = 0; private static final int ACTIVITY_EDIT = 1; private static final int DELETE_ID = Menu.FIRST + 1; // private Cursor cursor; private SimpleCursorAdapter adapter;
@Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.todo_list); this.getListView().setDividerHeight(2); fillData(); registerForContextMenu(getListView()); } // create the menu based on the XML defintion @Override public boolean onCreateOptionsMenu(Menu menu) { MenuInflater inflater = getMenuInflater(); inflater.inflate(R.menu.listmenu, menu); return true; } // Reaction to the menu selection @Override public boolean onOptionsItemSelected(MenuItem item) { switch (item.getItemId()) { case R.id.insert: createTodo(); return true; } return super.onOptionsItemSelected(item); } @Override public boolean onContextItemSelected(MenuItem item) { switch (item.getItemId()) { case DELETE_ID: AdapterContextMenuInfo info = (AdapterContextMenuInfo) item .getMenuInfo(); Uri uri = Uri.parse(MyTodoContentProvider.CONTENT_URI + "/" + info.id); getContentResolver().delete(uri, null, null); fillData(); return true; } return super.onContextItemSelected(item); }
private void createTodo() { Intent i = new Intent(this, TodoDetailActivity.class); startActivity(i); }
vogella.com
Tutorials Training Books Shop Contact us Intent i = new Intent(this, TodoDetailActivity.class); Uri todoUri = Uri.parse(MyTodoContentProvider.CONTENT_URI + "/" + id); i.putExtra(MyTodoContentProvider.CONTENT_ITEM_TYPE, todoUri);
startActivity(i); }
// Fields from the database (projection) // Must include the _id column for the adapter to work String[] from = new String[] { TodoTable.COLUMN_SUMMARY }; // Fields on the UI to which we map int[] to = new int[] { R.id.label };
getLoaderManager().initLoader(0, null, this); adapter = new SimpleCursorAdapter(this, R.layout.todo_row, null, from, to, 0); setListAdapter(adapter); }
@Override public void onCreateContextMenu(ContextMenu menu, View v, ContextMenuInfo menuInfo) { super.onCreateContextMenu(menu, v, menuInfo); menu.add(0, DELETE_ID, 0, R.string.menu_delete); } // creates a new loader after the initLoader () call @Override public Loader<Cursor> onCreateLoader(int id, Bundle args) { String[] projection = { TodoTable.COLUMN_ID, TodoTable.COLUMN_SUMMARY }; CursorLoader cursorLoader = new CursorLoader(this, MyTodoContentProvider.CONTENT_URI, projection, null, null, null); return cursorLoader; } @Override public void onLoadFinished(Loader<Cursor> loader, Cursor data) { adapter.swapCursor(data); } @Override public void onLoaderReset(Loader<Cursor> loader) { // data is not available anymore, delete reference adapter.swapCursor(null); }
}
TodoDetailActivity.java
package de.vogella.android.todos; import import import import import import import import import import import import import android.app.Activity; android.content.ContentValues; android.database.Cursor; android.net.Uri; android.os.Bundle; android.text.TextUtils; android.view.View; android.widget.Button; android.widget.EditText; android.widget.Spinner; android.widget.Toast; de.vogella.android.todos.contentprovider.MyTodoContentProvider; de.vogella.android.todos.database.TodoTable;
/* * TodoDetailActivity allows to enter a new todo item * or to change an existing */ public class TodoDetailActivity extends Activity { private Spinner mCategory; private EditText mTitleText; private EditText mBodyText;
private Uri todoUri;
vogella.com
// Or passed from the other activity if (extras != null) { todoUri = extras .getParcelable(MyTodoContentProvider.CONTENT_ITEM_TYPE);
fillData(todoUri); } confirmButton.setOnClickListener(new View.OnClickListener() { public void onClick(View view) { if (TextUtils.isEmpty(mTitleText.getText().toString())) { makeToast(); } else { setResult(RESULT_OK); finish(); } } }); } private void fillData(Uri uri) { String[] projection = { TodoTable.COLUMN_SUMMARY, TodoTable.COLUMN_DESCRIPTION, TodoTable.COLUMN_CATEGORY }; Cursor cursor = getContentResolver().query(uri, projection, null, null, null); if (cursor != null) { cursor.moveToFirst(); String category = cursor.getString(cursor .getColumnIndexOrThrow(TodoTable.COLUMN_CATEGORY)); for (int i = 0; i < mCategory.getCount(); i++) { String s = (String) mCategory.getItemAtPosition(i); if (s.equalsIgnoreCase(category)) { mCategory.setSelection(i); } } mTitleText.setText(cursor.getString(cursor .getColumnIndexOrThrow(TodoTable.COLUMN_SUMMARY))); mBodyText.setText(cursor.getString(cursor .getColumnIndexOrThrow(TodoTable.COLUMN_DESCRIPTION)));
vogella.com
Tutorials
Training
Books
Shop
Contact us
<?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="de.vogella.android.todos" android:versionCode="1" android:versionName="1.0" > <uses-sdk android:minSdkVersion="15" /> <application android:icon="@drawable/icon" android:label="@string/app_name" > <activity android:name=".TodosOverviewActivity" 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=".TodoDetailActivity" android:windowSoftInputMode="stateVisible|adjustResize" > </activity> <provider android:name=".contentprovider.MyTodoContentProvider" android:authorities="de.vogella.android.todos.contentprovider" > </provider> </application> </manifest>
TodoDetailActivity
vogella.com
Tutorials
Training
Books
Shop
Contact us
adb shell
# Switch to the data directory cd /data/data # Our application cd de.vogella.android.todos # Switch to the database dir cd databases # Check the content ls # Assuming that there is a todotable file # connect to this table sqlite3 todotable.db
ListViews
ListActivities
db.beginTransaction(); try { for (int i= 0; i< values.lenght; i++){ // TODO prepare ContentValues object values db.insert(your_table, null, values); // In case you do larger updates yieldIfContededSafely() } db.setTransactionSuccessful(); } finally { db.endTransaction(); }
yieldIfContededSafely()
vogella.com
Tutorials
Training
Books
Shop
Contact us