0% found this document useful (0 votes)
405 views

Visual Basic For Android June11

Using Begin / End transaction greatly improves "writing" speed in Sql. 5 Debug with a Toastmessage. 5 Design resources and graphics.

Uploaded by

Huitzoiltl
Copyright
© Attribution Non-Commercial (BY-NC)
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
405 views

Visual Basic For Android June11

Using Begin / End transaction greatly improves "writing" speed in Sql. 5 Debug with a Toastmessage. 5 Design resources and graphics.

Uploaded by

Huitzoiltl
Copyright
© Attribution Non-Commercial (BY-NC)
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 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. 4.

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


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

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. 10.

Getting an error in your hc_ResponseSuccess? Fix the taskID. ........................... 67 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. 13.

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


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

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. 15.

Project: Voice Recognition program ...................................................................... 99 Project: Voice recognition in SMS messages program. ....................................... 101
Create a transparent layout a floating button .............................................................. 101 The Voice Recognition Activity Module .......................................................................... 103

16. 17. 18.

Maps Hashmap for Java, Hashtables for .net ................................................... 107 Use Map to save multiple data to a single file ..................................................... 108 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.
ToastMessageShow("message here",false) ' true=3sec , false=2 sec

File saved to SDCARD/Android/data/ your com file name


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

Design resources and graphics

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


API Interfaces

How to open a webpage with WebView.

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


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

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

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

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)

"The application ... has stopped unexpectedly. Please try again."

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")

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.


Page 4

Basic For Android

Monday, 11 June 2012

Usually you will want to call it in Sub Activity_Create.


Use #Region ... #End Region.

Log(whatever you want)

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

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:[email protected] :3128

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.
Tool tip information

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

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)

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

Built in buttons and images

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

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)

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
Page 6

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

Monday, 11 June 2012

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.
Write / Read to files 'write it to a file

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

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 Create some data to use as an example

of your program, or move it there later.

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 you need to add this for later

Dim bmp As Bitmap Dim Dim Dim Dim

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.

So that it runs at

Basic For Android

Monday, 11 June 2012

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

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

Basic For Android

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

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

Basic For Android

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()); //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"; } } ?>

) or

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()); }

WHERE ID = '$deleteID'"

) or

Basic For Android

Monday, 11 June 2012

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 End Sub Used: " &

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
Monday, 11 June 2012 Page 89

Basic For Android

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.
Create a transparent layout a floating button

Activity then when all the

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 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

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

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":"https:\/\/fanyv88.com:443\/http\/www.recipepuppy.com\/", "results": [{ "title":"Vegetable-Pasta Oven Omelet", "href":"https:\/\/fanyv88.com:443\/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":"https:\/\/fanyv88.com:443\/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.
'https:\/\/fanyv88.com:443\/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

You might also like