Você está na página 1de 115

Contents

1.

B4A Cheatsheet ...................................................................................................... 4


Debug with a Toastmessage ............................................................................................. 4
Design resources and graphics ......................................................................................... 4
API Interfaces .................................................................................................................... 4
Dates................................................................................................................................. 4
Getting Date from Sql database......................................................................................... 4
Read text file from External SD Card. ................................................................................ 4
Write text to a text file to SD Card...................................................................................... 4
How to open a webpage with WebView. ............................................................................ 4
Using Begin/End transaction - along with TransactionSuccessful greatly improves "writing"
speed in SQL..................................................................................................................... 4
"The application ... has stopped unexpectedly. Please try again." ..................................... 4
Adding menu items ............................................................................................................ 4
Use #Region ... #End Region. ........................................................................................... 5
Panel arrays ...................................................................................................................... 5
Ctrl + Space = auto complete ............................................................................................ 5
Tool tip information ............................................................................................................ 5
LogCat - logs ..................................................................................................................... 5
Open a PDF ...................................................................................................................... 5
Open an Excel file ............................................................................................................. 5
Running the Emulator through a proxy via the Command prompt ...................................... 5
Send data to Android calendar .......................................................................................... 6
Create a Glow, Blur, DropShadow effect on text ................................................................ 6
Built in buttons and images................................................................................................ 6
Free database hosting ....................................................................................................... 6
Getting two lines in a listview ............................................................................................. 6
File Locations and working ................................................................................................ 6
Write / Read to files ........................................................................................................... 7

2.

Project Download content using HTTP - dictionary ................................................. 8


HttpRequest ...................................................................................................................... 8
HttpResponse.................................................................................................................... 9

3.

Project Metservice weather app ............................................................................ 10


Adding more cities to the weather app using Spinner. ..................................................... 13

4.

Project The BikeFit calculator ................................................................................ 15


Create the Database ....................................................................................................... 15
SQL in the code............................................................................................................... 17
Create the layout ............................................................................................................. 18
Activity Create code......................................................................................................... 21
Load the Database code.................................................................................................. 22
Listview Click Event ......................................................................................................... 23
Delete and Update - Database commands ...................................................................... 24
Add New Record to the Database ................................................................................... 24
Code for calculate............................................................................................................ 25
The Modules tab .............................................................................................................. 26
Easily find repeated code ................................................................................................ 26

Basic For Android

Monday, 11 June 2012

Page 1

The Results Activity ......................................................................................................... 27


The Results2 Activity ....................................................................................................... 28
The Results Layout using 2 panels .................................................................................. 29
The Help screen .............................................................................................................. 30

5.

Project: Online Database Communication system................................................. 34


How to create an online Database ................................................................................... 34
Establish a connection string ........................................................................................... 36
Sending data to the database .......................................................................................... 37
Retrieving data from the database ................................................................................... 37
Uploading your PHP script............................................................................................... 39

Android Communication Program Basic setup ................................................................. 40


Android Communication Program Timestamp and Limit ............................................... 43
Using Timestamp ............................................................................................................ 43
Using Limit ...................................................................................................................... 44
Cutting out the unwanted text .......................................................................................... 44
Deleting data from your database. ................................................................................... 45

6.

Project: GPS Program ........................................................................................... 49


Create the graphic Compass ........................................................................................... 49
Create the GPS ............................................................................................................... 50
GPS LocationChanged .................................................................................................... 52
Activity Pause and Resume code .................................................................................... 53
The Orientation_SensorChanged sub.............................................................................. 54
GPS on Google maps using Intents .............................................................................. 55

7.

Project: GPS and the net SQL: Record your position online ................................. 56
Create a new database table ........................................................................................... 56
Create a new PHP script ................................................................................................. 57
Getting satellites .............................................................................................................. 59
Retrieving data from the database and displaying distance to saved GPS location ......... 60

8.

Project: Getting an address from a Geolocation using XML .................................. 63


Geolocation ..................................................................................................................... 66
XML parser...................................................................................................................... 66

9.

Getting an error in your hc_ResponseSuccess? Fix the taskID. ........................... 67

10.

Project: Creating a Weather Widget ...................................................................... 68


The Service Module......................................................................................................... 69
Designing the Temperature Widget ................................................................................. 76

11.

Project: Alarm scheduler sends email to contacts ................................................. 79


Date and Time ................................................................................................................. 80
Write to a file ................................................................................................................... 82
Read from a file to a list ................................................................................................... 82
Sending an SMS ............................................................................................................. 83

12.

Project: Text to Speech Program........................................................................... 85


Text to speech stripped for other programs .................................................................. 87

13.

Project: Capture all SMS messages entering your phone ..................................... 88


Logs and Toastmessageshow are crucial to debugging .................................................. 88
Working with Service and Activity Modules ...................................................................... 89

Basic For Android

Monday, 11 June 2012

Page 2

Saving and Reading to files ............................................................................................. 89


The Activity (main) code .................................................................................................. 89
Code for the Service Activity(sms) ................................................................................... 94
The Activity(smstest) ....................................................................................................... 97
Designing the Widget ...................................................................................................... 98

14.

Project: Voice Recognition program ...................................................................... 99

15.

Project: Voice recognition in SMS messages program. ....................................... 101


Create a transparent layout a floating button .............................................................. 101
The Voice Recognition Activity Module .......................................................................... 103

16.

Maps Hashmap for Java, Hashtables for .net ................................................... 107

17.

Use Map to save multiple data to a single file ..................................................... 108

18.

Project: Recipe selector using JSON................................................................... 109


JSON Overview ............................................................................................................. 109
Recipe Program construction ........................................................................................ 111
How to make a hyperlink that opens the web browser ................................................... 114

Basic For Android

Monday, 11 June 2012

Page 3

1. B4A Cheatsheet
Debug with a Toastmessage

Write text to a text file to SD Card.

Toastmessage is a timed popup useful to


show you whats happening in your code.

File saved to SDCARD/Android/data/ your


com file name

