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