Survey							
                            
		                
		                * Your assessment is very important for improving the workof artificial intelligence, which forms the content of this project
* Your assessment is very important for improving the workof artificial intelligence, which forms the content of this project
Mobile Computing
DataBase and
Content Providers
Assg
Copyright 2014 by Janson Industries
EC Assg
1
Objectives
▀
Explain
 SQLite
 Data
Encapsulation
 Content
providers
 Permissions
2
Copyright 2014 by Janson Industries
SQLite
▀
▀
▀
DataBase Management System
that comes with Android
A database consists of many
tables
Tables hold data
In
rows/columns (records/fields)
3
Copyright 2014 by Janson Industries
SQLite
▀
To create and manipulate
databases and tables, use:
 Standard
SQL commands
 Specialized
Android object’s
► SQLiteDatabase
► SQLiteOpenHelper
► Cursor
► ContentValues
4
Copyright 2014 by Janson Industries
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
5
Copyright 2014 by Janson Industries
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
Copyright 2014 by Janson Industries
(1,2,3)
 To do item text
 Due date
 Responsible person
6
7
Copyright 2014 by Janson Industries
8
Copyright 2014 by Janson Industries
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
9
Copyright 2014 by Janson Industries
10
Copyright 2014 by Janson Industries
Displays all the item info and allow changes
11
Copyright 2014 by Janson Industries
To Do List
▀
Create a new Android 2.2 project
called DBProj
 App
called ToDoList
 Package
 Activity
is my.tdl.com
is Main, layout is main
12
Copyright 2014 by Janson Industries
To Do List
Change Main.java to be an
Activity not ActionBarActivity
//import android.support.v7.app.ActionBarActivity;
import android.app.Activity;
:
:
:
:
:
public class Main extends Activity {
In manifest, change the
application theme
:
:
:
:
:
:
:
android:theme="@android:style/Theme.Black"
:
:
:
:
:
:
:
13
Copyright 2014 by Janson Industries
main.xml
<?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
Copyright 2014 by Janson Industries
Test by running in emulator
15
Copyright 2014 by Janson Industries
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
16
Copyright 2014 by Janson Industries
17
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" />
insert.xml
<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>
Copyright 2014 by Janson Industries
18
Insert and Display Stubs
package 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 Industries
19
Main
package 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);
} 2014 by Janson Industries
Copyright
20
Main
}
Copyright 2014 by Janson Industries
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;
}
}
21
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>
22
Copyright</activity>
2014 by Janson Industries
Manifest
Activity definitions for Insert
and Display
<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>
23
Copyright 2014 by Janson Industries
To Do List
▀
Run the program
▀
Click Insert check box
▀
Make sure the Insert screen
is displayed
24
Copyright 2014 by Janson Industries
25
Copyright 2014 by Janson Industries
SQLite
▀
▀
Need to create the ToDoList data
base and the tasks table
The structure of the tasks table is:
 _id
Copyright 2014 by Janson Industries
INTEGER PRIMARY KEY
 Task
TEXT
 Priority
TEXT
 CreatedDate
TEXT
 DueDate
TEXT
 Responsible
TEXT28
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
29
Copyright 2014 by Janson Industries
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
30
Copyright 2014 by Janson Industries
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
31
Copyright 2014 by Janson Industries
ToDoListDBHelper
package 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";
32
Copyright 2014 by Janson Industries
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);";
33
Copyright 2014 by Janson Industries
ToDoListDBHelper
public ToDoListDBHelper(Context context) {
}
// Creates the database
super(context, DATABASE_NAME, null, DATABASE_VERSION);
public void onCreate(SQLiteDatabase db) {
}
// Creates the tasks table
db.execSQL(TABLE_CREATE);
public void onUpgrade(SQLiteDatabase db, int oldVersion, int
newVersion) {
}
}
Copyright 2014 by Janson Industries
34
Encapsulation
Many terms used to describe:
 Transparency
 Information
hiding
 Implementation
Copyright 2014 by Janson Industries
ignorance
Programmers have an
“interface” to an object with no
idea of how it works
35
Encapsulation
For example, driving a car
Someone knows how to drive:
 Turn
the key
 Step on gas pedal
 Steer
 Step on brake pedal