ToastMessageShow("message
here",false) ' true=3sec , false=2
sec

File.WriteString(File.DirDefaultExter
nal, "mytextfile.txt", "text to
write")

Design resources and graphics

How to open a webpage with WebView.

http://developer.android.com

1. add Webview to designer.


2. add button to designer.
3. generate members.

http://www.androidpatterns.com/
http://jgilfelt.github.com/android-actionbar
Nine patch images nine-patch-images-tutorial
API Interfaces

http://www.programmableweb.com/
http://cloudmade.com/
Dates

Dates values are stored as the number of


milliseconds since 1 January, 1970. This value
is too large for an Int. It must be saved in a
Long variable.
Dim now As Long
now = DateTime.Now

Getting Date from Sql database

The date from my SQL database comes in as


yyyy/MM/dd
Here is a simple way to display in the required
format.
Dim TheDate As Long
DateTime.DateFormat = "yyyy-MM-dd"
TheDate=
DateTime.DateParse(Cursor1.GetString(
"Dob"))
DateTime.DateFormat = "dd/MM/yyyy"
Text= DateTime.Date(TheDate)

Read text file from External SD Card.

Folder SDCARD/Android/data/ your app


name
Dim savedtext As String
savedtext =
File.ReadString(File.DirDefaultExtern
al, "mytextfile.txt")

Basic For Android

Button1_Click
Dim UserURL As String
UserURL = "http://www.google.com.au/"
WebView1.LoadUrl(UserURL)
End Sub

Using Begin/End transaction - along with


TransactionSuccessful greatly improves
"writing" speed in SQL.

My code went from 12 seconds to


milliseconds in writing records.
SQL1.BeginTransaction
Try
'block of statements like:
For i = 1 to 1000
SQL1.ExecNonQuery("INSERT INTO table1
VALUES(...)
Next
SQL1.TransactionSuccessful
Catch
Log(LastException.Message) 'no
changes will be made
End Try
SQL1.EndTransaction

"The application ... has stopped


unexpectedly. Please try again."

Some errors are not caught by Basic4android


and then you see this message. To find the
cause of the error you should check the
unfiltered logs in the Logs tab (right pane).
The filtered logs will usually not show any
message about this error.
Adding menu items

Adding menu items to activity is done by


calling Activity.AddMenuItem or
AddMenuItem2.

Monday, 11 June 2012

Page 4

Usually you will want to call it in Sub


Activity_Create.
Use #Region ... #End Region.

to create custom collapsible sections in your


code. Very handy for hiding a large blocks of
source code
#Region My collection of functions
Sub SomeThing()
End Sub
Sub Another()
End Sub
#End Region

Panel arrays

Dim panels(8) As Panel


Defines 8 Panels.
panels.Length = number of items, number of
Panels.
The Panel items go from
panels(0), panels(1), panels(2), panels(3),
panels(4), panels(5), panels(6),
panels(7) 8 items with indexes from 0 to 7 so
panels.Length - 1 .
So
Dim panels(8) As Panel
For i = 0 To panels.Length 1

is correct and necessary


Ctrl + Space = auto complete

Pressing Ctrl + Space activates the auto


complete feature which will then show you a
list with the available keywords, variables,
modules, methods, subs, properties and fields.
The list includes a description for most items.
Pressing Ctrl + Space after typing the first few
letters will usually select the required item
automatically.

Log(whatever you want)

Open a PDF
Sub OpenPDF(FileName As String)
Dim i As Intent 'Requires a
reference to the Phone library
i.Initialize(i.ACTION_VIEW,
FileName)
i.SetType("application/pdf")
i.WrapAsIntentChooser("Choose PDF
Viewer")
StartActivity(i)
End Sub
Open an Excel file
Sub OpenExcel(FileName As String)
Dim i As Intent 'Requires a
reference to the Phone library
i.Initialize(i.ACTION_VIEW,
FileName)
i.SetType("application/vnd.msexcel")
i.WrapAsIntentChooser("Choose
Excel Viewer")
StartActivity(i)
End Sub
Running the Emulator through a proxy via
the Command prompt
c:\Android\androidsdk\tools>emulator.exe -avd
test -http-proxy
http://Username:PW@10.6.0.254
:3128

This c:\Android\android-sdk\tools> has to be


done first then attach the rest. Test = avd
name, IP address:port 10.6.0.254:3128

Tool tip information

While writing methods parameters, a tool tip


will be opened with the method signature and
description.
The tool tip might hide some important code
that you now need.
LogCat - logs

The LogCat tab displays the device built-in


logs. These logs are very useful for debugging.
You can log messages with the Log keyword.
In order to start displaying the logs you press
on the Connect button.
Basic For Android

Monday, 11 June 2012

Page 5

Send data to Android calendar


Sub Activity_Create(FirstTime As
Boolean)
Dim Intent1 As Intent
Intent1.Initialize(Intent1.ACTION_
MAIN,"com.androi d.calendar")
Intent1.SetComponent("com.android.
calendar/.LaunchActivity")
StartActivity(Intent1)
End Sub
Create a Glow, Blur, DropShadow effect on
text
Dim Obj1 As Reflector
Obj1.Target = Label1
args(0) = 3 'Radius of the
Blur/GlowDropShadow
types(0) = "java.lang.float"
args(1) = 3
types(1) = "java.lang.float"
args(2) = 3
types(2) = "java.lang.float"
args(3) = Colors.ARGB(255,0,0,255)
' Color of th Glow/Blur
types(3) = "java.lang.int"
Obj1.RunMethod4("setShadowLayer",
args, types)

Built in buttons and images

Go to
http://developer.android.com/reference/androi
d/R.drawable.html images
http://androiddrawables.com/ put the number
in code below
Dim bd As BitmapDrawable
bd = p.GetResourceDrawable(17301555)
Msgbox2("Message", "OK",
"","",bd.Bitmap)

Free database hosting

http://www.000webhost.com/
Getting two lines in a listview
Sub Globals
Type ListViewData (FirstRow As
String, SecondRow As String)
End Sub
For i = 0 to 100
Dim lvd As ListViewData
lvd.Initialize
lvd.FirstRow = "abc"
lvd.SecondRow= "def"
ListView1.AddTwoLines2(lvd.FirstRow,
lvd.SecondRow, lvd)
Basic For Android

Next
Sub ListView1_ItemClick(Position As
Int, Value As Object)
Dim lvd As ListViewData
lvd = Value
...
End Sub

File Locations and working

There are several important locations where


you can read or write files.
File.DirAssets

The assets folder includes the files that were


added with the file manager. These files are
read-only. You cannot create new files in
this folder (which is actually located inside
the apk file).
File.DirInternal / File.DirInternalCache

These two folders are stored in the main


memory and are private to your application.
Other applications cannot access these
files.The cache folder may get deleted by the
OS if it needs more space.
File.DirRootExternal

The storage card root folder.


File.DirDefaultExternal

The default folder for your application in the


SD card. It will be created if required. The
folder is: <storage
card>/Android/data/<package>/files/
File.WriteString - Writes the given text to a
new file.
File.ReadString - Reads a file and returns it
content as a string.
File.WriteList - Writes all values stored in a
list to a file. All values are converted to string
type if required. Each value will be stored in
its own line. Note that if a value contains the
new line character it will saved over more than
one line and when you read it, it will be read
as multiple items.
File.ReadList - Reads a file and stores each
line as an item in a list.
File.WriteMap - Takes a map object which

Monday, 11 June 2012

Page 6

holds pairs of key and value elements and


stores it in a text file. The file format is not too
important unless the file is supposed to be
edited manually. This format makes it easy to
edit it manually. One common usage of
File.WriteMap is to save a map of "settings" to
a file.
File.ReadMap - Reads a properties file and
returns its key/value pairs as a Map object.
Note that the order of entries returned might be
different than the original order.

File.WriteString(File.DirInte
rnalCache,
"nettalk.txt",result)
'get it back from the file
reader.Initialize(File.OpenIn
put(File.DirInternalCache,
"nettalk.txt"))
Dim name As String
name = reader.ReadLine

Write / Read to files


'write it to a file

Basic For Android

Monday, 11 June 2012

Page 7

2. Project Download content using HTTP - dictionary


The basic steps in getting content from the net to your phone are quite simple.
In this project we are going to access the online dictionary at
http://dictionary.reference.com/ enter a term and get the results.
First add the Http library. Here is the basic documentation on it
http://www.basic4ppc.com/android/help/http.html

Create a layout with an Edittext box named WordBox and a button named SearchButton.
HttpRequest

Holds the target URL and other data sent to the web server. The initial time out is to 30000
milliseconds (30 seconds).
Sub Process_Globals
Dim hc As HttpClient
Dim req As HttpRequest
End Sub

Sub Globals
'define the views on the layout, a text box and a button
Dim WordBox As EditText
Dim SearchButton As Button
End Sub

Sub Activity_Create(FirstTime As Boolean)


'load the layout
Activity.LoadLayout("Main")
hc.Initialize("hc")
End Sub

'#### Controls ####


Sub SearchButton_Click
req.InitializeGet("http://dictionary.reference.com/browse/" &
WordBox.Text)
hc.Execute(req, 1)
End Sub

Basic For Android

Monday, 11 June 2012

Page 8

HttpResponse

An object that holds the response returned from the server. The object is passed in the
ResponseSuccess event. You can choose to read the response synchronously or
asynchronously. It is important to release this object when it is not used anymore by calling
Release.
'#### Routines ####
Sub hc_ResponseSuccess(Response As HttpResponse, TaskId As Int)
Dim SearchWord As String
SearchWord = Response.GetString("UTF8") 'Get the whole page
'The line below finds <div class="pbk"><span class="pg">
SearchWord = SearchWord.Replace(QUOTE, "'") 'Replace double quotes with
single quotes for easy handling.
SearchWord = SearchWord.SubString(SearchWord.IndexOf("<div
class='pbk'><span class='pg'>") + 34) 'Add 34 so we grab the definition
after the tag (there are 34 characters in the above string when you count
to the right) You can add 34 to the 0 substring start below instead
SearchWord = SearchWord.SubString2(0, SearchWord.IndexOf("</span>")) 'Grab
only the definition enclosed
Msgbox(WordBox.Text & " is a " & SearchWord, "") 'Voila!!
End Sub

Sub hc_ResponseError(Response As HttpResponse, Reason As String,


StatusCode As Int, TaskId As Int)
If Response <> Null Then
Msgbox("Error: " & Response.GetString("UTF8"), "Connection Error")
Response.Release
End If
End Sub

Basic For Android

Monday, 11 June 2012

Page 9

3. Project Metservice weather app


Similar to the above exercise this exercise downloads the current temperature from the
metservice and extracts the temp from it.
The heart of it is cutting out the temperature from the code.
Improve this code by:
1. Allowing people to change the city to another one.
2. We will make it into a widget so it stays on the front of the phone
later.
Sub Process_Globals
Dim hc As HttpClient 'download the page
Dim hcimage As HttpClient 'download the image
Dim req As HttpRequest
Dim reqimage As HttpRequest
End Sub

Sub Globals
Dim temp As String
Dim btnweather As Button
Dim edtweather As EditText
Dim lbltemperature As Label
Dim img As Bitmap
Set a default start city when there is nothing in the DB
Dim selectedcity As String :selectedcity ="Christchurch"
Dim townpath As String
Dim label1 As Label holds the temp
Dim imgtemp As ImageView
Dim pic As String 'holds the image
End Sub

Sub Activity_Create(FirstTime As Boolean)


Activity.LoadLayout("main")
hc.Initialize("hc")
hcimage.Initialize("hcimage")
End Sub

Sub btnweather_click
strplace = "christchurch" 'note its lower case
townpath = "http://m.metservice.com/towns/"& strplace
'Log(townpath)
req.InitializeGet(townpath)
Basic For Android

Monday, 11 June 2012

Page 10

hc.Execute(req, 1)
End Sub
Sub hc_ResponseSuccess(Response As HttpResponse, TaskId As Int)
Dim temp As String
temp = Response.GetString("UTF8") 'Get the whole page
'Cut beginning and end to get the code for the temp itself
temp = temp.SubString(temp.IndexOf("<div class=" & QUOTE & "summary" &
QUOTE & ">")) 'cut to first occurance off
temp = temp.SubString2(21, temp.IndexOf("</ul></div></div>")) ' find last
occurance
temp = temp.Replace(QUOTE,"'") ' replace double with single quotes
edtweather.Text = temp 'show the downloaded code so you can work on it.
Dim temperature As String 'pull the temperature from the code
temperature = temp
temperature = temperature.SubString(temperature.IndexOf("ul'><h2>"))
temperature = temperature.SubString2(8, temperature.IndexOf("<span "))
lbltemperature.Text = temperature
pic = temp 'pull the pic from the code
pic = pic.SubString(pic.IndexOf("wx-icons/"))
'start position
pic = pic.SubString2(9, pic.IndexOf("' width")) ' 6 is the number from
counting the letters above
pic = pic.Trim
'looking for the image, is it already in the cache?
If File.Exists(File.DirInternalCache, pic) Then
'if so then load it
imgtemp.Bitmap = LoadBitmap(File.DirInternalCache, pic)
Log("image in cache")
Else 'otherwise go and get it from the net
Getimage run the get image sub
End If
Dim strtime As String 'pull the time from the code
strtime = temp
Dim timecolon As String
timecolon = strtime.IndexOf(":") 'find the colon between the time eg
11:23am
strtime = strtime.SubString2(timecolon -2, timecolon +5) 'take 2 off the
colon and add 5 on to get the whole time 11:23am
label1.Text = strtime
End Sub

Basic For Android

Monday, 11 June 2012

Page 11

Sub getimage 'this gets the image from the net


Dim imagepath As String
imagepath = "http://m.metservice.com/sites/all/themes/mobile/images/wxicons/"& pic
reqimage.InitializeGet(imagepath)
hcimage.Execute(reqimage, 1)
End Sub

Sub hcimage_ResponseSuccess(Response As HttpResponse, TaskId As Int)


If you successfully get the image then run this code its sitting in the
cache so get it out
Response.GetAsynchronously("ImageResponse", _
File.OpenOutput(File.DirInternalCache, pic, False), True, TaskId)
End Sub
when the image has stopped downloading (useful for big images)
Sub ImageResponse_StreamFinish (Success As Boolean, TaskId As Int)
If Success = False Then
Msgbox(LastException.Message, "Error")
Return
End If
load it into the image bitmap
imgtemp.Bitmap = LoadBitmap(File.DirInternalCache, pic)
End Sub

typical error reporting when the image was unable to be downloaded


Sub hcimage_ResponseError(Response As HttpResponse, Reason As String,
StatusCode As Int, TaskId As Int)
If Response <> Null Then
Msgbox("Error: " & Response.GetString("UTF8")& "Cannot find ",
"Connection Error")
Response.Release
ProgressDialogHide
ToastMessageShow("Image not loading",True)
End If
End Sub

typical error reporting when the temp was unable to be downloaded


Sub hc_ResponseError(Response As HttpResponse, Reason As String,
StatusCode As Int, TaskId As Int)
If Response <> Null Then
Msgbox("Error: " & Response.GetString("UTF8")& "Cannot find ",
"Connection Error")
Response.Release
ProgressDialogHide
ToastMessageShow("bugger",True)
Basic For Android

Monday, 11 June 2012

Page 12

End If
End Sub

Adding more cities to the weather app using Spinner.


Create a Spinner, Dim SPcity As Spinner and a variable to hold the city Dim
selectedcity As String in Globals.

Create a sub to add the cities to the spinner


Sub addCity
'add more cities
SPcity.Add("Christchurch")
SPcity.Add("Auckland")
SPcity.Add("Wellington")
SPcity.Add("Dunedin")
SPcity.Add("Hamilton")
End Sub

At the end of Sub Activity_Create add the following code to load the spinner with the
cities Give it a default value SPcity.SelectedIndex = 1 so it loads a city at startup. AddCity
will load the cities above to the spinner.
addCity
SPcity.SelectedIndex = 1
Activity.Title="Mothership for weather app for " & selectedcity

This is the click event on the spinner, passing the value of what you clicked on to the
selectedcity variable. It also turns on a button to save the city to a text file.
Sub SPcity_ItemClick (Position As Int, Value As Object)
'pass the value you have selected to the variable
selectedcity = Value
btnsavecity.Enabled = True
End Sub

Change the Sub btnweather_click button click event so that it loads the spinner value. Note
that it has to be lower case for the url to work.
strplace = selectedcity.ToLowerCase 'note its lower case
townpath = "http://m.metservice.com/towns/"& strplace

If you want to save it so that it will open at that city later, and when you create a widget then
you need to save it to a text file. That is really easy.
Sub btnsavecity_click
Basic For Android

Monday, 11 June 2012

Page 13

'save the city you has selected to a text file


File.WriteString(File.DirInternal, "WeatherCity.txt",selectedcity)
End Sub

Change the btnweather_click code to open the file that has been saved.
The first time you run it there is no file to draw from. So If File.Exists checks that the file is
there. If not it just uses the value that was given in the Dim selectedcity As String
:selectedcity ="Christchurch"
Sub btnweather_click
If File.Exists(File.DirInternal, "WeatherCity.txt") Then
selectedcity = File.ReadString(File.DirInternal, "WeatherCity.txt")
End If
strplace = selectedcity 'note its lower case
townpath = "http://m.metservice.com/towns/"& strplace
'Log(townpath)
req.InitializeGet(townpath)
hc.Execute(req, 1)
End Sub

Basic For Android

Monday, 11 June 2012

Page 14

4. Project The BikeFit calculator


Create the Database

Go to Firefox/Tools/ Addons. Add in the SQLite manager

After you have installed SQLite manager in to Firefox open a new database and call it
Bikefit.
Create a new table using right click Create table from the Tables(0)

Click on ADD
Add the following fields. Also call the table bikefit (or any name you want).
Read about SQLlite datatypes here http://www.sqlite.org/datatype3.html

Basic For Android

Monday, 11 June 2012

Page 15

Save the file to the Files folder

of your program, or move it there later.

Create some data to use as an example

Close out from your program and rename the file itself from bikefit.sqlite to bikefit.sql. (I
dont know why, considering that Android uses sqlite files and not sql, but it must be a bug
somewhere in the SQL Library ), and make sure its saved in your files folder.

Basic For Android

Monday, 11 June 2012

Page 16

SQL in the code

We are going to use the SQL library so need to load it in. There are two
types in this library.
An SQL object gives you access to the database. The Cursor object
allows you to process queries results.
Usually you will want to declare the SQL object as a process global
object. This way it will be kept alive when the activity is recreated. SQLite
stores the database in a single file. When we initialize the SQL object we
pass the path to a database file (which can be created if needed).
First we define our database variables.
Sub Process_Globals
Dim SQL1 As SQL
Dim cursor1 As Cursor

Now we need to start coding for it. In the Activity Sub, which runs when the program first
begins, we need to copy the database from the Assets folder to the Internals folder as files
cant be written to in the Assets folder.
Files distributed as part of an app cannot be written to in the default location. To move the
file(s) to a storage area which allows writing to the file, add the file to the app in
Activity_Create add the following code:
Sub Activity_Create(FirstTime As Boolean)
If File.Exists(File.DirInternal,"bikefit.sql") = False Then
File.Copy(File.DirAssets,"bikefit.sql",File.DirInternal,"bikefit.sql")
End If
If SQL1.IsInitialized = False Then
SQL1.Initialize(File.DirInternal, "bikefit.sql", False)
End If

Basic For Android

Monday, 11 June 2012

Page 17

Create the layout

There are a number of ways to create your layout. The most obvious is to make a panel
and attach the objects to it.
Create the panel pnlbg first, The other objects will be stuck to the panel and can be
manipulated with the panel later. At this stage size is not an issue as it can be set
programmatically.
Labels just holding text dont need to be explicitly named as they wont be in the code.
Open the Designer and the Abstract Designer and click on the Status to connect it to the
emulator
Then you can see the design in the emulator and adjust it from there as well as using the
Abstract designer to find the names of the Views. If you are lucky enough to have your
phone plugged in you can see the layout on the phone and move it around by hand as well.

Basic For Android

Monday, 11 June 2012

Page 18

In the Designer you can see the Views and their properties. Firstly set the pnlbg panel with
the values in the properties. Each of the Views you add to your layout then attaches to this
panel.

Basic For Android

Monday, 11 June 2012

Page 19

Once you have made your layout you need to generate the
members. This mostly a shortcut way to declare the variables
that you are going to use.
Go Tools, in the Designer window and then click Generate
Members
This will create the Dims in Sub Globals

Sub Globals
'These global variables will be redeclared each time the activity is
created.
'These variables can only be accessed from this module.
Dim edtarm As EditText
Dim edtseam As EditText
Dim edtshoulder As EditText
Dim edtsternum As EditText ' height
Dim
Dim
Dim
Dim
Dim

panelbg As Panel
btncalculate As Button 'run
btndelete As Button 'delete
btnsave As Button ' change
btnnew As Button 'save new

Dim bmp As Bitmap


Dim
Dim
Dim
Dim

you need to add this for later

btnarm As Button
btnseam As Button
btnshoulder As Button
btnsternum As Button

Dim LVdb As ListView

Basic For Android

Monday, 11 June 2012

Page 20

Activity Create code

After you have created your layout it needs to be added to the Sub
Activity_Create(FirstTime As Boolean) so that its loaded when the program runs.
You can replace Main with the name of whatever your layout is.
Activity.LoadLayout("Main")

We can also add the rest of the code that needs to run when the program is first created.
At the beginning of an object's life, the Java virtual machine (JVM) allocates enough
memory on the heap to accommodate the object's instance variables. When that memory is
first allocated, however, the data it contains is unpredictable.
If the memory were used as is, the behaviour of the object would also be unpredictable. To
guard against such a scenario, Java makes certain that memory is initialized, at least
to predictable default values, before it is used by any code.
Initialization is important because, historically, uninitialized data has been a common source
of bugs. The Java language, has built-in mechanisms that help you ensure proper
initialization of the memory occupied by a newly-created object. With proper use of these
mechanisms, you can prevent an object of your design from ever being created with an
invalid initial state.
Earlier we defined a bitmap image (Dim bmp As Bitmap). And now we have to initialise it
bmp.Initialize(File.DirAssets, "android48.png")
For our Edittext boxes we can specify what type of keyboard will be used. In this case we
only want numbers to be added to the boxes.
edtarm.InputType = edtarm.INPUT_TYPE_NUMBERS

Finally we want a title to appear at the top of the layout.


Activity.Title="Bike Fit: Sizing calculator"

All the code added to Activity_Create.


bmp.Initialize(File.DirAssets, "android48.png")
'uses only the numeric keyboard
edtarm.InputType = edtarm.INPUT_TYPE_NUMBERS
edtseam.InputType = edtseam.INPUT_TYPE_NUMBERS
edtshoulder.InputType = edtshoulder.INPUT_TYPE_NUMBERS
edtsternum.InputType = edtsternum.INPUT_TYPE_NUMBERS
Activity.Title="Bike Fit: Sizing calculator"

Basic For Android

Monday, 11 June 2012

Page 21

Load the Database code

Now that we have the Views loaded into the layout we can start to write the code that loads
the database into the Listview. The ListView control is a very powerful control. It allows you
to show short or long lists in a very "sleek" way. Read more about it here.
First we get the data from the database and pass it to Cursor1 which we defined earlier.
Cursor is just the name of the object that holds the data from the database, it might also be
thought of as a datatable.
Pass the data to cursor1
cursor1 = SQL1.ExecQuery("SELECT * FROM bikefit")

Then we make a For next loop, starting at 0 and ending with the rowcount 1 (because we
started at 0 instead of 1)
For i = 0 To cursor1.RowCount 1

Then we just get the data we want and pass it as a long line of data, to the
Listview.AddSingleLine
LVdb.AddSingleLine(cursor1.GetString("ID")& " : "
&cursor1.GetString("Name")& " " & cursor1.GetLong("Sternum")& " " &
cursor1.GetLong("Inseam")& " " & cursor1.GetLong("Arm")& " " &
cursor1.GetLong("Shoulder"))

We then set the details for that line and finish with the next
LVdb.SingleLineLayout.ItemHeight = 40

etc

All code.
Sub DBload
LVdb.Clear'need to clear the list
cursor1 = SQL1.ExecQuery("SELECT * FROM bikefit")
For i = 0 To cursor1.RowCount - 1
cursor1.Position = i
LVdb.AddSingleLine(cursor1.GetString("ID")& " : "
&cursor1.GetString("Name")& " " & cursor1.GetLong("Sternum")& " " &
cursor1.GetLong("Inseam")& " " & cursor1.GetLong("Arm")& " " &
cursor1.GetLong("Shoulder"))
LVdb.SingleLineLayout.ItemHeight = 40
LVdb.SingleLineLayout.Label.TextSize = 20
LVdb.SingleLineLayout.label.TextColor = Colors.Black
LVdb.SingleLineLayout.label.Color = Colors.White
Next
End Sub

Finally add DBload to the VERY END of Sub Activity_Create


startup.

Basic For Android

Monday, 11 June 2012

So that it runs at

Page 22

Listview Click Event

When we click on an item in the listview we want those numbers to be passed to the edittext
boxes in the layout. This is a Short Click event, there is also a Long Click event
Value is the data of the line that is being clicked. Value As Object It is passed to the idvalue.
idvalue = Value

We want to get the place of the first : and pass that number to countit. Then using Substring
we get the ID number by starting at 0 and going to the countit number.
countIt = idvalue.IndexOf(":") 'find location of separator
idvalue = idvalue.SubString2(0,countIt) 'find first part of label text

Now we have the ID of the row we can put it back into the database to pull out the values
again and pass them to the edittext boxes. We also could carry on using the code above to
find the next : and then getting the number from there as well.
Sub lvdb_ItemClick (Position As Int, Value As Object)' click on the entry
in the list
Dim idvalue As String
idvalue = Value
countIt = idvalue.IndexOf(":") 'find location of sperator
idvalue = idvalue.SubString2(0,countIt) 'find first part of label text
ID = idvalue
cursor1 = SQL1.ExecQuery("SELECT * FROM bikefit where ID = '" & ID & "' ")
For i = 0 To cursor1.RowCount - 1
cursor1.Position = i
edtarm.text=cursor1.getString("Arm")
edtseam.text=cursor1.getString("Inseam")
edtshoulder.text=cursor1.getString("Shoulder")
edtsternum.text=cursor1.getString("Sternum")
Next
End Sub

Basic For Android

Monday, 11 June 2012

Page 23

Delete and Update - Database commands

Clicking on the listview row selected the ID for that row, as seen above, then when you have
that number you can easily delete the row or save it back to the database if you changed it.
Sub btndelete_click
SQL1.ExecNonQuery("DELETE FROM bikefit where ID = '" &ID & "' ")
DBload
End Sub

Saving the row by taking the text from the edittext boxes.
Sub btnsave_click
SQL1.ExecNonQuery("UPDATE bikefit set Sternum ='"& edtsternum.text &"',
Inseam ='"& edtseam.text &"', Arm ='"& edtarm.text &"' , Shoulder = '"&
edtshoulder.text &"' WHERE ID = " & ID)
DBload
End Sub

Add New Record to the Database

Adding a new record uses the Dialogs library to enter the name. This
means someone else did all the hard work for you.
This library contains several modal, that is blocking, dialogs by which the user can enter
data. Presently they are an InputDialog for text, a TimeDialog for times, a DateDialog for
dates, both a ColorDialog and a ColorPickerDialog for colors, a NumberDialog for
numbers,a FileDialog for folders and file names and a CustomDialog.
Sub btnnew_click ' save new
Dim dialog As InputDialog
dialog.Input = ""
dialog.HintColor = Colors.ARGB(196, 255, 140, 0)
Dim ret As Int
ret = DialogResponse.CANCEL
ret = dialog.Show("Enter Your name", "Bike Fit", "Save", "Exit", "", bmp)
Dim strname As String ' name of person
strname = dialog.Input
If strname = "" OR edtarm.text = "" OR edtseam.text = "" OR
edtshoulder.text = "" OR edtsternum.text ="" Then
Msgbox("You have to enter all fields","Missed data field")
Else
'Grab the last ID number which is the highest number
cursor1 = SQL1.ExecQuery("SELECT ID FROM bikefit ")
If cursor1.RowCount > 0 Then
For i = 0 To cursor1.RowCount - 1
Basic For Android

Monday, 11 June 2012

Page 24

cursor1.Position = i
Dim NewID As Int
NewID = cursor1.GetInt("ID")
Next
End If
NewID = NewID +1 ' add 1 to the ID number to make a new ID field
SQL1.ExecNonQuery("INSERT INTO bikefit VALUES('" & NewID & "','" & strname
& "','" & edtsternum.text & "','" & edtseam.text & "','"& edtarm.text
&"', '" & edtshoulder.text & "')")
DBload
End If
End Sub

Code for calculate


Under the Sub Process_Globals define the following variables. They are defined here

because they will be used in other activities, Results, and Results2


Dim
Dim
Dim
Dim
Dim
Dim

helpselect As Int
lngsternum As Long
lnginseam As Long
lngarm As Long
lngshoulder As Long
ID As Int ' ID of each entry

The click event for the Run Button. Pass the data from the text boxes to the variables.
This loads the next activity called results that we make next.
StartActivity("results")

Sub btncalculate_click
lngsternum
=
edtsternum.Text
lnginseam
=
edtseam.Text
lngarm
=
edtarm.Text
lngshoulder =
edtshoulder.Text
StartActivity("results")
End Sub

Basic For Android

Monday, 11 June 2012

Page 25

The Modules tab

The modules tab on the right is really handy to use. The top section
shows you the activities in your project, while the bottom shows each
sub in your activity.. Just click on the Sub to go to that part of the code.
Easily find repeated code

If you are looking for all the places where a piece of your code, be it a
variable or view etc is repeated in your activity just double click on it to
select it. Then down the right you will see light blue lines. Scroll down to
the lines with the scrollbar and each duplicate entry will show up. Its a
really good tool.

Basic For Android

Monday, 11 June 2012

Page 26

The Results Activity

In order to show the results of the bikefit, the 4


fields from the Main layout page, we will create 2
Activities to hold the code. This might be overkill, I imagine we could have the code for the
results all on one activity, but this is to show how you can share a layout between Activities.
So we will have two activities, Results and Results2, they will both
Create a new activity and call it results
There are no process Globals as all the results are kept in this activity. You might want to
create the layout first and then generate these views using the generate tool.
Sub Globals
Dim lblhandlebar As Label
Dim Lblreach As Label
Dim btnback As Button
Dim btnnext As Button
Dim pnlHelp As Panel
Dim pnlhelp2 As Panel
End Sub

The Result and Results2 Activities uses one layout named results which has two panels
on it. pnlHelp and pnlHelp2. PnlHelp.Visible is set to True to show it for the results activity
while the second panel is set to .visible = False to hide it.
In the next Activity Results2, the panel visibility is reversed.
Sub Activity_Create(FirstTime As Boolean)
Activity.LoadLayout("results")
pnlHelp.Visible = True
pnlhelp2.Visible = False
pnlHelp.Top=0
pnlHelp.Left=0
pnlHelp.Height=Activity.Height
pnlHelp.Width=Activity.Width
Activity.Title="Bike Fit: Handlebar and Reach"
result
End Sub

The sub that calculates the results and passes it to the label
Sub result
lblhandlebar.text = (Main.lngshoulder * 0.875)&"cm" 'handlebar
Lblreach.text = ((((Main.lngsternum - Main.lnginseam) + Main.lngarm) / 2)
+ 4) &"cm"
End Sub
Basic For Android

Monday, 11 June 2012

Page 27

Sub btnnext_click
StartActivity("results2")
End Sub

Sub btnback_click
Activity.Finish
End Sub

The Results2 Activity


Sub Globals
Dim lblframe As Label
Dim lblsaddle As Label
Dim pnlHelp As Panel
Dim pnlhelp2 As Panel
Dim btnback2 As Button
Dim btnnext2 As Button
End Sub

Sub Activity_Create(FirstTime As Boolean)


Activity.LoadLayout("results")
pnlHelp.Visible = False
pnlhelp2.Visible = True
pnlhelp2.Top=0
pnlhelp2.Left=0
pnlhelp2.Height=Activity.Height
pnlhelp2.Width=Activity.Width
Activity.Title="Bike Fit: Frame and Saddle"
result
End Sub

Sub result
lblframe.text = (Main.lnginseam * 0.67)&"cm" 'frame
lblsaddle.text = (Main.lnginseam * 0.883)&"cm" 'saddle
End Sub

Sub btnnext2_click
StartActivity("results")
Basic For Android

Monday, 11 June 2012

Page 28

btnback2_click
End Sub

Sub btnback2_click
Activity.Finish
End Sub

The Results Layout using 2 panels

This layout uses two panels, and the Views for each Activity are stuck on their panel. Then
the panels are either made visible or invisible.
Here are the Views to be added to each panel. This is taken directly from the Sub Globals
Create the panel first then make sure you stick the views on them.
Results Activity
Dim pnlHelp As Panel
Dim lblhandlebar As Label
Dim Lblreach As Label
Dim btnback As Button
Dim btnnext As Button

Basic For Android

Results2 Activity
Dim pnlhelp2 As Panel
Dim lblframe As Label
Dim lblsaddle As Label
Dim btnback2 As Button
Dim btnnext2 As Button

Monday, 11 June 2012

Page 29

The Help screen

One layout with changing data depending on the case statement in the Activity.
In the Main Activity need to make a variable to hold the help number that will be accessed
later from the Help Activity. Therefore it needs to be declared in the Process Globals sub of
the Main Activity.
Sub Process_Globals
Dim helpselect As Int

In the Main activity add the code to activate each of the help buttons. We could use the
Sender property to get the value of the helpselect, which is smaller, however its nice to be
lazy sometimes.
Sub btnarm_click
helpselect = 1
StartActivity("help")
End Sub
Sub btnseam_click
helpselect = 3
StartActivity("help")
End Sub
Sub btnshoulder_click
helpselect = 4
Basic For Android

Monday, 11 June 2012

Page 30

StartActivity("help")
End Sub
Sub btnsternum_click
helpselect = 5
StartActivity("help")
End Sub

Create a new Activity and call it Help.

In the designer create a new layout called Help and layout the fields something like this.

Generate your Views into the Help Activity you made earlier, it should look something like
below. Its pretty obvious.
Sub Globals
Dim imgbox As ImageView
Dim lblhelp As Label
Dim lbltitle As Label
Dim panel1 As Panel
Dim btnclose As Button
Dim imgarm As Bitmap
Dim imgheight As Bitmap
Dim imgsternum As Bitmap
Dim imgshoulder As Bitmap
Dim imginseam As Bitmap
Dim lblcalc As Label
End Sub

Basic For Android

Monday, 11 June 2012

Page 31

In Sub Activity_Create we need to create the select statement that will load which of the 4
help information clicked on by the button.
Sub Activity_Create(FirstTime As Boolean)
Activity.LoadLayout("help")
Select Main.helpselect
Case 1 'arm
lbltitle.Text ="Measure your arm length"
lblhelp.text = "Measure from your shoulder to your knuckles. "
imgarm.Initialize(File.DirAssets,"arm.jpg")
imgbox.Bitmap = imgarm
lblcalc.Text ="This helps give your reach. (((sternum - inseam) + arm) /
2) + 4)"
Activity.Title="Bike Fit: Arm measuring"
Case 2 'height
lbltitle.Text ="Measure your height"
lblhelp.text = "In your socks or bare feet, stand with your heels and
buttocks against the wall Measure from the ground to the top of your head"
imgheight.Initialize(File.DirAssets,"height.jpg")
imgbox.Bitmap = imgheight
lblcalc.Text ="???"
Case 3 'seam
lbltitle.Text ="Measure your inner leg"
lblhelp.text = "Wear your cycling shorts, and take the measurements in
bare feet. Place a book OR other solid Object up against the top of your
inner leg pelvic bone AND measure from the top of that To the Floor."
imginseam.Initialize(File.DirAssets,"inseam.jpg")
imgbox.Bitmap = imginseam
lblcalc.Text ="Frame size = inseam * 0.67, Saddle height = inseam *
0.883"
Activity.Title="Bike Fit: Inseam measuring"
Case 4 'shoulder
lbltitle.Text ="Measure your shoulder width"
lblhelp.text = "Measure your shoulder width by the outside of the bony
protrusions at the top of your shoulders"
imgshoulder.Initialize(File.DirAssets,"shoulder.jpg")
imgbox.Bitmap = imgshoulder
lblcalc.Text ="Handle Bar width = shoulder * 0.875"
Activity.Title="Bike Fit: Shoulder measuring"
Case 5 'sternum
lbltitle.Text ="Measure from your sternum to the floor"

Basic For Android

Monday, 11 June 2012

Page 32

lblhelp.text = "In your socks or bare feet, stand with your heels and
buttocks against the wall. Measure from the ground to the sternum notch
at the top of your ribcage / bottom of your neck."
imgsternum.Initialize(File.DirAssets,"sternum.jpg")
imgbox.Bitmap = imgsternum
lblcalc.Text ="Used to calcualte Reach and Frame height, Saddle height"
Activity.Title="Bike Fit: Sternum measuring"
End Select
End Sub

Sub btnclose_click
'StartActivity("Main")
Activity.Finish
End Sub

Basic For Android

Monday, 11 June 2012

Page 33

5. Project: Online Database Communication system


This program connects to an internet server and allows the user to send and receive data,
particularly text in this case. This requires 3 parts, the Android program, a PHP interface,
and a web based database in SQL.
Android PHP script Database
First thing we need is a web based database to hold our data.

How to create an online Database


The steps below are not specific just to this website, but to any webhost using the Cpanel,
MySql and PHPAdmin programs which is a very high proportion of them.
1. Go here and create an account and WRITE YOUR DETAILS DOWN
2. Once you are logged in go to your
account and click on Go to CPanel

3. Scroll down to MySQL and click on it

4. Create a new Database using your names and pws


5. Keep a record of the details you get, you
will need them soon.
$mysql_host = "mysql8.000webhost.com";
$mysql_database = "a5858161_test";
$mysql_user = "a5858161_gary";
$mysql_password = "PW";

6. Go back to CPanel and click on PHP


MyAdmin

7. Click to enter your database

Basic For Android

Monday, 11 June 2012

Page 34

8. Create a new table for your database. It


doesnt matter how many fields, you can
add them easily when needed later (as we
will)

9. Create the following fields

10. Once created click on Insert


11. Add some sample data to your database to have something to work with

Under Browse you can see the added data

12. Go back to Insert and add some more rows set


Insert another new row so that you stay in the same window

You should now have a simple database with some data


Creating a PHP script to provide access to your database.
Basic For Android

Monday, 11 June 2012

Page 35

Android cannot directly access the internet based database so needs to go through a script.
This can be written in a number of languages such as PHP or ASP, we will use PHP as its
easy and very popular.
PHP can be written in many programming systems, even as simple as notepad. I use
Komodo Edit from http://www.activestate.com/komodo-edit however you might have another
program.
There are two ways to create your PHP page, one is to act to let Android pass directly
through and do whatever it wants to the database. This leaves the database open to
hacking and attacks, as any device can access the PHP script when you know the path so
its not a secure option.
The other way is to put your SQL code in the PHP page in functions and control what the
program does by controlling the function allowed to run. So you can stop people deleting
data by not having a delete function in the PHP code, or restricting it.
This is by far the best option. This is the code below, its quite easy to follow when you get it.
PHP starts and ends with <?php to ?> . Everything between these tags is seen as PHP
code.
Establish a connection string

This passes your DB details to 3 connection variables (created with a $ in front) which are
then passed to the connection string to gain access to the database. These 3 variables
could be named anything its the mysql_connect(Server, Username, Password) that is
the key here.
When you have a connection to the database you need to select the table in that database
you want. mysql_select_db("Table")
$mysqlDatabaseName = "mysql8.000webhost.com";
$mysqlUsername = "a5858161_gary";
$mysqlPassword = "PW";
mysql_connect($mysqlDatabaseName, $mysqlUsername, $mysqlPassword) or
die(mysql_error());
mysql_select_db("a5858161_test") or die(mysql_error());

Once this works then you can pass whatever SQL statements you want to the database and
get replies.

Basic For Android

Monday, 11 June 2012

Page 36

Sending data to the database

In this case we send the data from the phone to the PHP of.
"http://androiddsed.host22.com/netdb.php?action=add&name=me&deviceID=deviceID&text=inputtext

The code in the PHP scans the url we send and extracts from it the values we want to pass
to the database, name, device and text.
Action is used to tell the PHP which function we are to run, Add or Getall. We can create
any number of functions and run them this way.
So here we run the Action function and get the name, device, text from the string passing it
to the variables $name, $deviceID, $text.
if($action == "add"){
$name = $_GET['name'];
$deviceID = $_GET['deviceID'];
$text = $_GET['text'];

Then we run an SQL query and pass those three variables into the database.
mysql_query("INSERT INTO webDB
(name, deviceid, text) VALUES('$name', '$deviceID', '$text') ") or die(mysql_error());

The or die(mysql_error()) is just to give an escape in case the query doesnt work, like Try
/ Catch.
Retrieving data from the database

When retrieving data from the database we just use a straight SQL statement again.
$result = mysql_query("SELECT name, text, deviceID FROM webDB") or die(mysql_error());

Data is formatted by line when it returns with "\r\n" being a line break. The string is
concatenated with a . (as opposed to a & or + that we are used to).
while($row = mysql_fetch_array($result)){
echo $row['name'];
echo "\r\n".$row['text'];
echo "\r\n".$row['deviceID']."\r\n";

This will return from


the DB
Me
Message
DeviceID

Basic For Android

In the Android code we use reader.readline to return the following in


the same order as left.
name = reader.ReadLine
linetext = reader.ReadLine
postdeviceID = reader.ReadLine

Monday, 11 June 2012

Page 37

Here is the full PHP code, save it as netdb.php or any other name you can remember.
<?php
$mysqlDatabaseName = "mysql8.000webhost.com";
$mysqlUsername = "a5858161_gary";
$mysqlPassword = "PW";
mysql_connect($mysqlDatabaseName, $mysqlUsername, $mysqlPassword) or
die(mysql_error());
mysql_select_db("a5858161_test") or die(mysql_error());
if(isset($_GET['action'])){
$action = $_GET['action'];
}
if($action == "add"){
$name = $_GET['name'];
$deviceID = $_GET['deviceID'];
$text = $_GET['text'];
mysql_query("INSERT INTO webDB
(name, deviceid, text) VALUES('$name', '$deviceID', '$text') ")
or die(mysql_error());
}
if($action == "getall"){
$result = mysql_query("SELECT name, text, deviceID FROM webDB"
die(mysql_error());

) or

//DATA OUT TO PROGRAM


while($row = mysql_fetch_array($result)){
echo $row['name'];
echo "\r\n".$row['text'];
echo "\r\n".$row['deviceID']."\r\n";
}
}
?>

Basic For Android

Monday, 11 June 2012

Page 38

Uploading your PHP script

Now we have a php script acting as a gateway to the database we need to upload it on to
the server. Thats easy.
Go to File Manager in your CPanel

Go to the Public_html folder in your account.


Then upload your file to that folder.

Done!
Check your php is working by typing in the path to the DB as well as the Getall action.
Your path will have another name, instead of android-dsed below. This should return the
sample data you have in your database.
http://android-dsed.host22.com/netdb.php?action=getall

It wont look much, just raw data on your screen something like this although I have more
data in my Database.

Basic For Android

Monday, 11 June 2012

Page 39

Android Communication Program Basic setup


The coding for this program is remarkably easy. At this stage its just
a simple system but has a myriad of potential uses. Think of this as a
bare bones system to be further developed to meet the needs.
The code is commented. Replace the Android-DSED in
req.InitializeGet("http://androiddsed.host22.com/netdb.php?&action=getall")

with the path to your own path


Test that the path is correct by putting your path http://androiddsed.host22.com/netdb.php?&action=getall in the browser If its
OK it will return the data from your database in the browser itself.

The android code below is commented to make it easy to follow.


Basically you make a connection using HTTpClient, (Dim httpC As
HttpClient ) then make a request using HTTpRequest (Dim Req As
HttpRequest).
This returns an HttpResponse which is either successful Sub
httpC_ResponseSuccess or not Sub httpC_ResponseError.
All the rest is window dressing to make it work.
When you add your text you cant have any spaces between the words as they break the
URL that being sent. So
inputtext = inputtext.Replace(" ", "_")

is added to the code to replace the spaces with an underscore


When the text is returned to the phone we want to get rid of those underlines again to make
it look nice. So use
'strip out the underscores
result = result.Replace("_"," ")

As a result it looks like ordinary text leaves the phone and ordinary text is shown back on
the phone.

Sub Process_Globals
Dim httpC As HttpClient 'the Connection client
End Sub
Sub Globals
Dim pnlbg As Panel
Basic For Android

' background panel


Monday, 11 June 2012

Page 40

Dim
Dim
Dim
Dim
Dim

btnsubmit As Button ' Send to DB


btncallDB As Button ' Retrieve from DB
txtinput As EditText ' Text entry field
lvoutput As ListView ' Show the messages from the DB
reader As TextReader ' reading the text from the DB

Dim phoneInfo As PhoneId


Dim deviceID As String
deviceID = phoneInfo.GetDeviceId ' getting the Phone ID
End Sub

Sub Activity_Create(FirstTime As Boolean)


Activity.LoadLayout("main")
httpC.Initialize("httpC")
'keeps it transparent when you scroll to see the text
lvoutput.ScrollingBackgroundColor = Colors.Transparent
End Sub
Nothing here for these two subs
Sub Activity_Resume
End Sub

Sub Activity_Pause (UserClosed As Boolean)


End Sub

click event getting data from the DB


Sub btncallDB_Click
Dim req As HttpRequest ' requesting net data
req.InitializeGet("http://androiddsed.host22.com/netdb.php?&action=getall") create the connection string
httpC.Execute(req, 1) send the request
ProgressDialogShow("Fetching all data...") make a progress dialog
that give the viewer something to look at
End Sub

Sub httpC_ResponseSuccess (Response As HttpResponse, TaskId As Int)


lvoutput.Clear clear the list box so it loads the new data in fresh
Dim result As String
'download results
result = Response.GetString("UTF8")
'strip out the underscores
result = result.Replace("_"," ")
'write it to a file
Basic For Android
Monday, 11 June 2012

Page 41

File.WriteString(File.DirInternalCache, "nettalk.txt",result)
'get it back from the file
reader.Initialize(File.OpenInput(File.DirInternalCache, "nettalk.txt"))
'read it line by line to a string called line,
Dim name As String
name = reader.ReadLine this loads the username "me"

echo $row['name'];

Dim i As Int :i = 0'dimension a counter just to show in the scrollview


Do While name <> Null
i = i+1

'run a loop while there is a line

'returns the message text echo "\r\n".$row['text'];


Dim linetext As String
linetext = reader.ReadLine
'returns the DeviceID text echo "\r\n".$row['text'];
Dim postdeviceID As String
postdeviceID = reader.ReadLine
'Set up the listview formatting and adds name and then text
lvoutput.SingleLineLayout.Label.TextSize = 16
lvoutput.SingleLineLayout.ItemHeight = 35
lvoutput.SingleLineLayout.Label.TextColor = Colors.Black
lvoutput.AddSingleLine(i&" "& name & " "& linetext)
name = reader.ReadLine
'passes only to the ME text
Loop
reader.Close
ProgressDialogHide stop the progress dialog box
lvoutput.SetSelection(0)
End Sub

Sub lvoutput_ItemClick(Position As Int, Value As Object)


Msgbox(Value, "Message") 'click on the message shows it in a msgbox
End Sub

Sub httpC_ResponseError (Response As HttpResponse, Reason As String,


StatusCode As Int, TaskId As Int)
Msgbox("Error connecting to score server"&CRLF&CRLF&Reason,"Error
("&StatusCode&")")
ProgressDialogHide
End Sub

Basic For Android

Monday, 11 June 2012

Page 42

'SUBMIT MESSAGE
Sub btnsubmit_click
Activity.Title = "Submitted"
Dim inputtext As String
inputtext = txtinput.Text
If inputtext <>"" Then 'if there is something in the textbox
inputtext = inputtext.Replace(" ", "_")
ProgressDialogShow("Submitting data...")
Dim req As HttpRequest 'create a DB request
sendrequest = "http://androiddsed.host22.com/netdb.php?action=add&name=me&deviceID="
req.InitializeGet(sendrequest & deviceID &"&text=" & inputtext)
httpC.Execute(req, 1)
Else 'if empty show an error message
ToastMessageShow("Put a message in first", False)
End If
txtinput.Text = ""
'clear the text box
End Sub

Android Communication Program Timestamp and Limit


So you got it to work, and it looks OK, however there are some major flaws.
1. How do you know when a message was sent?
2. How do you limit how many messages are returned? Every time you click Read All
the entire database is sent to you which will quickly become a pain in the neck.
3. How do we get the listview to show the data with the most recent entry at the top?
Using Timestamp

To solve the first one we could send a time with your message which gets stored on the net,
however the problem with this is that if someone else is in another part of the world that
timestamp will be different to yours.
Lets make a timestamp that is on the server so that all messages are tagged with the same
timezone.
Go back to PhpAdmin, and open your database and find the Add New Field area, it appears
in a number of windows.

Basic For Android

Monday, 11 June 2012

Page 43

Create a new field called Timestamp

The TIMESTAMP data type is used for values that contain both date and time parts.
TIMESTAMP has a range of '1970-01-01 00:00:01' UTC to '2038-01-19 03:14:07' UTC.
If the column is auto-updated, it is automatically updated to the current timestamp when the
value of any other data in the row is changed from its current value.
We can use the Timestamp as an index field as well if we want and we can perform time
calculations from it to get all the posts in the last 24 hours for example.
Using Limit

We can limit how many records are returned with the Limit command. In your PHP getall
code set the limit to 10 (LIMIT 10 ), or whatever number you wish.
Using our new Timestamp order the records by Timestamp and in reverse order (ORDER
BY TIMESTAMP DESC)
if($action == "getall"){
$result = mysql_query("SELECT name, text, deviceID FROM scoreTable
ORDER BY TIMESTAMP DESC LIMIT 10 " ) or die(mysql_error());

Save and upload your new PHP script to the server.


Cutting out the unwanted text

Notice that when you return the data to the phone it comes back with
two unwanted lines of code at lines 7 and 8 in the image.
We can easily remove this using indexof and substring commands
from our earlier exercise. Go ahead and make the changes.

Basic For Android

Monday, 11 June 2012

Page 44

Deleting data from your database.

This is easy in theory but takes more work than you think.
First make a new button on your layout and call it Btndelete.
Declare the following under Sub Globals
Dim btndelete As Button
Dim message As String holds the message string

Firstly we need to get a field to identify the row of data. The


best field for this, being the easiest, is the ID field.
In your PHP we need to call down the ID field as well so we
can use it int eh delete query. In the code below I have
added ID, and echo $row['ID']; to get the ID field into your
program.
if($action == "getall"){
$result = mysql_query("SELECT ID, name, text, deviceID FROM webDB
ORDER BY TIMESTAMP DESC LIMIT 10" ) or die(mysql_error());
//DATA OUT TO PROGRAM
while($row = mysql_fetch_array($result)){
echo $row['ID'];
echo "\r\n".$row['name'];
echo "\r\n".$row['text'];
echo "\r\n".$row['deviceID']."\r\n";
}
}

Now that it is being returned. We need to put it into the program.


Since we now have an ID field lets rebuild the following sub using ID as the main control.
As well we can do some housework.
'strip out the end text with the annoying text at the end
Dim Endstring As Int
Endstring = result.IndexOf("<!")
result = result.SubString2(0, Endstring)

Full code.
Sub httpC_ResponseSuccess (Response As HttpResponse, TaskId As Int)
lvoutput.Clear
'download results
Dim result As String
result = Response.GetString("UTF8")
Basic For Android

Monday, 11 June 2012

Page 45

'strip out the end text with the annoying text at the end
Dim Endstring As Int
Endstring = result.IndexOf("<!")
result = result.SubString2(0, Endstring)
'strip out the underscores
result = result.Replace("_"," ")
'write it to a file
File.WriteString(File.DirInternalCache, "nettalk.txt",result)
'get it back from the file
reader.Initialize(File.OpenInput(File.DirInternalCache, "nettalk.txt"))
'Starts the download Get back the ID echo $row['ID'];
Dim ID As String
ID = reader.ReadLine
'run a loop while there is a still an ID - it gets the next ID at the end
of the loop
Do While ID <> Null
'read it line by line to a string called line this loads the user name
"name"
echo $row['name'];
Dim name As String
name = reader.ReadLine
'returns the message text echo "\r\n".$row['text'];
Dim linetext As String
linetext = reader.ReadLine
'returns the message text echo "\r\n".$row['text'];
Dim postdeviceID As String
postdeviceID = reader.ReadLine
'adds name and then text otherwise will be on seperate lines
lvoutput.SingleLineLayout.Label.TextSize = 16
lvoutput.SingleLineLayout.ItemHeight = 35
lvoutput.SingleLineLayout.Label.TextColor = Colors.Black
lvoutput.AddSingleLine(ID &": "& name & " "& linetext & " " &
postdeviceID)
ID = reader.ReadLine
Loop
reader.Close
ProgressDialogHide
lvoutput.SetSelection(0)
End Sub
Basic For Android

Monday, 11 June 2012

Page 46

We now have the Device ID of the phone showing as well. If


you are just using the Emulator it comes up blank (no phone).
Later we can use the device ID to make the Me only show for
your phone.
Once we can see the data on your screen we need to find a
way to delete out the fields we want.
As we have a touch device the easiest way is to touch the
entry you dont want.

The Listview Itemclick is the event that a touch on the text raises so this will be changed
adding message = Value to the variable so that message holds the string that is raised
when you click on it. We have to declare it under Globals as well Dim message As String
Sub lvoutput_ItemClick(Position As Int, Value As Object)
message = Value
Msgbox(Value, "Message") 'click on the message shows it in a msgbox
End Sub

Finally we need to add the code under the Delete Button. First it looks in the message for
the : eg in

We want what is left of the : to get the ID number (4 or 5).


IndexOf returns the number of where the : is stripstring = IDdelete.IndexOf(":")
This number is then put into IDdelete = IDdelete.SubString2(0, stripstring) which has the
following Substring2(startnumber, endnumber) So it starts at 0 and ends at the number of
the : Of course the end number will vary depending on how many numbers in the ID eg: 4,
or 32, or 45342345.

Basic For Android

Monday, 11 June 2012

Page 47

Sub btndelete_click
Dim IDdelete As String
IDdelete = message
'need to strip the message back to the first ID, by using the indexof
Dim stripstring As Int
stripstring = IDdelete.IndexOf(":")
IDdelete = IDdelete.SubString2(0, stripstring)
'this shows me in the code if I have it right
Log(IDdelete)
Dim req As HttpRequest ' requesting net data
req.InitializeGet("http://androiddsed.host22.com/netdb.php?&action=delete&ID="&IDdelete)
httpC.Execute(req, 1)
ProgressDialogShow("deleting message...")
End Sub

In the webDB.php add the following code, anywhere outside of the other functions.
First it looks for the action delete. When it finds that it pulls out the ID which is then passed
to $deleteID and run in the SQL.
//delete messages
if($action == "delete"){
$deleteID = $_GET['ID'];
mysql_query("DELETE FROM webDB
die(mysql_error());
}

Basic For Android

WHERE ID = '$deleteID'"

Monday, 11 June 2012

) or

Page 48

6. Project: GPS Program


Creating a GPS system involves two parts, the first is getting the GPS subsystems to work
on the phone, this is pretty easy. The second part is
getting the rotating arrow in the compass to work. This is
also easy but requires accepting some design voodoo is
going on.
Start with a new project
Set your Orientation to portrait, otherwise it will change
all the time when you wave your phone around.

Create the graphic Compass

Create an imageview named IVcompass


Set it with the values for dimensions
shown in the image. They will be seen in
the code with
Dim x, y, h, w As Int

Use the Add Images to add in the


compass and the arrow and then add the
compass (the circular background
image) to the Image

File. Save the layout as Main.

Basic For Android

Monday, 11 June 2012

Page 49

The difficulty with the compass is that the background image is static but the Arrow itself
rotates depending on the GPS bearings.
Its getting that rotation of the Arrow that is the issue, we need to create a zone for the
Arrow to rotate with the rectangle object and using canvas.
Sub Process_Globals
'create a bitmap to hold the compass and the arrow
Dim imgcompass, imgArrow As Bitmap
Dim Rect1 As Rect
End Sub

Sub Globals
Dim IVcompass As ImageView 'the compass background
Dim Canvas1 As Canvas
Dim Bitmap1 As Bitmap
End Sub

Sub Activity_Create(FirstTime As Boolean)


Dim x, y, h, w As Int
Activity.LoadLayout("main.bal")
'set the compass and arrow
imgArrow.Initialize(File.DirAssets, "arrow.png")
imgcompass.Initialize(File.DirAssets, "compass.png")
Canvas1.Initialize(IVcompass)
w=IVcompass.Width
h=IVcompass.Height
Bitmap1.Initialize3(Canvas1.Bitmap)
Rect1.Initialize(0,0,w,h)
Canvas1.DrawBitmap(imgArrow, Null, Rect1)
End Sub

This should give a centred arrow on the Compass background.


Create the GPS

Import and activate the GPS and Phone Libraries.


There are three relevant objects.
The main one is GPS. The GPS manages the connection and events.
The second is Location.
A Location is a structure that holds the data available regarding a specific "fix". The data
includes the latitude and longitude coordinates, the time (expressed as ticks) of this fix
and other information like bearing, altitude etc
Basic For Android

Monday, 11 June 2012

Page 50

The Location also includes other functionalities like calculating the distance and bearing
to another location and methods to convert the coordinates string formats.
Usually you will work with Location objects passed to you in the LocationChanged events.
However you can also initialize such objects yourself (this is useful for calculating distance
and bearing between locations).
The last one is GPSSatellite. This is a structure that holds information regarding the
currently known satellites. It is passed to you in GPSStatus event.
We are also going to create a location to save out GPS to called Dim SETloc As Location
and another using the Compass Dim Compass As PhoneSensors to show the direction
North Dim NPloc As Location
Lets create a new GPS and some storage places to record locations. Dim SETloc As
Location and Dim NPloc As Location so we can always find North again. To keep track of
the current location Dim Currentloc As Location. The locations are generated in the
LocationChanged sub later on.
Sub Process_Globals
'Create the GPS
Dim GPS1 As GPS
Dim SETloc As Location 'SET LOCATION
Dim NPloc As Location 'NORTH POLE
Dim Currentloc As Location 'CURRRENT LOC FROM THE GPS
Dim Compass As PhoneSensors
Dim GPSbearing, Compassbearing As Float
Dim Latitude, Longitude, lastlat, lastlon As Double

Under Activity Create lets initialise the GPS


If FirstTime Then
'North pole
NPloc.Initialize2("90:00:00", "00:00:00") 'North Pole
SETloc.Initialize()
SETloc = NPloc 'first time pass NP to Setloc to point north
Compass.Initialize(Compass.TYPE_ORIENTATION)
GPS1.Initialize("GPS")
Currentloc.Initialize() create a location to hold current location
End If

Basic For Android

Monday, 11 June 2012

Page 51

GPS LocationChanged

The main part of the GPS is the LocationChanged sub.


Sub GPS_LocationChanged (Loc As Location)

This gives us the Location object named here loc. The heart of
the GPS
Loc can be broken down to all sorts of
properties such as Latitude and
Longitude.

We will need to pass these values back to


the screen so make 3 labels
Dim lblaccalt As Label
Dim lbllonlat As Label
Dim lblspeed As Label

As loc is stuck inside of that sub if you want to use it anywhere


else in the program you need to pass it to another Location
variable. In this case we pass it to Currentloc. This holds all of the
properties of the Loc
Currentloc = Loc
You can pass the Lat and Lon in 2 ways Decimal values or Hours,
minutes etc. You need decimal to pass to google maps, but people
like to see minutes on the screens for their GPS systems. This
'textlon = Loc.Longitude gives decimal and textlat =
Loc.ConvertToMinutes(Loc.Latitude) gives minutes, you choose
for what you need.

'textlon =
'textlat =

Loc.Longitude
Loc.Latitude

textlat = Loc.ConvertToMinutes(Loc.Latitude)
textlon = Loc.ConvertToMinutes(Loc.Longitude)

All code
Sub GPS_LocationChanged (Loc As Location)
'This Is the main event. Loc holds the data for the new fix.
Longitude = Loc.Longitude
Basic For Android

Monday, 11 June 2012

Page 52

Latitude = Loc.Latitude ' Store the new latitude position in this string
Currentloc = Loc
' make a new location called Current LOC give it
current data
Dim degrees As Float
'bearing is the direction
If GPSbearing <> Loc.BearingTo(SETloc) Then ' change the compass to point
to the setLOC
GPSbearing = Loc.BearingTo(SETloc)
degrees = (GPSbearing - Compassbearing)
Canvas1.DrawBitmap(Bitmap1, Null, Rect1)
Canvas1.DrawBitmapRotated(imgArrow, Null, Rect1, degrees)
Activity.Invalidate()
End If
'work out speed
Dim locspeed As Double
locspeed = Loc.Speed * 3.6 '= kmh
lblspeed.Text = "Speed = " & Round2(locspeed ,2) &" KPH"
Dim textalt, textacc As Double
Dim textlat, textlon As String
'textlon =
'textlat =
textlat
textlon
textalt
textacc

=
=
=
=

Loc.Longitude
Loc.Latitude

Loc.ConvertToMinutes(Loc.Latitude)
Loc.ConvertToMinutes(Loc.Longitude)
Loc.Altitude
Loc.Accuracy

lbllonlat.Text =" Lat - " & textlat & CRLF & " Lon - " & textlon
lblaccalt.Text ="Altitude - " & Round2(textalt, 0) & " Meters" & CRLF &
"Accuracy - " & Round2(textacc, 0) & " Meters"
End Sub

Activity Pause and Resume code

The GPS turns off when you leave the activity, this is to save the battery. When you restart
the program, or reenter this activity it is turned on again. Obviously there might be times
when you dont want it turned off.
Sub Activity_Pause (UserClosed As Boolean)
'turn off the GPS to save the battery
GPS1.Stop
End Sub

Basic For Android

Monday, 11 June 2012

Page 53

Sub Activity_Resume
'start listening for GPS - turn it on
If GPS1.GPSEnabled = False Then 'turn on your GPS
ToastMessageShow("Please enable the GPS device", True)
'Will open the relevant settings screen.
StartActivity(GPS1.LocationSettingsIntent)
Else
'Listen to GPS with no filters.
'The Start method receives two values which are the minimum time
(milliseconds) AND the minimum distance (meters) between events. An event
will be raised when at least one of these criterions are met. This can
help saving battery. In our case we are passing 0 AND therefore will get
all fix events.
GPS1.Start(0,0)
End If
Compass.StartListening("Orientation")
End Sub

The Orientation_SensorChanged sub

Orientation_SensorChanged is used to expose the changes in the GPS to the arrow on the
compass. The code is trying to limit the compass reading to +/- 360 in quarter degrees units
by using an integer value for x where x Is the value of the compass bearing * 4, rather than
using the raw GPS values and so smoothing it out and saving on battery and CPU.
The If statement, If Compassbearing <> x/4.0 Then checks if the stored value for the
bearing has changed (that Is, has the bearing changed by more than a degree); If so, it
updates the stored value and moves the arrow.
Sub Orientation_SensorChanged(Values() As Float)
Dim degrees As Float, x As Int
x = ((2880 + Values(0) * 4) Mod 2880) - 1440
If Compassbearing <> x/4.0 Then
Compassbearing = x/4.0
degrees = GPSbearing - Compassbearing
Canvas1.DrawBitmap(Bitmap1, Null, Rect1)
Canvas1.DrawBitmapRotated(imgArrow, Null, Rect1, degrees)
Activity.Invalidate()
End If
End Sub

Basic For Android

Monday, 11 June 2012

Page 54

GPS on Google maps using Intents

We are going to add the Google map link as a menu item. You can easily use a button but
menus are good to develop
Add the following to Sub Activity_Create
Activity.AddMenuItem("Google Map Location", "Googlemap")

Then at the bottom of the code have a click event for that menu item. Sub Googlemap_click
Intent objects are messages which you can send to the OS in order to do some external
action in the phone. We want to open the Google maps on the cell phone.
Firstly you have define a new intent, Dim Intent1 As Intent
Then initialise it with the options you want Initialize (Action As String, Uri As String)
Intent1.Initialize(Intent1.ACTION_VIEW,URI)

Gets or sets the Intent action. Other actions are .

ACTION_APPWIDGET_UPDATE As String
ACTION_CALL As String
ACTION_EDIT As String
ACTION_MAIN As String
ACTION_PICK As String
ACTION_SEND As String
ACTION_VIEW As String

Then we need a SetComponent (Component As String). Explicitly sets the component that
will handle this intent.
Intent1.SetComponent("googlemaps")

The Intent object should finally be started with StartActivity keyword StartActivity(Intent1)
Sub Googlemap_click
Dim Intent1 As Intent
URI= "geo:" & Latitude & "," & Longitude & "?q=" & Latitude & "," &
Longitude
Intent1.Initialize(Intent1.ACTION_VIEW,URI)
Intent1.SetComponent("googlemaps")
StartActivity(Intent1)
'streetview works as well
' URI= "google.streetview:cbll=" & Latitude & "," & Longitude & "&cbp=1"
'google.streetview:cbll= Latitude, Longitude
&cbp=1,yaw,,pitch,zoom&mz=mapZoom
End Sub
Basic For Android

Monday, 11 June 2012

Page 55

This should give you a start with working with GPS. From here
you could make a DB and save GPS locations then show the
distance between them and current position.

7. Project: GPS and the net SQL: Record


your position online
Now we have two programs that can come together to make
something interesting. What if we were able to save our latitude
and longitude to an SQL database table on the net? Then we, or
someone else, could download those coordinates, and run them
through the Google maps to see where we are, or were. This is
easy to do.
Check back with the earlier program to get the finer details of what
we must do.
Here are the steps.
Create a new database table

1. Create a new table in your SQL database named GPSLocation make 5 fields

Set them as below.

You now have 2 tables in your database

Basic For Android

Monday, 11 June 2012

Page 56

Create a new PHP script

We could use the same PHP script we made before but lets make a new one so we can
keep it with our program in the same folder to make it easier updating. Copy and paste your
webDB.php file and save it as GPSLocation.php into your project.
Add a new function addgps
if($action == "addgps"){
$lat = $_GET['lat'];
$lon = $_GET['lon'];
$deviceID = $_GET['deviceID'];
mysql_query("INSERT INTO GPSlocation
(lat, lon, deviceid) VALUES('$lat', '$lon', '$deviceID') ")
or die(mysql_error());
}

We are using the INSERT command and this will make a new entry each time it saves.
However you might want to consider using an UPDATE command which will just change the
single saved GPS location if you only want to record the current location.
UPDATE table_name
SET column1=value, column2=value2,...
WHERE some_column=some_value

Use the Submit code from the last exercise to submit this to the DB.
First define the following under Sub Process_Globals
Dim phoneInfo As PhoneId
Dim deviceID As String
deviceID = phoneInfo.GetDeviceId ' getting the Phone ID
Dim httpC As HttpClient 'the Connection client

Initialise the HTTPC under Sub Activity_Create(FirstTime As Boolean)


httpC.Initialize("httpC")

Click on the HTTP library and the Phone Library to add it to the project.
Add the Menu button code to the Activity_Create
Activity.AddMenuItem("Upload Location", "uploadlocation")

Basic For Android

Monday, 11 June 2012

Page 57

Create a new sub, Sub uploadlocation_click that is the click event of the menu item
above, add the code full version below to it. And try it.
The 'sendrequest1 comment can be used to check if the php script is working, without
having to see if the rest is OK. Just change the request to req.InitializeGet(sendrequest1).
Here you can clearly see the 3 code blocks of Sending, Sub httpC_ResponseSuccess, and
Sub httpC_ResponseError needed to work with HTTP.
'SUBMIT GPS
Sub uploadlocation_click
variables to hold the lat and lon locations
Dim lat, lon As Double
lon = Currentloc.Longitude
lat = Currentloc.Latitude
Just a dialog to tell the user something is working
ProgressDialogShow("Submitting GPS ...")
Make a request
Dim req As HttpRequest
sendrequest = "http://androiddsed.host22.com/gpslocation.php?action=addgps&lat="
'sendrequest1 = "http://androiddsed.host22.com/gpslocation.php?action=addgps&lat=456&lon=123&deviceID=123
456"
Sending the request
req.InitializeGet(sendrequest & lat & "&lon=" & lon &"&deviceID=" &
deviceID)
httpC.Execute(req, 1)
Check to see what is going is OK
Activity.Title = lat &" "&lon &" " & deviceID
End Sub

Sub httpC_ResponseSuccess (Response As HttpResponse, TaskId As Int)


show a message
ToastMessageShow("Success GPS uploaded", False)
Turn the dialog off
ProgressDialogHide
End Sub

Sub httpC_ResponseError (Response As HttpResponse, Reason As String,


StatusCode As Int, TaskId As Int)
Msgbox("Error connecting to score server"&CRLF&CRLF&Reason,"Error
("&StatusCode&")")
ProgressDialogHide
End Sub

Basic For Android

Monday, 11 June 2012

Page 58

Your Database will show the details right. If your


program hasnt picked up the location it will return 0.
Thats still OK its just a GPS issue rather than a coding
issue (hopefully).

Getting satellites
Sub GPS_GpsStatus (Satellites As List)
'This event allows you To display information about the currently
available satellites. Note that Not all satellites in the List are
actually used For calculating the last fix. So it Is possible that the
List will include several satellites but still the reception Is Not good
enough For a fix.
Dim SatCount As Int
SatCount = 0
For i = 0 To Satellites.Size - 1
'loop through counting satellites
Dim Satellite As GPSSatellite
Satellite = Satellites.Get(i)
If Satellite.UsedInFix = True Then SatCount = SatCount + 1
Next
lblsatt.Text = "Satellites In View: " & Satellites.Size & "
SatCount

Used: " &

End Sub

Basic For Android

Monday, 11 June 2012

Page 59

Retrieving data from the database and displaying distance to saved GPS location

We have the GPS location saved in the database and


now we want it back in the phone.

First we need the PHP code to call. I kept it simple by


using the same structure as the last exercise but changing the limit to 1. ORDER BY
TIMESTAMP DESC LIMIT 1 This means it takes the most recent entry only.
if($action == "getgps"){
$result = mysql_query("SELECT lat, lon, deviceID FROM GPSLocation ORDER BY
TIMESTAMP DESC LIMIT 1" ) or die(mysql_error());
//DATA OUT TO PROGRAM
while($row = mysql_fetch_array($result)){
echo $row['lat'];
echo "\r\n".$row['lon'];
echo "\r\n".$row['deviceID']."\r\n";
}
}

In Sub Activity_Create(FirstTime As Boolean) create a new menu item to use as


the click event.
We also want to create a new Location named SavedLocation that will allow me to get
distance and bearing from the current location to the saved location.
In Globals create the Location object Dim savedlocation As Location, and initialise it
in Activity Create below.
Activity.AddMenuItem("Download to GoogleMaps", "downloadgps")
savedlocation.Initialize()

Basic For Android

Monday, 11 June 2012

Page 60

Then in a new click event for the menu I put the following which by now is quite
straightforward calling the getgps function in the gpslocation.php above.
'GET THE GPS BACK INTO THE PHONE FROM THE DB
Sub downloadgps_click
Dim req As HttpRequest ' requesting net data
req.InitializeGet("http://androiddsed.host22.com/gpslocation.php?&action=getgps")
'(req, 2) means it has a taskid of 2 see in the Sub httpC_ResponseSuccess
httpC.Execute(req, 2)
ProgressDialogShow("Fetching all data...")
End Sub

The result that is returned comes in via the httpC_ResponseSuccess. The pattern is the
same as the previous example. Read the data in line by line to a datafile, read it out to the
variables.
When we get the Lat and Lon, pass them to the savedlocation.Latitude to be used later. The
deviceID is downloaded but not used at this point. After getting the data we close the
reader with reader.Close.
Using the previous code for the GoogleMaps we pass the data to the maps. Finally with our
new SavedLocation we can see the distance from current GPS location to that point.
Sub httpC_ResponseSuccess (Response As HttpResponse, TaskId As Int)
'(req, 1) means that taskID = 1 the upload function only
If TaskId = 1 Then
ToastMessageShow("Success GPS uploaded", False)
ProgressDialogHide
Else
'Any other function with a taskID of 2 - the download function
Dim result As String result from the database being passed in
result = Response.GetString("UTF8")
'write it to a file
File.WriteString(File.DirInternalCache, " gpsdownload.txt",result)
'get it back from the file
reader.Initialize(File.OpenInput(File.DirInternalCache, "
gpsdownload.txt"))
Dim latgps As String make a latitude variable to hold lat
latgps = reader.ReadLine read the data to the variable
savedlocation.Latitude = latgps save it also to the savedlocation object
Dim longps As String
Basic For Android

Monday, 11 June 2012

Page 61

longps = reader.ReadLine
savedlocation.Longitude = longps
Dim deviceID As String
deviceID = reader.ReadLine
reader.Close
Dim Intent1 As Intent
URI= "geo:" & latgps & "," & longps & "?q=" & latgps & "," & longps
Intent1.Initialize(Intent1.ACTION_VIEW,URI)
Intent1.SetComponent("googlemaps")
StartActivity(Intent1)
Activity.Title = "Distance to location " &
Currentloc.DistanceTo(savedlocation)& " in meters"
End Sub

Here is a pic of the Google maps showing the saved location at and the current location
with the blue Arrow. (Note this this pre earthquake so there are far more buildings and cars).
You can see on the title bar that the distance is 80.2 meters to the saved location.

As the distance has a ridiculous amount of decimal spaces in it lets round it off to 2 decimal
places. Round2(distloc, 2) is the primary code for this.
Dim distloc As Long
distloc = Currentloc.DistanceTo(savedlocation)
distloc = Round2(distloc, 2)
Activity.Title = "Dist to saved location " & distloc & " meters"

Basic For Android

Monday, 11 June 2012

Page 62

8. Project: Getting an address from a Geolocation using


XML
As well as returning a map reference from lat and lon you can also use Google to return the
actual address of the place as well.
Instead of adding this ability to the last exercise I have left it as a stand alone project so that
you can add it in yourself, and see how it works. (Otherwise the code gets mixed up and
you never know what does what). Its your job to add it in.
The data that is returned comes down in an XML format and has to be parsed using
XMLSAX. SAX (Simple API for XML) is an event-based sequential access parser API
developed by the XML-DEV mailing list for XML documents to return XML to a useable
structure.
The edtgeo text field is only there so you can see the output returned from Google. You can
see in the code where it looks for the <formatted Address> field and extracts it to show in
the Message Box below.
If Name = "formatted_address" Then
'then pass the address details to the items list
Address = Text.ToString
Items.Add(Address)

Basic For Android

Monday, 11 June 2012

Page 63

Here is all the code and the libraries on the right


Sub
Dim
Dim
Dim
Dim
End

Process_Globals
GPS1 As GPS
Parser As SaxParser
'Parser library
hc As HttpClient
'Required to connect to the Internet
req As HttpRequest
Sub

Sub
Dim
Dim
Dim
Dim
Dim

Globals
lblLon As Label
lblLat As Label
lblSpeed As Label
Button1 As Button
edtgeo As EditText

Dim gLatitude As Float


Dim gLongitude As Float
Dim Address As String 'Variable to save the Address parsed
Dim Items As List 'A list to hold parsed items
End Sub

Sub Activity_Create(FirstTime As Boolean)


If FirstTime Then
GPS1.Initialize("GPS")
End If

Activity.LoadLayout("1") ' the layout is called 1 instead of main, just


for variety
Parser.Initialize
hc.Initialize("hc")
Items.Initialize
'this formats up the text box to make it as big as possible.
edtgeo.Width = Activity.Width ' the width of the phone
edtgeo.Top = 250 ' 250 from the top to show the button etc
edtgeo.Left = Activity.left ' left hand side
edtgeo.Height = Activity.Height - 250 ' height of the phone - the 250
End Sub

Sub Activity_Resume
If GPS1.GPSEnabled = False Then
ToastMessageShow("Please enable the GPS device.", True)
Basic For Android

Monday, 11 June 2012

Page 64

StartActivity(GPS1.LocationSettingsIntent) 'Will open the relevant


settings screen.
Else
GPS1.Start(0, 0) 'Listen to GPS with no filters.
End If
End Sub

Sub Activity_Pause(UserClosed As Boolean)


GPS1.Stop
End Sub

Sub GPS_LocationChanged(Location1 As Location)


gLatitude = Location1.Latitude
gLongitude = Location1.Longitude
'show the lat
lblLat.Text =
lblLon.Text =
lblSpeed.Text

and lon on the labels


"Latitude = " & gLatitude
"Longitude = " & gLongitude
= "Speed = " & Location1.Speed

'when you get a GPS fix then make the button show
If Location1.Latitude <> 0 AND Location1.Longitude <> 0 Then
Button1.Visible = True
End If
End Sub

Sub GPS_UserEnabled(Enabled As Boolean)


'just shows you have GPS enabled
ToastMessageShow("GPS device enabled = " & Enabled, True)
End Sub

Sub Button1_Click
Items.Clear 'Empty the list
edtgeo.Text = "" ' empty the text box
'send the request to the server
req.InitializeGet("http://maps.googleapis.com/maps/api/geocode/xml?latlng=
" & gLatitude & "," & gLongitude & "&sensor=true")
hc.Execute(req, 1)
End Sub

Basic For Android

Monday, 11 June 2012

Page 65

If you get a result back then save it to a text file - File.OpenOutput(File.DirDefaultExternal,


"Geo.xml", False).
'GetAsynchronously (EventName As String, Output As java.io.OutputStream, CloseOutput
As Boolean, TaskId As Int) As Boolean

'EventName As String = GetGeoLocation


'Output As java.io.OutputStream = File.OpenOutput(File.DirDefaultExternal,
"Geo.xml", False)
'CloseOutput As Boolean = true
'TaskId As Int = taskID
Sub hc_ResponseSuccess(Response As HttpResponse, TaskId As Int)
Response.GetAsynchronously("GetGeoLocation",File.OpenOutput(File.DirDefaul
tExternal, "Geo.xml", False), True, TaskId)
End Sub

Sub hc_ResponseError(Response As HttpResponse, Reason As String,


StatusCode As Int, TaskId As Int)
If Response <> Null Then
Msgbox("Connection Error", "")
Response.Release
End If
End Sub

Geolocation
'when the GetGeoLocation from the Response above has finished
Sub GetGeoLocation_StreamFinish(Success As Boolean, TaskId As Int)
Dim in As InputStream
'read the file into the input stream variable
in = File.OpenInput(File.DirDefaultExternal, "Geo.xml")
edtgeo.Text= File.ReadString(File.DirDefaultExternal, "Geo.xml")
'parse it through the parser and name the event as "Parser"
Parser.Parse(in, "Parser")' below are the start and end events of the
parsing. Close the input stream
in.Close
'show the items list that is filled below in the Parser_EndElement
Msgbox(Items.Get(0), "")
End Sub

XML parser

The last two are happening at the start and the end of Parser.Parse(in, "Parser")
Sub Parser_StartElement(Uri As String, Name As String, Attributes As
Attributes)
End Sub

Basic For Android

Monday, 11 June 2012

Page 66

Sub Parser_EndElement(Uri As String, Name As String, Text As


StringBuilder)
'if there is Activity result (> -1)
If Parser.Parents.IndexOf("result") > -1 Then
'if the name (the string being parsed above) has in it formatted address
If Name = "formatted_address" Then
'then pass the address details to the items list
Address = Text.ToString
Items.Add(Address)
End If
End If
End Sub

9. Getting an error in your hc_ResponseSuccess? Fix the


taskID.
If you are adding in new code that calls the internet into your program you may / will get an
error that we havent covered so far.
Each call to the internet via the HTTP used the code similar to hc.Execute(req, 1). The 1 is
the taskID that is passed to the hc_ResponseSuccess. You see it being passed as TaskId
As Int.
Sub hc_ResponseSuccess(Response As HttpResponse, TaskId As Int).
Multiple calls to the net all return through the same subroutine above and regardless of what
they do will work with every line of text in there. To prevent errors occurring, which they will,
we need to change our taskID for each request.
So 3 calls to the net for different processes will look like this.
hc.Execute(req, 1).
hc.Execute(req, 2).
hc.Execute(req, 3).
Then in your hc_ResponseSuccess bracket your response code with the appropriate taskID
Sub hc_ResponseSuccess(Response As HttpResponse, TaskId As Int).
If taskID = 1 then
End if
If taskID = 2 then
End IF
If taskID = 3 then
End if

Basic For Android

Monday, 11 June 2012

Page 67

10.

Project: Creating a Weather Widget

Widgets are the little programs that run on the front of your phone. They are active
programs, and more than just shortcuts that open the program.
Widgets are created and managed in another process, different than the process that your
application is running in. So its not just a front end of your
program and they run when your program has turned off. They
use a Service Module rather than the Activity Module that we
are used to. Each widget is tied to their own Service Module.
Through this module the widget is created and updated.
In this case we are making the Widget alongside the same
temperature program we made previously, but it could be in
a new program. The program only shares the text file that holds
the city selected.

The home screen application (the front of your phone) hosts your widgets and means that it
is not possible to directly access the widgets views. Instead we use a special object named
RemoteViews which gives us indirect access to the widget views.
Widgets do not support all views types. The following views are supported:
-

Button (default drawable)


Label (ColorDrawable or GradientDrawable)
Panel (ColorDrawable or GradientDrawable)
ImageView
ProgressBar (both modes)

All views only support the Click event.

To make a widget we have to add a Service module. Note that the service module
handling the widget is a standard service. Design the widget layout with the designer.

Basic For Android

Monday, 11 June 2012

Page 68

The Service Module

Create a Service module by going Project / Service Module. Name it ServiceWidget

A Service Module is good for scheduling a repeating task. By calling StartServiceAt you
can schedule your service to run at a specific time. You can call StartServiceAt in Sub
Service_Start to schedule the next time and create a repeating task (for example a task
that checks for updates every couple of minutes).
You can also run a service after the phone boots by checking Project - Service properties Start At Boot your service will run after boot is completed.

The Service Module has familiar areas to the Activity Module we have used to date.
Sub Process_Globals is the place to declare the service global variables. There is no
Globals sub like in Activity as Service doesn't support Activity objects. Sub process globals
should only be used to declare variables.
Note that Process_Global variables are kept as long as the process runs and are accessible
from other modules.
Sub Service_Create is called when the service is first started. This is the place to initialize
and set the process global variables. Once a service is started it stays alive until you call
StopService or until the whole process is destroyed.
Sub Service_Start is called each time you call StartService (or StartServiceAt). When
this subs runs the process is moved to the foreground state. Which means that the OS will
not kill your process until this sub finishes running. If you want to run some code every
couple of minutes / hours you should schedule the next task with StartServiceAt inside this
sub.
Sub Service_Destroy is called when you call StopService. The service will not be running
after this sub until you call StartService again (which will run Sub Service_Create followed
by Sub Service_Start).

Basic For Android

Monday, 11 June 2012

Page 69

A Standard template for a Widget in the Service Activity


Sub Process_Globals
Dim rv As RemoteViews
End Sub
Sub Service_Create
rv = ConfigureHomeWidget("LayoutFile", "rv", 0, "Widget Name")
End Sub
Sub Service_Start (StartingIntent As Intent)
If rv.HandleWidgetEvents(StartingIntent) Then Return
End Sub
Sub rv_RequestUpdate
rv.UpdateWidget
End Sub
Sub rv_Disabled
StopService("")
End Sub
Sub Service_Destroy
End Sub

The code below is in the order that it can be placed on the Service Activity
Open your weather program and add a Service Module to it. Then add in the code.
'Service module
Sub Process_Globals
Dim rv As RemoteViews
Dim hc, hcimage As HttpClient
Dim req, reqimage As HttpRequest
Dim temp, strplace, townpath, pic, selectedcity, temperature As String
Dim oldtemp As Short : oldtemp = 0
' holds the old temperature
End Sub

Basic For Android

Monday, 11 June 2012

Page 70

ConfigureHomeWidget("wlayout", "rv", 0, "Temp Widget 26-4")


The four parameters are: layout file, event name, update interval and the widget name.
Widget name = the name that will appear in the widgets List.
Event name sets the subs that will handle the RequestUpdate AND Disabled events.
You can configure the widget and set it to update every 24 hours (1440 minutes). The
interval, measured in minutes, defines how often will the widget request To update itself. Set
To 0 To disable automatic updates. Updating the widget too often will have a bad impact on
the battery. The minimum value Is 30 minutes. We can use a timer to get a shorter interval.
Sub Service_Create
rv = ConfigureHomeWidget("wlayout", "rv", 0, "Temp Widget 26-4")
hc.Initialize("hc")
hcimage.Initialize("hcimage")
GetTemp
End Sub

This checks the Intent message that caused this Service To start and is responsible for
raising the events related to the widget. It returns True If an event was raised.
Sub Service_Start (StartingIntent As Intent)
If rv.HandleWidgetEvents(StartingIntent) Then Return
End Sub

The widget raises two events. RequestUpdate is raised when the widget needs to update
itself. It will fire after adding the widget to the screen, after the device has booted, based on
the scheduled updating interval (If set) or after the application was updated.
Sub rv_RequestUpdate
GetTemp
End Sub

Sub rv_Disabled
StopService("")
End Sub
Sub imgNext_Click click event of the image
GetTemp
End Sub
Sub panel1_click click event of the panel
GetTemp
End Sub

Basic For Android

Monday, 11 June 2012

Page 71

This is the main sub of the widget. I will comment it throughout the code. This is mostly the
same code as we used in our earlier exercise.
Sub GetTemp
we call the selected city that has been stored in the text file of the
weather program
selectedcity = File.ReadString(File.DirInternal, "WeatherCity.txt")
What if there isnt anything in the text file? Give it a default city
If selectedcity = "" Then
selectedcity = "Auckland"
End If
We want to get two temperatures, the current temp from the internet, and
the old temp from before the update. This means you can tell if the temp
is going up or down.
If temperature <>"" Then if there is a temp then pass it to oldtemp
before getting a new temp
oldtemp = temperature
End If
strplace = selectedcity.ToLowerCase
townpath = "http://m.metservice.com/towns/"& strplace
'Just to show its updating make the temp in the label go away and make a
message show
rv.SetText("lbltemperature", "")
rv.SetText("lbltime", "Updating ...")
Update the widget
rv.UpdateWidget
req.InitializeGet(townpath)
hc.Execute(req, 1)
End Sub
Sub Service_Destroy
End Sub

Sub hc_ResponseSuccess(Response As HttpResponse, TaskId As Int)


Dim temp As String
temp = Response.GetString("UTF8") 'Get the whole page
'Cut beginning and end to get the code for the temp itself
temp = temp.SubString(temp.IndexOf("<div class=" & QUOTE & "summary" &
QUOTE & ">")) 'cut to first occurrence of
temp = temp.SubString2(21, temp.IndexOf("</ul></div></div>")) 'find last
occurance of
temp = temp.Replace(QUOTE,"'") ' replace double with single quotes
'pull the city from the code
Dim city As String
Basic For Android

Monday, 11 June 2012

Page 72

city = temp
'start at the 4th letter and end with the /h1
city = city.SubString2(4, city.IndexOf("</h1>"))
temperature = temp 'pull the temperature from the code
temperature = temperature.SubString(temperature.IndexOf("ul'><h2>"))
temperature = temperature.SubString2(8, temperature.IndexOf("<span "))
Dim shtemp As Short
shtemp = temperature
'get the difference between the old temp and the new temp
Dim updowntemp As Short
updowntemp = shtemp - oldtemp
'set the colors red = up blue = down white no change
Dim temptext As String
If updowntemp > 0 Then
temptext = " Up"
rv.SetTextColor("lbltemperature", Colors.RGB(255,204,225))
Else
temptext = " Down"
rv.SetTextColor("lbltemperature", Colors.RGB(141,197,224))
End If
If updowntemp = 0 Then
temptext = ""
rv.SetTextColor("lbltemperature", Colors.White)
End If
'remote view passes the data to the label
rv.SetText("lbltemperature", temperature)

pic = temp 'pull the pic from the code


pic = pic.SubString(pic.IndexOf("wx-icons/"))
'start position
pic = pic.SubString2(9, pic.IndexOf("' width")) ' 6 is the number from
counting the letters above
pic = pic.Trim
'looking for the image, is it already in the cache?
If File.Exists(File.DirInternalCache, pic) Then
'if so then load it, show the imgnext view and load an image into it
rv.SetVisible("imgnext", True)
rv.SetImage("imgnext", LoadBitmap(File.DirInternalCache, pic))
Else
Getimage 'otherwise go and get it from the net
Basic For Android

Monday, 11 June 2012

Page 73

End If
Dim strtime As String 'pull the time from the code
strtime = temp
Dim timecolon As String
timecolon = strtime.IndexOf(":") 'find the colon between the time eg
11:23am
strtime = strtime.SubString2(timecolon -2, timecolon +5) 'take 2 off and
add 5 on to get the whole time 11:23am
rv.SetText("lbltime", strtime & CRLF & city & temptext)
rv.UpdateWidget
End Sub
Sub getimage
Dim imagepath As String 'this gets the image from the net
imagepath = "http://m.metservice.com/sites/all/themes/mobile/images/wxicons/"& pic
reqimage.InitializeGet(imagepath)
hcimage.Execute(reqimage, 1)
End Sub

Sub hcimage_ResponseSuccess(Response As HttpResponse, TaskId As Int)


Response.GetAsynchronously("ImageResponse", _
File.OpenOutput(File.DirInternalCache, pic, False), True, TaskId)
End Sub

Sub ImageResponse_StreamFinish (Success As Boolean, TaskId As Int)


If Success = False Then
Msgbox(LastException.Message, "Error")
Return
End If
rv.SetImage("imgnext", LoadBitmap(File.DirInternalCache, pic))
End Sub
Sub hcimage_ResponseError(Response As HttpResponse, Reason As String,
StatusCode As Int, TaskId As Int)
If Response <> Null Then
Msgbox("Error: " & Response.GetString("UTF8")& "Cannot find ", "Connection
Error")
Response.Release
ProgressDialogHide
ToastMessageShow("Image not loading",True)
End If
End Sub
Basic For Android

Monday, 11 June 2012

Page 74

Sub hc_ResponseError(Response As HttpResponse, Reason As String,


StatusCode As Int, TaskId As Int)
If Response <> Null Then
Msgbox("Error: " & Response.GetString("UTF8")& "Cannot find ", "Connection
Error")
Response.Release
ProgressDialogHide
ToastMessageShow("bugger",True)
End If
End Sub

Basic For Android

Monday, 11 June 2012

Page 75

Designing the Temperature Widget

This is a small layout so will be tricky to show. This is


a NEW LAYOUT. Not part of the existing one that the
Activity used.
It has 5 parts.
Pnlbg a transparent panel to space the widget out from the other widgets
Panel1 a visible graduated
panel
Imgnext a small imageview
to hold the pic
Lbltime holds time and City
Lbltemperature holds the
temperature.

Basic For Android

Monday, 11 June 2012

Page 76

This is a white square behind the temperature that is curved like a circle, its hard to make
out unless you see the entire widget.

Basic For Android

Monday, 11 June 2012

Page 77

Back on your phone click your menu button (bottom left blank space on mine and click on
Add. Then click on Widgets and drag onto the phone the one we have created.

Basic For Android

Monday, 11 June 2012

Page 78

11.
Project: Alarm scheduler sends
email to contacts
This program incorporates four main areas,

An alarm which is created with date and time.


The ability to extract your contacts list from your phone
The ability to send SMS messages
Working with Lists

Imagine you wanted to send a message to some people in your contacts list
at a set time every day. This program does that.
There are two Modules, a Main Activity module and a Service Module. The
main module sets up the program while the service module runs when the
alarm time equals the cell phone time.

'Activity module
Sub Process_Globals
Dim alarmHours, alarmMinutes As Int
Dim noti As Notification 'shows in the notification window
End Sub
Sub
Dim
Dim
Dim
Dim

Globals
SetTime As Button
CancelAlarm As Button
lvphone As ListView
btnSavephone As Button

Dim Panel1 As Panel


Dim btnloadlist As Button
Dim edtmessage As EditText
Dim phonelist As List
Dim listOfContacts As List
End Sub
Sub Activity_Create(FirstTime As Boolean)
Activity.LoadLayout("main")
getcontacts
listOfContacts.Initialize using a List
phonelist.Initialize
End Sub

Basic For Android

Monday, 11 June 2012

Page 79

Date and Time

Main Sub to get the alarm time. (Note that Alarm isnt defined thats because I dont know
what type it is. It still works, just gives a nice red color).
Sub SetTime_Click
Dim td As TimeDialog 'the dialog from the dialog library
td.Hour = alarmHours
td.Minute = alarmMinutes
If td.Show("Select time to activate alarm", "", "Ok", "Cancel", "",
Null) = DialogResponse.POSITIVE Then
alarmHours = td.Hour
alarmMinutes = td.Minute
Dim today As Long
today = DateTime.DateParse(DateTime.Date(DateTime.Now)) 'Sets today at
12:00 AM
alarm = today + td.Hour * DateTime.TicksPerHour + td.Minute *
DateTime.TicksPerMinute
If alarm < DateTime.Now Then alarm = DateTime.Add(alarm, 0, 0, 1)
Log(DateTime.Date(alarm) & " " & DateTime.Time(alarm)) 'check the logs to
see the set date and time
'Calculate time to alarm
Dim h, m As Int
h = Floor((alarm - DateTime.Now) / DateTime.TicksPerHour)
m = ((alarm - DateTime.Now) - h * DateTime.TicksPerHour) /
DateTime.TicksPerMinute
ToastMessageShow("Alarm will start after: " & NumberFormat(h, 2, 0) & "
hour(s) and " & NumberFormat(m, 2, 0) & " minute(s)", True)
'You should schedule the next task with StartServiceAt.Android will
eventually kill your process if you use a timer. By scheduling the Next
task with StartServiceAt you make sure that a new process will be created
when the scheduled time arrives. This Is Not the Case with a regular
Timer.
StartServiceAt(AlarmService, (DateTime.Now+((h*60*60*1000)+(m*60*1000))),
True) ' Schedule AlarmService will start by add
time to DateTime.Now (note that Android use
millisecond)
This sets out the notification features that
appear on the notification front part of your
phone
noti.Initialize
noti.Light = True
noti.Vibrate = False
Basic For Android

Monday, 11 June 2012

Page 80

noti.OnGoingEvent = True
noti.Sound = False
noti.Icon = "icon" set your own image if you want
noti.SetInfo("Alarm", "will start at " & DateTime.Date(alarm) & " " &
DateTime.Time(alarm), "")
noti.Notify(1) Displays the notification. Id This id can be used to later
update this notification (by calling Notify again with the same Id),
or to cancel the notification.
End If
End Sub

Turn off the alarm


Sub CancelAlarm_Click
noti.Cancel(1) This cancels the Notification number 1 set above
StopService(AlarmService)
CancelScheduledService(AlarmService)
End Sub

Main sub to get the contacts from the Phone I left the commented out section in case you
want to see whats happening, and grab them yourself
Sub getcontacts
Dim Contacts2 As Contacts2
listOfContacts = Contacts2.GetAll(True,False)
For i = 0 To listOfContacts.Size - 1
Dim Contact As Contact
Contact = listOfContacts.Get(i)
'Logging to check how it works can uncomment
Log(Contact) 'will print the fields to the LogCat
' Dim photo As Bitmap
' photo = Contact.GetPhoto
' If photo <> Null Then Activity.SetBackgroundImage(photo)
'
Dim emails As Map
'
emails = Contact.GetEmails
'
If emails.Size > 0 Then Log("Email addresses: " & emails)
'
Dim phones As Map
'
phones = Contact.GetPhones
'
If phones.Size > 0 Then Log("Phone numbers: " & phones)
If Contact.PhoneNumber <>"" Then If there is a contact number pass it to
the listview so you can see it
lvphone.SingleLineLayout.Label.TextSize = 15
lvphone.SingleLineLayout.ItemHeight = 40
lvphone.AddSingleLine(Contact.DisplayName &": " &Contact.PhoneNumber)
lvphone.ScrollingBackgroundColor =Colors.DarkGray
End If
Next
Basic For Android

Monday, 11 June 2012

Page 81

End Sub

This is the click event on the listview. We want to take the value that we click on (the name
and phone number) and add it to our Phonelist as a List object.
Sub lvphone_ItemClick (Position As Int, Value As Object)
pass the value to details and then save it to the phone list. Might be
able to bypass all this and just go phonelist.Add(Value)
Dim details As String
details = Value
Activity.Title = details Show the name at the top as a check
Log(details) Show the name in the logs as a check
phonelist.Add(details)
End Sub

Write to a file

The button save click saves two parts, the message that you want sent, and the phone list
that you have created. These text files are then opened and used by the service when the
alarm is activated.
Note the easy File.WriteString(File.DirInternal, "message.txt", edtmessage.text) structure.
Of Filename "message.txt" and Content. edtmessage.text.
Sub btnSavephone_Click
Check to see if a message has been written and a list has been made
If
edtmessage.text <>"" AND phonelist.Size >0 Then
Write the message and list to files to be accessed later
File.WriteString(File.DirInternal, "message.txt", edtmessage.text)
File.WriteList(File.DirInternal, "phonelist.txt", phonelist)
ToastMessageShow("List saved", False)
lvphone.Clear clear the listview screen ready to show its saved
Else
bozo notification
ToastMessageShow("Save a list and write a message first", True)
End If
End Sub

Read from a file to a list

This button allows you to load the list you made to check that its the correct people in it.
This shows how easy a list is to use as well.
Sub btnloadlist_Click
Dim list1 As List
quit if no phonelist (If statements dont need an endif they are only on
one line.)
If File.Exists(File.DirInternal, "phonelist.txt") = False Then Return
Basic For Android

Monday, 11 June 2012

Page 82

pass the data to the list


list1 = File.Readlist(File.DirInternal, "phonelist.txt")
Here is the data being looped into the list
Dim j As Int
j = list1.Size make J the size of the list
If j < 0 Then Return
For i = 0 To j-1 add each item to the listview
lvphone.AddSingleLine(list1.Get(i))
Next
End Sub

'Service module
Sub Process_Globals
Dim mp As MediaPlayer
Dim noti As Notification
End Sub

' You need to declare mp as Mediaplayer


make a new notification

Sub Service_Create
End Sub

Sending an SMS

In this module the heart is Sms.Send(phonelist, messagetext) which is commented out


so you dont lose all your friends while building it.
Sub Service_Start
mp.Initialize() 'Initialize Mediaplayer
PlayAlarm run the play alarm sub
ToastMessageShow("Emails sent", True) emails sent
'LOAD LIST
Dim list1 As List
Dim messagetext As String
Dim j As Int
Dim phonelist As String
If File.Exists(File.DirInternal, "phonelist.txt") = False Then Return
list1 = File.Readlist(File.DirInternal, "phonelist.txt")
note this is ReadString as its only one word not a list
If File.Exists(File.DirInternal, "message.txt") = False Then Return
messagetext = File.ReadString(File.DirInternal, "message.txt")
j = list1.Size
If j < 0 Then Return
For i = 0 To j-1
the phone list consists of Name: number we only want number to send the
message (although we could use the name in the message field if were
Basic For Android

Monday, 11 June 2012

Page 83

wanted). So we have to do our chopping the string at : to get the number


from it
phonelist = list1.Get(i)
phonelist = phonelist.SubString2(phonelist.IndexOf(":")+2,
phonelist.Length)
Log(phonelist) check to see it working
ToastMessageShow(list1.Get(i)&" " & phonelist & " " & messagetext, False)
Dim Sms As PhoneSms
Dim number As PhoneId
Dim senttext As String
'Send (PhoneNumber As String, Text As String)
'Sms.Send(phonelist, messagetext)
Next
noti.Initialize
noti.SetInfo("message sent",messagetext,"")
End Sub

End the Service


Sub Service_Destroy
StopService("")
'Stop this service
CancelScheduledService("")
'Cancel this service
End Sub

Play the alarm


Sub PlayAlarm
mp.Load(File.DirAssets, "sound.wav")
mp.Play
End Sub

Basic For Android

Monday, 11 June 2012

Page 84

12.

Project: Text to Speech Program

The beauty of this simple little program is not in its novelty value, but that it can be added to
any other program to add functionality and make a point of difference. Imagine you add it to
your Weather Widget, or your GPS locator, so that people can just click on the program and
hear the temperature and location without taking their eyes off the road.
As well it could be the heart of a program for disabled people, and later we will use it to read
emails as well.
Note that the text read is held in the edttext.text field, which
means that any strings can be read as well.

Sub Process_Globals
Dim TTS1 As TTS
End Sub

Sub Globals
Dim barPitch As SeekBar
Dim barSpeechRate As SeekBar
Dim btnSpeak As Button
Dim EditText1 As EditText
Dim spnrLanguages As Spinner
End Sub

Sub Activity_Create(FirstTime As Boolean)


Activity.LoadLayout("1")
spnrLanguages.AddAll(Array As String("en", "fr", "de"))
'As TTS doesn't support the volume control - you can't
change the volume - you need to use Reflector to get the
Music volume, which is louder I suppose, and use that
instead.
Dim r As Reflector
r.Target = r.GetActivity
r.RunMethod2("setVolumeControlStream", 3,
"java.lang.int")
End Sub

Sub TTS1_Ready (Success As Boolean)


If Success Then
'enable all views
For i = 0 To Activity.NumberOfViews - 1
Basic For Android

Monday, 11 June 2012

Page 85

Activity.GetView(i).Enabled = True
Next
btnSpeak_Click 'play first sentence
Else
Msgbox("Error initializing TTS engine.", "")
End If
End Sub

Sub Activity_Resume
If TTS1.IsInitialized = False Then
TTS1.Initialize("TTS1")
End If
End Sub

Sub Activity_Pause (UserClosed As Boolean)


TTS1.Release
End Sub

Sub btnSpeak_Click
If EditText1.Text.Length > 0 Then
TTS1.Speak(EditText1.Text, True)
EditText1.SelectAll
End If
End Sub

Sub barSpeechRate_ValueChanged (Value As Int, UserChanged As Boolean)


If UserChanged Then
TTS1.SpeechRate = Value / 10
End If
End Sub

Sub barPitch_ValueChanged (Value As Int, UserChanged As Boolean)


If UserChanged Then
TTS1.Pitch = Value / 10
End If
End Sub

Sub spnrLanguages_ItemClick (Position As Int, Value As Object)


If btnSpeak.Enabled = False Then Return
If TTS1.SetLanguage(Value, "") = False Then
ToastMessageShow("Language data not found.", True)
Basic For Android

Monday, 11 June 2012

Page 86

Return
End If
End Sub

Text to speech stripped for other programs

Here is the stripped down version that you can just drop into your programs. Dont forget to
add the TTS library.
It doesnt have to come off the button click, thats just an example.
Dim TTS1 As TTS

Sub Activity_Resume
If TTS1.IsInitialized = False Then
TTS1.Initialize("TTS1")
TTS1.SetLanguage("en","")
End If
End Sub
Sub Activity_Pause (UserClosed As Boolean)
TTS1.Release
End Sub
Sub Button1_Click
If .yourtext.Text.Length > 0 Then
TTS1.Speak(yourtext.Text, True)
End If
End Sub

Basic For Android

Monday, 11 June 2012

Page 87

13.
Project: Capture all SMS messages entering your
phone
Imagine that when a text message came into your phone that you didnt have to stop what
you are doing and have to look to see who sent it. Maybe you are driving, working, or busy
elsewhere and want to know if its important or not.
Thats what this program does. It tells you who sent the text message so you can decide if
you need to reply immediately. This is based on the previous lessons and looks at a few of
the many features of the phone you can use in programming.
When a text message comes in the number it comes from is checked against the contacts
list in your phone. If a match is made then it speaks out the name of the person in the
contact list.
For this to work you need to have the Phone library 1.8 installed. To do that
download it from B4A website, and put it into the internal library folder, not the
usual external one. The internal folder is usually at C:\Program Files\Anywhere
Software\Basic4android\Libraries

If you have a Phone library in the external library then you need to delete it as it will
overwrite the internal Phone Library.
Logs and Toastmessageshow are crucial to debugging

Debugging is crucially important and especially so in this exercise. I have used copious
amounts of Logs and Toastmessageshow to see what is happening in the code. What is the
number coming in? How does it change when you strip it? Does it match up with the
contacts? What happens next etc.
You need to do this as well. Debugging IS coding. Not just following this exercise.

Basic For Android

Monday, 11 June 2012

Page 88

Working with Service and Activity Modules

This project has 2 main parts. An Activity Module (Main) that


holds the code for the screen above, and a Service Module
(sms) that runs all the time and listens for incoming text
messages. Another Activity module smstext holds a data file,
but its not important
I think of the Activity Module (main). as my test bed, I get the Activity module working first,
and then when its all OK I make the Service Module (sms). Thats because its easier to
think and code in the activity module and to see what you are doing and you can have
sample test data.
In this exercise I copied all the working code from the Activity Module to the Service module,
did final changes and moved the changed code back in to the Activity Module to check it.
Saving and Reading to files

When working with a Service module you need to pass data to it from the Activity module
using text files. So if you make a setting in your activity module, you have to save it as a text
file then upload it into the service module. That way the settings are saved when you turn off
your program and only the service is running.
Saving and reading from text files is really easy, and I use it throughout the code.
Here for example is data held in the details variable being written to a file "from.txt"
From = File.WriteString(File.DirInternal, "from.txt",details)

And here is the data from that "from.txt" file being passed back into the From variable.
From = File.ReadString(File.DirInternal, "from.txt")

Its fast and easy.


The Activity (main) code
'Activity module
Sub Process_Globals
Dim TTS1 As TTS 'text to speech
End Sub

Sub
Dim
Dim
Dim
Dim
Dim
Dim
Dim
End

Globals
lvphone As ListView 'the listview holding the contacts
edtmessage As EditText 'messagebox that holds the phone number
Panel1 As Panel ' background panel
Button1 As Button ' the Simulator run button
listOfContacts As List 'holds the contacts list
btnservicestart As Button ' start the service button
btnservicestop As Button 'stop the service button
Sub

Basic For Android

Monday, 11 June 2012

Page 89

Sub Activity_Create(FirstTime As Boolean)


Activity.LoadLayout("main") ' load the main layout
StartService(Sms)
If TTS1.IsInitialized = False Then ' turn on text to speech and set the
language
TTS1.Initialize("TTS1")
TTS1.SetLanguage("en","")
End If
getcontacts ' load the contacts into the listview
End Sub

Sub Activity_Resume
End Sub
Sub Activity_Pause (UserClosed As Boolean)
End Sub

Sub MessageReceived (From As String, Body As String) As Boolean


Msgbox("From " & From & " Text " & Body, "Title")
End Sub

'this sumulates a text arriving


Sub Button1_Click
smscopy ' copy of the sms activity code modified for the activity runs
End Sub

'fills the listview with the data from the contact list
Sub getcontacts
'Create a Contacts to hold the contacts from your phone. Contacts2 object
allows you to access the device stored contacts. This type is based on a
new API supported by Android 2.0 and above.This type supersedes Contacts
type.
Dim Contacts2 As Contacts2
'pass the contacts to a list to hold them. Note that each contact has
about 6 or so fields, that at the moment you can't get to
listOfContacts = Contacts2.GetAll(True,False)
'loop through each of the contacts in your new list
For i = 0 To listOfContacts.Size - 1
'for each contact pass it to the Contact object. This object allows you to
extract out each field held in filed, so you can use Contact.phonenumber
and Contact.DisplayName as well as many others.
Basic For Android

Monday, 11 June 2012

Page 90

Dim Contact As Contact


Contact = listOfContacts.Get(i)
'Logging to check how it works
Log(Contact) 'will print the fields to the LogCat
'We don't want contacts who don't have a phone number or contacts with
short number such as your phone provider. A 3 digit number will screw with
the next part of the code where we cut the beginning off.
If Contact.phonenumber <>"" AND Contact.phonenumber.Length > 7 Then
'show the name and number from the contacts list in your listview and
format it up to make it easy to read
lvphone.SingleLineLayout.Label.TextSize = 15
lvphone.SingleLineLayout.Label.TextColor = Colors.Black
lvphone.SingleLineLayout.ItemHeight = 40
lvphone.ScrollingBackgroundColor =Colors.Transparent
'data goes in here the name and number separated by a :, this is what we
use to get the name out later.
lvphone.AddSingleLine(Contact.DisplayName &": " & Contact.phonenumber)
End If
Next
End Sub

Clicking on the listview


Sub lvphone_ItemClick (Position As Int, Value As Object)
'strip out the name and leave the number and write it to the FROM text
file. its broken out at the :
Dim details As String
details = Value
details = details.SubString2(details.IndexOf(":")+2, details.Length)
'write the number in the text box
edtmessage.text = details
'write the number to the from.txt file
File.WriteString(File.DirInternal, "from.txt",details)
End Sub

Sub btnservicestop_Click
StopService(Sms) ' stop the service running (turn it off)
End Sub
Sub btnservicestart_Click
StartService(Sms) ' start the service running (turn it on)
End Sub

Basic For Android

Monday, 11 June 2012

Page 91

'I called this smscopy as its a copy of the sms main code
Sub smscopy
'this reads the file in from the from.txt. in the sms code it comes in via
the sms message
Dim From As String
From = File.ReadString(File.DirInternal, "from.txt")
'logs and toastmessages to see what is happening
ToastMessageShow("Text from " & From, True)
Log ("From before cut" & From)
'strips out the first numbers of the incoming phone number. The number
coming into the phone can have different prefixes on it to the one stored
in the phone. eg: number in is always 642.. country code and cellphone,
but the number in the contacts can be just cellphone 027.. we need to make
both equal. So stripping out the first numbers down to 7 digits fixes
this. Thats why empty entries and ones with 3 numbers are blocked earlier,
it crashes here. (took me hours to work out).
' From.Length-7 find the length of the number eg: 11, take of 7 and = 4,
so start number for the substring is 4.
'SubString2(startnumber, to end number)
From = From.SubString2(From.Length-7, From.Length)
'show me the chopped number as a check
ToastMessageShow("Chopped from " & From, True)
'same code as above getting the contacts2 list, passing it to a
listofcontacts and a contacts object to extract out the name and number.
Dim listOfContacts As List
Dim Contacts2 As Contacts2
listOfContacts = Contacts2.GetAll(True,False)
For i = 0 To listOfContacts.Size - 1
Dim Contact As Contact
Contact = listOfContacts.Get(i)
'just to see what the counter is doing
Log(i)
Dim phonenumber As String
Dim startphone, endphone As Int
If

Contact.phonenumber <>"" AND Contact.phonenumber.Length > 8 Then

Basic For Android

Monday, 11 June 2012

Page 92

'this strips out the first numbers of the phone list. its the same as we
did above but I broke it down into its component parts to make it easier
for you to read
phonenumber = Contact.phonenumber
startphone = phonenumber.Length-7
endphone = phonenumber.Length
phonenumber = phonenumber.SubString2(startphone,endphone)
Log ("From after the cut" & From)
If From = phonenumber Then
'a whole bunch of testing going on
' ToastMessageShow("PH " & phonenumber & " From " & From, True)
Log("PH " & phonenumber & " From after cut " & From)
ToastMessageShow("Incoming text from " & Contact.Name, True)
'text to speech finally working
TTS1.Speak("Text from " & Contact.Name, True)
'this text file holds the name and message, it will go on the widget so
you can read it
File.WriteString(File.DirInternal, "body.txt","From " & Contact.Name &"
This is a test message, Its a really long one, I hope you can read it
all")
Else
'ToastMessageShow("No matching contact", True)
Log("PH " & phonenumber & " From after cut " & From)
End If
End If
Next
End Sub

Basic For Android

Monday, 11 June 2012

Page 93

Code for the Service Activity(sms)


'Service module
Sub Process_Globals
Dim SI As SmsInterceptor
Dim TTS1 As TTS
'remote view for the widget RV is how the widget communicates with the
service and visa versa as we don't DIM or pass variables
Dim rv As RemoteViews
End Sub

Sub Service_Create
'starting the service in the foreground means it won't get killed by the
Android system - it stays alive
Service.StartForeground(1,"SMSInterceptor running")
'You intercept SMS messages and prevent the messages from being handled by
the default messaging application by initializing SmsInterceptor with
Initialize2 AND setting the Priority parameter To 999 (highest application
priority For Intent filters).
'This then handles the Sub SI_MessageReceived part
SI.Initialize2("SI", 999)
'make sure text to speech is initialised and set the details
If TTS1.IsInitialized = False Then
TTS1.Initialize("TTS1")
TTS1.SetLanguage("en","")'language
End If
Log("Service initialized")
'Widget name - the name that will appear in the widgets List.
rv = ConfigureHomeWidget("smslayout", "rv", 0, "SMS Inteceptor")
End Sub

Sub Service_Start (StartingIntent As Intent)


'setting out the notification features of the phone
Dim noti As Notification 'shows in the notification window
noti.Initialize
noti.Icon = "icon"
'noti.Notify(1)
noti.Sound=False
noti.Vibrate = False
noti.Light = False
'this runs the next Activity (smstext)
noti.SetInfo("SMS Interceptor","Running", "smstext")
Service.StartForeground(1, noti)
ToastMessageShow("SMS inteceptor has started", False)

Basic For Android

Monday, 11 June 2012

Page 94

'This code checks the Intent message that caused this service to start in
this case the text message recieved and is responsible for raising the
events related to the widget. It returns true if an event was raised.
If rv.HandleWidgetEvents(StartingIntent) Then Return
End Sub

Sub Service_Destroy
SI.StopListening()
Service.StopForeground(1)
ToastMessageShow("SMS inteceptor has stopped", False)
End Sub

'The heart of the program


Sub SI_MessageReceived (From As String, Body As String) As Boolean
'Body and From are the two parts of the text message that are passed into
the phone from the incoming sms
ToastMessageShow("Text from " & From, True)
Log ("From before cut" & From)
'strips out the first numbers of the incoming phone number
From = From.SubString2(From.Length-7, From.Length)
'ToastMessageShow("Chopped from " & From, True)
Dim listOfContacts As List
Dim Contacts2 As Contacts2
listOfContacts = Contacts2.GetAll(True,False)
For i = 0 To listOfContacts.Size - 1
Dim Contact As Contact
Contact = listOfContacts.Get(i)
'this strips out the first numbers of the phone list
Dim phonenumber As String
Dim startphone, endphone As Int
If Contact.phonenumber <>"" AND Contact.phonenumber.Length > 8 Then
phonenumber = Contact.phonenumber
startphone = phonenumber.Length-7
endphone = phonenumber.Length
phonenumber = phonenumber.SubString2(startphone,endphone)
Log ("From after the cut" & From)
'write a file to open with the widget
Basic For Android

Monday, 11 June 2012

Page 95

File.WriteString(File.DirInternal, "body.txt","From " & From & " " & Body)
If From = phonenumber Then
' ToastMessageShow("PH " & phonenumber & " From " & From, True)
Log("PH " & phonenumber & " From after cut " & From)
ToastMessageShow("Incoming text from " & Contact.Name, True)
TTS1.Speak("Text from " & Contact.Name, True)
File.WriteString(File.DirInternal, "body.txt","From " & Contact.Name & " "
& Body)
Else
'ToastMessageShow("No matching contact", True)
Log("PH " & phonenumber & " From after cut " & From)
End If
End If
Next
updateTheWidget
End Sub

'this loads the widget with the updated information


Sub updateTheWidget
Dim message As String
message = File.ReadString(File.DirInternal, "body.txt")
If message <>"" Then
show the message on the lbltext on the widget
rv.SetText("lbltext", message)
Else
rv.SetText("lbltext", "No message")
End If
'update the widget action
rv.updatewidget
End Sub
'click on the panel to update the widget
Sub pnlcolor_click
updatewidgettext
End Sub

Sub updatewidgettext
rv.SetText("lbltext","Working ...")
ToastMessageShow("Click event on lblclick?", True)
Dim message As String
Basic For Android

Monday, 11 June 2012

Page 96

message = File.ReadString(File.DirInternal, "body.txt")


If message <>"" Then
show the message on the lbltext on the widget
rv.SetText("lbltext", message)
Else
rv.SetText("lbltext", "No message")
End If
rv.updatewidget
End Sub

Sub rv_RequestUpdate
rv.updatewidget
End Sub
Sub rv_Disabled
StopService("")
End Sub

The Activity(smstest)

This activity is just a tacked on piece, its working code but I think it might be better used
elsewhere. What I was trying to do is when a message is received and the Notification is
activated a text is placed in the Notification window.
This is loaded in with the code from the Service
'this runs the next Activity (smstext)
noti.SetInfo("SMS Interceptor","Running", "smstext")

If we want to see what the message is then we can click on the notification and it will run the
"smstext" activity which loads the messagebox with the message.

Basic For Android

Monday, 11 June 2012

Page 97

Sub Globals
End Sub
Sub Activity_Create(FirstTime As Boolean)
If File.Exists(File.DirInternal, "body.txt") = False Then
ToastMessageShow("No message", False)
Else
Dim message As String

message = File.ReadString(File.DirInternal, "body.txt")


Msgbox(message, "latest message")
End If
Activity.Finish
End Sub
Sub Activity_Resume
End Sub
Sub Activity_Pause (UserClosed As Boolean)
End Sub

Designing the Widget

This widget is almost exactly the same as the last widget we made.
We have the following

Pnlbg transparent background panel


Pnlcolor color panel with curved corners
Lbltext holds the text of the message
IVimage holds the icon.

Basic For Android

Monday, 11 June 2012

Page 98

14.

Project: Voice Recognition program

This simple little program is easy to create and can add variety and value to your Android
programs.
All it requires is a layout with a button on it. The VR program generates its own interface.
The button doesnt have to be as big as it is it does not affect the VR layout.
We will use this program later back in our last program to allow you to talk in commands to
create text messages mostly by just adding this entire activity as a new activity to the
program.
Designer

Running

Google VR Program runs generating


its own interface

Basic For Android

Monday, 11 June 2012

Page 99

'Activity module
Sub Process_Globals
Dim VR As VoiceRecognition
Dim TTS1 As TTS
End Sub
Sub Globals
End Sub
Sub Activity_Create(FirstTime As Boolean)
If FirstTime Then
VR.Initialize("VR")
TTS1.Initialize("TTS1")
End If
'load the layout named 1 (just a button)
Activity.LoadLayout("1")
'tells the user if they can use voice recognition
If VR.IsSupported Then
ToastMessageShow("Voice recognition is supported.", False)
Else
ToastMessageShow("Voice recognition is not supported.", True)
End If
'just a text message on the program neat the top
VR.Prompt = "Say your message"
End Sub
Sub Button1_Click
VR.Listen 'calls the voice recognition external activity
End Sub
Sub VR_Result (Success As Boolean, Texts As List)
'Texts is a list object, the VR program creates a list of potential
phrases it hears ie: You say "Today is hot" it lists "Today is not",
"Today is snot" "Today is a lot" etc, then lists it in order of preference
and at Texts.Get(0)gives the most likely choice "Today is Hot".
If Success = True Then
ToastMessageShow(Texts.Get(0), True)
TTS1.Speak(Texts.Get(0), True)
End If
End Sub

Basic For Android

Monday, 11 June 2012

Page 100

15.
Project: Voice recognition in SMS messages
program.
The addition of voice recognition is actually pretty easy. Rather than writing the code from
scratch and embedding it into the existing program I merely copy it over to a new activity
icon that loads a button.
and then connected it through via the click on the widget
First of all lets get it working in your testbed the Main
bugs are ironed out make a link in your Service (SMS) Module.

Activity then when all the

Create a transparent layout a floating button

We need a layout for the button to be clicked to activate the voice recognition. Its only one
button on a Layout. The new layout is called Voice.

Go to the manifest Editor Project / manifest Editor


In the manifest editor add the line to the bottom. (Its all one line except for the comment)
'The line below needs to be added to make the activity transparent
SetActivityAttribute(voice1, android:theme,
@android:style/Theme.Translucent.NoTitleBar)

Voice1 is the name of the new Activity we will make, not the name of the layout.

Basic For Android

Monday, 11 June 2012

Page 101

When activated the button will appear to float over the top of the window, but in reality it just
has a transparent background.
At this stage we cant test it and see, you will just have to trust me.

Basic For Android

Monday, 11 June 2012

Page 102

The Voice Recognition Activity Module

Back in the program go Project / Add New Module / Activity Module. Then create new
Activity Module named Voice1.

This activity module is a copy of the earlier exercise with added sections. The two new parts
are Sub smstextready which loads the SMS reply window ready for a message and Sub
readtext that reads back the incoming SMS message.
'Activity module
Sub Process_Globals
Dim vr As VoiceRecognition ' first time
Dim vrtext As VoiceRecognition ' for message
Dim TTS1 As TTS
End Sub

Sub
'if
Dim
End

Globals
people get it wrong, lets insult them.
insult As Int :insult = 0
Sub

Sub Activity_Create(FirstTime As Boolean)


If FirstTime Then
vr.Initialize("VR")
vrtext.Initialize("VR")
TTS1.Initialize("TTS1")
End If
'loading the layout we use with the button on it.
Activity.LoadLayout("voice")
Activity.Color = Colors.Transparent 'Make the Activity transparent
If vr.IsSupported Then
ToastMessageShow("Voice recognition is supported.", False)
Else
ToastMessageShow("Voice recognition is not supported.", True)
End If
End Sub

Sub Button1_Click
vr.Listen 'calls the voice recognition external activity
End Sub
Basic For Android

Monday, 11 June 2012

Page 103

Sub Activity_Resume
End Sub

Sub Activity_Pause (UserClosed As Boolean)


End Sub

In the next section I used message.Contains("reply") which meant that it parses the text
looking for the word reply. This can be used to detect accents as well. Read can be Reed,
or Red etc. Surprisingly it is Case Sensitive, and will not return if you make the words
capital case (well not for me anyway).
This system could be expanded for any number of keywords or phrases. Even to loading an
SMS with a nickname for a person The Old Trout for your Mother in law. Nicknames could
be kept in a database attached to the contacts list.
This part insult = Rnd(1,5) gives a random number between 1 and 5 not including 5.

Sub VR_Result (Success As Boolean, Texts As List)


If Success = True Then
ToastMessageShow(Texts.Get(0), True)
TTS1.Speak(Texts.Get(0), True)
Dim message As String
message = Texts.Get(0)
'if the person says ... then
If message.Contains("reply") Then
smstextready
Else If message.Contains("read")OR message.Contains("reed") OR
message.Contains("red")Then
readtext
Else
'random insult until they get it
insult = Rnd(1,5)
Select insult
Case 1
TTS1.Speak("Please speak clearer. Are you drunk?", True)
Case 2
TTS1.Speak("Don't take drugs and operate a phone. Try again", True)
Case 3
TTS1.Speak("Your breath smells of onions. Please move the phone away
before trying again", True)
Basic For Android

Monday, 11 June 2012

Page 104

Case 4
TTS1.Speak("Please don't gargle and talk at the same time. Spit it out
first then try again", True)
End Select
End If
End If
End Sub

In this section we get into the heart of the program. We load 2 text files, which we will have
to make later fromsms.txt and contactname.txt.
Note the If File.Exists(File.DirInternal, which is used to check that there is a file there to
start with. The first time its used there wont be one and the program will crash, its a good
bit of protection.
The Dim i As Intent i.Initialize(i.ACTION_VIEW, "sms:" & number) is part for creating and
accessing an Intent, opening the SMS reply window which is another program. You use
Intents to open other programs on your phone. The action we are going to perform is VIEW
adding the number.

'OPEN THE REPLY WINDOW AND FILL THE NAME


Sub smstextready
Dim number, name As String
'get the smsnumber from the from file for the txtreply part of the program
its the raw phone number
If File.Exists(File.DirInternal, "fromsms.txt")Then
number = File.ReadString(File.DirInternal, "fromsms.txt")
Else
number = File.ReadString(File.DirInternal, "from.txt")
End If
'get the name of the person to send it to and put it in the bar
If File.Exists(File.DirInternal, "contactname.txt")Then
name = File.ReadString(File.DirInternal, "contactname.txt")
Else 'you know you have a mistake when you want to call Howard
name = "Howard the Duck"
End If
Dim i As Intent
'set up the sms window with voodoo
i.Initialize(i.ACTION_VIEW, "sms:" & number)
'put the text into the body
TTS1.Speak("message ready", False)
i.PutExtra("sms_body", "")
Basic For Android

Monday, 11 June 2012

Page 105

'start it
StartActivity(i)
End Sub

'READ THE TEXT


Sub readtext
Dim message As String
message = File.ReadString(File.DirInternal, "body.txt")
TTS1.Speak(message, False)
End Sub

Finally we need to create the text files. Back in your Service Module (SMS) Find the
following areas and add the code. We save to a text file to get it back later.
Add File.WriteString(File.DirInternal, "Fromsms.txt",From) here.
'The heart of the program
Sub SI_MessageReceived (From As String, Body As String) As Boolean
'Body and From are the two parts of the text message that are passed into
the phone. write a file to open with the new text in txtreply on voice1
File.WriteString(File.DirInternal, "Fromsms.txt",From)

The contact name for the reply comes under the Sub SI_MessageReceived sub below If
From = phonenumber.
If From = phonenumber Then
File.WriteString(File.DirInternal, "contactname.txt",Contact.Name)

Finally we need a way to start the Voice1 Activity. We are going to do that off the click on
the heart is StartActivity("voice1")
the image

Sub ivimage_click
TTS1.speak("Press the Button. Then say Read or Reply", False)
StartActivity("voice1")
End Sub

Basic For Android

Monday, 11 June 2012

Page 106

16.

Maps Hashmap for Java, Hashtables for .net

Map is a structure that is used frequently in Java. Its listed as an advanced tool but it is very
versatile and useful.
A Map consists of two parts a KEY and a VALUE pair. The key is unique, while the value
can be anything. KEY VALUE are separated by a colon : If you enter a key/value pair and
the collection already holds an entry with the same key, the previous entry will be removed
from the map so it overwrites existing entries.
The idea is to look down the Key field for what you are seeking and take the data from the
value field. This is far faster than looping through all the entries in the ordinary way.
Fetching an item is done by looking for its key. This is usually a very fast operation (O(1)
compared to O(n) in a list).
The key could be a string or a number. The value can be any type of object. Eg:
Lists
1:chocolate
2:apple
3:orange

Phone numbers
345456:Susan
545678:Harvey
434565:Harold

Date and Time


21/2/12-10.32am:meeting
21/2/12-11.15am:Break
21/2/12-12.00pm:Lunch

Add data to your map with Put


Map1.Put("Key","Value")
Get keys and values back with Map.GetKeyAt(i)) and Map.GetValueAt(i)).and check if the
key exists then get it with If Map.ContainsKey("some key") Then ...
Data has to be looped in and out of a map.
For example
For i = 0 to Map.Size - 1
Log("Key: " & Map.GetKeyAt(i))
Log("Value: " & Map.GetValueAt(i))
Next

Or as we will do later insert the Map into other loops.


For x = 0 To phones.Size 1
mastermapnames.Put(PhoneNum,Contact.DisplayName)
Next

You can have Maps of Maps and Lists of Maps.


Basic For Android

Monday, 11 June 2012

Page 107

Here is a good example of saving and retrieving data from two text boxes using a map.

17.

Use Map to save multiple data to a single file

Imagine you wanted to save all the text in a range of text boxes to a single file and then load
it back into the program later. It might be an edit option for long text entering, or an offline
option, or even to save a range of drafts. Its actually really easy to do with Maps
This very handy tool is easy to follow and uses PUT to save, and GET to retrieve.
The extra window shows the text file as saved and automatically saves with a data stamp.
This could create options for calling up versions.
Sub Globals
Dim map1 As Map
map1.Initialize
Dim btnsave As Button
Dim EditText1 As EditText
Dim EditText2 As EditText
Dim btnload As Button
Dim EditText3 As EditText
End Sub
Sub Activity_Create(FirstTime As Boolean)
Activity.LoadLayout("main")
End Sub
Sub btnsave_Click
map1.Clear'clear the map, empty the data
'put the data in the map (KEY, VALUE)
map1.Put("EditText1", EditText1.Text)
map1.Put("EditText2", EditText2.Text)
File.WriteMap(File.DirInternal, "btnset.set", map1) 'write to file
EditText1.Text = ""'clear text boxes
EditText2.Text = ""
ToastMessageShow("data saved", False)
End Sub
Sub btnload_Click
'load back to map1 as a map (file.Readmap)
map1 = File.ReadMap(File.DirInternal, "btnset.set")
'show back in text boxes
EditText1.Text = map1.Get("EditText1")
EditText2.Text = map1.Get("EditText2")
ToastMessageShow("data loaded", False)
'show the datafile as saved for interest
EditText3.text = File.ReadString(File.DirInternal, "btnset.set")
Basic For Android

Monday, 11 June 2012

Page 108

End Sub

18.

Project: Recipe selector using JSON

Get an API from this site http://www.programmableweb.com/ to practise on and to see


whats available.
JSON Overview

JSON (JavaScript Object Notation) is a lightweight data-interchange format. It is easy for


humans to read and write. It is easy for machines to parse and generate. It is a popular way
of transferring related data from internet databases to applications, and preferred by
Google. The ability to use JSON opens a vast area of data manipulation.
JSON is built on two structures:

A collection of name/value pairs. In various languages, this is realized as an object, a


map, struct, dictionary, hash table, keyed list, or associative array.

An ordered list of values. In most languages, this is realized as an array, vector, list,
or sequence.

An object is an unordered set of name/value pairs. An object begins with { (left brace) and
ends with } (right brace). Each name is followed by : (colon) and the name/value pairs are
separated by , (comma).
An array is an ordered collection of values. An array begins with [ (left bracket) and ends
with ] (right bracket). Values are separated by , (comma).
A value can be a string in double quotes, or a number, or true or false or null, or an object or
an array. These structures can be nested.
Here is a request to a server for some data that is returned in the JSON format.
http://www.recipepuppy.com/api/?i=onions,garlic&q=omelet&p=3
The data that is returned is in a string, to see the structure of it paste the link into
http://jsonformat.com/ and run.

Basic For Android

Monday, 11 June 2012

Page 109

A good overview can be found on the Wikipedia http://en.wikipedia.org/wiki/Json

The structure is nested. Here is the first set of data returned, with the end added on to make
it a single unit. Subsequent sets have the same structure.
{"title":"Recipe Puppy","version":0.1,
"href":"http:\/\/www.recipepuppy.com\/",
"results":
[{
"title":"Vegetable-Pasta Oven Omelet",
"href":"http:\/\/find.myrecipes.com\/recipes\/recipefinder.dyn?action=disp
layRecipe&recipe_id=520763",
"ingredients":"tomato, onions, red pepper, garlic, olive oil, zucchini,
cream cheese, vermicelli, eggs, parmesan cheese, milk, italian seasoning,
salt, black pepper",
"thumbnail":"http:\/\/img.recipepuppy.com\/560556.jpg"},
}
],}

This data looks confusing on the first look, and the second, and the .
However look at the main text in terms of Maps. A Map is a Key:Value pair separated by a :
and this data is make up of maps with each map separated by a comma,
"title":"Vegetable-Pasta Oven Omelet"
Its the format of Key:Value , Key:Value , Key:Value , Key:Value , Key:Value ,
This is an array of maps
The main part the data
"results":
[{

Is again Key:Value, the Key being Result, the Value being everything inside of the [{

The next page gives a better idea of the structure using a Firefox addon below. You can
clearly see the Blue Green matched Key Value pairs

Basic For Android

Monday, 11 June 2012

Page 110

Recipe Program construction

This program requires us to access the net and download the JSON from the
http://www.recipepuppy.com website using their API (Application programming interface).
As a result we need the HTTP library.
We need
1 panel
2 Buttons
3 Labels
2 edit boxes
1 imageview
Edtcode is only to see if the
code is coming down OK
LBLhyperlink and IVpic are
not set up so far, the pic will
go in the pic box and the
hyperlink will take you to the
website.

Basic For Android

Monday, 11 June 2012

Page 111

The code
'Activity module
Sub Process_Globals
Dim hc As HttpClient 'download the json
Dim req As HttpRequest
Dim JSON As JSONParser
Dim Map1 As Map
End Sub

Sub Globals
Dim btnrun As Button
Dim datamap As Map
Dim btnnext As Button
Dim edtsearch, edtcode As EditText
Dim lblhyperlink,lblingredients, lbltitle
Dim counter As Int :counter = 0
Dim ivpic As ImageView
Dim recipecode As String
End Sub

As Label

Sub Activity_Create(FirstTime As Boolean)


Activity.LoadLayout("main")
hc.Initialize("hc")
datamap.Initialize
'set as a default to save typing in all the time while testing
edtsearch.Text = "i=onions,garlic&q=omelet&p=3"
'initialise the JSON and tells it what it has to parse
JSON.Initialize(recipecode)
End Sub

Sub
End
Sub
End

Activity_Resume
Sub
Activity_Pause (UserClosed As Boolean)
Sub

Sub btnrun_Click
Dim url, search As String
search = edtsearch.Text
url = "http://www.recipepuppy.com/api/?"& search
'i=onions,garlic&q=omelet&p=3"
'OPTIONS
'i=ingredients comma deliminated
'q=type of food eg omelet
Basic For Android
Monday, 11 June 2012

Page 112

'p= page number? -put page number in a counter so that it increments each
time you press run? 1, 2, 3 still to do
req.InitializeGet(url)
hc.Execute(req, 1)
ProgressDialogShow("downloading ...")
End Sub

Sub hc_ResponseSuccess(Response As HttpResponse, TaskId As Int)


Dim temp As String
temp = Response.GetString("UTF8") 'Get the whole page
recipecode = temp
edtcode.text = temp Just to see what the code is on the screen
ProgressDialogHide
'run the download sub below (gets the first entry up and running)
download
counter = 0
End Sub

Totally standard error message copied from an earlier exercise


Sub hc_ResponseError(Response As HttpResponse, Reason As String,
StatusCode As Int, TaskId As Int)
If Response <> Null Then
Msgbox("Error: " & Response.GetString("UTF8")& "Cannot find ", "Connection
Error")
Response.Release
ProgressDialogHide
ToastMessageShow("bugger",True)
End If
End Sub

Sub btnnext_Click
download
End Sub

Sub download
JSON.Initialize(recipecode)
'JSON.NextObject parses the string and returns a Map with the parsed
data. This method should be called when the top level value is an object
(which is usually the case).
Map1 = JSON.NextObject
Dim results As List 'list holds all the recipes

Basic For Android

Monday, 11 June 2012

Page 113

results = Map1.Get("results")'top level with a key: the value is


everything else in the code. key:value pass it to m
'Counter to move between recipes
counter = counter + 1
'If the counter reaches the last recipe then go back to the first one,
otherwise crashes
If counter = results.Size Then
counter = 1
End If
'get the results at the place of the counter 1, 2, 3 etc
'some voodoo here
datamap = results.Get(counter)
lbltitle.Text = counter &" " & datamap.Get("title")
lblingredients.Text = datamap.Get("ingredients")
lblhyperlink.Text = datamap.Get("href")
m
End Sub

Create your own APIS with http://apify.heroku.com/resources


How to make a hyperlink that opens the web browser

Creating a link to a local webbrowser is simple. In the code above we directly passed the
html to the text box, lblhyperlink.Text = datamap.Get("href") giving us a string of text that
sort of looks like an url.
'http:\/\/find.myrecipes.com\/recipes\/recipefinder.dyn?action=displayReci
pe&recipe_id=520763",

To use this we need to remove the \\ symbols and turn it into an active URL.
The code for that is simple, create a new variable called hyperlink to hold the data and then
do a string replace to take out the unwanted symbols.
As I was feeling somewhat lazy I attached the url to the click event of the label box itself,
Sub lblhyperlink_Click it might go better under a button.
hyperlink = datamap.Get("href")
hyperlink = hyperlink.Replace("\","")
lblhyperlink.Text = hyperlink
End Sub

Sub lblhyperlink_Click
Dim p As PhoneIntents
StartActivity(p.OpenBrowser(hyperlink))
End Sub

This is no way the end of this program, only the beginning.

Basic For Android

Monday, 11 June 2012

Page 114

Basic For Android

Monday, 11 June 2012

Page 115

Você também pode gostar