120 pages of tutorials, covering the main concepts of Android programming.
Citation preview
1. Basic4android Tutorials
http://www.basic4android.comFeedback: [email protected]:
March 23, 2011 1
2. No part of this document may be reproduced in any form or by
any electronic ormechanical means including information storage and
retrieval systems, withoutpermission in writing from the
author.This document collects some of Basic4android tutorials
andexamples.The most updated tutorials can be found
online:http://www.basic4ppc.com/forum/basic4android-getting-started-tutorials/
2
3. Table of contentsInstalling Basic4android and Android SDK
.....................................................................4Hello
world - Installing Android Emulator
......................................................................7Guess
my number - Visual designer & Events
...............................................................
13IDE Tips
.......................................................................................................................
19B4A-HelpViewer - View and search the documentation
offline..................................... 24B4A-Bridge a new way
to connect to your device
.........................................................
25Connecting your device to the IDE using
ADB..............................................................
28Android Process and activities life
cycle........................................................................
32Static Code Modules
.....................................................................................................
36Service
Modules............................................................................................................
37Variables & Objects
......................................................................................................
41Currency Converter libraries, file manager and other important
concepts.................... 45Working with
files.........................................................................................................
53Views (controls) and Dialogs
........................................................................................
57GPS tutorial
..................................................................................................................
64MediaPlayer Playing music
........................................................................................
68ListView tutorial
...........................................................................................................
71ScrollView tutorial
........................................................................................................
76TabHost tutorial
............................................................................................................
78FlickrViewer example Download multiple images concurrently
................................. 80Two activities
example..................................................................................................
81Building a linked list using Type
keyword.....................................................................
83SQL tutorial
..................................................................................................................
85XML parsing with the XMLSax
library.........................................................................
90Take pictures with the internal
camera...........................................................................
93Serial (Bluetooth)
tutorial..............................................................................................
95JSON parsing and generating
......................................................................................
100Animation tutorial
.......................................................................................................
103Network tutorial
..........................................................................................................
107Regular Expressions
....................................................................................................
111Downloading files using
Services................................................................................
114AsyncStreams tutorial
.................................................................................................
116 3
4. Installing Basic4android and Android SDKBasic4android
depends on two additional (free) components:- Java JDK- Android
SDKInstallation instructions:The first step should be to install
the Java JDK as Android SDK requires it as well.Note that there is
no problem with having several versions of Java installed on the
samecomputer.- Open the Java 6 JDK download link.- Select "Windows"
in the platform combo box (for 64 bit machines as well). AndroidSDK
doesnt work with Java 64bit JDK. You should install the regular JDK
for64bit computers as well.- Press on the red Continue button.
There is no need to sign in!If for some reason you dont see the red
Continue button try to switch to a differentbrowser.- On the next
page you should press on the file link:- Download the file and
install it.Next step is to install the Android SDK and a platform:-
Download Android SDK.- Install the SDK.- When the application opens
it will show a page with all the available packages. Press"Cancel"
button as you do not need to install all the platforms.- Choose
"Available Packages" and choose "SDK Platform 2.2, API 8". It
should appearunder the "Android repository" node. The file
structure of API 9 is different. For nowyou should use API 8.
4
5. Note that you can install more packages later.- Press on
Install Selected and install both packages.Install and configure
Basic4android- Download and install Basic4android.- Open
Basic4android.- Choose Tools menu - Configure Paths. 5
6. - Use the browse buttons to locate "javac.exe" and
"android.jar"javac is located under bin.android.jar is located
under platformsandroid-8On Windows 64 bit, Java will probably be
installed under C:Program Files (x86). 6
7. Hello world - Installing Android EmulatorIn this tutorial we
will create a new AVD (Android Virtual Device) which is an
emulatorinstance. Then we will create a simple program that
displays a simple message box andalso writes a message to the
log.You can also connect a real device to the IDE:Connecting your
device with ADBConnecting your device with B4A-BridgeCreate new
AVD- Run Basic4android.- Choose Tools Menu - Run AVD Manager.Wait a
few seconds.- The AVD Manager should appear:- Choose New and fill
the fields similar to the following image: 7
8. - Press on Create AVD.- Note that you can create more than
one AVD. Each can have a different resolution orcan target a
different API version (you will need to install additional
platforms first).- Now press Start in order to start the emulator-
You will see several windows popping up and disappearing. This is
fine.- The emulator should boot up: 8
9. Wait... on the first time it can take several minutes till
the emulator is ready.The emulator is ready when it gets to this
screen:You may see this screen, which is the lock screen,
instead:Drag the lock icon to the right to unlock the device.Note
that there is no need to restart the emulator each time you deploy
a program. Theemulator can be kept running all the time.If you are
not familiar with Android you can play with the emulator. Press on
the buttonwith the small squares to get to the application page.
9
10. Writing your first Basic4android program- As this is a new
program we should first set its location by choosing File - Save.It
is highly recommended to save each project in its own folder.-
Create a new folder: "Hello world", open the folder and save the
program as "Helloworld".- Write the following code under Sub
Activity_Create:Code:Sub Activity_Create(FirstTime As Boolean)
Log("Hello world!") Msgbox("Hello world?", "First program")End Sub
- Press F5 to compile and deploy your program to the emulator. The
package dialog should appear (empty): Each Android application is
identified by a unique package string. This is a string built of
several parts separated with periods. The string should include at
least two parts. You cannot install two applications with the same
package on one device. Note that you can always change the package
name (and the label) under tools menu. - Enter a package name. -
Next you will be asked to enter the application "label". This is
the application name that the user will see. Your program will now
be compiled and installed to the emulator: 10
11. The emulator is significantly slower than a real device.In
many cases it is more convenient to work with a real device as the
installationis much faster.Note that you can always redeploy your
program. There is no need to close therunning program on the
emulator.Tracking the log with LogCatAndroid devices keep an
internal buffer of log messages. These messages can bevery handy
for debugging.To view the logs you should switch to the LogCat tab
in the right pane and pressconnect: 11
12. There are two "Hello world!" messages in the screenshot as
I ran the programtwice.Unchecking "Filter" will show all available
messages (not just messages relevantto your program).Hello world
12
13. Guess my number - Visual designer & EventsIn this
tutorial we will use the designer to create the layout. The layout
includes anEditText (TextBox) and a Button.The user needs to guess
a random number. The user enters the number in the EditTextview
(control) and presses on the button to submit the guess.A "toast"
message will appear, indicating to the user whether the number is
larger orsmaller than the chosen number.- Create a new project and
save it.- Open the designer by choosing the Designer menu.The
designer is made of two main components. The "control panel" which
contains allthe available properties and options, and is part of
the IDE:and the "visual" component which runs on a device or
emulator: 13
14. The visual component, as it names suggests, displays the
layout. It also allows you tomove and resize the views
(controls).Changing the layout in the visual component will also
change the values stored in thecontrol panel.Note that all the data
is stored in the control panel component. Therefore nothing bad
willhappen if the emulator crashes or is turned off.You can connect
to it again and the layout will appear.The first step is to connect
to the device. Press Tools - Connect.This step takes several
seconds. Note that the IDE will stay connected until the IDEcloses.
Closing the designer will not disconnect the connection.Use the Add
View menu to add a Button, an EditText and a Label.Change the views
Text property and position them similar to this: 14
15. Change the Activity Drawable property to GradientDrawable
to achieve the gradienteffect.Tip: When working with a small
monitor you may find it convenient to check the "TopMost" option
(in the upper right corner). It will cause the control panel to
stay on top andnot be hidden by the emulator.Save your layout, name
it Layout1.An important concept about layouts is that there is a
complete separation between yourcode and the layouts.The layout is
saved as a file, with ".bal" extension. Each project can have any
number ofsuch files and unless you explicitly load a layout file,
it will not have any effect on yourapplication.Once you have saved
a layout, it is automatically added to the "File manager". You
cansee it under the "Files" tab in the IDE right pane.We want to
catch the buttons click event.Each view has an EventName value. It
is a property in the Designer, and a parameterpassed to the
Initialize method when adding views programmatically.In order to
catch an event you should write a Sub with the following structure
(it issimpler than it sounds):Sub _ (event parameters).In the
designer, the EventName property is set by default to the views
name.If we want to catch the Click event of a button with EventName
value of Button1 weshould write the following sub signature:Sub
Button1_ClickSo here is the complete code: 15
16. Code:Sub Process_GlobalsEnd SubSub Globals Dim MyNumber As
Int Dim EditText1 As EditText will hold a reference to the view
addedby the designerEnd SubSub Activity_Create(FirstTime As
Boolean) Activity.LoadLayout("Layout1") Load the layout file.
MyNumber = Rnd(1, 100) Choose a random number between 1 to 99End
SubSub Button1_Click If EditText1.Text > MyNumber Then
ToastMessageShow("My number is smaller.", False) Else If
EditText1.Text < MyNumber Then ToastMessageShow("My number is
larger.", False) Else ToastMessageShow("Well done.", True) End If
EditText1.SelectAllEnd SubSome notes:- Every activity module comes
with an Activity object that you can use to access theactivity.-
Activity.LoadLayout loads the layout file.- There are other views
that can load layout files. Like Panel and TabHost. ForTabHost each
tab page can be created by loading a layout file.- In order to
access a view that was added with the designer we need to declare
it underSub Globals.- ToastMessageShow shows a short message that
disappears after a short period.Using a toast message in this case
is not optimal as it may be unnoticed when the softkeyboard is
open.Tip for writing events subs:In the IDE, write Sub and press
space. You should see a small tooltip saying "press tab toinsert
event declaration".Press tab, choose the object type and choose the
event. 16
17. Now all you need to do is to write the required event name
and press enter.Supporting multiple screen resolutions and
orientationsEach layout file can include a number of layout
variants. Each layout variant holds adifferent set of values for
the position and size of the views.If for example, you change the
text of any view it will be changed in all variantsautomatically.
However if you change the position of a view it will only affect
the currentvariant.Note that scaling is handled automatically if
required. Which means that if we run ourprogram on a high
resolution device, the layout will be automatically scaled.Still
you may choose to create different variants for different
scales.When you load a layout file the variant that best matches
the current device will beloaded.Usually you will need two
variants:- 320 x 480, scale = 1 (160 dpi). This is the default
scale in portrait mode.- 480 x 320, scale = 1 (160 dpi). Default
scale in landscape mode.Ok, so open the designer again. Load
Layout1 file if it is not opened.Choose "New Variant" and choose
480 x 320 (second option).Change the emulator orientation by
clicking on the emulator and then press on Ctrl +F11.Note that the
device layout details appear under the list of variants.Change the
layout to be similar to this: 17
18. You can change the current selected variant and see how it
affects the visual layout.Save the layout and run the
program.Change the emulator orientation and see how the layout
changes accordingly.Android destroys the old activity and creates a
new activity each time the orientationchanges. Therefore
Activity.LoadLayout will be called again each time.
Unfortunatelythe number will also be randomly chosen again each
time. This can be easily fixed... Butnot in this tutorial.The
project is attached.Last tip for this tutorial:- The IDE includes
an "Export as zip" option under Files menu. This method creates a
zipfile with all the required files. 18
19. IDE TipsThe IDE has several powerful features which can
help you concentrate on writing yourcode and building your
application.Im listing here some of the less obvious features:-
Ctrl + Space = auto completePressing Ctrl + Space activates the
auto complete feature which will then show you a listwith 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 itemautomatically.- Tool tip information - while
writing methods parameters, a tool tip will be opened withthe
method signature and description.The tool tip might hide some
important code that you now need.You can hide it by pressing
escape. You can also turn it almost invisible by pressing thectrl
key. Another press will return it to be fully opaque. 19
20. LogCat - The LogCat tab displays the device built-in logs.
These logs are very useful fordebugging. You can log messages with
the Log keyword.In order to start displaying the logs you press on
the Connect button.The logs can be filtered and then you only see
messages generated by Basic4android oryour application.Note that if
you have more than one device connected you can switch to a
differentdevice by pressing on the Connect button.Designer
generated members tool - This tool allows you to add the
declaration code forthe designer views and to add event subs.Note
that you only need to declare views that you intend to access by
code.Nothing will happen if you select an existing item (there will
be no duplicated code). 20
21. To open this tool choose - Tools - Generate Members (from
the designer form).Background compilation - Pressing Alt + 3 will
compile and install your applicationwhile keeping the IDE
responsive. The status bar at the bottom of the screen displays
theprogress of the process and when the installation is completed.A
short sound will notify you if the process failed. In that case you
may need to compileregularly (F5) in order to see the error message
(it depends on the type of error).Working with multiple connected
devices - In many cases you have more than onedevice connected. For
any operation that starts a connection you will be shown the list
ofconnected device and you will choose the target device.If you
compile in the background the last device will be used again. This
is usually moreconvenient than compiling in the foreground and
selecting the target device each time.Designer - Duplicate - You
can duplicate any view by selecting the view and thenchoosing Tools
- Duplicate View. If the view has child views then all its child
views willbe duplicated as well.Export as zip - Export as zip
option creates a zip file with all the required project files.This
is useful when you want to share your project with others or create
a backup. It islocated under Files menu.Clean Project / Clean
Unused Files - Clean project deletes all generated files. These are
21
22. files that are generated during compilation.Clean unused
files deletes files that are located under the Files folder but are
not used bythe project (it will not delete any file reference by
any of the project layouts). A list ofunused files will be
displayed before deletion (and allows you to cancel the
operation).Run AVD Manager - The AVD manager allows you to create
and start emulators. Thismenu opens the manager. Note that there is
no need to keep the AVD manager open afterstarting an
emulator.Events subs signatures -There is a special auto complete
feature that can help you writethe event subs signatures.Start with
writing Sub followed by a space:A message will appear as in the
image.Press Tab key:A list will be displayed with all the available
types (that have at least one event). Choosethe required type and
press enter.Choose the specific event.Code similar to the following
code will be generated: 22
23. The EventName string will be selected. Change it to match
the object "EventName" valueand press enter. Thats it.Designer top
most property - The designer has a "top most" check box which you
canuse to keep the designer as the top most form. This is useful
when working with thedesigner and the emulator on a small
screen.Debugging data - By default Basic4android compiler adds some
debugging data to yourcode.This data is used when an error occurs.
It allows the program to show the original codeline which raised
the error.This data does take some space and may impact
performance, though it usually should beinsignificant. You can
remove this data by unchecking Project - Include DebugInformation.
23
24. B4A-HelpViewer - View and search the documentationofflineIm
happy to release the second beta version of B4A HelpViewer.This
utility allows you to browse and search the documentation and the
forum postsfrom the desktop.It automatically checks for updated
libraries and forum posts during start-up. Thelibraries manuals are
downloaded and stored locally.The search functionality is built
using Lucene.For now there is no installation step. You should
unzip the file and run B4A-HelpViewer.Note that it should not be
located under Program Files as it needs "write
permissions".Download link 24
25. B4A-Bridge a new way to connect to your deviceCurrently
there are two ways which you can use to test your application
duringdevelopment.You can either work with the Android emulator or
if your device supports ADBdebugging, you can connect to your real
device.The Android emulator is very slow compared to a real device
(especially withapplications installation).Therefore in most cases
it is more convenient to work with a real device.Personally Im only
using the emulator when working with the visual designer.However
not all devices support ADB debugging. This is exactly the reason
for the newB4A-Bridge tool.B4A-Bridge is made of two components.
One component runs on the device and allowsthe second component
which is part of the IDE to connect and communicate with
thedevice.The connection is done over a network (B4A-Bridge cannot
work if there is no networkavailable).Once connected, B4A-Bridge
supports all of the IDE features which include:
installingapplications, viewing LogCat and the visual
designer.Android doesnt allow applications to quietly install other
applications, therefore whenyou run your application using
B4A-Bridge you will see a dialog asking for yourapprovement.Getting
started with B4A-Bridge1. First you need to install B4A-Bridge on
your device.B4A-Bridge can be downloaded
here:http://www.basic4ppc.com/android/files/b4a_bridge.apk.B4A-Bridge
is also available in Android market. Search for: B4A Bridge.Note
that you need to allow install of applications from "Unknown
sources". This is doneby choosing Settings from the Home screen -
Manage Applications.2. Run B4A-Bridge on your device. It will
display a screen similar to: 25
26. Status will be: Waiting for connections.3. In the IDE
choose Tools - B4A Bridge - Connect.You will need to enter the IP
address that appears on the device screen.The status bar at the
bottom of the screen shows the current status:Thats it.When
B4A-Bridge gets connected it first checks if the designer
application needs to beupdated. In that case it will first install
the designer application.B4A-Bridge keeps running as a service
until you press on the Stop button.You can always reach it by
opening the notifications screen: 26
27. Pressing on the notification will open the main screen.As
mentioned above, when you run an application you are required to
approve theinstallation. You will usually see the following
screens:In the above dialog you should choose Open to start the
application.If you try to install an existing application signed
with a different key, the install willfail (without any meaningful
message). You should first uninstall the existingapplication. Go to
the home screen - Settings - Applications - Manage applications
-choose the application - Uninstall.Once you finished developing
you should press on the Stop button in order to savebattery.Note
that B4A-Bridge was written with Basic4android.The source code is
available
here:http://www.basic4ppc.com/forum/basic...html#post45854 27
28. Connecting your device to the IDE using ADBThis tutorial
was written by Andrew GrahamIntroductionA program called adb.exe -
Android Debug Bridge - is the key component that is used
tocommunicate between programs on your desktop and the emulator or
device. adb can beinvoked without user intervention by programs
such as Basic4Android and Eclipse butalso has a command line
interface that can be used by advanced users. adb.exe isprovided
with the Android SDK and is located, together with other
development tools, onearly versions of the Android SDK in the tools
and on morerecent versions in the platform-tools folder. Unless adb
canconnect properly to the emulator or device Basic4Android will
not be able to load andrun applications, however in this event they
could still be compiled then copied to the SDcard on the device by
USB and installed from there. This tutorial tries to explain how
toget your device connected to adb so that you can use it with the
Basic4Android IDE.Device SD cards and USBAlthough this capability
is entirely independent of adb it is worth including here
forcompleteness in describing how devices use USB connections.
Android devices have aUSB port that when plugged into a desktop
lets the SD card on the device look like aUSB memory stick. The
first time that a device is connected to a desktop by USBWindows
should automatically detect this and install the necessary driver
without youhaving to do anything. The SD card will then appear as a
disc drive in Windows Explorerand Device Manager while the device
is connected. While the SD card is visible to thedesktop as a drive
the device will not be able to access it as it is unmounted from
thedevice. Some, but not all, devices allow you to mount and
unmount the SD card from thedevice when it is plugged into the
desktop USB. Other devices do not offer this optionbut
automatically unmount it on connection to USB and remount it on
disconnection.You will have to see how your own device behaves in
this regardThe emulator and adbThere should be absolutely no
problem using the emulator with Basic4Android. adb willconnect
automatically and should work well, although I have found that if
the emulator isrunning Android 1.6 the adb connection will
frequently drop and cause problems.Therefore I recommend using
Android 2.1 or later in the emulator to avoid any possibleproblems.
Also there should be no problem interacting with the emulator with
adb incommand line mode if that is required. Because the emulator
should just work the 28
29. remainder of this article deals with connecting devices by
means of adb.Devices and adbIn my experience so far devices differ
in their USB capability and in their interactionwith adb and
Windows so the following can only be a guide. Your experience may
vary.adb can connect a device to the desktop by two different
means, Wi-Fi and USB. In bothcases for adb to recognise the device
Settings -> Applications -> Development -> USBdebugging
must be checked. This runs the adb daemon on the device
whichcommunicates with adb on the desktop.adb and WiFiTo connect to
a device wirelessly you need to connect the device to the network
by Wi-Fiand obtain the device IP address. This can be found under
Settings -> Wireless &Networks -> Wi-Fi Settings. Press
the connected network under the WiFi Networkssection and a message
box will display the connection details.Before running
Basic4Android open a Command Window in the tools folder and type
the commandadb connect 192.168.0.10replacing the IP address with
the correct one for the device.if you get an error try specifying
the portadb connect 192.168.0.10:5555I have encountered only
partial functionality with adb over Wi-Fi. I have a tablet
thatworks fine with adb and so with Basic4Android - which is just
as well as the tablet lacksthe USB connectivity needed for adb. I
also have a phone that mostly works with adb incommand line mode
but adb hangs and doesnt return to the command prompt
afterperforming an install or uninstall although the actual
operation on the device issuccessful. This behaviour means that
neither Basic4Android nor Eclipse can be usedwith the phone over
wireless but thankfully they work perfectly over USB.adb and USB
29
30. Many Android devices, but not all like some cheap Chinese
Android tablets, have twomore USB interfaces "Android ADB
Interface" and "Android Composite ADBInterface". These belong to a
device that, on successful USB driver installation, appearsas
"Android Phone" in Device Manager and is used by adb to connect to
the phone overUSB. If your phone lacks these it may still be
possible to connect adb to it by means ofwireless as described
above.These Android interfaces, unlike SD card access, need custom
USB drivers that arelocated in the usb_driver. In this folder there
is aandroid_winusb.inf file that contains the USB IDs needed to
install the drivers fordifferent phones. When a phone is connected
and Windows asks for the drivers for thisdevice point it to this
folder. If the drivers then fail to install it is likely that
theandroid_winusb.inf does not contain the IDs for the phone. In
android_winusb.inf thereare two sections the one named
[Google.NTx86] contains the details for 32 bit systems,another
named [Google.NTamd64] contains the details for 64 bit systems. The
twosections are in fact identical. For my phone to be recognised
the following details neededto be inserted in each of the two
sections mentioned.;Orange San Francisco%SingleAdbInterface% =
USB_Install,
USBVID_19D2&PID_1354&MI_00%CompositeAdbInterface% =
USB_Install, USBVID_19D2&PID_1354&MI_02These necessary
details were obtained courtesy of a certain well known Internet
searchengine. However, rather belatedly, Google now at last has a
list of links to manufacturersites that provide USB drivers for
their devices on this page Google USB Driver . Theactual link is
OEM USB Drivers.Note that for some devices, like my phone, Windows
may try to install the driverswithout USB Debugging being enabled
on the phone. This is likely to fail even when youpoint Windows at
the drivers that installed successfully with USB Debugging
enabled.As this will happen every time the phone is plugged in to
USB the solution is to keepUSB Debugging enabled. This has no
downside as, for this phone at least, the USBaccess to the SD card
is entirely independent of whether USB Debugging is enabled
ornot.More on adb and WiFiSome devices seem to not have the adb
daemon enabled for wireless. There is anapplication called
adbWireless that can overcome this for many, but not all, devices.
It isavailable on the Android Market, the latest version is 1.4.1,
but it needs root access to thephone to work.Another application
called UniversalAndroot may help here - it worked on my ZTE 30
31. Blade/Orange SanFrancisco to let me run adbWireless on it.
It can be downloaded fromuniversalandroot by clicking one of the
links at the bottom of the page by the 2Dbarcodes. 31
32. Android Process and activities life cycleLets start
simple:Each Basic4android program runs in its own process.A process
has one main thread which is also named the UI thread which lives
as long asthe process lives. A process can also have more threads
which are useful for backgroundtasks.A process starts when the user
launches your application, assuming that it is not runningalready
in the background.The process end is less determinant. It will
happen sometime after the user or system hasclosed all the
activities.If for example you have one activity and the user
pressed on the back key, the activitygets closed. Later when the
phone gets low on memory (and eventually it will happen)the process
will quit.If the user launches your program again and the process
was not killed yet the sameprocess will be reused.A Basic4android
application is made of one or more activities. Android support
severalother "main" components. These will be added to
Basic4android in the future.Activities are somewhat similar to
Windows Forms.One major difference is that, while an activity is
not in the foreground it can be killed inorder to preserve memory.
Usually you will want to save the state of the activity before
itgets lost. Either in a persistent storage or in memory that is
associated with the process.Later this activity will be recreated
when needed.Another delicate point happens when there is a major
configuration change in the device.The most common is an
orientation change (user rotates the device). When such a
changeoccurs the current activities are destroyed and then
recreated. Now when we create theactivity we can create it
according to the new configuration (for example, we now knowthe new
screen dimensions).How do we handle it?When you create a new
activity you will start with the following code template:Code:Sub
Process_Globals These global variables will be declared once when
the applicationstarts. These variables can be accessed from all
modules.End Sub 32
33. Sub Globals These global variables will be redeclared each
time the activityis created. These variables can only be accessed
from this module.End SubSub Activity_Create(FirstTime As
Boolean)End SubSub Activity_ResumeEnd SubSub Activity_Pause
(UserClosed As Boolean)End SubVariables can be either global or
local. Local variables are variables that are declaredinside a sub
other than Process_Globals or Globals.Local variables are local to
the containing sub. Once the sub ends these variables nolonger
exist.Global variables can be accessed from all subs.There are two
types of global variables.Process variables and activity
variables.Process variables - These variables live as long as the
process lives.You should declare these variables inside sub
Process_Globals.This sub is called once when the process starts
(this is true for all activities, not just thefirst activity).These
variables are the only "public" variables. Which means that they
can be accessedfrom other modules as well.However, not all types of
objects can be declared as process variables.All of the views for
example cannot be declared as process variables.The reason is that
we do not want to hold a reference to objects that should be
destroyedtogether with the activity.In other words, once the
activity is being destroyed, all of the views which are containedin
the activity are being destroyed as well.If we hold a reference to
a view, the garbage collector would not be able to free theresource
and we will have a memory leak.The compiler enforces this
requirement.Activity variables - These variables are contained by
the activity.You should declare these variables inside Sub Globals.
33
34. These variables are "private" and can only be accessed from
the current activity module.All objects types can be declared as
activity variables.Every time the activity is created, Sub Globals
is called (before Activity_Create).These variables exist as long as
the activity exists.Sub Activity_Create (FirstTime As Boolean)This
sub is called when the activity is created.The activity is created
when the user first launches the application, the
deviceconfiguration has changed (user rotated the device) and the
activity was destroyed, orwhen the activity was in the background
and the OS decided to destroy it in order to freememory.This sub
should be used to load or create the layout (among other uses).The
FirstTime parameter tells us if this is the first time that this
activity is created. Firsttime relates to the current process.You
can use FirstTime to run all kinds of initializations related to
the process variables.For example if you have a file with a list of
values that you need to read, you can read itif FirstTime is True
and store the list as a process variable.Now we know that this list
will be available as long as the process lives and there is noneed
to reload it even when the activity is recreated.To summarize, you
can test whether FirstTime is True and then initialize
processvariables.Sub Activity_Resume and Sub Activity_Pause
(UserClosed As Boolean)Each time the activity moves from the
foreground to the background Activity_Pause iscalled.Activity_Pause
is also called when the activity is in the foreground and a
configurationchange occurs (which leads to the activity getting
paused and then destroyed).Activity_Pause is the last place to save
important information.Generally there are two types of mechanisms
that allow you to save the activity state.Information that is only
relevant to the current application instance can be stored in oneor
more process variables.Other information should be stored in a
persistent storage (file or database).For example, if the user
changed some settings you should save the changes to apersistent
storage at this point. Otherwise the changes may be
lost.Activity_Resume is called right after Activity_Create finishes
or after resuming a pausedactivity (activity moved to the
background and now it returns to the foreground).Note that when you
open a different activity (by calling StartActivity), the
currentactivity is first paused and then the other activity will be
created if needed and (always)resumed.As discussed above
Activity_Pause is called every time that the activity moves from
the 34
35. foreground to the background. This can happen because:1. A
different activity was started.2. The Home button was pressed3. A
configuration changed event was raised (orientation changed for
example).4. The Back button was pressed.In scenarios 1 and 2, the
activity will be paused and for now kept in memory as it isexpected
to be reused later.In scenario 3 the activity will be paused,
destroyed and then created (and resumed) again.In scenario 4 the
activity will be paused and destroyed. Pressing on the Back button
issimilar to closing the activity. In this case you do not need to
save any instance specificinformation (the position of pacman in a
PacMan game for example).The UserClosed parameter will be true in
this scenario and false in all other. Note that itwill also be true
when you call Activity.Finish. This method pauses and destroys
thecurrent activity, similar to the Back button.You can use
UserClosed parameter to decide which data to save and also whether
to resetany related process variables to their initial state (move
pacman position to the center ifthe position is a process
variable). 35
36. Static Code ModulesBasic4android v1.2 includes a new type
of module which is the static code module.Adding a static code
module is done by choosing Project - Add New Module -
CodeModule.Unlike Activities and Services, code modules are not
related in any way with Androidprocess life cycle. These are just
containers for code.All of the subs in these modules are public and
can be accessed from other modules.Code modules use cases include:-
Avoiding duplicate code in multiple modules.- Sharing code between
projects. For example you can create a code module that parsessome
file. Later you can easily reuse this module in other
applications.- Separating your application logic. Each code module
can be used for a specific task.This will make your program clearer
and easier to maintain.As a code module is not tied to an activity
or service it uses the calling componentcontext when required.For
example, calling a code module sub that shows a Msgbox from an
activity will work.However if you call it from a service it will
fail as services are not allowed to showdialogs.Code modules cannot
catch events.While you can use a code module to initialize a button
for example:Code:Sub ButtonsCreator(Text As String) As Button Dim b
As Button b.Initialize("Button") b.Text = Text Return bEnd SubFrom
the activity module you can
call:Code:Activity.AddView(CodeModule.ButtonsCreator("press here"),
10dip, 10dip,200dip, 200dip)Now in order to catch the click event
you should create a sub named Button_Click.This sub should be
located in the Activity module, as Code modules cannot catch
events.CallSub which internally uses the events mechanism cannot be
used to call code modulesubs (which can be called directly
instead). 36
37. Service ModulesBasic4android v1.2 adds support for Service
modules.Service modules play an important role in the application
and process life cycle.Start with this tutorial if you havent read
it before: Android Process and activities lifecycleCode written in
an activity module is paused once the activity is not visible.So by
only using activities it is not possible to run any code while your
application is notvisible.Services life cycle is (almost) not
affected by the current visible activity. This allows youto run
tasks in the background.Services usually use the status bar
notifications to interact with the user. Services do nothave any
other visible elements. Services also cannot show any dialog
(except of toastmessages).Note that when an error occurs in a
service code you will not see the "Do you want tocontinue?" dialog.
Androids regular "Process has crashed" message will appear
instead.Before delving into the details I would like to say that
using services is simpler than itmay first sound. In fact for many
tasks it is easier to work with a service instead ofan activity as
a service is not paused and resumed all the time and services are
notrecreated when the user rotates the screen. There is nothing
special with code written inservice.Code in a service module runs
in the same process and the same thread as all other code.It is
important to understand how Android chooses which process to kill
when it is low onmemory (a new process will later be created as
needed).A process can be in one of the three following states:-
Foreground - The user currently sees one of the process
activities.- Background - None of the activities of the process are
visible, however there is a startedservice.- Paused - There are no
visible activities and no started services.Paused processes are the
first to be killed when needed. If there is still not enoughmemory,
background processes will be killed.Foreground processes will
usually not be killed.As you will soon see a service can also bring
a process to the foreground.Adding a service module is done by
choosing Project - Add New Module - ServiceModule.The template for
new services is:Code: 37
38. Sub Process_GlobalsEnd SubSub Service_CreateEnd SubSub
Service_StartEnd SubSub Service_DestroyEnd SubSub Process_Globals
is the place to declare the service global variables. There is
noother Globals sub like in Activity as Service doesnt support
Activity objects.Sub process globals should only be used to declare
variables. It should not run any othercode as it might fail. This
is true for other modules as well.Note that Process_Global
variables are kept as long as the process runs and are
accessiblefrom other modules.Sub Service_Create is called when the
service is first started. This is the place toinitialize and set
the process global variables. Once a service is started it stays
alive untilyou call StopService or until the whole process is
destroyed.Sub Service_Start is called each time you call
StartService (or StartServiceAt). Whenthis subs runs the process is
moved to the foreground state. Which means that the OS willnot kill
your process until this sub finishes running. If you want to run
some code everycouple of minutes / hours you should schedule the
next task with StartServiceAt insidethis sub.Sub Service_Destroy is
called when you call StopService. The service will not berunning
after this sub until you call StartService again (which will run
SubService_Create followed by Sub Service_Start).Service use
casesAs I see it there are four main use cases for services.-
Separating UI code with "business" or logic code. Writing the
non-UI code in a serviceis easier than implementing it inside an
Activity module as the service is not paused andresumed and it is
usually will not be recreated (like an Activity).You can call
StartService during Activity_Create and from now on work with the
servicemodule. 38
39. A good design is to make the activity fetch the required
data from the service in SubActivity_Resume. The activity can fetch
data stored in a process global variable or it cancall a service
Sub with CallSub method.- Running a long operation. For example
downloading a large file from the internet. Inthis case you can
call Service.StartForeground (from the service module). This will
moveyour activity to the foreground state and will make sure that
the OS doesnt kill it. Makesure to eventually call
Service.StopForeground.- Scheduling a repeating task. By calling
StartServiceAt you can schedule your service torun at a specific
time. You can call StartServiceAt in Sub Service_Start to schedule
thenext time and create a repeating task (for example a task that
checks for updates everycouple of minutes).- Run a service after
boot. By checking Project - Service properties - Run At Boot
yourservice will run after boot is completed.NotificationsStatus
bar notifications can be displayed by activities and
services.Usually services use notifications to interact with the
user. The notification displays anicon in the status bar. When the
user pulls the status bar they see the notification message.Example
of a notification (using the default icon):The user can press on
the message, which will open an activity as configured by
theNotification object.The notification icon is an image file which
you should manually put in the followingfolder:
Objectresdrawable.Accessing other modules 39
40. Process global objects are public and can be accessed from
other modules.Using CallSub method you can also call a sub in a
different module.It is however limited to non-paused modules. This
means that one activity can neveraccess a sub of a different
activity as there could only be one running activity.However an
activity can access a running service and a service can access a
runningactivity.Note that if the target component is paused then an
empty string returns.No exception is thrown.You can use IsPause to
check if the target module is paused.For example if a service has
downloaded some new information it can call:Code:CallSub(Main,
"RefreshData")If the Main activity is running it will fetch the
data from the service process globalvariables and will update the
display.It is also possible to pass the new information to the
activity sub. However it is better tokeep the information as a
process global variable. This allows the activity to
callRefreshData whenever it want and fetch the information (as the
activity might be pausedwhen the new information arrived).Note that
it is not possible to use CallSub to access subs of a Code
module.Examples:Downloading a file using a service
modulePeriodically checking Twitter feeds 40
41. Variables & ObjectsTypesBasic4android type system is
derived directly from Java type system.There are two types of
variables: primitives and non-primitives types.Primitives include
the numeric types: Byte, Short, Int, Long, Float and
Double.Primitives also include: Boolean and Char.List of types with
their ranges:
http://www.basic4ppc.com/forum/basic...html#post45511Primitive
types are always passed by value to other subs or when assigned to
othervariables.For example:Code:Sub S1 Dim A As Int A = 12 S2(A)
Log(A) Prints 12End SubSub S2(B As Int) B = 45End SubAll other
types, including arrays of primitives types and strings are
categorized as non-primitive types.When you pass a non-primitive to
a sub or when you assign it to a different variable, acopy of the
reference is passed.This means that the data itself isnt
duplicated.It is slightly different than passing by reference as
you cannot change the reference of theoriginal variable.All types
can be treated as Objects.Collections like lists and maps work with
Objects and therefore can store any value.Here is an example of a
common mistake, where the developer tries to add several arraysto a
list:Code:Dim arr(3) As IntDim List1 As ListList1.InitializeFor i =
1 To 5 arr(0) = i * 2 arr(1) = i * 2 arr(2) = i * 2 41
42. List1.Add(arr) Add the whole array as a single itemNextarr
= List1.Get(0) get the first item from the listLog(arr(0)) What
will be printed here???You may expect it to print 2. However it
will print 10.We have created a single array and added 5 references
of this array to the list.The values in the single array are the
values set in the last iteration.To fix this we need to create a
new array each iteration.This is done by calling Dim each
iteration:Code:Dim arr(3) As Int This call is redundant in this
case.Dim List1 As ListList1.InitializeFor i = 1 To 5 Dim arr(3) As
Int arr(0) = i * 2 arr(1) = i * 2 arr(2) = i * 2 List1.Add(arr) Add
the whole array as a single itemNextarr = List1.Get(0) get the
first item from the listLog(arr(0)) Will print 2Tip: You can use
agrahams CollectionsExtra library to copy an
array.CastingBasic4android casts types automatically as needed. It
also converts numbers to stringsand vice versa automatically.In
many cases you need to explicitly cast an Object to a specific
type.This can be done by assigning the Object to a variable of the
required type.For example, Sender keyword returns an Object which
is the object that raised the event.The following code changes the
color of the pressed button. Note that there are multiplebuttons
that share the same event sub.Code:Sub Globals Dim Btn1, Btn2, Btn3
As ButtonEnd SubSub Activity_Create(FirstTime As Boolean)
Btn1.Initialize("Btn") Btn2.Initialize("Btn")
Btn3.Initialize("Btn") Activity.AddView(Btn1, 10dip, 10dip, 200dip,
50dip) Activity.AddView(Btn2, 10dip, 70dip, 200dip, 50dip)
Activity.AddView(Btn3, 10dip, 130dip, 200dip, 50dip) 42
43. End SubSub Btn_Click Dim b As Button b = Sender Cast the
Object to Button b.Color = Colors.RGB(Rnd(0, 255), Rnd(0, 255),
Rnd(0, 255))End SubThe above code could also be written more
elegantly:Code:Sub GlobalsEnd SubSub Activity_Create(FirstTime As
Boolean) For i = 0 To 9 create 10 buttons Dim Btn As Button
Btn.Initialize("Btn") Activity.AddView(Btn, 10dip, 10dip + 60dip *
i, 200dip, 50dip) NextEnd SubSub Btn_Click Dim b As Button b =
Sender b.Color = Colors.RGB(Rnd(0, 255), Rnd(0, 255), Rnd(0,
255))End SubScopeVariables that are declared in Sub Globals or Sub
Process_Globals are global and can beaccessed from all subs.Other
variables are local and can only be accessed from the sub that they
are declared in.See the Activity lifecycle tutorial for more
information about Globals vs.Process_Globals variables.TipsAll
views types can be treated as Views. This allows you to change the
commonproperties of views easily.For example, the following code
disables all views that are direct children of the
activity:Code:For i = 0 To Activity.NumberOfViews - 1 Dim v As View
v = Activity.GetView(i) v.Enabled = FalseNextIf we only want to
disable buttons: 43
44. Code:For i = 0 To Activity.NumberOfViews - 1 Dim v As View
v = Activity.GetView(i) If v Is Button Then check whether it is a
Button v.Enabled = False End IfNextThe Type keyword allows you to
create your own type of objects. Custom types behaveexactly like
other non-primitive types. 44
45. Currency Converter libraries, file manager and
otherimportant conceptsIn this tutorial we will use the following
web service to convert
currencies:http://www.webservicex.net/CurrencyC...ToCurrency=EURThere
are several important aspects in this application.This tutorial
will only briefly touch each topic.FilesYou can add files to your
project using the Files tab: 45
46. In our case we have two file. CountryCodes.txt is a text
file containing the list ofcurrencies. Each line contains exactly
one value.layout1.bal is the layout file created with the designer.
Layout files are addedautomatically to the file manager.Note that
the layout file contains another two image files, the buttons
arrows. These filesare listed in the designer. If we remove
layout1.bal they will be removed from thepackage as well.The
packaged files are also named assets. Locally they are stored under
the Files subfolder.This code reads the text file and stores the
data in a list:Code: If FirstTime Then countries =
File.ReadList(File.DirAssets, "CountryCodes.txt")File.ReadList is a
convenient method that opens a file and adds all its lines to a
List. Filesare always referenced by their folder and name.The
assets are referenced by the File.DirAssets value.Android file
system is case sensitive. Which means that image1.jpg is not the
sameas Image1.jpg (unlike Windows file system).StructuresYou can
create new types or structures using the Type keyword. Later you
can declarevariables of these new types.Types can hold any other
objects, including other types and including themselves
(andincluding arrays of all of these).Structures will be covered
more deeply in a different tutorial...Structures are declared in
one of the global subs.Code:Type MyTag (FromValue As EditText,
ToValue As EditText, _ FromCurrency As Spinner, ToCurrency As
Spinner) Dim CurrentTask As MyTagThis code declares a type that
holds two EditTexts (textboxes) and two Spinners(Comboboxes).We
also declare a variable of that type named CurrentTask.In the code
you will see that we have another type named StateType which we use
tostore the current state.All views have a property named Tag. You
can set this property to any object you like.We are using it
together with the Sender keyword to handle both buttons with the
samesub. 46
47. LibrariesAs you can see in the image, the Libraries tab
page shows a list of available libraries. Thechecked libraries are
referenced. Note that you cannot remove the reference to the
corelibrary.Adding additional librariesLibraries are made of a pair
of files. The xml file that describes the library and the jar
filewhich holds the compiled code.Additional libraries and updates
to official libraries are available
here:http://www.basic4ppc.com/forum/addit...icial-updates/Note that
only users who bought Basic4android can download these libraries.To
add a library to Basic4android all you need to do is to copy both
files to a folderrecognized by Basic4android.By default this is the
Libraries folder that is usually located in: c:ProgramFilesAnywhere
SoftwareBasic4androidLibraries.You can also configure an additional
libraries folder by choosing Tools - ConfigurePaths. Note that the
additional folder is scanned first for libraries. This means that
youcan update an existing library by putting the new files in the
additional libraries folder(there is no need to delete the old
files from the internal folder).Http libraryThe Http library
includes three objects.HttpClient - This is the main object that
executes and manages the requests andresponses. The HttpClient can
execute multiple requests concurrently.It is very important to
declare it as a Process global. The HttpClient handles requests
thatrun in the background and it should not be tied to the activity
life cycle.Communication is done in two steps. First a connection
is established by sending aHttpRequest object and then the response
is read from the server.The first step is always a non blocking
action. It can take a long period till the connection 47
48. is established and you do not want to make your application
be non-responsive at thistime. Note that Android has a special
"Application not responding" dialog which allowsthe user to force
close the application.The second step, which is the consumption of
the response can be either blocking ornonblocking. If you download
a file for example you should probably choose thenonblocking
option.This code creates and sends the GET request.Code:Dim request
As HttpRequest request.InitializeGet(URL & fromCountry &
"&ToCurrency=" &toCountry) request.Timeout = 10000 set
timeout to 10 seconds If HttpClient1.Execute(request, 1) = False
Then Return Will befalse if their is already a running task (with
the same id).We are setting the timeout to 10 seconds which is
quite short. The default is 30 seconds.The target web service is
pretty unstable, which makes things more interesting. I prefer itto
fail fast in our case.HttpClient.Execute method receives two
parameters. The first is the request object andthe second is the
Task ID. This integer will be passed back in the ResponseSuccess
orResponseError events.It allows you to differentiate between
different tasks that may be running in
thebackground.HttpClient.Execute will return false if their is
already a running task with the same ID.This helps you prevent
unnecessary multiple requests.You can also check the status of
running tasks with the IsBackgroundTaskRunningkeyword.Once the
response is ready, ResponseSuccess or ResponseError will be raised.
If thingswent well, we can now read the response, find the rate and
display it. Otherwise wedisplay a "toast" message with the error
message.As I wrote above, this specific web service seems to be
unstable so your experience mayvary.StateAs discussed in the life
cycle tutorial we are required to save and restore the state of
theapplication. In our case the state is made of the values in the
text boxes and the currentselected currencies. 48
49. The following type and variable are declared in Sub
Process_Globals:Code: Type StateType (TextUp As String, TextDown As
String, _ IndexUp As Int, IndexDown As Int) Dim State As StateType
This must be a process variable as itstores the state and should
not be released when theactivity is destroyed.On the first run we
set its values with the default values we want:Code:Sub ResetState
set the starting state State.TextUp = 1 State.TextDown = ""
State.IndexUp = 0 USD State.IndexDown = 43 EuroEnd SubLater we save
and read it as needed:Code:Sub Activity_Resume txtUp.Text =
State.TextUp txtDown.Text = State.TextDown spnrUp.SelectedIndex =
State.IndexUp spnrDown.SelectedIndex = State.IndexDownEnd SubSub
Activity_Pause (UserClosed As Boolean) If UserClosed Then
ResetState reset the state to the initial settings. Else
State.TextUp = txtUp.Text State.TextDown = txtDown.Text
State.IndexUp = spnrUp.SelectedIndex state.IndexDown =
spnrDown.SelectedIndex End IfEnd SubIn Activity_Resume we read the
values and set the required views. Note thatActivity_Resume is
called right after Activity_Create. So it will also be called on
the firsttime we run the application.In Activity_Pause we save the
value in the state object (which is a process variable).Note that
if the user pressed on the back key (which means that he wants to
close ourapplication) we return the state to the initial state.
Therefore the user will see a "cleannew" application the next time
he will run our application. 49
50. It is worth paying attention to this
line:Code:CurrentTask.FromCurrency.SelectedItem.SubString2(0,
3)CurrentTask is of type MyTag.It has a field named FromCurrency
which is of type Spinner.Spinner has a property named SelectedItem
which returns a String.String has a method named Substring2.Also
note that this code is valid:"abcd".Substring(2)The complete code
(file is also attached):Code:Activity moduleSub Process_Globals Dim
countries As List Dim URL As String URL
="http://www.webservicex.net/CurrencyConvertor.asmx/ConversionRate?FromCurrency="
Dim HttpClient1 As HttpClient Type StateType (TextUp As String,
TextDown As String, _ IndexUp As Int, IndexDown As Int) Dim State
As StateType This must be a process variable as itstores the state
and should not be released when theactivity is destroyed.End SubSub
Globals Dim txtUp, txtDown As EditText Dim spnrUp, spnrDown As
Spinner Dim btnUp, btnDown As Button Type MyTag (FromValue As
EditText, ToValue As EditText, _ FromCurrency As Spinner,
ToCurrency As Spinner) Dim CurrentTask As MyTagEnd SubSub
ResetState set the starting state State.TextUp = 1 State.TextDown =
"" State.IndexUp = 0 USD State.IndexDown = 43 EuroEnd SubSub
Activity_Create(FirstTime As Boolean) If FirstTime Then
Log("************************") 50
51. load the list of countries countries =
File.ReadList(File.DirAssets, "CountryCodes.txt") initialize the
HttpClient object which is responsible for allcommunication.
HttpClient1.Initialize("HttpClient1") ResetState End If
Activity.LoadLayout("layout1") spnrUp.AddAll(countries)
spnrDown.AddAll(countries) Dim t1 As MyTag t1.FromValue = txtUp
t1.ToValue = txtDown t1.FromCurrency = spnrUp t1.ToCurrency =
spnrDown btnDown.Tag = t1 Dim t2 As MyTag t2.FromValue = txtDown
t2.ToValue = txtUp t2.FromCurrency = spnrDown t2.ToCurrency =
spnrUp btnUp.Tag = t2End SubSub Activity_Resume txtUp.Text =
State.TextUp txtDown.Text = State.TextDown spnrUp.SelectedIndex =
State.IndexUp spnrDown.SelectedIndex = State.IndexDownEnd SubSub
Activity_Pause (UserClosed As Boolean) If UserClosed Then
ResetState reset the state to the initial settings. Else
State.TextUp = txtUp.Text State.TextDown = txtDown.Text
State.IndexUp = spnrUp.SelectedIndex state.IndexDown =
spnrDown.SelectedIndex End IfEnd SubSub btn_Click Dim btn As Button
btn = Sender Fetch the actual button that raised this event.
CurrentTask = btn.Tag Take the object from its Tag property. Dim
fromCountry, toCountry As String fromCountry =
CurrentTask.FromCurrency.SelectedItem.SubString2(0,3) get the
currency code 51
52. toCountry =
CurrentTask.ToCurrency.SelectedItem.SubString2(0, 3) Dim request As
HttpRequest request.InitializeGet(URL & fromCountry &
"&ToCurrency=" &toCountry) request.Timeout = 10000 set
timeout to 10 seconds If HttpClient1.Execute(request, 1) = False
Then Return Will befalse if their is already a running task (with
the same id). ProgressDialogShow("Calling server...")End SubSub
HttpClient1_ResponseSuccess (Response As HttpResponse, TaskId
AsInt) Log("ResponseSuccess") ProgressDialogHide Dim result As
String result = Response.GetString("UTF8") Convert the response to
astring Log(result) Dim rate As Double Parse the result i =
result.IndexOf(".NET/") If i = -1 Then Msgbox("Invalid response.",
"Error") Return End If i2 = result.IndexOf2("