Copyright 2014 by Janson Industries
The driver doesn’t have to know
how the car works or any of its
internal components
36
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
37
Copyright 2014 by Janson Industries
Data Encapsulation
Getters
Constructors
DATA
Rules
Copyright 2014 by Janson Industries
Setters
38
Encapsulation
Copyright 2014 by Janson Industries
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
39
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
Copyright 2014 by Janson Industries
Define CRUD functions
40
How to Encapsulate a File
Copyright 2014 by Janson Industries
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
41
TasksTable
Define a private variable for
each field
private
private
private
private
private
private
private
int ID;
String Task;
String Priority;
String CreatedDate;
String DueDate;
String Responsible;
String CompletionDate;
42
Copyright 2014 by Janson Industries
TasksTable
Define getters and setters
public
public
public
public
public
public
public
public
int getID() { return ID; }
void setID(int iD) { ID = iD; } // Need for updates
String getTask() { return Task; }
void setTask(String task) { Task = task; }
String getPriority() { return Priority; }
void setPriority(String priority) { Priority = priority;}
String getCreatedDate() { return CreatedDate; }
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) {
Copyright 2014
by Janson Industries
CompletionDate
= completionDate; }
43
CRUD Functions
Create pretty easy, plus it creates
the helper class that…
public TasksTable(Context ctx) {
this.context = ctx;
DBHelper = new ToDoListDBHelper(context);
this.open();
}
…supplies the ToDoList DB (a
SQLite DB) that we will read and
write to
public TasksTable open() throws SQLException {
db = DBHelper.getWritableDatabase();
return this;
}
Copyright 2014 by Janson Industries
44
CRUD Functions
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
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);
45
} by Janson Industries
Copyright 2014
CRUD Functions
Need some import statements
package my.tdl.com;
import android.content.ContentValues;
import android.content.Context;
import android.database.SQLException;
import android.database.sqlite.SQLiteDatabase;
Also need some other variables
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";
Copyright 2014 by Janson
Industries
protected
final String COMP_FN = "CompletionDate";
Let’s test
46
To Do List
Time to test
Prove the insert works:
 Switch
 Click
to the DDMS perspective
on emulator
 Expand
 Scroll
 No
data/data
down and expand my.tdl.com
databases folder
47
Copyright 2014 by Janson Industries
No databases folder, just lib
48
Copyright 2014 by Janson Industries
Insert
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
Copyright 2014 by Janson Industries
a success msg
49
package my.tdl.com;
import
import
import
import
import
import
import
Insert
android.app.Activity;
android.os.Bundle;
android.view.View;
android.view.View.OnClickListener;
android.widget.Button;
android.widget.EditText;
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
}
Copyright 2014 by Janson Industries
Insert
public 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 toast
String 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();
}
}
51
Copyright 2014 by Janson Industries
52
Copyright 2014 by Janson Industries
Proof that it worked
53
Copyright 2014 by Janson Industries
To Do List
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
54
Copyright 2014 by Janson Industries
DDMS Perspecitive
Allows you to download the DB
Select the DB and click the Pull
a file from the device button
55
Copyright 2014 by Janson Industries
56
Copyright 2014 by Janson Industries
Then specify where to store it
57
Copyright 2012 by Janson Industries
SQLite browser lets you access and
Copyright 2014 by Janson Industriesmanipulate the DB
58
http://web.fscj.edu/Janson/CIS2930
Download SQLite
browser, unzip,
run the exe file
59
Copyright 2014 by Janson Industries
File, Open Database, specify ToDoList
Then click Browse Data, select TasksTable
60
Copyright 2014 by Janson Industries
To Do List
Need a display function
 Will
display all tasks text
When a task is clicked, will allow
user to update all the task info
61
Copyright 2014 by Janson Industries
Display all the tasks
62
Copyright 2014 by Janson Industries
Display all task info and allow changes
63
Copyright 2014 by Janson Industries
To Do List
Going to need:
 Read
and update functions in
TasksTable
 Two
new screen definitions
 display.xml
 edit.xml
 Change
 React
Display.java to
to a click on a task
 Retrieve that tasks info from DB
 Invoke TaskEdit and pass DB info via
the bundle
64
Copyright 2014 by Janson Industries
To Do List
 Create
