Basic4android programming tutorials collection for Android apps developers

download Basic4android programming tutorials collection for Android apps developers

If you can't read please download the document

description

120 pages of tutorials, covering the main concepts of Android programming.

Transcript of Basic4android programming tutorials collection for Android apps developers

  • 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("