Download - 1 Mobile Computing DataBase and Content Providers Copyright 2014 by Janson Industries EC AssgAssg
1
Mobile ComputingDataBase and Content Providers
Copyright 2014 by Janson Industries
EC AssgAssg
Copyright 2014 by Janson Industries2
Objectives▀ Explain
SQLite
Data Encapsulation
Content providers
Permissions
Copyright 2014 by Janson Industries3
▀ DataBase Management System that comes with Android
▀ A database consists of many tables
▀ Tables hold data
In rows/columns (records/fields)
SQLite
Copyright 2014 by Janson Industries4
▀ To create and manipulate databases and tables, use:
Standard SQL commands
Specialized Android object’s►SQLiteDatabase►SQLiteOpenHelper►Cursor►ContentValues
SQLite
Copyright 2014 by Janson Industries5
SQLite▀ Will create a To Do List
application
▀ Will allow To Do List items to be entered, displayed, and edited
▀ Will use the Contacts content provider that comes with Android to provide responsible names
More on this a little later
Copyright 2014 by Janson Industries6
To Do List▀ Will display an initial screen that allows
user to select the function to be performed Insert a to do list item Display a to do list item End to do list app
▀ If insert, user specifies Priority (1,2,3) To do item text Due date Responsible person
Copyright 2014 by Janson Industries7
Copyright 2014 by Janson Industries8
Copyright 2014 by Janson Industries9
To Do List▀ If display
Will display all items text
If user clicks on a item’s text, an edit screen with all the item info will be displayed
▀ Will also display a toast with a success message after inserts and updates
Copyright 2014 by Janson Industries10
Copyright 2014 by Janson Industries11
Displays all the item info and allow changes
Copyright 2014 by Janson Industries12
To Do List
▀ Create a new Android 2.2 project called DBProj
App called ToDoList
Package is my.tdl.com
Activity is Main, layout is main
Copyright 2014 by Janson Industries13
To Do List Change Main.java to be an Activity not ActionBarActivity
In manifest, change the application theme
: : : : : : : android:theme="@android:style/Theme.Black"
: : : : : : :
//import android.support.v7.app.ActionBarActivity;import android.app.Activity;
: : : : :public class Main extends Activity {
Copyright 2014 by Janson Industries
<?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" ><TextView android:layout_width="fill_parent" android:layout_height="wrap_content" android:text="Choose the function to perform" android:textSize="35sp" /> <CheckBox android:id="@+id/insertCB" android:text="Insert"
android:onClick="clickHandler" android:layout_width="wrap_content"android:layout_height="wrap_content" android:textSize="25sp"/>
<CheckBox android:id="@+id/displayCB" android:text="Display"android:onClick="clickHandler" android:layout_width="wrap_content"android:layout_height="wrap_content" android:textSize="25sp"/>
<CheckBox android:id="@+id/finishedCB" android:text="End App"android:onClick="clickHandler" android:layout_width="wrap_content"android:layout_height="wrap_content" android:textSize="25sp"/>
</LinearLayout>
14
main.xml
Copyright 2014 by Janson Industries15
Test by running in emulator
Copyright 2014 by Janson Industries16
To Do List▀ When insert clicked, the
Specify To Do List Task screen will be displayed to collect the info
▀ When Insert button clicked A row with the info will be inserted
into a table named task
The Insert/Display/End App screen redisplayed
Copyright 2014 by Janson Industries17
Copyright 2014 by Janson Industries
<?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:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center_horizontal" android:gravity="center_vertical" android:text="Specify a To Do List Task" android:textSize="20sp" />
<LinearLayout android:layout_width="wrap_content" android:layout_height="wrap_content" android:orientation="horizontal" >
<TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center_vertical" android:gravity="center_vertical" android:text="Enter the task " android:textSize="15sp" />
<EditText android:id="@+id/task" android:layout_width="fill_parent" android:layout_height="wrap_content" android:layout_gravity="center" android:text="" android:width="300px"/></LinearLayout>
<LinearLayout android:layout_width="wrap_content" android:layout_height="wrap_content" android:orientation="horizontal" >
<TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center_vertical" android:text="Enter a priority of 1, 2, or 3 " android:textSize="15sp"/>
<EditText android:id="@+id/priority" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center" android:text=" " /></LinearLayout>
<LinearLayout android:layout_width="wrap_content" android:layout_height="wrap_content" android:orientation="horizontal" >
<TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center_vertical" android:gravity="center_vertical" android:text="Enter a due date as YYYY/MM/DD " android:textSize="15sp"/>
<EditText android:id="@+id/DueDate" android:layout_width="fill_parent" android:layout_height="wrap_content" android:layout_gravity="center" android:text="" android:width="150px" /></LinearLayout>
<Button android:id="@+id/insert" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Insert" android:onClick="onClick" android:layout_gravity="center_horizontal"/></LinearLayout>
18
insert.xml
Copyright 2014 by Janson Industries19
Insert and Display Stubspackage my.tdl.com;import android.app.Activity;import android.os.Bundle; public class Insert extends Activity { public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.insert); }}
package my.tdl.com;import android.app.Activity;import android.os.Bundle;
public class Display extends Activity {public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);}
}
Copyright 2014 by Janson Industries20
Mainpackage my.tdl.com;import android.app.Activity;import android.content.Intent;import android.os.Bundle;import android.view.View;import android.widget.CheckBox;import android.widget.TextView;
public class Main extends Activity {Intent intent;String actionName;@Override
public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); } protected void onResume() { super.onResume();
CheckBox icb = (CheckBox) findViewById(R.id.insertCB);CheckBox dcb = (CheckBox) findViewById(R.id.displayCB);
/** Erases any checks in the check boxes. */icb.setChecked(false);dcb.setChecked(false);
}
Copyright 2014 by Janson Industries21
Main public void clickHandler(View target) { switch(target.getId()) { case R.id.insertCB:
actionName = "my.tdl.com.Insert";intent = new Intent(actionName);
startActivity(intent); break; case R.id.displayCB:
actionName = "my.tdl.com.Display";intent = new Intent(actionName);
startActivity(intent); break; case R.id.finishedCB: finish(); break; } } }
Copyright 2014 by Janson Industries22
Manifest<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="my.tdl.com" android:versionCode="1" android:versionName="1.0" >
<uses-sdk android:minSdkVersion="8" android:targetSdkVersion="21" />
<application android:allowBackup="true" android:icon="@drawable/ic_launcher" android:label="@string/app_name" android:theme="@android:style/Theme.Black" > <activity android:name=".Main" android:label="@string/app_name"> <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity>
Copyright 2014 by Janson Industries23
Manifest
<activity android:name="Insert" android:label="Insert To Do List Task"android:theme="@android:style/Theme.Black"><intent-filter> <action android:name="my.tdl.com.Insert" />
<category android:name="android.intent.category.DEFAULT" /></intent-filter>
</activity>
<activity android:name="Display" android:label="Display To Do List Tasks"android:theme="@android:style/Theme.Black"><intent-filter>
<action android:name="my.tdl.com.Display" /><category android:name="android.intent.category.DEFAULT" />
</intent-filter></activity></application></manifest>
Activity definitions for Insert and Display
Copyright 2014 by Janson Industries24
To Do List
▀ Run the program
▀ Click Insert check box
▀ Make sure the Insert screen is displayed
Copyright 2014 by Janson Industries25
Copyright 2014 by Janson Industries28
SQLite▀ Need to create the ToDoList data
base and the tasks table
▀ The structure of the tasks table is: _id INTEGER PRIMARY KEY
Task TEXT
Priority TEXT
CreatedDate TEXT
DueDate TEXT
Responsible TEXT
Copyright 2014 by Janson Industries29
SQLite▀ Need a java program to create
the DB
A folder called databases will be created in data/data/my.tdl.com on the device/emulator
The DB will be stored in the databases folder
▀ After created, can see the DB in the DDMS perspective
Copyright 2014 by Janson Industries30
SQLite▀ To create DB, create Java class
(ToDoListDBHelper) as a subclass of SQLiteOpenHelper
It’s constructor will call SQLiteOpenHelper’s constructor
If the DB doesn’t exist, SQLiteOpenHelper’s constructor will call it’s own onCreate method
►onCreate will create the DB
Copyright 2014 by Janson Industries31
SQLite▀ SQLiteOpenHelper does all the
"heavy lifting"
No only creates the DB, will provide a "writable" version of the DB for our app to use
▀ ToDoListDBHelper must code an onUpgrade method
Copyright 2014 by Janson Industries32
ToDoListDBHelperpackage my.tdl.com;
import android.content.Context;import android.database.sqlite.SQLiteDatabase;import android.database.sqlite.SQLiteOpenHelper;
public class ToDoListDBHelper extends SQLiteOpenHelper {
// Variables to hold metadata about the DB and task table protected static final String DATABASE_NAME = "ToDoList";protected static final int DATABASE_VERSION = 1;protected final static String TASK_FN = "Task";protected final static String PRI_FN = "Priority";protected final static String CREATE_FN = "CreatedDate";protected final static String DUE_FN = "DueDate";protected final static String RESP_FN = "Responsible";protected final static String COMP_FN = "CompletionDate";
Copyright 2014 by Janson Industries33
ToDoListDBHelper
// This SQL statement that will create the table private static final String TABLE_CREATE =
"create table TasksTable (" +"_id integer primary key autoincrement, " +
TASK_FN + " text, " + PRI_FN + " text, " + CREATE_FN + " text, " + DUE_FN + " text, " + RESP_FN + " text, " + COMP_FN + " text);";
Copyright 2014 by Janson Industries34
ToDoListDBHelperpublic ToDoListDBHelper(Context context) {
// Creates the databasesuper(context, DATABASE_NAME, null, DATABASE_VERSION);
}
public void onCreate(SQLiteDatabase db) {
// Creates the tasks tabledb.execSQL(TABLE_CREATE);
}
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
}
}
Copyright 2014 by Janson Industries 35
Encapsulation Many terms used to describe:
Transparency
Information hiding
Implementation ignorance
Programmers have an “interface” to an object with no idea of how it works
Copyright 2014 by Janson Industries 36
Encapsulation For example, driving a car
Someone knows how to drive: Turn the key Step on gas pedal Steer Step on brake pedal
The driver doesn’t have to know how the car works or any of its internal components
Copyright 2014 by Janson Industries37
Encapsulation Many methods and data are
hidden from the user/ application
Changes to the class (variables and methods) do not affect users of the class
Data accessible only through publicly defined methods
Copyright 2014 by Janson Industries 38
Data Encapsulation
DATA
Getters
SettersRules
Constructors
Copyright 2014 by Janson Industries 39
Encapsulation If programmers can’t directly
access the data, their applications are less likely to screw it up!!
PUBLIC methods comprise the interface
PRIVATE methods for internal functions and non-user fields
Copyright 2014 by Janson Industries 40
How to Encapsulate a File Define a class for the file (ex.
TasksTable)
In the class, define private variables for each field in the file
For each private variable: Define a getter method Define a setter with validation
functions
Define CRUD functions
Copyright 2014 by Janson Industries 41
How to Encapsulate a File Define unique functions to return
data
All tasks for a particular person
All tasks for a certain priority
Define business functions
Number of tasks closed by day
Number of tasks opened by day
Copyright 2014 by Janson Industries
Define a private variable for each field
42
TasksTable
private int ID;private String Task;private String Priority;private String CreatedDate;private String DueDate;private String Responsible;private String CompletionDate;
Copyright 2014 by Janson Industries43
TasksTable
public int getID() { return ID; }public void setID(int iD) { ID = iD; } // Need for updatespublic String getTask() { return Task; }public void setTask(String task) { Task = task; }public String getPriority() { return Priority; }public void setPriority(String priority) { Priority = priority;}public String getCreatedDate() { return CreatedDate; }public void setCreatedDate(String createdDate) {
CreatedDate = createdDate;}public String getDueDate() { return DueDate; }public void setDueDate(String dueDate) { DueDate = dueDate;}public String getResponsible() { return Responsible; }public void setResponsible(String responsible) {
Responsible = responsible;}public String getCompletionDate() {return CompletionDate; }public void setCompletionDate(String completionDate) {
CompletionDate = completionDate; }
Define getters and setters
Copyright 2014 by Janson Industries
Create pretty easy, plus it creates the helper class that…
…supplies the ToDoList DB (a SQLite DB) that we will read and write to
44
CRUD Functions
public TasksTable(Context ctx) {this.context = ctx;DBHelper = new ToDoListDBHelper(context);this.open();
}
public TasksTable open() throws SQLException { db = DBHelper.getWritableDatabase(); return this;}
Copyright 2014 by Janson Industries45
CRUD Functions
public long insert() { values.put(TASK_FN, getTask()); values.put(PRI_FN, getPriority()); values.put(CREATE_FN, getCreatedDate()); values.put(DUE_FN, getDueDate()); values.put(RESP_FN, getResponsible()); values.put(COMP_FN, getCompletionDate()); return db.insert(DATABASE_TABLE, null, values);}
Insert and Update require a ContentValues object It holds the data to be inserted
Each data paired with the field name that will hold the data
Copyright 2014 by Janson Industries
Need some import statements
Also need some other variables
Let’s test
46
CRUD Functions
private SQLiteDatabase db;private Context context; private ToDoListDBHelper DBHelper;private ContentValues values = new ContentValues();private final String DATABASE_TABLE = "TasksTable";protected final String ID_FN = "ID";protected final String TASK_FN = "Task";protected final String PRI_FN = "Priority";protected final String CREATE_FN = "CreatedDate";protected final String DUE_FN = "DueDate";protected final String RESP_FN = "Responsible";protected final String COMP_FN = "CompletionDate";
package my.tdl.com;import android.content.ContentValues;import android.content.Context;import android.database.SQLException;import android.database.sqlite.SQLiteDatabase;
Copyright 2014 by Janson Industries
Time to test
Prove the insert works: Switch to the DDMS perspective
Click on emulator
Expand data/data
Scroll down and expand my.tdl.com No databases folder
47
To Do List
Copyright 2014 by Janson Industries48
No databases folder, just lib
Copyright 2014 by Janson Industries
Need to display Insert screen
When Insert button pressed need a java activity (insert) to: Read screen data
Create TasksTable object
Set the TasksTable object’s task, priority, and due date properties
Insert the data into the table
Display a success msg49
Insert
Copyright 2014 by Janson Industries
package my.tdl.com;
import android.app.Activity;import android.os.Bundle;import android.view.View;import android.view.View.OnClickListener;import android.widget.Button;import android.widget.EditText;import android.widget.Toast;
public class Insert extends Activity implements OnClickListener {TasksTable tt;EditText taskET, priorityET, dueDateET;long insertResult;
public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.insert); taskET = (EditText) findViewById(R.id.task); // get priorityET = (EditText) findViewById(R.id.priority); // GUI dueDateET = (EditText) findViewById(R.id.DueDate); // fields Button insertBtn = (Button) findViewById(R.id.insert); insertBtn.setOnClickListener(this); // add listener to button tt = new TasksTable(this); // create TasksTable object }
50
Insert
Copyright 2014 by Janson Industries51
Insertpublic void onClick(View target) {
// Set TasksTable properties tt.setTask(taskET.getText().toString()); tt.setPriority(priorityET.getText().toString()); tt.setDueDate(dueDateET.getText().toString());
// Insert the data insertResult = tt.insert();
// Build msg and display it in a toastString text = "The task '" + tt.getTask() +
" was added successfully! Return code was " + insertResult;int duration = Toast.LENGTH_LONG;Toast toast = Toast.makeText(this, text, duration);toast.show();
}}
Copyright 2014 by Janson Industries52
Copyright 2014 by Janson Industries53
Proof that it worked
Copyright 2014 by Janson Industries54
Need to return to the main menu after insert
After the toast is shown add finish();
For the example, I added a couple of other tasks
To Do List
Copyright 2014 by Janson Industries55
Allows you to download the DB
Select the DB and click the Pull a file from the device button
DDMS Perspecitive
Copyright 2014 by Janson Industries56
Copyright 2012 by Janson Industries57
Then specify where to store it
Copyright 2014 by Janson Industries58
SQLite browser lets you access and manipulate the DB
Copyright 2014 by Janson Industries59
http://web.fscj.edu/Janson/CIS2930
Download SQLite browser, unzip, run the exe file
Copyright 2014 by Janson Industries60
File, Open Database, specify ToDoListThen click Browse Data, select TasksTable
Copyright 2014 by Janson Industries61
Need a display function
Will display all tasks text
When a task is clicked, will allow user to update all the task info
To Do List
Copyright 2014 by Janson Industries62
Display all the tasks
Copyright 2014 by Janson Industries63
Display all task info and allow changes
Copyright 2014 by Janson Industries64
Going to need:
Read and update functions in TasksTable
Two new screen definitions display.xml edit.xml
Change Display.java to React to a click on a task Retrieve that tasks info from DB Invoke TaskEdit and pass DB info via
the bundle
To Do List
Copyright 2014 by Janson Industries65
Create TaskEdit.java to
Display the task info
Update the task
Display a confirmation of the update
Return back to the main menu
Add TaskEdit activity to manifest
To Do List
Copyright 2014 by Janson Industries66
Update works similarly to insert
Uses a ContentValues object to hold data
Uses the writable ToDoList db object (provided by ToDoListDBHelper)
New requirement: must identify the row to be updated
TasksTable Update
Copyright 2014 by Janson Industries67
Going to execute an SQL Select statement
Will use the writable db object’s rawQuery method to perform the Select statement
Returns the results in a Cursor object Essentially a table with rows and
columns
TasksTable Read
Copyright 2014 by Janson Industries68
TasksTableimport android.database.Cursor; : : : : :
public long update() { values.put(TASK_FN, getTask()); values.put(PRI_FN, getPriority()); values.put(CREATE_FN, getCreatedDate()); values.put(DUE_FN, getDueDate()); values.put(RESP_FN, getResponsible()); values.put(COMP_FN, getCompletionDate()); return db.update(DATABASE_TABLE, values, "_id = " + getID(), null ); }
public Cursor read() { return db.rawQuery("SELECT * FROM TasksTable ", null); }
Copyright 2014 by Janson Industries69
display.xml Create a ListView object called
list (holds list of scrollable items)
<?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"><ListView android:id="@+id/android:list"
android:layout_width="wrap_content"android:layout_height="wrap_content" />
<TextView android:id="@+id/taskTV" android:layout_width="wrap_content"
android:layout_height="wrap_content"android:textSize="30sp" />
</LinearLayout>
Copyright 2014 by Janson Industries70
edit.xml Initial LinearLayout and Textview
Followed by a series of horizontal LinearLayouts with components
<?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"><TextView android:layout_width="wrap_content"
android:layout_height="wrap_content" android:textSize="18sp"
android:text="" android:gravity="center_vertical"android:layout_gravity="center_horizontal" />
Copyright 2014 by Janson Industries71
<LinearLayout android:layout_width="wrap_content" android:layout_height="wrap_content"android:orientation="horizontal"><TextView android:layout_width="wrap_content"
android:layout_height="wrap_content" android:text="Change the task "
android:gravity="center_vertical" android:layout_gravity="center_vertical"
android:textSize="15sp" /><EditText android:id="@+id/taskET" android:text=""
android:layout_height="wrap_content" android:layout_width="fill_parent"android:layout_gravity="center" android:width="300px">
</EditText></LinearLayout>
For each db field will have text and an entry field
Copyright 2014 by Janson Industries72
<LinearLayout android:orientation="horizontal" android:layout_width="wrap_content"android:layout_height="wrap_content"><TextView android:layout_width="wrap_content"
android:layout_height="wrap_content"android:textSize="15sp"
android:text="Change the priority (1, 2, or 3) "android:layout_gravity="center_vertical" />
<EditText android:id="@+id/priorityET" android:layout_width="wrap_content"
android:layout_gravity="center" android:text=" "android:layout_height="wrap_content"></EditText>
</LinearLayout><LinearLayout android:layout_width="wrap_content"
android:layout_height="wrap_content"android:orientation="horizontal"><TextView android:layout_width="wrap_content"
android:layout_height="wrap_content" android:text="Change created date (YYYY/MM/DD) "android:gravity="center_vertical"
android:layout_gravity="center_vertical"android:textSize="15sp" />
<EditText android:id="@+id/createdDateET" android:text=""android:layout_height="wrap_content"
android:layout_width="fill_parent"android:layout_gravity="center"
android:width="150px"></EditText></LinearLayout>
Copyright 2014 by Janson Industries73
<LinearLayout android:layout_width="wrap_content" android:layout_height="wrap_content"android:orientation="horizontal"><TextView android:layout_width="wrap_content"
android:layout_height="wrap_content" android:text="Change due date (YYYY/MM/DD) "android:gravity="center_vertical" android:layout_gravity="center_vertical"android:textSize="15sp" />
<EditText android:id="@+id/dueDateET" android:text=""android:layout_height="wrap_content" android:layout_width="fill_parent"android:layout_gravity="center" android:width="150px"></EditText>
</LinearLayout><LinearLayout android:layout_width="wrap_content"
android:layout_height="wrap_content"android:orientation="horizontal"><TextView android:layout_width="wrap_content"
android:layout_height="wrap_content" android:text="Change/enter person assigned "android:gravity="center_vertical" android:layout_gravity="center_vertical"android:textSize="15sp" />
<EditText android:id="@+id/respET" android:text=""android:layout_height="wrap_content" android:layout_width="fill_parent"android:layout_gravity="center" android:width="150px"></EditText>
</LinearLayout>
edit.xml
Copyright 2014 by Janson Industries74
<LinearLayout android:layout_width="wrap_content" android:layout_height="wrap_content"android:orientation="horizontal"><TextView android:layout_width="wrap_content"
android:layout_height="wrap_content" android:text="Change/enter finished date (YYYY/MM/DD) "android:gravity="center_vertical" android:layout_gravity="center_vertical" android:textSize="15sp"/>
<EditText android:id="@+id/compDateET" android:text=""android:layout_height="wrap_content" android:layout_width="fill_parent"android:layout_gravity="center" android:width="150px"></EditText>
</LinearLayout>
<Button android:id="@+id/update" android:layout_width="wrap_content"android:layout_height="wrap_content" android:text="Update"android:onClick="onClick" android:layout_gravity="center_horizontal" />
</LinearLayout>
edit.xml
Copyright 2014 by Janson Industries75
Has to invoke TransTable’s read method
Read returns a Cursor object
Should make sure cursor is managed, startManagingCursor
i.e. Cursor automatically deleted when activity is finished
Display.java
Copyright 2014 by Janson Industries76
To move between records/rows and retrieve field data, use Cursor methods
To retrieve a field must know the column/field number
Will use a SimpleCursorAdapter to populate the list view
Adapters are classes that make managing list views way easier
Display.java
Copyright 2014 by Janson Industries77
Requires
The layout be identified
The Cursor object with the data
In a String array (we’ll call it from), the field(s) in the cursor object that are to be retrieved
In an int array (we’ll call it to), the project ids of the GUI component(s) that will display the retrieved data
SimpleCursorAdapter
Copyright 2014 by Janson Industries78
package my.tdl.com;
import android.app.Activity;import android.app.ListActivity;import android.widget.SimpleCursorAdapter;import android.content.Intent;import android.database.Cursor;import android.os.Bundle;import android.view.View;import android.widget.EditText;import android.widget.ListView;import android.widget.TextView;
public class Display extends ListActivity {// Various variables needed to display the list of tasksTextView taskTV;TasksTable tt;Cursor c;SimpleCursorAdapter taskAdapter;String[] from;int[] to;
Change Display.java
Copyright 2014 by Janson Industries
onCreate will show the current tasks
79
public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.display); // Display the list view from = new String[]{"Task"}; // Identify the task field as the source of data to = new int[]{R.id.taskTV}; // Identify taskTV as the target of the data tt = new TasksTable(this); // Create TasksTable object c = tt.read(); // Invoke the read method and store in c startManagingCursor(c); // Let system manage the c
// Create the SimpleCursorAdapter object taskAdapter = new SimpleCursorAdapter(this, R.layout.display, c, from, to); setListAdapter(taskAdapter); // Binds adapter to the listview in display layout }
Display.java
Copyright 2014 by Janson Industries
onListItemClick is passed both
The location in the list that was clicked
The associated DB record/row id for the clicked item
To read data must first position to the correct row with cursor’s moveToPosition method
c.moveToPosition(rowid);80
Display
Copyright 2014 by Janson Industries
Then for each field in the row, retrieve the column # with the cursor’s getColumnIndexOrThrow method
int colNum = c. getColumnIndexOrThrow(“fld_name”)
Lastly retrieve the field data with the getString method passing the column number
c.getString(colNum)
81
Display
Copyright 2014 by Janson Industries
Will create a TaskEdit intent and pass the DB data via the intent’s bundle
Mentioned a while ago that bundles used to pass info between activities
Today’s the day we do it
82
Display
Copyright 2014 by Janson Industries
Like the ContentValues object, bundle holds paired data
In this case, the name of the DB field and the value of the field
To write to the bundle use the intents putExtra method
83
Display
Copyright 2014 by Janson Industries84
protected void onListItemClick(ListView l, View v, int position, long id) { super.onListItemClick(l, v, position, id);
c.moveToPosition(position); //Position to correct row in cursor Intent i = new Intent(this, TaskEdit.class); //Create the edit intent i.putExtra("_id", id); //Populate the bundle with the task info
//Pass the field name to get the column number, which is used in getString to retrieve //the data from the cursor then the field name and data are written to the bundle i.putExtra(ToDoListDBHelper.TASK_FN, c.getString( c.getColumnIndexOrThrow(ToDoListDBHelper.TASK_FN))); i.putExtra(ToDoListDBHelper.PRI_FN, c.getString( c.getColumnIndexOrThrow(ToDoListDBHelper.PRI_FN))); i.putExtra(ToDoListDBHelper.CREATE_FN, c.getString( c.getColumnIndexOrThrow(ToDoListDBHelper.CREATE_FN))); i.putExtra(ToDoListDBHelper.DUE_FN, c.getString( c.getColumnIndexOrThrow(ToDoListDBHelper.DUE_FN))); i.putExtra(ToDoListDBHelper.RESP_FN, c.getString( c.getColumnIndexOrThrow(ToDoListDBHelper.RESP_FN))); i.putExtra(ToDoListDBHelper.COMP_FN, c.getString( c.getColumnIndexOrThrow(ToDoListDBHelper.COMP_FN))); startActivity(i); //Start the edit task finish(); //End the display task }}
Display.java
Copyright 2014 by Janson Industries85
package my.tdl.com;
import android.app.Activity;import android.os.Bundle;import android.view.View;import android.widget.Button;import android.widget.EditText;import android.widget.Toast;
public class TaskEdit extends Activity {EditText taskET, priorityET, createdDateET, dueDateET, respET, compDateET;Button updateBtn;long _id;String task, priority, createdDate, dueDate, responsible, completionDate;Bundle extras;TasksTable tt;
TaskEdit Create various variables needed
to display and edit task info
Copyright 2014 by Janson Industries86
protected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.edit);
// Retrieve visual components used to display info
taskET = (EditText) findViewById(R.id.taskET);priorityET = (EditText) findViewById(R.id.priorityET);createdDateET = (EditText) findViewById(R.id.createdDateET);dueDateET = (EditText) findViewById(R.id.dueDateET);respET = (EditText) findViewById(R.id.respET);compDateET = (EditText) findViewById(R.id.compDateET);
// Retrieve the button and the bundle
updateBtn = (Button) findViewById(R.id.update);extras = getIntent().getExtras();
TaskEdit
Copyright 2014 by Janson Industries87
// Get data from bundle and assign to string variables
_id = extras.getLong("_id");task = extras.getString(ToDoListDBHelper.TASK_FN);priority = extras.getString(ToDoListDBHelper.PRI_FN);createdDate = extras.getString(ToDoListDBHelper.CREATE_FN);dueDate = extras.getString(ToDoListDBHelper.DUE_FN);responsible = extras.getString(ToDoListDBHelper.RESP_FN);completionDate = extras.getString(ToDoListDBHelper.COMP_FN);
// Put task data into edit text components
taskET.setText(task);priorityET.setText(priority);createdDateET.setText(createdDate);dueDateET.setText(dueDate);respET.setText(responsible);compDateET.setText(completionDate);
}
TaskEdit
Copyright 2014 by Janson Industries88
public void onClick(View view) {// Create new TasksTable objecttt = new TasksTable(this);
// Set TasksTable object’s properties to values entered by usertt.setID((int) _id);tt.setTask(taskET.getText().toString());tt.setPriority(priorityET.getText().toString());tt.setCreatedDate(createdDateET.getText().toString());tt.setDueDate(dueDateET.getText().toString());tt.setResponsible(respET.getText().toString());tt.setCompletionDate(compDateET.getText().toString());
// Invoke update and display a success msglong updateResult = tt.update();String text = "The task '" + tt.getTask()
+ "' was editted successfully! Return code was "+ updateResult;
int duration = Toast.LENGTH_LONG;Toast toast = Toast.makeText(this, text, duration);toast.show();finish(); //End task edit activity
}}
TaskEdit
Copyright 2014 by Janson Industries89
Manifest Need to add a TaskEdit activity inside the application tags
Time to test
Run DBProj, click Display
<activity android:name="Display" android:label="Display To Do List Tasks" android:theme="@android:style/Theme.Black"> <intent-filter>
<action android:name="my.tdl.com.Display" /><category android:name="android.intent.category.DEFAULT" />
</intent-filter></activity><activity android:name="TaskEdit" android:label="Edit Task"
android:theme="@android:style/Theme.Black"></activity>
Copyright 2014 by Janson Industries90
Click Test payroll program
Copyright 2014 by Janson Industries91
Initial displayChange the text and add a created date
Copyright 2014 by Janson Industries92
Click Update then display the task
Copyright 2014 by Janson Industries93
Notice Test text changed and if you click on it…
Copyright 2014 by Janson Industries94
… created date was saved and retrieved
Copyright 2014 by Janson Industries95
Created DBProj such that items can be added and edited in the table
Assg
Copyright 2014 by Janson Industries96
Basically, a formalized interface to an encapsulated database table
Allows multiple apps access to the stored data
Many already provide a user interface to insert, read, and update
Content Providers
Copyright 2014 by Janson Industries97
Content Providers Lots of different ones:
Browser CallLog Contacts
People Phones Photos Groups
MediaStore Audio
Albums Artists Genres Playlists
Copyright 2014 by Janson Industries99
On the Home screen, click the Phone icon
Copyright 2014 by Janson Industries100
Click Menu button then New contact
Copyright 2014 by Janson Industries101
Initial entry screen
Copyright 2014 by Janson Industries102
Enter some info and click DoneA toast will be displayed saying info was saved
Copyright 2014 by Janson Industries103
Click < button to go to contacts
Copyright 2014 by Janson Industries104
For this example, will add a couple more contacts
Copyright 2014 by Janson Industries105
Content Providers Have an API (application program
interface)
An API provides applications access to the content providers data
Lots of rules and objects to work with a content provider
Copyright 2014 by Janson Industries106
Content Providers Identified by a URI called an authority
name content://com.compname.provider/
NotePads URI is: content://com.google.provider.NotePad/
Some native Android providers don’t have a fully qualified name For example, content://contacts
Copyright 2014 by Janson Industries107
Content Providers To identify the underlying DB:
content://com.google.provider.NotePad/Notes
To identify a particular note : content://com.google.provider.NotePad/
Notes/14 Each added element is called a path
segment and is identified by a number (1, 2, 3, etc) So, the provider URI acts like a Web
domain name
Copyright 2014 by Janson Industries108
Content Providers The Android SDK provides predefined
authority name URI variables
For example, instead of creating a URI and specifying this character string:
content://contacts/people/
You can use
Contacts.People.CONTENT_URI
Copyright 2014 by Janson Industries109
Content Providers To insert, need ContentValues
and ContentResolver objects
ContentValues holds the data to be inserted (just like with SQLite)
Use the put method to identify the field and specify the value
ContentResolver does the insert
Returns the URI of the new row
Copyright 2014 by Janson Industries110
Content Providers
To read:
Define/identify the URI
Run a managed query an inherited Activity method
Retrieve the data from the returned Cursor
Copyright 2014 by Janson Industries111
Content Providers To read and display a contact:
import android.provider.Contacts;import android.net.Uri;import android.database.Cursor;import android.provider.Contacts.People; : : : : ://This identifies the second contactUri respPersonUri = Uri.withAppendedPath(Contacts.People.CONTENT_URI, "2");Cursor c = managedQuery(respPersonUri, null, null, null, null);c.moveToFirst();int nameColumnIndex = c.getColumnIndex(People.NAME);
//This is how to read the field and put the result in a String//String name = c.getString(nameColumnIndex);
// This is how to put the name into the responsible ET on the TaskEdit screenrespET.setText(c.getString(nameColumnIndex));
Copyright 2014 by Janson Industries112
Security Android protects a mobile
device’s resources and features Camera, Contact info, Internet
access, Phone, etc.
Complete list at: http://developer.android.com/
reference/android/Manifest.permission.html
An app must have a permission request defined in the manifest file to access these items
Copyright 2014 by Janson Industries113
Security Permissions are placed either
before or after the application tags like this:
When an app is installed permission is granted/denied
: :</application><uses-permission android:name="android.permission.CAMERA" /><uses-permission android:name="android.permission.READ_CONTACTS"/></manifest>
Copyright 2014 by Janson Industries114
Content Providers
Must add permission for contacts
<?xml version="1.0" encoding="utf-8"?><manifest xmlns:android="http://schemas.android.com/apk/res/android" package="my.tdl.com" android:versionCode="1" android:versionName="1.0"> <uses-sdk android:minSdkVersion="8" android:targetSdkVersion="21" /> <uses-permission android:name="android.permission.READ_CONTACTS"/> <application
android:icon="@drawable/ic_launcher" : : : : :
Copyright 2014 by Janson Industries115
Copyright 2014 by Janson Industries116
Content Providers Really what we should do is:
Add a “person responsible” spinner to the insert screen
Populate the spinner with all the contact people so user can just select one
Also, should set a created date when inserted
Copyright 2014 by Janson Industries117
Content Providers New spinner with text for insert.xml
Don't forget the permission!
<LinearLayout android:layout_width="wrap_content" android:layout_height="wrap_content" android:orientation="horizontal"> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Assign the task to " android:gravity="center_vertical"
android:layout_gravity="center_vertical"android:textSize="15sp"/>
<Spinnerandroid:id="@+id/respSpinner"android:layout_width= "wrap_content"android:layout_height="wrap_content">
</Spinner></LinearLayout>
Copyright 2014 by Janson Industries118
Content Providers In Insert.java
import android.widget.Spinner;import android.provider.Contacts.People;import android.widget.SimpleCursorAdapter;import android.database.Cursor;
: : : Spinner respSpinner; //Spinner variable for spinner to display contactsString[] from; //Array for field names to be retrieved from Cursorint[] to; //Array to hold GUI component(s) to display contactsCursor c; //Holds the retrieved contact info : : : respSpinner = (Spinner) findViewById(R.id.respSpinner); Cursor c = managedQuery(People.CONTENT_URI, null, null, null, People.NAME); //Query contactsfrom = new String[] {People.NAME}; //Specify the field to be retrievedto = new int[] {android.R.id.text1}; //Specify the text portion of the
//spinner as the target for nameSimpleCursorAdapter adapter = new SimpleCursorAdapter(this,
android.R.layout.simple_spinner_item, c, from, to); //create the adapter respSpinner.setAdapter(adapter); //assign the adapter to the spinner
Copyright 2014 by Janson Industries119
Run and the spinner will be displayed
Copyright 2014 by Janson Industries120
Click the drop down button and list is displayed
Copyright 2014 by Janson Industries121
Date and Time Formatters A little complicated
First of all, you can get the current date by
Importing java.util.Date
Creating a date objectimport java.util.Date; : : : Date d = new Date();System.out.println(d);
Results in: Tue May 31 13:11:59 EDT 2011
Copyright 2014 by Janson Industries122
DateFormat DateFormat class has predefined formats
To use a DateFormat:
Import DateFormat class
Get a DateFormat instance (getDateInstance) and specify the format to use
Create a date object
Passing the date object as a parameter, use date format object’s format method
Copyright 2014 by Janson Industries
Results in: Tue Mar 13 14:38:59 EDT 20143/13/14Mar 13, 2014March 13, 2014Tuesday, March 13, 2014 123
DateFormat import java.text.DateFormat; : : : :
Date d = new Date();DateFormat dfShort= DateFormat.getDateInstance(DateFormat.SHORT);DateFormat dfMed = DateFormat.getDateInstance(DateFormat.MEDIUM);DateFormat dfLong = DateFormat.getDateInstance(DateFormat.LONG);DateFormat dfFull = DateFormat.getDateInstance(DateFormat.FULL);System.out.println(d);System.out.println(dfShort.format(d));System.out.println(dfMed.format(d));System.out.println(dfLong.format(d));System.out.println(dfFull.format(d));
Copyright 2014 by Janson Industries124
SimpleDateFormat Allows you to define a unique format
To use a SimpleDateFormat: Import SimpleDateFormat class Create a SimpleDateFormat object and
specify the format using date format symbols
y – year, s – seconds, a – (AM or PM) M – month, m – minute H – hour (0-23), h – hour (1-12) d – day of month (1-31), D – day of year z – time zone
Copyright 2014 by Janson Industries
Results: 05/31/201101:19 PM1 O'clock PM, Eastern Daylight Time151 125
SimpleDateFormatimport java.text.SimpleDateFormat; : : : :SimpleDateFormat sdf = new SimpleDateFormat("MM/dd/yyyy"); SimpleDateFormat stf = new SimpleDateFormat("hh:mm a");SimpleDateFormat st2f = new SimpleDateFormat("h 'O''clock' a, zzzz"); SimpleDateFormat sd2f = new SimpleDateFormat("D"); System.out.println(sdf.format(d));System.out.println(stf.format(d));System.out.println(st2f.format(d));System.out.println(sd2f.format(d));
Copyright 2014 by Janson Industries126
Extra Credit Assg Finish Insert such that
The selected name in the spinner is read and inserted into the TasksTable
Add a created date text view and edit view
Put the current date in the edit view in YYYY/MM/DD format
Read the entered created date and insert it into TasksTable
Copyright 2014 by Janson Industries127
When Insert selected, screen should look like this with current date
Copyright 2014 by Janson Industries128
Adding this info and clicking Insert…
Copyright 2014 by Janson Industries129
…means the update screen would look like this
Copyright 2014 by Janson Industries130
Error You Will Get In a Year Error generating final archive:
Debug certificate expired on XXXX
Android requires that apps be signed
It uses a keystore file called debug.keystore to hold the keys
By default the keystore file is valid for 365 days
Copyright 2014 by Janson Industries131
Error You Will Get In a Year Solution:
Navigate to the .android folder in your home directory
C:\Users\youruserid\.android
Delete the debug.keystore file
Go to eclipse and clean all your projects
This creates a new debug.keystore file which will be valid for 365 more days