Download 8.SQLite.2015

Document related concepts
no text concepts found
Transcript
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