1.1. Apa SQLite
SQLite
adalah database Open Source yang tertanam ke Android. SQLite
mendukung fitur database relasional standar seperti sintaks SQL, transaksi dan pernyataan siap. Selain itu hanya memerlukan sedikit memori pada saat runtime (sekitar 250 KByte).SQLite
mendukung tipe data TEXT
(mirip ke String di Jawa), INTEGER
(mirip dengan yang lama di Jawa) danREAL
(mirip dengan ganda di Java). Semua jenis lain harus dikonversi ke pada bidang ini sebelum menyimpannya dalam database. SQLite
sendiri tidak memvalidasi jika jenis ditulis untuk kolom sebenarnya dari jenis didefinisikan, Anda dapat menulis sebuah integer ke dalam kolom string.Informasi
lebih lanjut tentang SQLite tersedia di http://www.sqlite.org .
SQLite
tersedia pada setiap perangkat Android. Menggunakan SQLite
database di Android tidak memerlukan setup database atau administrasi. Anda menentukan SQL untuk bekerja dengan database dan database dikelola secara otomatis untuk Anda.Bekerja dengan database bisa lambat. Oleh karena itu dianjurkan untuk melakukan tugas tersebut di latar belakang, misalnya melalui
AsyncTask
.Jika aplikasi Anda menciptakan sebuah database database ini disimpan di direktori
DATA/data/APP_NAME/databases/FILENAME
. DATA
adalah jalan yangEnvironment.getDataDirectory()
mengembalikan, APP_NAME
adalah nama aplikasi Anda danFILENAME
adalah nama yang Anda berikan database selama penciptaan.Environment.getDataDirectory()
biasanya kembali kartu SD sebagai lokasi.
Sebuah
SQLite
database pribadi ke aplikasi yang menciptakan itu. Jika Anda ingin berbagi data dengan aplikasi lain Anda dapat menggunakan ContentProvider
. Jika data tidak dibagi biasanya lebih mudah untuk bekerja secara langsung dengan database. ContentProviders
bukan bagian dari tutorial ini.
Paket
android.database
berisi semua kelas umum untuk bekerja dengan database.android.database.sqlite
berisi kelas SQLite tertentu.
Untuk membuat dan meng-upgrade database dalam aplikasi Android Anda Anda biasanya subclass
Untuk primary key dari tabel database Anda selalu harus menggunakan identifier
Sebuah praktek terbaik adalah untuk menciptakan per meja kelas terpisah yang menentukan statis
SQLiteOpenHelper
. Di kelas ini, Anda perlu mengganti metode onCreate()
untuk membuat database danonUpgrade()
untuk meng-upgrade database dalam kasus perubahan dalam skema database. Kedua metode menerima SQLiteDatabase
objek yang mewakili database.SQLiteOpenHelper
menyediakan metode getReadableDatabase()
dan getWriteableDatabase()
untuk mendapatkan akses ke SQLiteDatabase
objek yang memungkinkan akses database baik dalam membaca atau menulis modus.Untuk primary key dari tabel database Anda selalu harus menggunakan identifier
_id
karena beberapa fungsi Android bergantung pada standar ini.Sebuah praktek terbaik adalah untuk menciptakan per meja kelas terpisah yang menentukan statis
onCreate()
dan onUpdate()
metode. Metode ini kemudian disebut dalam metode yang sesuai SQLiteOpenHelper
.Penerapan cara ini Anda SQLiteOpenHelper
tidak akan bisa besar bahkan jika Anda memiliki beberapa tabel.SQLiteDatabase
adalah kelas dasar untuk bekerja dengan SQLite
database di Android dan menyediakan metode untuk membuka, query, update dan menutup database. Lebih khusus SQLiteDatabase
menyediakaninsert()
, update()
dan delete()
metode. Para execSQL()
metode memungkinkan untuk mengeksekusi SQL secara langsung. Objek ContentValues
memungkinkan untuk mendefinisikan kunci / nilai untuk insert dan update. Kuncinya adalah kolom dan nilai adalah nilai untuk kolom ini.Query dapat dibuat melalui metode
rawQuery()
yang menerima SQL atau query()
yang menyediakan sebuah antarmuka untuk menentukan data yang dinamis atau SQLiteQueryBuilder
.Misalnya untuk menjalankan
rawQuery()
Anda dapat melakukan hal berikut:Kursor kursor = getReadableDatabase () rawQuery ("* pilih dari todo mana = _id?", New String [] {id}).;
Metode
query()
memiliki parameter berikut.String dbName
- Nama tabel untuk mengkompilasi query terhadapint[] columnNames
- Sebuah daftar yang kolom untuk kembali. Melewati null akan mengembalikan semua kolom.String whereClause
- Filter untuk pemilihan data tanpa "MANA" klausa, null akan memilih semuaselectionArgs
Anda mungkin termasuk s di whereClause, yang akan digantikan oleh nilai-nilai dari selectionArgs?.String[] groupBy - A filter declaring how to group rows, null will cause the rows to not be grouped.
String[] having
- Filter untuk goups, nol berarti tidak ada filterString[] orderBy - row which will be used to order the data, null means no ordering
Jika semua data harus dipilih, Anda dapat melewati
null
sebagai klausa mana. Klausul mana ditentukan tanpawhere
, misalnya _id=19 and summary=?
. Jika beberapa nilai yang diperlukan melalui ?
Anda melewatkan mereka dalam array valuesForWhereClause untuk query. Secara umum, jika ada sesuatu yang tidak diperlukan Anda dapat melewati null
, misalnya untuk kelompok dengan klausa.Misalnya untuk menjalankan
query()
Anda dapat melakukan hal berikut:kembali database.query (DATABASE_TABLE, new String [] {KEY_ROWID, KEY_CATEGORY, KEY_SUMMARY, KEY_DESCRIPTION}, null, null, null, null, null);
Sebuah permintaan selalu mengembalikan
Untuk mendapatkan jumlah elemen menggunakan metode
Kursor dapat langsung digunakan melalui
Cursor
. Kursor mewakili hasil dari query dan pada dasarnya poin selalu satu baris dari database. Dengan cara ini Android dapat buffer hasil efisien karena tidak harus memuat semua data ke dalam memori.Untuk mendapatkan jumlah elemen menggunakan metode
getCount()
. Untuk beralih di antara baris data individu, Anda dapat menggunakan metode moveToFirst()
dan moveToNext()
. Melalui metodeisAfterLast()
Anda dapat memeriksa apakah masih ada beberapa data.Kursor dapat langsung digunakan melalui
SimpleCursorAdapter
di ListViews
.
Hal ini dimungkinkan untuk mengakses database SQLite pada emulator atau perangkat berakar melalui baris perintah. Untuk menggunakan ini
adb shell
untuk menghubungkan ke perangkat dan perintah "sqlite3" untuk menghubungkan ke database yang.
Berikut ini mengasumsikan bahwa Anda memiliki pengetahuan dasar dalam pembangunan sudah Android. Silakan periksa tutorial pengembangan Android untuk mempelajari dasar-dasar.
Kita akan membuat aplikasi Todo yang memungkinkan pengguna untuk mempertahankan tugas untuk dirinya sendiri. Item ini akan disimpan dalam
Aplikasi ini akan terdiri dari dua
Aplikasi yang dihasilkan akan terlihat seperti berikut.
SQLite
database.Aplikasi ini akan terdiri dari dua
Activities
, satu untuk melihat daftar semua item agenda dan satu untuk membuat / mempertahankan todo tertentu. Kedua Activities
akan berkomunikasi melalui Intents
.Aplikasi yang dihasilkan akan terlihat seperti berikut.
Buat proyek
Buat paket
de.vogella.android.todos
dengan aktivitas TodosOverview
. Buat kegiatan lainTodoDetails
.Buat paket
de.vogella.android.todos.database
. Paket ini akan menyimpan kelas untuk penanganan database.
Kita akan menciptakan sebuah kelas terpisah untuk menciptakan dan memperbarui
Buat berikut
Berdasarkan kelas pembantu kita dapat menulis kelas
todo
meja.paket de.vogella.android.todos.database; android.database.sqlite.SQLiteDatabase impor; android.util.Log impor; public class TodoTable { / / Database penciptaan pernyataan SQL DATABASE_CREATE private String statis akhir = "membuat tabel todo" + "(_id Bulat autoincrement kunci utama," + "Kategori teks tidak null," + "ringkasan teks tidak null," + "Deskripsi teks tidak null);"; public static void OnCreate (SQLiteDatabase database) { database.execSQL (DATABASE_CREATE); } public static void onUpgrade (SQLiteDatabase database, oldVersion int, newVersion int) { Log.w (kelas TodoTable. getName (.), "Upgrade database dari versi" + OldVersion + "untuk" + newVersion + ", Yang akan menghancurkan semua data lama"); database.execSQL ("DROP TABLE IF EXISTS todo"); OnCreate (database); } }
Buat berikut
TodoDatabaseHelper
kelas.paket de.vogella.android.todos.database; android.content.Context impor; android.database.sqlite.SQLiteDatabase impor; android.database.sqlite.SQLiteOpenHelper impor; public class TodoDatabaseHelper meluas SQLiteOpenHelper { private static final String database_name = "applicationdata"; private static final int DATABASE_VERSION = 1; publik TodoDatabaseHelper (konteks Konteks) { super (konteks, database_name, nol, DATABASE_VERSION); } / / Metode disebut selama pembuatan database @ Override public void OnCreate (SQLiteDatabase database) { TodoTable.onCreate (database); } / / Metode disebut selama upgrade dari database, / / Misalnya jika Anda meningkatkan versi database @ Override public void onUpgrade (SQLiteDatabase database, oldVersion int, newVersion int) { TodoTable.onUpgrade (database, oldVersion, newVersion); } }
Berdasarkan kelas pembantu kita dapat menulis kelas
TodoDbAdapter
yang akan menyediakan fungsionalitas untuk query, membuat dan memperbarui todos. Metode open()
akan membuka database melalui kelas pembantu.Untuk memperbarui dan menciptakan nilai-nilai kita menggunakan android.content.ContentValues
kelas.Kelas ini memungkinkan untuk menyimpan kunci / nilai. Anda menggunakan nama kolom sebagai kunci dalamContentValues
dan lulus objek dengan metode memasukkan atau memperbarui database Anda.paket de.vogella.android.todos.database; android.content.ContentValues impor; android.content.Context impor; android.database.Cursor impor; android.database.SQLException impor; android.database.sqlite.SQLiteDatabase impor; public class TodoDbAdapter { / / Database bidang public static final String KEY_ROWID = "_id"; public static final String KEY_CATEGORY = "kategori"; KEY_SUMMARY public String statis akhir = "ringkasan"; KEY_DESCRIPTION public String statis akhir = "description"; private static final String DB_TABLE = "todo"; Konteks swasta konteks; swasta SQLiteDatabase db; swasta TodoDatabaseHelper dbHelper; publik TodoDbAdapter (konteks Konteks) { konteks ini = konteks.; } TodoDbAdapter publik terbuka () throws SQLException { dbHelper = baru TodoDatabaseHelper (konteks); db = dbHelper.getWritableDatabase (); kembali ini; } public void close () { dbHelper.close (); }/ ** * Buat agenda baru Jika todo tersebut berhasil diciptakan kembali yang baru * Rowid untuk dicatat bahwa, jika tidak kembali -1 untuk mengindikasikan kegagalan. * /publik yang panjang createTodo (String kategori, ringkasan String, deskripsi String) { ContentValues nilai = createContentValues (kategori, ringkasan, deskripsi); kembali db.insert (DB_TABLE, null, nilai); }/ ** * Update todo * /public boolean updateTodo (rowid panjang, kategori String, ringkasan String, String deskripsi) { ContentValues nilai = createContentValues (kategori, ringkasan, deskripsi); kembali db.update (DB_TABLE, nilai, KEY_ROWID + "=" + rowid, null)> 0; }/ ** * Menghapus todo * /public boolean deleteTodo (rowid panjang) { kembali db.delete (DB_TABLE, KEY_ROWID + "=" + rowid, null)> 0; }/ ** * Kembali kursor atas daftar semua todo dalam database * * @ Return kursor atas semua catatan * /publik kursor fetchAllTodos () { kembali db.query (DB_TABLE String, baru [] {KEY_ROWID, KEY_CATEGORY, KEY_SUMMARY, KEY_DESCRIPTION}, null, null, null, null, null); }/ ** * Kembali kursor diposisikan di todo didefinisikan * /publik kursor fetchTodo (rowid panjang) throws SQLException { MCursor kursor = db.query (benar, DB_TABLE, baru String [] {KEY_ROWID, KEY_CATEGORY, KEY_SUMMARY, KEY_DESCRIPTION}, KEY_ROWID + "=" + Rowid, null, null, null, null, null); jika (mCursor = null) { mCursor.moveToFirst (); } kembali mCursor; } swasta ContentValues createContentValues (String kategori, ringkasan String, String deskripsi) { Nilai ContentValues = baru ContentValues (); values.put (KEY_CATEGORY, kategori); values.put (KEY_SUMMARY, ringkasan); values.put (KEY_DESCRIPTION, deskripsi); kembali nilai-nilai; } }
Buat membuat beberapa sumber daya yang nanti akan kita gunakan.
Juga mendefinisikan menu
Untuk prioritas kita membuat sebuah array string. Buat
Kami menciptakan sumber daya lain untuk string lain dalam aplikasi kita. Mengedit
Juga mendefinisikan menu
listmenu.xml
yang kemudian akan menggunakan membuat todo baru."1.0" encoding = "utf-8"??>
Untuk prioritas kita membuat sebuah array string. Buat
priority.xml
bawah res/values
."1.0" encoding = "utf-8"??>"priorities"> - Mendesak
- Pengingat
Kami menciptakan sumber daya lain untuk string lain dalam aplikasi kita. Mengedit
strings.xml
bawahres/values
."1.0" encoding = "utf-8"??>"hello"> Hello World, Todo!"app_name"> Todo"no_todos"> Saat ini tidak ada item Todo dipertahankan"menu_insert"> Tambahkan Item"menu_delete"> Hapus Todo"todo_summary"> Ringkasan"todo_description"> Hapus Todo"todo_edit_summary"> Ringkasan"todo_edit_description"> Deskripsi"todo_edit_confirm"> Konfirmasi"listcolor"> # FFE87C"black"> # 000000
Kami ditetapkan tiga layout, satu untuk daftar, satu untuk deretan daftar dan satu untuk pemeliharaan dari todo individu.
Harap dicatat bahwa tata letak baris mengacu pada ikon. Silahkan ganti dengan icon pilihan Anda.
Buat layout
Tempel sebuah ikon
Membuat tata letak
Akhirnya mengubah pengkodean dari aktivitas Anda untuk mengikuti. Pertama
Dan kemudian
Yang dihasilkan
Harap dicatat bahwa tata letak baris mengacu pada ikon. Silahkan ganti dengan icon pilihan Anda.
Buat layout
todo_list.xml
. Tata letak ini akan menentukan bagaimana daftar tampak seperti."1.0" encoding = "utf-8"??>"http://schemas.android.com/apk/res/android" android: layout_width = "fill_parent" android: layout_height = "fill_parent" android: latar belakang = "@ warna / listcolor" android: Orientasi = "vertikal">android: id = "@ android: id / daftar" android: layout_width = "wrap_content" android: layout_height = "wrap_content"> android: id = "@ android: id / kosong" android: layout_width = "wrap_content" android: layout_height = "wrap_content" android: teks = "@ string / no_todos" />
Tempel sebuah ikon
reminder
ke dalam res/layout
folder yang akan digunakan dalam tata letak berikutnya.Atau menghapus ikon dari tata letak baris. Setelah itu membuat tata letak todo_row.xml
yang akan digunakan untuk layout dari sebuah baris individu. ."1.0" encoding = "utf-8"??>"http://schemas.android.com/apk/res/android" android: layout_width = "fill_parent" android: layout_height = "wrap_content">android: id = "@ + id / ikon" android: layout_width = "30px" android: layout_height = "40px" android: layout_marginLeft = "4px" android: layout_marginRight = "8px" android: layout_marginTop = "8px" android: src = "@ ditarik / pengingat"> android: id = "@ + id / label" android: layout_width = "fill_parent" android: layout_height = "wrap_content" android: layout_marginTop = "6px" android: baris = "1" android: teks = "@ + id/TextView01" android: textColor = "@ warna / hitam" android: textSize = "40px">
Membuat tata letak
todo_edit
. Tata letak ini akan digunakan kemudian untuk menampilkan dan mengedit todo individu."1.0" encoding = "utf-8"??>"http://schemas.android.com/apk/res/android" android: layout_width = "fill_parent" android: layout_height = "fill_parent" android: latar belakang = "@ warna / listcolor" android: Orientasi = "vertikal">android: id = "@ + id / kategori" android: layout_width = "wrap_content" android: layout_height = "wrap_content" android: entri = "@ array / prioritas"> android: id = "@ + id/LinearLayout01" android: layout_width = "fill_parent" android: layout_height = "wrap_content"> android: id = "@ + id / todo_edit_summary" android: layout_width = "wrap_content" android: layout_height = "wrap_content" android: layout_weight = "1" android: petunjuk = "Ringkasan" android: imeOptions = "actionNext"> android: id = "@ + id / todo_edit_description" android: layout_width = "fill_parent" android: layout_height = "fill_parent" android: layout_weight = "1" android: gravitasi = "top" android: petunjuk = "Deskripsi" android: imeOptions = "actionNext"> android: id = "@ + id / todo_edit_button" android: layout_width = "wrap_content" android: layout_height = "wrap_content" android: teks = "@ string / todo_edit_confirm">
Akhirnya mengubah pengkodean dari aktivitas Anda untuk mengikuti. Pertama
TodoOverview.java
.paket de.vogella.android.todos; android.app.ListActivity impor; android.content.Intent impor; android.database.Cursor impor; android.os.Bundle impor; android.view.ContextMenu impor; android.view.ContextMenu.ContextMenuInfo impor; android.view.Menu impor; android.view.MenuInflater impor; android.view.MenuItem impor; android.view.View impor; android.widget.AdapterView.AdapterContextMenuInfo impor; android.widget.ListView impor; android.widget.SimpleCursorAdapter impor; de.vogella.android.todos.database.TodoDbAdapter impor; public class TodosOverview meluas ListActivity { swasta TodoDbAdapter dbHelper; private static int ACTIVITY_CREATE akhir = 0; private static final int ACTIVITY_EDIT = 1; private static final int DELETE_ID = Menu.FIRST + 1; swasta kursor kursor;/ ** Disebut ketika aktivitas tersebut pertama kali diciptakan. * /@ Override public void OnCreate (Bundle savedInstanceState) { Super OnCreate (savedInstanceState).; setContentView (R.layout.todo_list); .. ini getListView () setDividerHeight (2); dbHelper = baru TodoDbAdapter (ini); dbHelper.open (); fillData (); registerForContextMenu (getListView ()); } / / Buat menu berdasarkan Defintion XML @ Override public boolean onCreateOptionsMenu (menu Menu) { MenuInflater inflater = getMenuInflater (); inflater.inflate (R.menu.listmenu, menu); kembali benar; } / / Reaksi terhadap pilihan menu @ Override public boolean onMenuItemSelected (int featureId, MENUITEM item) { switch (item.getItemId ()) { kasus R.id.insert: createTodo (); kembali benar; } Super kembali onMenuItemSelected (featureId, item).; } @ Override public boolean onOptionsItemSelected (MENUITEM item) { switch (item.getItemId ()) { kasus R.id.insert: createTodo (); kembali benar; } Super kembali onOptionsItemSelected (item).; } @ Override public boolean onContextItemSelected (MENUITEM item) { switch (item.getItemId ()) { kasus DELETE_ID: Info AdapterContextMenuInfo = (AdapterContextMenuInfo) item GetMenuInfo ();. dbHelper.deleteTodo (info.id); fillData (); kembali benar; } Super kembali onContextItemSelected (item).; } private void createTodo () { Intent i = new Intent (ini, TodoDetails kelas.); startActivityForResult (i, ACTIVITY_CREATE); } / / ListView dan tampilan (baris) yang di atasnya diklik, posisi dan @ Override void dilindungi onListItemClick (ListView l, v Lihat, int posisi, panjang id) { . Super onListItemClick (l, v, posisi, id); Intent i = new Intent (ini, TodoDetails kelas.); i.putExtra (TodoDbAdapter.KEY_ROWID, id); / / Kegiatan mengembalikan hasilnya jika disebut dengan startActivityForResult startActivityForResult (i, ACTIVITY_EDIT); } / / Disebut dengan hasil dari kegiatan lain / / RequestCode adalah Permintaan kode asal kirim ke aktivitas / / ResultCode adalah kode kembali, 0 adalah semuanya ok / / Berniat dapat digunakan untuk mendapatkan beberapa data dari pemanggil @ Override void dilindungi onActivityResult (int requestCode, int resultCode, Niat niat) { Super onActivityResult (requestCode, resultCode, niat).; fillData (); } private void fillData () { kursor = dbHelper.fetchAllTodos (); startManagingCursor (kursor); String [] from = new String [] {} TodoDbAdapter.KEY_SUMMARY; int [] untuk = new int [] {} R.id.label; / / Sekarang membuat adaptor array dan set ke tampilan menggunakan baris kami SimpleCursorAdapter catatan = baru SimpleCursorAdapter (ini, R.layout.todo_row, kursor, dari, ke); setListAdapter (catatan); } @ Override public void onCreateContextMenu (ContextMenu menu, Lihat v, ContextMenuInfo menuInfo) { Super onCreateContextMenu (menu, v, menuInfo).; menu.add (0, DELETE_ID, 0, R.string.menu_delete); } @ Override void dilindungi onDestroy () { . Super onDestroy (); jika (dbHelper = null) { dbHelper.close (); } } }
Dan kemudian
TodoDetails.java
paket de.vogella.android.todos; android.app.Activity impor; android.database.Cursor impor; android.os.Bundle impor; android.util.Log impor; android.view.View impor; android.widget.Button impor; android.widget.EditText impor; android.widget.Spinner impor; de.vogella.android.todos.database.TodoDbAdapter impor; TodoDetails kelas publik meluas Aktivitas { swasta EditText mTitleText; swasta EditText mBodyText; pribadi yang panjang mRowId; swasta TodoDbAdapter mDbHelper; Spinner mCategory swasta; @ Override void dilindungi OnCreate (bundel Bundle) { Super OnCreate (bundel).; mDbHelper = baru TodoDbAdapter (ini); mDbHelper.open (); setContentView (R.layout.todo_edit); mCategory = (Spinner) findViewById (R.id.category); mTitleText = (EditText) findViewById (R.id.todo_edit_summary); mBodyText = (EditText) findViewById (R.id.todo_edit_description); Tombol confirmButton = (Button) findViewById (R.id.todo_edit_button); mRowId = null; . Bundel tambahan = getIntent () getExtras (); mRowId = (bundel == null)? nol: (Panjang) bundel GetSerializable (TodoDbAdapter.KEY_ROWID).; jika (tambahan = null) { mRowId = extras.getLong (TodoDbAdapter.KEY_ROWID); } populateFields (); confirmButton.setOnClickListener (baru View.OnClickListener () { public void onClick (Tampilan) { setResult (RESULT_OK); menyelesaikan (); } }); } private void populateFields () { jika (mRowId = null) { Kursor todo = mDbHelper.fetchTodo (mRowId); startManagingCursor (todo); String kategori = todo.getString (todo GetColumnIndexOrThrow (TodoDbAdapter.KEY_CATEGORY));. for (int i = 0; iString s = (String) mCategory.getItemAtPosition (i); Log.e (null, s + "" + kategori); jika (s.equalsIgnoreCase (kategori)) { mCategory.setSelection (i); } } mTitleText.setText (todo.getString (todo GetColumnIndexOrThrow (TodoDbAdapter.KEY_SUMMARY))).; mBodyText.setText (todo.getString (todo GetColumnIndexOrThrow (TodoDbAdapter.KEY_DESCRIPTION))).; } } void dilindungi onSaveInstanceState (Bundle outState) { Super onSaveInstanceState (outState).; saveState (); outState.putSerializable (TodoDbAdapter.KEY_ROWID, mRowId); } @ Override void dilindungi onPause () { . Super onPause (); saveState (); } @ Override void dilindungi onResume () { . Super onResume (); populateFields (); } private void saveState () { Kategori string = (String) mCategory.getSelectedItem (); . Ringkasan String = mTitleText.getText () toString (); String deskripsi = mBodyText.getText () toString ().; jika (mRowId == null) { lama id = mDbHelper.createTodo (kategori, ringkasan, deskripsi); jika (id> 0) { mRowId = id; } } Else { mDbHelper.updateTodo (mRowId, kategori, ringkasan, deskripsi); } } }
Yang dihasilkan
AndroidManifest.xml
terlihat seperti berikut."1.0" encoding = "utf-8"??>"http://schemas.android.com/apk/res/android" paket = "de.vogella.android.todos" android: versionCode = "1" android: versionName = "1.0">android: icon = "@ ditarik / todo" android: label = "@ string / APP_NAME"> android: label = "@ string / APP_NAME" android: nama = ". TodosOverview"> "android.intent.action.MAIN" />"android.intent.category.LAUNCHER" />android: nama = ". TodoDetails" android: windowSoftInputMode = "stateVisible | adjustResize"> android: Pemerintah = "de.vogella.android.todos.provider" android: nama = "MyTodoContentProvider"> "9" />