TaskEdit.java to
 Display
the task info
 Update
the task
 Display
a confirmation of the update
 Return
 Add
back to the main menu
TaskEdit activity to manifest
65
Copyright 2014 by Janson Industries
TasksTable Update
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
66
Copyright 2014 by Janson Industries
TasksTable Read
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
67
Copyright 2014 by Janson Industries
TasksTable
import 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);
} 2014 by Janson Industries
Copyright
68
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>
69
Copyright 2014 by Janson Industries
edit.xml
Initial LinearLayout and Textview
<?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" />
Followed by a series of horizontal
LinearLayouts with components
70
Copyright 2014 by Janson Industries
For each db field will have text
and an entry field
<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>
71
Copyright 2014 by Janson Industries
<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 Industries
72
edit.xml
<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>
73
</LinearLayout>
Copyright
2014 by Janson Industries
edit.xml
<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>
Copyright 2014 by Janson Industries
74
Display.java
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
75
Copyright 2014 by Janson Industries
Display.java
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
76
Copyright 2014 by Janson Industries
SimpleCursorAdapter
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
Copyright 2014 by Janson Industries
77
Change Display.java
package my.tdl.com;
import
import
import
import
import
import
import
import
import
import
android.app.Activity;
android.app.ListActivity;
android.widget.SimpleCursorAdapter;
android.content.Intent;
android.database.Cursor;
android.os.Bundle;
android.view.View;
android.widget.EditText;
android.widget.ListView;
android.widget.TextView;
public class Display extends ListActivity {
// Various variables needed to display the list of tasks
TextView taskTV;
TasksTable tt;
Cursor c;
SimpleCursorAdapter taskAdapter;
String[] from;
int[] to;
Copyright 2014 by Janson Industries
78
Display.java
onCreate will show the current
tasks
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
79
Copyright 2014 by Janson Industries
Display
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
Copyright 2014 by Janson Industries
Display
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)
Copyright 2014 by Janson Industries
81
Display
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
Copyright 2014 by Janson Industries
Display
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
Copyright 2014 by Janson Industries
Display.java
}
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
}
84
Copyright 2014 by Janson Industries
TaskEdit
Create various variables needed
to display and edit task info
package my.tdl.com;
import
import
import
import
import
import
android.app.Activity;
android.os.Bundle;
android.view.View;
android.widget.Button;
android.widget.EditText;
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;
85
Copyright 2014 by Janson Industries
TaskEdit
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();
86
Copyright 2014 by Janson Industries
TaskEdit
// 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);
} 2014 by Janson Industries
Copyright
87
public void onClick(View view) {
// Create new TasksTable object
tt = new TasksTable(this);
TaskEdit
// Set TasksTable object’s properties to values entered by user
tt.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 msg
long 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
88
Copyright 2014 by Janson Industries
Manifest
Need to add a TaskEdit activity
inside the application tags
<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>
Time to test
 Run
DBProj, click Display
89
Copyright 2014 by Janson Industries
Click Test payroll program
90
Copyright 2014 by Janson Industries
Initial display
Change the text and add a created date
91
Copyright 2014 by Janson Industries
Click Update then display the task
92
Copyright 2014 by Janson Industries
Notice Test text changed and if you click on it…
93
Copyright 2014 by Janson Industries
… created date was saved and retrieved
94
Copyright 2014 by Janson Industries
Assg
Created DBProj such that items
can be added and edited in the
table
95
Copyright 2014 by Janson Industries
Content Providers
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
96
Copyright 2014 by Janson Industries
Content Providers
Lots of different ones:
 Browser
 CallLog
 Contacts
 People
 Phones
 Photos
 Groups
 MediaStore
 Audio
 Albums
 Artists
 Genres
Copyright 2014 by Janson Industries
 Playlists
97
On the Home screen, click the Phone icon
99
Copyright 2014 by Janson Industries
Click Menu button then New contact
100
Copyright 2014 by Janson Industries
Initial entry screen
101
Copyright 2014 by Janson Industries
Enter some info and click Done
A toast will be displayed saying info was saved
102
Copyright 2014 by Janson Industries
Click < button to go to contacts
103
Copyright 2014 by Janson Industries
For this example, will add a couple more contacts
104
Copyright 2014 by Janson Industries
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
105
Copyright 2014 by Janson Industries
Content Providers
Identified by a URI called an
authority name
 content://com.compname.provider/
NotePads URI is:
 content://com.google.provider.Note
Pad/
Some native Android providers
don’t have a fully qualified name
For
Copyright 2014 by Janson Industries
example, content://contacts
106
Content Providers
To identify the underlying DB:
 content://com.google.provider.Note
Pad/Notes
To identify a particular note :
 content://com.google.provider.Note
Pad/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 Industries
107
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 Industries
108
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
109
Copyright 2014 by Janson Industries
Content Providers
To read:
 Define/identify
 Run
the URI
a managed query
 an
inherited Activity method
 Retrieve
the data from the returned
Cursor
110
Copyright 2014 by Janson Industries
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 contact
Uri 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 screen
respET.setText(c.getString(nameColumnIndex));
Copyright 2014 by Janson Industries
111
Security
Android protects a mobile
device’s resources and features
 Camera,
Contact info, Internet
access, Phone, etc.
 Complete
list at:
 http://developer.android.com/referen
ce/android/Manifest.permission.html
An app must have a permission
request defined in the manifest
file to access these items
112
Copyright 2014 by Janson Industries
Security
Permissions are placed either
before or after the application
tags like this:
:
:
</application>
<uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.READ_CONTACTS"/>
</manifest>
When an app is installed
permission is granted/denied
113
Copyright 2014 by Janson Industries
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"
:
:
:
:
:
114
Copyright 2014 by Janson Industries
115
Copyright 2014 by Janson Industries
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
116
Copyright 2014 by Janson Industries
Content Providers
New spinner with text for insert.xml
<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"/>
<Spinner
android:id="@+id/respSpinner"
android:layout_width= "wrap_content"
android:layout_height="wrap_content">
</Spinner>
</LinearLayout>
Don't forget the permission!
117
Copyright 2014 by Janson Industries
Content Providers
import
import
import
import
In Insert.java
android.widget.Spinner;
android.provider.Contacts.People;
android.widget.SimpleCursorAdapter;
android.database.Cursor;
:
:
:
Spinner respSpinner; //Spinner variable for spinner to display contacts
String[] from;
//Array for field names to be retrieved from Cursor
int[] to;
//Array to hold GUI component(s) to display contacts
Cursor c;
//Holds the retrieved contact info
:
:
:
respSpinner = (Spinner) findViewById(R.id.respSpinner);
Cursor c = managedQuery(People.CONTENT_URI, null, null, null,
People.NAME);
//Query contacts
from = new String[] {People.NAME}; //Specify the field to be retrieved
to = new int[] {android.R.id.text1};
//Specify the text portion of the
//spinner as the target for name
SimpleCursorAdapter adapter = new SimpleCursorAdapter(this,
android.R.layout.simple_spinner_item,
c, from, to);
//create the adapter
118
Copyright
2014 by Janson Industries
respSpinner.setAdapter(adapter);
//assign the adapter to the spinner
Run and the spinner will be displayed
119
Copyright 2014 by Janson Industries
Click the drop down button and list is displayed
120
Copyright 2014 by Janson Industries
Date and Time Formatters
A little complicated
First of all, you can get the
current date by
 Importing
 Creating
java.util.Date
a date object
import 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 Industries
121
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 method122
Copyright 2014 by Janson Industries
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));
Results in:
Copyright 2014 by Janson Industries
Tue Mar 13 14:38:59 EDT 2014
3/13/14
Mar 13, 2014
March 13, 2014
Tuesday, March 13, 2014
123
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
– 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
124
y
Copyright 2014 by Janson Industries
SimpleDateFormat
import 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));
Results:
05/31/2011
01:19 PM
1 O'clock PM, Eastern Daylight Time
151
Copyright 2014 by Janson Industries
125
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 Industries
126
When Insert selected, screen should look like this
with current date
127
Copyright 2014 by Janson Industries
Adding this info and clicking Insert…
128
Copyright 2014 by Janson Industries
…means the update screen would look like this
129
Copyright 2014 by Janson Industries
Error You Will Get In a Year
Copyright 2014 by Janson Industries
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
130
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
131
Copyright 2014 by Janson Industries