182 24 9MB
English Pages 482 [337] Year 2010
Introduction to bada: A Developer's Guide - (draft preview, July 2010)
Part 1: About bada
0
Introduction to bada: A Developer's Guide - (draft preview, July 2010)
Chapter 1: The mobile difference In this chapter we present detailed information about what the ‘difference’ of mobile software is made up of and we describe the essential characteristics as opposed to ‘conventional’ fixed software for desktops or web applications. We also summarise some recommended mobile software development bestpractices. Where appropriate we give forward references to later chapters where we deal with specific topics and how bada implements or supports the various aspects of development.
1.1 The mobile context Some 20 years from the birth of mobile, hardware and telecoms have changed out of recognition – mobile usage has changed the way people behave. But the exploitation of mobile services has hardly begun. The apps revolution of last few years, dominated by iPhone, is a signpost – but the real revolution will be the arrival of apps and services for the mass market. bada could be the game changer. With the bada platform and the accompanying ecosystem we pick up the characteristics of mobile app development as you will see in this chapter and throughout the book. By using bada, you will be equipped with a proper environment and tools that lay the ideal foundations for your successful mobile applications. Mobile hardware is different from desktop hardware. It’s not just that mobile phones fit in your pocket. The relentless drive to fit more and more functionality into tinier and tinier physical packages has led to almost continuous innovation. Mobile storage (memory), mobile display, and mobile power technologies are different from their big brothers on the desktop. When you are developing for mobile, it is essential to understand how these differences can impact the way you design your apps and the way you write your code. But to some extent these differences are only skin deep, they are not what really differentiates mobile from fixed. Users use mobile differently. Users consume mobile services differently. Users buy and pay for their mobiles and mobile software differently. In fact this is a crucial difference – that users are 1
Introduction to bada: A Developer's Guide - (draft preview, July 2010)
willing to BUY mobile software! Again, these differences impact the way you design your apps and write your code. Take mobile services. We can differentiate between types of services that are only meaningful in a mobile context and others that are traditionally used in fixed or web browser-based environments and can now be extended to the mobile dimension. Take location-based or map services as a representative example for the former group. The idea of location-based services (LBS) has been around for over a decade now. The added-value of such services is clear and unchallenged. It is the provision of information that is related to a user's current position and addresses an immediate need. Services and information can be delivered filtered according to specific locations. Only a few such services, however, turned out to be really big hits. Technology and the whole ecosystem just was not ready back then. Today, however, everything is prepared such that LBS could deliver their promise. An example for the second group are the booming social network services (SNS) stemming from the Web 2.0 movement that gave birth to blogs, facebook, MySpace, YouTube, Twitter, you name it. Such applications and social networks can now be increasingly invoked and used from mobile handsets either by web sites customised for mobile browsers or standalone apps. This suggests how different mobile apps can be from desktop applications. On the desktop, your wordprocessor or spreadsheet or database application, and your first person shooter or adventure game, are big, complex, kitchen-sink type applications; they do everything, integrate with everything, and each would be very happy if it was the only application you ever needed. Mobile apps are almost exactly the opposite of this – they are small and focused pieces of software. (Are they complex? We will see…) Regardless of which type, software for mobile devices that can provide such added-value is what we refer to as mobile software. To deliver a successful mobile solution the specific characteristics must be respected such as hardware constraints, different ecosystem structures (like much shorter lifetime and hence shorter time to market), or diversified types of usage context (user experience). Ideally, the added value of mobile software in all application areas is directly addressing a need or the increase of comport. This can mean an optimisation for users in terms of costs, efforts, or time savings, increase of flexibility, improvement of communication means, or just fun. 2
Introduction to bada: A Developer's Guide - (draft preview, July 2010)
It is essential to understand that users’ requirements of mobile software are substantially different from software for fixed environments (such as Desktop software). Mobile software must be engineered by seriously respecting the different characteristics of mobile software. We define this type of software development for a mobile usage context as Mobile Software Engineering.
1.2 Characteristics of mobile software Mobile software has a number of characteristics that make it very different to desktop or web based software, the most important being: 1. Technological differences 2. Differences related to usability and user experiences 3. Differences in the ecosystem In the following sections we touch on each of these topics in more detail.
Technological differences Mobile handsets are getting steadily more powerful, with processor speeds of up to 1GHz, memory of up to 512MB and flash memory of 16GB or more being common on many devices. Advances in display technology have also enhanced the user experience. The first bada-powered device, the Samsung Wave, is equipped with the Super AMOLED 1 display which delivers better contrast, more efficient energy consumption and less sunlight reflection than older mobile displays. As connections get faster, the services available to users have grown to include rich multimedia streaming and games, while user confidence in increased connection security has led to an explosion in mobile eCommerce and eTicketing apps.
1
AMOLED stands for Active-matrix organic light-emitting diode.
3
Introduction to bada: A Developer's Guide - (draft preview, July 2010)
But it’s the advances in positioning technologies that have led to the biggest revolution in mobile apps. GPS is now standard even in low end devices and bada offers developers an easy and powerful way to develop location aware apps through its APIs for location services. Advances in hardware provide new development possibilities, such as the wide range of sensors which can be exploited to improve the user experience. Some devices include accelerometers, electronic compasses, tilt, light and temperature sensors and of course touch sensitive displays. Users will find it natural to tilt their device to the side to enable landscape mode or list a random set of restaurants by shaking the device. Sensors provide functionality not available to fixed, desktop applications. Developing for mobile devices also provides some challenges to those used to creating desktop or web applications. Mobile hardware is improving rapidly, but devices are still not as powerful or have as much storage as desktops or servers. While communications technology has become more reliable, a developer cannot assume an always on internet connection. The way that the user interacts with a device is also different. A smaller screen, touch screen or small keyboard input cannot offer the same experience as a proper keyboard and mouse. The most important, and often overlooked, difference in mobile compared to desktop development is energy consumption and the dependence on the battery. Battery capacity on devices has increased, but so have the range of technologies which consume a lot of energy: GPS, Wi-Fi, Bluetooth, 3G and multimedia support being prime examples. Some of the currently successful devices do not even make it through the day without needing recharging and battery life is a frequent user complaint. Device manufacturers are doing their best to improve battery life, but software developers have their part to play through careful use of resources. Because mobile phones typically run for days or weeks or longer without being switched off, memory leaks, for instance, can seriously compromise the phone's performance.
Differences related to usability and user experiences New mobile technologies such as sensors and touch screens allow us to build better user interfaces and to represent information in more user friendly and usable ways. In particular Web 2.0 applications such as
4
Introduction to bada: A Developer's Guide - (draft preview, July 2010)
Facebook and Twitter can all now be accessed easily by mobile users using web pages designed for access on-the-go or by applications. Users may be able to do more with their devices, but they are still confronted by a huge range of different screen sizes, input methods and user interface ‘look and feel’ approaches that can make using mobile applications a frustrating experience. Developers who follow user interface guidelines, such as those provided by bada, will create easy to use, consistent applications on a particular platform, but there are still many platforms available. Several initiatives such as bada, the LiMo foundation, the Open Handset Alliance and the Symbian Foundation show a trend towards open systems to facilitate harmonisation and the easing of application development and deployment. However, mobile developers will have to deal with the problem of incompatible platforms for some time to come. Mobile applications are also used differently to their desktop equivalents. If you are mobile and want to find information about what is showing at the local cinema, or a review of a particular restaurant, you want to find that specific information quickly and don’t want to spend time searching through information you don’t need. Your attention span for using the application is limited, so you want to be presented with location specific information. You might also be trying to find directions, or using the mobile in sunlight or somewhere with a lot of background noise, all environmental factors that need to be considered. The Samsung Wave device represents a very successful attempt of addressing such issues by deploying the AMOLED screen, whose design goal among others was to be less susceptible to sunlight reflections, or enriching the user interfaces with haptics and motion detection.
Differences in the ecosystem Users expect to be able to find and download the software they want using their device when they’re on the move. Users should be served following a wish and use notion. When users wish to satisfy a current need they should be able to get and use corresponding information or services as fast and simple as possible. They want the purchasing and installation process to be simple, which is where a central one stop shop such as the SamsungApps store comes in. Developers distribute their applications via SamsungApps, one central location from which users of bada devices can purchase and download apps and make in-app purchases. One side effect of this approach is that the network operator no longer plays the ‘gatekeeper’ role to their devices, the user can freely decide which apps to install. 5
Introduction to bada: A Developer's Guide - (draft preview, July 2010)
The lifetime and the time to market of a mobile app are substantially shorter than traditional software products and developers need to adapt. By having a central distribution system such as SamsungApps, the developer can concentrate on creating and marketing their application in the knowledge that the distribution, purchasing and revenue sharing model will be taken care of by the SamsungApps store. This simplified way of application distribution also has other advantages. Users can be sure that applications will be independently tested and will comply with a certain quality standard and will respect the integrity of the user’s data and won’t spend their money on phone and data calls without asking. A further positive side effect resulting from the app store initiatives is that costs all of a sudden become much more transparent. Network operators recognised this trend and came up with contract bundles with flat data rates or volume packages in order to encourage the download of apps from stores. In the past, incomprehensible and non-transparent cost models discouraged users from using mobile services or downloading mobile apps because they feared exaggerated costs. With new all-inclusive models, downloading apps and invoking mobile services has become a lot more user friendly and thus accepted. From this, we conclude that the future of mobile apps ahead of us should be quite promising. The bada platform in combination with SamsungApps represents an ecosystem that addresses, exploits, and in fact shapes some of the differences that we outlined in this chapter. Figure 1.1 summarises what the bada ecosystem stands for.
Figure 1.1 The bada ecosystem 6
Introduction to bada: A Developer's Guide - (draft preview, July 2010)
At the one end of the chain we have the developers or application providers who want to develop applications. On the other end are the users or customers who want to use mobile apps. Along this chain Samsung provides three core building blocks that foster the bada ecosystem. Central to it is the bada mobile platform which is the execution environment deployed on mobile handsets. This platform not only covers the mobile part but also allows seamless access to the bada server as you will get to know later in chapter 5. Powerful and well-abstracted APIs are exposed as an open SDK to developers. In addition to that the left block in Figure 1.1 covers a large number and variety of technical support resources such as training material, tutorials, sample code, tech blogs, videos, and the API reference documentation. The right block is the application store SamsungApps that allows certifying and publishing your apps. Once your app is ready for publication you can decide if – via the store – you want to sell your app or give it away for free, or however else you want to become rich and famous. In the next chapter we would like to introduce some app development best-practices that should help to produce successful mobile applications.
1.3 Mobile app development best-practices We argued that mobile apps show some specific characteristics that make them different from conventional software for desktops or servers. Related markets are also different and develop at a faster pace. Hence, in order to create successful mobile solutions or applications we recommend to deploy some best practices that we want to introduce in this chapter. In the appendix we provide an example of a full software engineering process for mobile applications. Of course, you can follow any process you prefer or develop your software without following any process at all. There is a range from strict waterfall model to cowboy coding. As a rule of thumb the more complex a project is and the more coordination it requires, the more formalisation in terms of processes is advisable. Experience showed that so called agile software development processes are very appropriate for fast paced software, which mobile apps definitely are.
7
Introduction to bada: A Developer's Guide - (draft preview, July 2010)
In the agile manifesto2 software engineering experts summarised the key factors that should help to produce better software faster and more reliably. They state that agile development is about focus on result. That means executable software should be built as soon as possible, which is the primary measure of progress. Software should be built incrementally starting from its core functions over various iterations. Tool and process support is relevant but must be chosen appropriate to the solution in order to avoid unnecessary overhead. Finally software engineering is about people working together. Hence, communication – ideally in a face-to-face and spoken way – is at the core of agile development. That does not only refer to the project team but also and similarly important to the stakeholders, clients and future end users. In line with this, we would like to add to this recommendation an emphasis on using as much prototyping and diverse testing as possible throughout the whole development, where both are integral parts of and inherently supported by the bada platform and its development tools. Prototypes can be exploited nearly in any phase during development of mobile software solutions. They are primarily helpful for eliciting requirements or to get a common understanding with various stakeholders early in the project. Testing surely is not unique to mobile software engineering but must be treated and executed differently. This is an effect of various issues related to mobile software such as the heterogeneity of hardware and devices, the dependence on context factors which are difficult to test on simulators (e.g. geographic locations), and the phenomenon of the discrepancy between the simulator versus real device behaviour. The bada toolset provides means to support both. First, the UI Builder, which is integrated into the bada IDE, allows building simple mock-up prototypes easily and quickly. Developers can use this WYSIWYG tool to create first “clickable” demos by visually placing a variety of UI controls onto the device screen. A second convenient tool is the Event Injector that comes with the bada simulator. This is useful for simulating a broad variety of context data. Incoming calls, text messages or battery level can be tested as well as different sensor such as location, acceleration, tilt, magnetic field or proximity. It is always difficult to test mobile apps in a simulator because obviously you are missing all the so necessary context data. So the by far more expensive and complex type of test is the deployment on the real devices and
2
See http://www.agilemanifesto.org/
8
Introduction to bada: A Developer's Guide - (draft preview, July 2010)
test-runs in the real world context. With the bada Event Injector (see Figure 1.2), a lot of this effort can be shifted to the simulator tests making system tests less time consuming and cheaper.
Figure 1.2 The bada Event Injector But let us come back to the ideas postulated by the agile manifesto. Thereby, ‘agile’ is often misused for everything which does not have clear rules or a process. This we would rather call ‘cowboy coding’. Agile cannot be equalled to chaos, or lack of rules or discipline. Agile app development does propose to follow some simple maxims and recommendations. So, let us describe some rules. We do so by listing a toolbox of some best-practices coming from various agile methodologies such as Scrum, Test-driven Development, eXtreme Programming, or Crystal. Again, 9
Introduction to bada: A Developer's Guide - (draft preview, July 2010)
the core cornerstones are focus on results, incremental iterations, appropriateness of the means, and communication. The following best-practice recommendations all deal with one or more of these cornerstones.
•
Focus on results more than on processes. Every procedure or means that does not help to achieve the goal of the software project should be cut off. The more complex a project is the more tools, rules and formalisms it will require.
•
Plan your software development into cycles or iterations. Identify the core and most critical components, priories and start with the most important ones (“first things first”).
•
Be tolerant towards change (changing requirements and change requests). Avoid rigid or inflexible structures, process, tools or methods.
•
Try to produce executable software at the end of every iteration.
•
After you finished an iteration a further increment to the final software product is added.
•
Try to keep design and software simple. Have possible extensions in mind but focus on producing executable code at least at end of each iteration (“keep it short and simple – KISS”)
•
Make use of early feedback from various stakeholders such as your client or end users. User acceptance tests could possibly be integrated into every iteration.
•
In early stages even use paper and pen to sketch software designs or early prototypes.
•
Make use of a test-oriented development where you write the test cases first, at least for core or critical code parts.
•
Build and integrate tested parts frequently (e.g. daily).
•
Set up communication means such that a close contact with client and end users is possible.
•
Try to have regular, frequent and brief intra-team communication without formal overhead (e.g. daily stand-up meetings).
•
Establish and publish team and project rules – such as a communication etiquette or coding standards.
•
Conduct code reviews or pair programming sessions for core or critical code parts.
10
Introduction to bada: A Developer's Guide - (draft preview, July 2010)
•
Make sure to have efficient knowledge transfer within the team but also to client and user. This may not always be applicable or sensible. Sometimes this knowledge transfer may also be unidirectional.
•
Use visualisations for your communication. Use, for instance, a visible whiteboard accessible for everyone in the team to sketch the tasks or features and development progress.
•
Some form of documentation is necessary but only as much as necessary and as little as possible. And beware of over-specifications.
Again, please bear in mind that you do not have to stick to the mobile software engineering process outlined here. This is merely advice and something you can stick to.
11
Introduction to bada: A Developer's Guide - (draft preview, July 2010)
Chapter 2: bada basics This chapter gets straight down to the essentials of developing native bada applications in C++. We’ll see just how easy it is to get a first skeleton application up and running on the bada Simulator. To start with, this little app doesn't do much – think Hello World! But this is the code at the heart of every bada app, and as we'll see in the next few chapters, bada makes it easy to build up from this basic skeleton to create a full-featured, native application. Note: the Simulator launches from the Eclipse-based bada IDE, which is included in the SDK. At the time of writing the SDK installs on Microsoft Windows only. It's likely that bada will support other development options eventually, but nothing is currently announced.
What you will learn This chapter aims to get you started quickly. You will learn: •
How to create a simple application using the Application Wizard
•
How to add a simple UI using UI Builder
What you will need This book assumes beginner's C++ skills. If you don't know C++, don't give up: bada works hard to make the app developer's life as easy as possible. If you have experience using any modern programming language, then a good C++ primer should be enough to get you up and running. By the way, don't worry if you are new to mobile development. As we saw in the previous chapter, there are some things that make mobile unique, and different from the world of the desktop. We'll highlight those issues as they arise in the context of each chapter.
12
Introduction to bada: A Developer's Guide - (draft preview, July 2010)
2.1 Your first bada application Native bada apps are C++ executables that combine the code that you write with framework code. Because the bada frameworks take care of the basic functionality that every app requires, there is very little code required to create a minimal app, as we will see. To start with, we will build for the bada Simulator only. In the next chapter we'll dig a little deeper and show you how to build for (and deploy to) a real bada phone. Because bada is highly modular, most of your time as a developer will be spent connecting together the pieces while the bada frameworks do the heavy lifting for you. As you might expect, all bada applications are fully graphical programs. In fact, one easy way to think of a bada application is as a GUI that does something (where a GUI, of course, is a Graphical User Interface). For any app, the GUI is where the user and the app meet. It’s the GUI that presents the application functionality to the user, and the GUI that allows the user to control that functionality. For the user, your GUI is your app, and to a large degree determines the complete app experience. All bada apps that use the standard UI elements share the distinctive look-and-feel and behaviour of the bada UI and application frameworks. When you need more customised elements, you can derive your own and extend the default behaviour. Of course, there may be times when you want complete UI control (in a game, for example), and don't want the standard look and feel. In that case bada allows you to write directly to the full-screen display to construct your own UI from scratch. But that's enough of an introduction! If your C++ is rusty, this is a good time to get out your favourite C++ primer. Then fire up the bada IDE, and follow along. Note: the bada IDE is included in the SDK and is based on the industry-standard Eclipse IDE, see http://eclipse.org/, and includes the Sourcery G++ GNU Toolchain, including C++ compilers for Win32 Simulator targets and ARM core phone targets. The SDK adds the bada header files, libraries, documentation, and code Example and Sample programs. See the Appendices for more information 13
Introduction to bada: A Developer's Guide - (draft preview, July 2010)
about obtaining and installing the SDK. Installation is usually straightforward; for a normal setup, no manual configuration or intervention is required.
2.1.1 A skeleton app Creating a new application is easy – the App Wizard does all the hard work for you, and generates complete C++ skeleton code (.h header and .cpp source files), together with all the additional files the app requires. Let's try it out. Launch the bada IDE, and select File | New | bada Application Project to pop up the Project Wizard. Give your project a name – we call ours BuddyFix – and choose Application | bada Form Based Application in the Project type panel.
Figure 2.1 Creating a new bada project in the IDE 14
Introduction to bada: A Developer's Guide - (draft preview, July 2010)
Note: BuddyFix is the name of the project we use as a running example throughout this book, showing you how to build it up from scratch. To start with, BuddyFix has only rudimentary functionality, but eventually it will be a useful little application that enables you to swap live location information with selected “buddies”. Select Next, and accept the default SDK Root path. This just tells the build tools where to find common headers and libraries; modify the path if you have multiple SDK versions installed. Finally, check the phone model you want to build for (at the time of writing, the default is Wave).
Figure 2.2 Setting the default SDK root path. We’re using the default To get started, that's all you need. There are more options available (you can explore them by choosing Next), but for now you can select Finish and let the wizard do its work.
15
Introduction to bada: A Developer's Guide - (draft preview, July 2010)
In the Project Explorer pane, you'll see that a folder has been created, named with the project name you specified. Inside is a basic skeleton app. Let's look at it.
2.1.2 Project structure Note: When you start the IDE, you can choose the workspace in which Eclipse will create new folders and look for existing project files. You can switch between workspaces at any time by choosing File | Switch Workspace from the IDE main menu. In your workspace, you will see a folder named BuddyFix (or the name you chose for your new project). Inside it you'll see some sub-folders:
Figure 2.3 The BuddyFix folder and subfolders
16
Introduction to bada: A Developer's Guide - (draft preview, July 2010)
•
The /inc and /src folders are where the generated C++ code files for your project are saved; .h files in /inc and .cpp files in /src
•
The /Home folder is the filesystem root for any data files or folders your app reads or writes
•
The /Icons folder is where you should store the icons used by your app, and it's where the Wizard copies the default app icon – which you should change for your own artwork, of course, when you create a real project
•
The /Res folder is where your application keeps resource files that it uses. We will see how resources are used when we create the BuddyFix UI.
Note that /Icons, /Home, and /Res are also created as folders on a real device when you install your app. On a phone, /Icons and /Res are read-only “system” locations, while /Home is readable and writeable, and private to your application. Note: in the IDE, the Project Explorer view also shows an /Includes folder, which is a virtual folder that maps all include paths for your project. It is not a physical folder in your Windows filesystem. Project Explorer also hides some files that you will see in your Windows filesystem, with names like .badaprj, .cproject, and .project. These are standard Eclipse house-keeping files which you can ignore. Table: Project folders generated by the wizard
/Home /Icons
/Res /inc /src
Root folder of the application private data area, which provides dedicated (and protected) file system storage. The folder is empty until the app creates and saves file data, but always exists, even if not used by the app Contains default .png app icon and splash screen files, which you should replace with your own custom graphics Contains all resources used by the app, typically Forms and Strings. Forms are defined by XML definition files, and partitioned into display resolution-specific sub-folders if you choose to target phones with different display resolutions. For BuddyFix, the supported resoilution is 480x800 pixels i.e. QVGA Contains the skeleton app's .h header files Contains the skeleton app's .cpp files, including an Entry file which defines the app entry point to the Framework. This is generated code which you will not need to modify
17
Introduction to bada: A Developer's Guide - (draft preview, July 2010)
2.1.3 App metadata There are two important files that we haven't mentioned yet, application.xml and manifest.xml. The application.xml is generated by the wizard, and placed into your project root directory. The manifest.xml is ideally created by using the Application Manager on the developer.bada.com website or alternatively you can use the default file created by the wizard. These are metadata files and are essential to your project. They declare application information used to create your final app package – the app name and version, vendor name, and so on – as well as critical information about the APIs that your app uses and any security permissions, known as privileges in bada, that are required to use them. Privileges are part of the bada security model, and we will look at them in detail in Chapter 4. When you start a real project, you’ll need to create a custom version of the manifest using the tools that are available through your account on the bada developer portal (see section 2.7). But to start with we needn't worry about these details at all; the default metadata files generated by the App Wizard will be fine to get started. Project metadata files application.xml Used by the app packaging tools to create an installable package. Declares the app name, description, vendor, and version; identifies the app icon files. manifest.xml Used for privilege checking and by the certification process. Declares app properties including keys and IDs; required device features, for example CPU type, minimum heap size, screen size, sensors used; and required privileges.
Note: if you've done any widget development, then application.xml will look familiar; it's the equivalent of the config.xml file that defines a widget package; and if you’ve developed for Android, manifest.xml does a similar job to the Android manifest file.
18
Introduction to bada: A Developer's Guide - (draft preview, July 2010)
2.1.4 Build and run Although we have done nothing more than run the wizard, we have enough code to build and launch a first, skeleton version of our app. Let's verify that the code builds. In the IDE, select your project by name in Project Explorer. From the menu bar select Project | Build Project, and your project should compile and link.
Figure 2.4 Building the project
19
Introduction to bada: A Developer's Guide - (draft preview, July 2010)
When your project has successfully built, a Binaries folder will display in Project Explorer, which maps to the.Simulator-Debug directory in your Windows filesystem, where the project binary and object files are stored. To launch your app, select your project by name in Project Explorer. From the menu bar select Run | Run As | 1 bada Simulator Application from the popdown menu. The bada Simulator will run. We chose Wave as the phone model when we created our project, so what we see is a good approximation of Wave, running on the PC screen. The Simulator launches and initialises, briefly displays the phone home screen, and then launches our app.
Figure 2.5 Our app running in the simulator 20
Introduction to bada: A Developer's Guide - (draft preview, July 2010)
Note: the App Wizard sets the application Title bar to 'Hello bada!' for any app generated with the Form Based Application option, and launches a pop up 'OK' button when the app runs. This is a bit confusing, because it's not obvious that it’s our app that's running. But take our word for it – it is! To close the app, select the phone’s Power/End key on the Simulator. Your app will close, and you will be returned to the home screen. Select the Menu key to go to the application manager. You’ll see your app displayed there in the icon menu list, using the default app icon.
Figure 2.6 BuddyFix showing in the application manager Note: when BuddyFix launched, you may have noticed that a splash screen was briefly displayed before the application was shown, based on splash.png, a default file in the /Icons folder. You can change the image that's displayed by changing this file. The splash screen is a customisable property of your bada project – it is set in the same way as setting your app icon. 21
Introduction to bada: A Developer's Guide - (draft preview, July 2010)
By the way, the splash screen is displayed to fill any delay while your app is launched. Delay may occur for a number of reasons, depending on the load on the phone at any time. The splash screen is not displayed by the app itself to hide a delay while the app initialises. And in fact you should design your app to postpone doing any initialisation which might cause perceptible delay in showing its main screen. You can do this either by performing such initialisation in the background using multithreading techniques, or by deferring this deeper initialisation until the app has launched, or both. A hint: in order to pass the certification process a bada app must have its own splash screen and app icon.
2.1.5 Standard output One useful view in the Eclipse IDE is the Output pane. When you launch an app in the Simulator, the system logs an ‘Application started’ message, and when you close the app the system logs an ‘Application finished’ message: 0010.200,INFO,P26,T-01,A-01,OspMain (24) > Application started. 0014.030,INFO,P26,T-01,A93,OspMain (39) > Application finished. Between these log points, you can output your own printf-like logging statements to trace your app's behaviour at runtime, using bada’s logging macros, AppLog(), AppLogDebug(), and AppLogException(). For example, to output a simple log message, add the line:
AppLog(“This message will display in the output view”); Log files can be exported to simple text files with a .log suffix. In the Output pane, once your application is running, select the second icon on the left (as indicated below); a dialog is invoked that allows saving the output into a logfile on your development machine.
Figure 2.7 Output pane of the bada IDE 22
Introduction to bada: A Developer's Guide - (draft preview, July 2010)
Log messages are also written by the assert macros AppAssert() and AppAssertf(), which test the truth (or falsity, respectively) of a condition, and by the exception handling macros, which we look at in detail in Chapter 4. The debugging macros are described in the SDK Help, select Help | Help Contents | bada Developer Guide in the IDE.
2.2 The application UI We’ve said that a bada application can be thought of as a GUI that does something, where the GUI is the public face that your app shows to the user. Before getting down to practicalities and showing you how to build a simple GUI, let’s fill in some background. Depending on its complexity, an application may require only a single screen – a simple calculator layout, for example, for a Calculator app. Or it may require multiple screens like an Address Book app, which might organise its main screen as a scrolling list of name and adresss entries, with a details screen to display details of a single complete entry, and editing screens to enable editing of entry details, labels, and so on. Getting your GUI design right is one of the most important tasks you’ll face as an app developer. Lots has been written about the art of good UI design, and a lot has been written about the special case of good mobile UI design. 3 Two attributes that characterise the best, are fanatical attention to detail and ruthless simplification.
3
Get hold of Scott Jensen's The Simplicity Shift, if you don't already know it (Cambridge, 2002). A classic mobile case study is Lindholm et al, Mobile Usability (McGraw-Hill, 2003). Ballard, Designing the Mobile User Experience (Wiley, 2007), is a good overview text. And no app developer should be without Bill Moggridge, Designing Interactions (MIT, 2007). There's also a wealth of material on the web that discusses the general
23
Introduction to bada: A Developer's Guide - (draft preview, July 2010)
It is important, too, to understand your app GUI in the context of the platform look and feel. Samsung has standardised on its TouchWiz UI across the complete range of its touch phones. Currently TouchWiz is at version 3.0, and this is the version that ships on Wave, and that you’ll see in the bada Simulator. Remember that bada is designed to push the smart phone experience down from the high end into the midrange. This influences the design of TouchWiz, and in turn it should influence your GUI design. While there is no substitute for getting your hands on a real device, the following points are worth bearing in mind: •
Touch – finger-based, direct manipulation, multi-touch including pinching and swiping, and of course tactile feedback
•
Simplicity – simple screen layout, relatively large and bold fonts, large GUI elements for interaction, large simple icons, limited customisation, simple menus
•
Bright and bold – making the most of superAMOLED display technology, high contrast, vivid colours, saturated blacks (and by the way, dark colour schemes are preferred to light, because with AMOLED technology dark pixels consume less power than light pixels)
•
Extended user input – as well as touch and hard keys, TouchWiz supports gestures (physical motions including tapping on the case, rotating the phone, snap and shake), even face detection
•
Multiple display sizes and resolutions – WVGA (Wide VGA) 480x800, WQVGA (Wide Quarter VGA) 240x400
You can find detailed UI guidelines in the SDK Help, select Help | Help Contents | bada Application UI Guide in the IDE.
2.2.1 Frames, Forms, and Controls The GUI is not just what you see on the screen. The simplicity of the TouchWiz look and feel extends to the architecture beneath it, and to the concepts that motivate the architecture. While bada won’t design your GUI for you, it does provide a simple and standardised GUI architecture for your app to use.
principles of mobile UI design, including some excellent documentation published for other mobile platforms you may be familiar with, relevant to all mobile app development, whatever the platform.
24
Introduction to bada: A Developer's Guide - (draft preview, July 2010)
You can think of everything your app displays as being organised in a hierarchical tree. The root of the tree is the appplication Frame. Within every app, the Frame is the top-level container to which all GUI elements are added. More formally, the Frame class encapsulates the device display, and plays the role of the application's top-level window, of which there is exactly one per application. All applications have a Frame, and you don't need to do anything to create it or set it up. It’s all taken care of by the framework. Within the Frame, what the GUI displays is based on a simple metaphor of Forms as containers for standard GUI elements. A Form implements a single application screen, and an app can include as many Forms as it needs to build a complete GUI. 4 Each Form is a layout container that is populated with Controls, which are the individual GUI elements required to construct the screen's behaviour – buttons, lists, pop-ups and so on – and any other graphical elements, backgrounds, or images which make up the screen's design. Controls are either standard controls that are ready-made by the framework, or your own derived custom controls. The Control class abstracts a screen region, both for display and capturing input. Naturally, bada provides comprehensive graphical primitives, bitmaps, animations, and fonts, so the real limits here are your imagination – and your design skills! 5 The relationship between Frames, Forms, and Controls is shown in Figure 2.8
4
To be precise, there is a limit of thirty Forms per app, but this is not a limit you should expect to encounter!
5
Under the hood, the raw horsepower for bada’s graphics capabilities is based on OpenGL ES, with support for 2.0 (hardware acceleration and hardware shaders) and 1.1 standards (hardware acceleration only). The OpenGL ES version available is device dependent. It is also possible that at the low end, some bada phones will not support OpenGL ES at all. Apps that require OpenGL ES will not install on phones that lack appropriate support.
25
Introduction to bada: A Developer's Guide - (draft preview, July 2010)
Figure 2.8 All applications have a Frame, the top level container within which Forms are added; Forms are populated with Controls
2.2.2 Standard elements of a Form – Indicator Bar, Title Bar, Soft Keys, Option Menu A Form occupies the full physical display area of the phone – everything visible on the screen. Forms therefore also optionally include some standard system elements. These are: •
The Indicator bar at the top of the display area, used to display system icons (like signal and battery strength) and notifications (whether you have unread messages)
•
The Title bar that displays the current application name
•
Soft keys that are displayed in the command area at the bottom of the main display
•
The Option menu key, displayed at the bottom between the soft keys, used to launch an Option menu
26
Introduction to bada: A Developer's Guide - (draft preview, July 2010)
Figure 2.9 The application name and standard system elements All of these elements are defined as properties of the Form. The decision whether to display all or some of these elements is made by each Form, and is therefore under the control of the application that defines the Form. However, the look and feel of these screen elements (and in the case of the Indicator bar, its contents too) is not directly controlled by the app. Although the Form displays these elements, the framework retains control of them.
2.2.3 Handling events We said that Controls abstracts a screen region, both for display and input, but we didn’t say how. Input events include input from the touch screen, including menus and soft keys, from the physical phone keys including side keys like Lock or Camera, from gestures and raw sensor events, from bada system events – potentially from any type of event. Listeners are the glue that binds behaviour to presentation in a bada app. In bada, listeners provide the mechanism for all event handling. At any time, exactly one control has “focus” in the GUI. “Focus” just means, which object is actively updating the display and receiving user and system events. Conceptually, focus belongs to the currently active control of the currently running foreground application. Events are cascaded down through the hierarchy of UI controls belonging to that application, starting with its Frame, 27
Introduction to bada: A Developer's Guide - (draft preview, July 2010)
then the current Form, and so on, until the currently active control is found. This Control then receives any input events that occur (and by the way, also initiates redrawing the display). Every Control has built-in listeners for the basic event types it recognises. Depending on the control, these might include any of the following: •
Focus events
•
Key events
•
Touch events
•
Drag and drop events
Many controls then add their own, control-specific listeners. For example, slider controls recognise the slider-specific “adjustment” event, which reports how far the slider has been moved. Also, many controls share an ‘action’ event listener, which responds to specific events generated by the UI framework, including: •
Button and CheckButton events
•
ContextMenu and OptionMenu events
•
Tab events
2.2.4 Summary Let's sum up the essentials. The application Frame, and the Form or Forms it contains, and the Controls that populate the Forms, are the building blocks from which a bada application constructs its GUI: •
Each application has a single Frame, which abstracts the device display
•
Frame is the root object of the app GUI
•
A Frame contains one or more Forms (usually – a special case is a full-screen, also known as Frame-based, app, which contains no Forms; instead it draws its graphics directly
•
A Form is the highest level container object after Frame, and defines one complete application screen 28
Introduction to bada: A Developer's Guide - (draft preview, July 2010)
•
Arbitrary Controls can be added to Forms
•
Listeners are added to Controls to hook events the app wants to respond to
2.3 UI Builder Now we know what’s in a GUI, let’s build one. The WYSIWYG, UI Builder tool makes it easy to create a basic GUI layout, using standard controls. UI Builder will also generate the underlying class source code for the controls we define. Only a small amount of hand coding will then be required to hook up the UI layout and controls with the application skeleton we have already created.
2.3.1 A simple UI BuddyFix is a single screen application, with a simple list-based presentation. The UI design is based on the requirements summarised in the box below. If this was a fully-fledged commercial app we would want something more than this simple spec; but it’s enough for our purposes, as an exercise in defining basic but realistic application functionality, and showing how to implement it in bada.
The BuddyFix UI BuddyFix is a simple app that enables a simple use-case. It enables a user to share periodically updated location information with a list of friends in order to converge in real-time on a meeting place. To do so, BuddyFix uses the Buddy service that bada provides as a service API. BuddyFix displays a list of buddies, with the following information displayed for each buddy:
29
Introduction to bada: A Developer's Guide - (draft preview, July 2010)
•
Picture
•
Name
•
Location fix, i.e. last known location
•
Time fix, i.e. time of last location fix
•
Location status, on or off the grid i.e. currently reachable or not
•
Whether location sharing is enabled for this buddy
Additionally the UI must provide the following information: •
Whether sharing is paused or active at application level
•
Interval at which location fixes are updated
Points to note: •
Location sharing is always in both directions
•
Location fixes are therefore always updated in both directions
•
Application-level pausing of location sharing allows power to be saved
•
Location display format should be user selectable
•
Location sharing is periodic not continuous, and is scheduled according to the update interval
•
Update interval should be user selectable
•
The update interval applies to all buddies
•
Individual buddies are added from the phone Contacts app
•
Friends must already be buddies on the Buddy service to be allowed by BuddyFix
Clearly, some of the above are too limiting for the app to be fully-featured, but for current purposes they keep complexity manageable.
30
Introduction to bada: A Developer's Guide - (draft preview, July 2010)
The UI must enable the following actions: •
Add/Remove a buddy
•
Start/Stop sharing, for some buddy
•
Nudge now, share a location fix with some buddy now, without waiting for the next scheduled update
•
Set the update interval
•
Pause/Unpause all sharing
So let's get started. We'll define a single MainListForm as the basic app screen, from which all functionality will be available. Launch the Resource Explorer by selecting Window | Show View | Other from the Eclipse main menu bar as shown in Figure 2.10.
Figure 2.10 Launching the Resource Explorer. 31
Introduction to bada: A Developer's Guide - (draft preview, July 2010)
Figure 2.11 Opening the Insert Wizard The Resource Explorer pane will open in the IDE. (If it is empty when it launches, make sure you have your project selected in the Project Explorer pane.) Right-click anywhere in the Resource Explorer and select Open Insert Wizard, as shown in Figure 2.11. It's a new Form we want to create, so select Create Form File, and Finish. A new Form appears in the Resource Explorer pane. Double click to launch the WYSIWYG UI Builder and you should see the screen shown in Figure 2.12. Note that the automaticly created form – for demonstration purposes – already contains a Button control, which you can use or simply delete.
32
Introduction to bada: A Developer's Guide - (draft preview, July 2010)
Figure 2.12 A new form has been created in the Resource Explorer pane. When the UI Builder pane is launched, double-click on the main Form pane to open the Form Properties pane as shown in Figure 2.13.
33
Introduction to bada: A Developer's Guide - (draft preview, July 2010)
Figure 2.13 The Form properties pane
2.3.2 Form properties Before doing anything else, let's change the Form name to something meaningful. Properties are simple name, value pairs. To edit a property, double click the property name in the property list and change the associated value. For BuddyFix, we retain the “IDF” prefix and the all-capitals resource naming convention, to provide clarity in our code, and name the Form IDF_MAIN_LIST_FORM. Next, notice that the Form that UI Builder has created for us is not empty. At the top, it already contains an Indicator bar and Title bar (though the Title bar is empty). We said earlier that each Form defines which standard elements to display, and that these are included as Form properties. Setting the “Title” property will display a title in the Title bar. A good rule of thumb is that the title displayed should describe the function of the Form that displays it. In a single Form app, this should always be the app name. We will set the value to “BuddyFix”.
34
Introduction to bada: A Developer's Guide - (draft preview, July 2010)
By default, all Forms display the Indicator bar. Unless you are writing a full-screen game or similar application, it is good practice always to include the Indicator bar in your UI, to enable the user to remain fully aware of the device state and to receive alerts. Note that although you can display it, you cannot update the Indicator bar directly. Displaying the Indicator bar is a Style option. Other style options include whether or not to show soft keys, and soft key styles if any. The look and feel of a Form is highly configurable. The most important properties are shown in the table below. For the complete list of properties, see the SDK documentation. Property Id Type
Title Orientation Layout | Mode
Purpose Form identifier, this is also used in C++ code to refer to the Form layout file WINDOW_FORM is the top level Form within any Frame, where the application Frame represents the screen window in which the app displays Title that will appear in the Form title bar, if enabled How the Form displays when the phone is rotated through a possible four directions Portrait or Landscape
Note: although you can set the background colour for both Frame and Form, you can’t set the background to be an image, unlike other types of control.
2.3.3 The Buddy List The most important part of the UI is the main buddy list itself, which will display a number of items of information for each buddy. UI Builder gives us a choice of several list types, and bada allows us to define custom lists of our own, but to start with we’ll keep things simple and use a basic, simple list, displaying the following fields for each item: •
Picture
•
Name 35
Introduction to bada: A Developer's Guide - (draft preview, July 2010)
•
Location fix/Time fix, last known
•
Whether location sharing is enabled for this buddy
To add a List to the Form in UI Builder, select the List icon from Palette of controls, and drag onto (or click inside) the main Form view as shown in Figure 2.14. Please note that the look&feel and the window arrangements of the bada IDE can be freely changed to one’s needs. We did so. This is why the following screenshots slightly deviate from the first ones.
Figure 2.14 Adding a list to our form Resize the List to occupy the whole area of the Form. Now double-click anywhere inside the List to open the Properties editor pane. Editing its properties is exactly like editing the Form properties. First let's rename the List to IDC_MAIN_LIST. 36
Introduction to bada: A Developer's Guide - (draft preview, July 2010)
Next, let’s look at the properties that are of interest. First, we can define basic properties like the row heights and widths for each item and the order in which the different fields will display: Row 1 Height Row 2 Height Column 1 Width Text Of Empty List List Item Format
Default 80 Default 50, only shown when a two-line format is selected Default 50 Text to display in case the list is empty One of 11 possible format styles specifying the structure of the list contents, for example LIST_ITEM_SINGLE_IMAGE, LIST_ITEM_DOUBLE_IMAGE_TEXT_FULLTEXT
A simple list can display one or two columns, and the first column can display one or two rows. We’ll set the format to LIST_ITEM_DOUBLE_IMAGE_TEXT_FULLTEXT, which will display a first line of image and text, and a second line of text. Next, under Layout, we can set the list style. Even with a simple list we have lots of styles to choose from, including: LIST_STYLE_NORMAL LIST_STYLE_NUMBER LIST_STYLE_RADIO LIST_STYLE_RADIO_WITH_DIVIDER LIST_STYLE_MARK LIST_STYLE_MARK_WITH_DIVIDER LIST_STYLE_ONOFF LIST_STYLE_ONOFF_WITH_DIVIDER
Normal style Numbered style Radio style for single selection Radio style with divider for single selection Mark style for multiple selection Mark style with divider for multiple selection On/Off style On/Off style with divider
37
Introduction to bada: A Developer's Guide - (draft preview, July 2010)
Figure 2.15 Using UI Builder to set the properties of our list We’ll choose LIST_STYLE_MARK, which displays a selection marker for each item, allowing us to make a selection and apply operations to the selected subset. Finally, we’ll set the Text Of Empty List property to ‘No buddies...’. UI Builder gives us a basic idea of how our list will look, but there is no substitute for seeing it in a running app. There is just a little more to do before we can do that. But first, we should save the changes that we have made. Select File | Save All Resources. Note: always save when you finish working with UI Builder, since resource files are only saved into your project /Res folder when you explicitly save them. If you don't, your changes may be lost when UI Builder exits.
38
Introduction to bada: A Developer's Guide - (draft preview, July 2010)
2.4 Hooking up your Forms to your code UI Builder takes the properties we have defined and generates a declarative XML layout file from them. If you open up IDF_MAIN_LIST_FORM in a text editor, then you will see the XML declarations.
It is easy enough to see how our property settings have been translated into attributes of the Form and List objects that the XML declares. However, the layout file is just a declaration, not an implementation. At runtime, if we load the layout file the framework will do the rest of the work of instantiating objects for us. But first we must first load the layout file. To do that, we need to create a Form class. UI Builder can do that for us. Note that so far, no changes at all (and no additions) have been made to our C++ code.
39
Introduction to bada: A Developer's Guide - (draft preview, July 2010)
In UI Builder, generate the underlying code for the main Form by right-clicking on the Form to open the context menu. (Be sure to click on the Form, not the List; clicking inside the Title bar ensures the Form is not hidden beneath another control.)
Figure 2.16 Using the New Class wizard Select Add Class as shown in Figure 2.16 to pop up the New Class wizard which will display the window shown in Figure 2.17. We will name the class MainListForm, matching the resource file name. Next, let's set its listeners. 40
Introduction to bada: A Developer's Guide - (draft preview, July 2010)
Figure 2.17 Setting control listeners In the EventListener dialog, we set IActionEventListener. We don't set IOrientationEventListener, because we have only designed a portrait-mode screen. In the Control Base EventListener dialog, we select focus, key, and touch events. These are the underlying events that will be detected by the framework and from which action events will be generated. We know therefore that in our code we should expect to handle key, touch, and focus events. We don't set drag and drop events, because we don’t want drag and drop interaction with the buddy list. Notice that the List control that the Form contains is also included in the wizard (because it is embedded inside the Form in the XML description). In the Control dialog, we set the List's IItemEventListener. Select Finish, and then Save from the main menu. 41
Introduction to bada: A Developer's Guide - (draft preview, July 2010)
If you open MainListForm.cpp, you can see that the Form is initialised by loading the resource declaration into the constructor: bool MainListForm::Initialize() { Form::Construct(L"IDF_MAIN_LIST_FORM"); return true; }
result MainListForm::OnInitializing(void) { result r = E_SUCCESS;
// TODO: Add your initialization code here
return r; }
Note: you will recognise that we use the letter ‘L’ in front of every String in this book. This is the socalled “L macro” that generates wide characters and strings encoded as unicode. It is recommended to use that in your code too for compatibility reasons.
In addition, all the listener methods of the events we chose to respond to have been added: class MainListForm : public Osp::Ui::Controls::Form, public Osp::Ui::IActionEventListener, public Osp::Ui::IFocusEventListener, public Osp::Ui::IKeyEventListener, public Osp::Ui::ITouchEventListener, public Osp::Ui::IItemEventListener {
// ... Other methods omitted
42
Introduction to bada: A Developer's Guide - (draft preview, July 2010)
// Generated call-back functions public: void OnActionPerformed(const Osp::Ui::Control&, int); void OnFocusGained(const Osp::Ui::Control&); void OnFocusLost(const Osp::Ui::Control&); void OnKeyLongPressed(const Osp::Ui::Control&, Osp::Ui::KeyCode); void OnKeyPressed(const Osp::Ui::Control&, Osp::Ui::KeyCode); void OnKeyReleased(const Osp::Ui::Control&, Osp::Ui::KeyCode); void OnTouchDoublePressed(const Osp::Ui::Control&, const Osp::Graphics::Point&, const Osp::Ui::TouchEventInfo&); void OnTouchFocusIn(const Osp::Ui::Control&, const Osp::Graphics::Point&, const Osp::Ui::TouchEventInfo&); void OnTouchFocusOut(const Osp::Ui::Control&, const Osp::Graphics::Point&, const Osp::Ui::TouchEventInfo&); void OnTouchLongPressed(const Osp::Ui::Control&, const Osp::Graphics::Point&, const Osp::Ui::TouchEventInfo&); void OnTouchMoved(const Osp::Ui::Control&, const Osp::Graphics::Point&, const Osp::Ui::TouchEventInfo&); void OnTouchPressed(const Osp::Ui::Control&, const Osp::Graphics::Point&, const Osp::Ui::TouchEventInfo&); void OnTouchReleased(const Osp::Ui::Control&, const Osp::Graphics::Point&, const Osp::Ui::TouchEventInfo&); void OnItemStateChanged(const Osp::Ui::Control&, int, int, Osp::Ui::ItemStatus);
// ... etc };
There is one final step to do to hook up our new Form. In BuddyFix.cpp, we still have the original code generated by the App Wizard, which constructed a default Form class, Form1. Instead, we construct our new Form class MainListForm: // Customised to load IDF_MAIN_LIST_FORM bool BuddyFix::OnAppInitializing(AppRegistry& appRegistry) { // TODO:
43
Introduction to bada: A Developer's Guide - (draft preview, July 2010)
// Initialize UI resources and application specific data. // The application's permanent data and context can be obtained from the appRegistry.
// If this method is successful, return true; otherwise, return false. // If this method returns false, the application will be terminated.
// Uncomment the following statement to listen to the screen on/off events. //PowerManager::SetScreenEventListener(*this);
// Create a form //REPLACED Form1 *pForm1 = new Form1(); MainListForm *pMainListForm = new MainListForm(); //REPLACED pForm1->Initialize(); pMainListForm->Initialize();
// Add the form to the frame //REPLACED Frame *pFrame = GetAppFrame()->GetFrame(); Frame *pFrame = GetAppFrame()->GetFrame(); //REPLACED pFrame->AddControl(*pForm1); pFrame->AddControl(*pMainListForm);
// Set the current form //REPLACED pFrame->SetCurrentForm(*pForm1); pFrame->SetCurrentForm(*pMainListForm);
// Draw and Show the form //REPLACED pForm1->Draw(); pMainListForm->Draw();
//REPLACED pForm1->Show(); pMainListForm->Show();
return true; }
44
Introduction to bada: A Developer's Guide - (draft preview, July 2010)
A quick look at the code in MainListForm.cpp shows us that the call to Initialize() completes the Form construction, loading the layout file: bool MainListForm::Initialize() { Form::Construct(L"IDF_MAIN_LIST_FORM");
// ... Etc. }
Don't forget to #include the header file for the new Form. In BuddyFix.cpp: #include "BuddyFix.h" //REPLACED #include "Form1.h" #include "MainListForm.h"
In Project Explorer we can now build and run the project.
Figure 2.18 Running BuddyFix in the Simulator 45
Introduction to bada: A Developer's Guide - (draft preview, July 2010)
When BuddyFix runs, instead of the buddy list, what we see is the default text that we set to display when the list is empty. Before we can actually see the list, we will need to populate it, and to do that we’ll need to write some code – which we’ll do in the next chapter.
2.5 The App Icon and other properties There is only one more thing to do to complete our app skeleton. Every app needs an icon. As we saw, the icon is displayed in the Main menu, and provides the mechanism for the user to launch your app. The app icon is defined as a property of the app project, and is easy to set. Select your project in Project Explorer, and select Project | Properties from the main menu to launch the Properties dialog. Expand the bada Build item and select Application Information. Here we can see some basic defining information for BuddyFix. To add an icon, you will first need to create the graphic of course. If you browse the file properties of the default icon (in Windows Explorer, for example), you'll see the following: File Type
PNG
Size
100x96 pixels
Resolution
72dpi
Bit depth
32 bit
Create an icon in your favourite graphics application, and add it to the /Icons folder. Select the File System button beside the Main Menu icon to browse the /Icons folder amd choose the app icon of choice. Select 'OK' to save. Next time you launch the Simulator, your chosen icon will display in the Main menu. (You do not need to rebuild for the change to take effect.) Note: no effects are applied to the icon, for example rounding or bevelling (other than dimming to indicate selection). You should create your icon with any such effects that 46
Introduction to bada: A Developer's Guide - (draft preview, July 2010)
you want, with a transparent background for example if you round the icon corners. The software platform on the device supplies the app name, so you only need to provide a graphic.
2.6 Becoming multilingual in 3 easy steps There is a serious limitation in the way we have implemented this example GUI: we have hard-coded English language strings into the UI text that we display – for example the soft-key text. One excellent feature of bada is its extensive language support. In fact, at the time of writing, the SDK (as of version 1.0b3) includes the following languages: Basque, Bulgarian, Catalan, Chinese Simplified, Chinese Traditional (Hong Kong), Chinese Traditional (Taiwan),Croatian, Czech, Danish, Dutch, English, Estonian, Finnish, French, Galician, German, Greek, Hungarian, Icelandic, Irish, Italian, Kazakh, Korean, Latvian, Lithuanian, Macedonian, Norwegian, Polish, Portuguese, Romanian, Russian, Serbian, Slovak, Slovenian, Spanish, Swedish, Turkish, and Ukrainian. Arabic, Farsi, Hebrew, Malay, Thai, Urdu and Vietnamese are promised soon. As the list makes clear, bada is a truly multilingual platform, with a wide range of support for both Roman and non-Roman languages, making it possible for you to localise your application for a huge range of potential markets. But localisation means more than ensuring that all the text you display in your application’s user interface matches the user’s language settings. Everything you display to the user should be in a format that they expect. Date and time information should appear in the right format for a particular country and language setting, with the appropriate separators and day and month names. Numbers should appear with the correct separators and the appropriate currency symbols should be used. Support for localised number formats, dates, times and currency is provided by the classes in the Locales namespace. (More detail in Chapter 6). The rest of this section will concentrate on how to make your application multilingual. It’s really important that all the text displayed in your user interface matches your user’s language settings. Supporting multiple languages and date, time and number formats really improves your application’s chances of worldwide success. 47
Introduction to bada: A Developer's Guide - (draft preview, July 2010)
The following steps explain how you can build multilingual support into your UI. Fortunately, bada makes this easy. Everything you need to create a multilingual UI is included in the UI builder.
2.6.1 Add new languages Adding languages is easy. To support additional languages, open the Resource Explorer in the IDE. Double click ‘String’. Right-click inside the String window and from the menu displayed, choose ‘Language Setting’. The Add New Language dialogue is now displayed, as shown in Figure 2.19.
Figure 2.19 Adding a new language in the UI builder string table view Choose the languages you want to support. When you’ve finished you’ll notice that the string table window has been updated to include a column for each language you’ve chosen. 48
Introduction to bada: A Developer's Guide - (draft preview, July 2010)
Note: an XML file containing a localised string table is added to the project for each language. For example, the British English string table is called eng-GB.xml, while the French one is fra-FRA.xml.
2.6.2 Add text for each language Now it’s just a matter of adding the strings that appear in your UI into the corresponding columns in the string table for every language you support. For example, in Figure 2.19, we’re adding the English and French version of every string displayed in our user interface. Add the appropriate text for each language and bada will choose the right one according to the user’s language settings. Next, you want to make sure that the title of a form or the text of a button control, for example, is shown correctly for each language. All you need to do is add localised text for each string resource and use UI Builder to ensure that the control uses a string resource for its title or text. Figure 2.20 shows you how.
49
Introduction to bada: A Developer's Guide - (draft preview, July 2010)
Figure 2.20 Using a stringID as a form title: bada will choose the correct localized string In Figure 2.20, we’ve set the title of form to be IDS_STRING5. If the user has set their language to French, the form title will automatically be set to “Bonjour bada”. If no localised string is found, the English one is used.
2.6.3 Use string resource IDs in your code To take full advantage of bada’s multilingual support, don’t hard-code strings in your code. Hard-coded strings are difficult to track down and update for multiple languages, so instead read the string from a resource, as shown in the following code: 50
Introduction to bada: A Developer's Guide - (draft preview, July 2010)
Application* pApp= Application::GetInstance(); String str1; r = pApp->GetAppResource()->GetString(L"IDS_STRING1", str1);
The value of str1 is read from a resource file rather than hard-coded. If you’ve set up a different string for each language, then the appropriate string will be chosen based on the user’s language setting.
2.7 From idea to published app If you have an idea for a ground-breaking bada app you only have to go through the following three steps:
Figure 2.21 The steps to publishing your app on SamsungApps
51
Introduction to bada: A Developer's Guide - (draft preview, July 2010)
Step 1: On the developer.bada.com portal After you signed up on the developer.bada.com portal to download the IDE and SDK, you did more than register for a download; you joined the bada developer program. This enables you to access the online services that provide many useful resources such as documentation, API reference, code samples, tutorials, blogs, videos, or a support forum.
Generate an application profile and download the manifest.xml In this section we concentrate on the custom app profile generator, which should be the starting point for your real projects, because it allows you to define the functionality of your app and to specify the hardware features your app requires or expects (for example screen size, sensors, default orientation). The portal also checks that your app name is globally unique, as well as assigning a unique numerical ID that your app uses to protect its private resources. In section 2.1, metadata, we looked very briefly at the two metadata files that every app project must include: application.xml and manifest.xml. These, we said, declare application information used to package the app – like names, versions, and intended target phone models – as well as critical security permission declarations. Configuration of the application.xml is handled by the IDE. The Web portal helps to establish the manifest.xml. To create your manifest file go to the developer.bada.com portal and click the “My Applications” tab. Then invoke the Application Manager on the left. There you can then start to generate your application profile. Figure 2.22 shows the web site and the five simple steps to follow.
52
Introduction to bada: A Developer's Guide - (draft preview, July 2010)
Figure 2.22 Application Manager on developer.bada.com First you give your app a name and can add a further description. Second you define the privileges which are the main functionalities of your app. If your application involves any remote services from bada servers you can define them during the third step. Fourth you specify the hardware requirements against the mobile handset. And finally you can download the manifest file.
53
Introduction to bada: A Developer's Guide - (draft preview, July 2010)
The downloaded manifest.xml typically contains info as illustrated below:
93bt1p123e 9C645DDBA19C71BAD1204DA4DAA7A0B9 1.0.0
IMAGE
Cortex8 16 4 OpenGL-ES1.1 OpenGL-ES2.0 OPP SPP Infrastructure Ad-hoc GPS Accelerometer Magnetic Proximity Touch 480x800 Enable 1.0
Here, the first attributes are basic application information. While and both appear in code, the framework takes care of their use. The ID is a random and unique number. The secret key is uniquely related to your app.
54
Introduction to bada: A Developer's Guide - (draft preview, July 2010)
Most interesting, then, is the attribute, and its sub-attributes. In the manifest file above, the single IMAGE privilege is specified:
IMAGE
The format of the declaration here is straightforward XML; is an attribute, and contains a list of sub-attributes, each of which is declared using the sub-sub-attribute, in this case IMAGE. 6 Privileges declare which functionality an app offers. If appropriate privileges are not declared, an exception will be thrown at runtime the first time the app attempts to use an undeclared, privileged API. More interesting than how to declare privileges is what they mean and what they do. Privileges are important for the security mechanisms in bada to ensure privacy (for instance). You can find more information about the privilege model in bada in Chapter 6. The next XML tag in the manifest file is the . It declares the minimum system requirements for the application. It is all automatically generated by the portal from the information the developer provides. You can update the manifest in the same way that you generate it, using the portal tools. Declaring privileges is easy. Just remember that whenever you add APIs from a new namespace, you probably need to declare a new privilege (and update the libraries you are linking when you build).
6
Instead of “attributes” you can call these “properties” if you prefer.
55
Introduction to bada: A Developer's Guide - (draft preview, July 2010)
Step 2: In the bada IDE/SDK Create bada app with the manifest file After you’ve downloaded the manifest file to your hard disk you can create a bada app project as described earlier. In the Wizard where you arrive at the point to select the manifest file, you should uncheck the default one and point the Wizard to the just downloaded manifest.xml on your hard disk. The other option – if you already have an existing project with an existing manifest file – is to simply overwrite the old manifest file with the new one. Program and build The next necessary bit to get your app to life is actually thinking of your logic and programming. When you think your app is in a runnable state you can build your bada project in the IDE as described earlier. Test and debug on simulator Once your app compiles and can be built without any errors, you can start test while running it in the simulator. The simulator is very useful for testing the principal correctness of your code. Traditionally there was a large discrepancy between the behaviour of simulators and real mobile devices. Because of the importance of context information intensive real-world tests had to be on the mobile device anyway. The bada Simulator comes the real device very close. In addition to that the bada Simulator provides an extra tool called the Event Injector that allows injecting sensor events of all kinds into the simulator. In fact, so too can other events including phone calls, messaging events, network events, and device events like low battery or low memory. This helps a lot and makes testing much more efficient since many of the real world context tests can be shifted to the less expensive simulator tests. The following events can be simulated: -
Incoming calls
-
Network characteristics and quality (e.g., service level, roaming, or network codes)
-
Transmission of text messages, WAP push, and push notifications
-
Location data (latitude and longitude) by choosing on a map or explicitly inserting
-
Various sensors such as accelerometer, GPS, magnetic, tilt, proximity, or weather 56
Introduction to bada: A Developer's Guide - (draft preview, July 2010)
-
Device events such as memory or battery level
The bada Motion sensor is a logical sensor, which is based on composite data from onboard hardware sensors. The Motion Sensor detects predefined movement of the phone by the user: Snap Rapid one-time back and forth movement of the phone in any of the X, Y, or Z dimensions. Three different events are recognised, one for each axis, in each of portrait and landscape modes Shake Rapid repeated sideways movement of the phone Double tap Double tap on any side of the phone case
Figure 2.23 The Event Injector
57
Introduction to bada: A Developer's Guide - (draft preview, July 2010)
Note: in effect, the simulator is a complete build of the bada platform, customised to run on top of a desktop OS, specifically Win32 in the Microsoft Windows hosted SDK, instead of a mobile phone OS.
Of course, your app might not run perfectly right from the beginning. There may be bugs in it. The bada IDE supports the GNU Project Debugger (GDB), which allows you to use the common functionalities of software code debugging such as setting breakpoints, stepping in, out or over methods or watch variables. The following two figures illustrate how to invoke debugging and show the Debug perspective of the IDE.
Figure 2.24 Invoking GDB in the bada IDE 58
Introduction to bada: A Developer's Guide - (draft preview, July 2010)
Figure 2.25 The Debug perspective of the bada IDE
Test and debug on real target device The obvious difference between developing for a mobile platform like bada, compared with the more conventional world of application development on the desktop, is the fact that the development environment is not the same as the execution environment. To understand and test the mobile app the simulator as described above is very useful. But eventually you really want to find out how your app behaves on a real mobile handset. 59
Introduction to bada: A Developer's Guide - (draft preview, July 2010)
Turning back the time machine, mobile platforms were difficult. But bada shows just how far things have come. Some platforms still bear the legacy - Symbian's quirky build-system, for example. In fact, these are all part of what makes mobile different and gives mobile development its reputation for difficulty. At the time of writing, the first bada phone has been shipped – the Samsung Wave, a feature-packed, topof-the-line phone that defines the high end of the bada product line. Eventually, bada phones will extend from this high point down through the midrange of affordable "smartphones for everyone", taking smartphone features to the mass-market. Before you can build and deploy a bada app on your Wave target you need to install the Wave device driver in your desktop operating system. These device drivers are a simple executable file shipped within the IDE/SDK bundle that you downloaded from the developer.bada.com portal. If this is successfully accomplished you need to copy and install the Test Root Certificate, which is necessary for testing an app on the target device. An app cannot be installed, run, and tested on the Wave without this Test Root Certificate. It is up to you how you transfer the Test Root Certificate file to your Wave. The easiest way is to push it from your desktop computer using Bluetooth. The other way is to use the USB cable connection in “Mass storage” mode. This can be set on the Wave by invoking the Menu and then going to Settings | Connectivity | USB | Mass storage and then click on the ‘Set’ soft key. The Test Root Certificate file that needs to be transferred from the desktop to the Wave device is shipped with the SDK/IDE download.
You will find the necessary file “rootCACert.cer” in \Tools\sbuild Then disconnect your Wave device from the desktop. On the Wave invoke the Menu and then go to 60
Introduction to bada: A Developer's Guide - (draft preview, July 2010)
My files | Other Tab the rootCACert.cer file and it should be installed automatically.
Figure 2.26 Installing the root certificate In order to make use of on device debugging via USB you need to explicitly set this in your Wave device. To do so open the Menu and go to Settings | Connectivity | USB | USB Debugging and then click on the ‘Set’ soft key.
Figure 2.27 Setting up the device for USB debugging 61
Introduction to bada: A Developer's Guide - (draft preview, July 2010)
In order to deploy your bada app on your Wave device all you have to do is changing the active build configuration and build it for the target platform. To do so, open your bada IDE and create or open your bada project. Go to the context menu of your project by right-clicking the project name in your Project Explorer window. Then go to Build Configurations | Set Active and check ‘Target-Debug’.
Figure 2.28 Setting Target-Debug as the active build configuration
62
Introduction to bada: A Developer's Guide - (draft preview, July 2010)
After that, build your project for the target device again by entering the context menu of your project and clicking ‘Build Project’. Before running your bada app on the target device make sure that it is connected to your computer via USB and that it is in USB Debugging mode so you can make use of the debugging messages in your IDE. To run your app go to the context menu of your project and select: Run As | bada Target Application
Figure 2.29 Running your application on the target device 63
Introduction to bada: A Developer's Guide - (draft preview, July 2010)
After this, your app should successfully run on your mobile device and logging messages should be visible in your IDE output window.
Note: a further very useful feature is in beta testing status during the writing of this book. Samsung will soon provide you the chance to make use of real device target deploying even if you do not have a device available. The code name for this is RTL: Remote Testing Lab. There will be a lab somewhere in the world hosting a large number of real bada-powered devices. Over the Internet you can conveniently connect to these and deploy your bada app there – just as if it lay on your desk in front of you. This all can be accessed by a RTL plug-in for the bada IDE soon. So stay tuned! Create Package The last task of this second step in the process from the idea to your published app is to create the full package that is then in the third step used for certifying your app. To create a package, select your bada project in the IDE which you want to submit for certification. Click on the Project menu and select “Make Package”.
Figure 2.30 Creating an application package In the next dialog you can define the output folder where the package (which is a zip) should be stored.
64
Introduction to bada: A Developer's Guide - (draft preview, July 2010)
Step 3: On the seller.samsungapps.com site When all this is done, when you have implemented your idea into an app that is built, run, tested, and packaged you are one step away from becoming rich and famous – or both. This final step is certifying your publishing your app. Get certification To get your certification you need to go to the seller.samsungapps.com site. There you can use the same account to log-in as you use for the developer.bada.com portal from step 1. Once you are logged in the main screen appears to you as shown in Figure 2.31.
Figure 2.31 SamsungApps Seller Office main screen The submission process starts by clicking the “Add New Application” button at the top. Then the website guides you step-by-step through the necessary tasks to submit your app for certification. 65
Introduction to bada: A Developer's Guide - (draft preview, July 2010)
Figure 2.32 Adding your application to the Seller Office After you complete the process, your app is submitted for certification. The app is tested such that it functionally and non-functionally works and that it meets quality standards (regarding usability, for instance). Our aim is to take no more than seven working days to do the QA and give you feedback. Publish app When you have your app certified, it will be published for download. You set the criteria like price or geographic markets during the upload for certification process. All the apps can be accessed though the samsungapps.com website or can be downloaded directly onto your bada phone. A handy way to manage your apps and downloads is the desktop software called Samsung Kies which you can also get from the SamsungApps Store at samsungapps.com.
66
Introduction to bada: A Developer's Guide - (draft preview, July 2010)
Part 2
0
Introduction to bada: A Developer's Guide - (draft preview, July 2010)
Chapter 3: Beyond the basics So far, BuddyFix is just a shell. In this chapter we begin to extend it. As we do, we will learn more about how apps interact with the bada frameworks to inherit their runtime architecture and the GUI look and feel. We also cover some essential topics that every bada developer needs to know about, including bada API privileges and the security model. What you will learn This chapter shows how to go beyond the App Wizard skeleton as you start to shape your application functionality. You will learn about:
How bada apps interact with the application and UI frameworks
The runtime application lifecycle
How to build for and deploy to a phone
The developer and publishing services provided by the bada developer portal
What you will need The emphasis in this chapter stays practical and hands on. Have your own code in front of you, and the bada reference documentation to hand to check out API details.
3.1 Expanding the application skeleton We have seen how easy it is to get a project started in bada; wizards do the hard work for you. Now let‟s dig a bit deeper into code. Let‟s start by walking through the main BuddyFix class as declared in buddyfix.h (this is code the App Wizard generated for us):
1
Introduction to bada: A Developer's Guide - (draft preview, July 2010)
class BuddyFix : public Osp::App::Application, public Osp::System::IScreenEventListener {
Every app derives from the App::Application class; so when you create your own app and derive from Application, you extend a class the bada frameworks already know about, with the custom behaviour you specify. All the methods the frameworks expect are present in your derived class. You‟ll notice that your app also derives from the System::IScreenEventListener class; “I” stands for “Interface”, which is a pattern we‟ll see a lot more of. Next, we see various constructors declared: public: static Osp::App::Application* CreateInstance(void); public: BuddyFix(); ~BuddyFix();
CreateInstance() is a so-called factory function that wraps the C++ constructor and when invoked, returns an instance of the application. The two declarations that follow it are the C++ constructor and destructor methods. Since the default implementations for all three will work fine for us, there‟s nothing to worry about here. The remaining public declarations, which complete the class, are the ones we‟re interested in: public: bool OnAppInitializing(Osp::App::AppRegistry& appRegistry); bool OnAppTerminating(Osp::App::AppRegistry& appRegistry, bool forcedTermination = false); void OnForeground(void); void OnBackground(void); void OnLowMemory(void); void OnBatteryLevelChanged(Osp::System::BatteryLevel batteryLevel); void OnScreenOn (void); void OnScreenOff (void); };
2
Introduction to bada: A Developer's Guide - (draft preview, July 2010)
Let‟s call these the „lifecycle‟ methods; every app has them, and every app must implement them. The wizard provides a minimal implementation for us, but as we‟ll see, these methods are important in defining the way our app behaves, so we definitely want to understand what they can do for us.
3.1.1 Being event driven A bada app is entirely event driven; its runtime behaviour is defined in response to events that it receives from the framework. These include user-originated events like touch events, soft key events and (hard) key events, and system-originated events like timers, sensor notifications, incoming voice calls or messages, and lifecycle events. In bada the event loop is hidden within the bada frameworks, and is not visible to the application. To receive the events that it wants to handle, the app just implements the appropriate listener call-back methods. This makes a bada application very straightforward to write. Applications are essentially reactive, and are completely defined by the set of events they handle. Choosing which events to listen for and handle depends on how you want your GUI to behave, and on your app‟s core functionality. However, the lifecycle methods define a common set of system events that every bada app should handle.
3.1.2 The runtime app lifecycle The application lifecycle defines the dynamic, runtime architecture of every application. The lifecycle is defined by the bada application frameworks, and when you derive your app from App::Application, your app inherits the lifecycle methods. In bada, the lifecycle is very simple. Your app exists in one of four possible states: Initializing, Running, Terminating, or Terminated. At any time, your app can be in only one of these states. You probably recognise this as a simple state machine: your application transitions between these states, and associated with the transitions or states are the lifecycle methods:
3
Introduction to bada: A Developer's Guide - (draft preview, July 2010)
1. Initializing OnAppInitializing() 2. Running OnForeground(); OnBackground(); OnLowMemory(); OnBatteryLevelChanged(); OnScreenOn(); OnScreenOff(); 3. Terminating OnAppTerminating(); 4. Terminated (no associated methods – your app is no longer running) The application lifecycle is show in Figure 3.1:
Figure 3.1 The application lifecycle Strictly speaking, only four of these methods relate specifically to the lifecycle; the others, like OnBatteryLevelChanged() and OnScreenOff(), respond to system events triggered by conditions that are so important, or so frequent on mobile, that the framework makes a special case of them and gives you the opportunity to respond appropriately. Let‟s look more closely at the four lifecycle states, and at how the lifecycle methods map to them. 4
Introduction to bada: A Developer's Guide - (draft preview, July 2010)
3.1.3 Initializing When launched by the bada application framework, your app enters the Initializing state and its OnAppInitializing() method is called. Look at the implementation in BuddyFix.cpp; recall that we have updated the code the App Wizard generated to load our own Form pMainListForm, otherwise this is the default implementation: // Customised to load IDF_MAIN_LIST_FORM bool BuddyFix::OnAppInitializing(AppRegistry& appRegistry) { // Initialize UI resources and application specific data. // The application's permanent data and context can be obtained from the appRegistry. // If this method is successful, return true; otherwise, return false. // If this method returns false, the application will be terminated. // Uncomment the following statement to listen to the screen on/off events. //PowerManager::SetScreenEventListener(*this); // Create a form //REPLACED Form1 *pForm1 = new Form1(); MainListForm *pMainListForm = new MainListForm(); //REPLACED pForm1->Initialize(); pMainListForm->Initialize(); // Add the form to the frame Frame *pFrame = GetAppFrame()->GetFrame(); //REPLACED pFrame->AddControl(*pForm1); pFrame->AddControl(*pMainListForm); // Set the current form //REPLACED pFrame->SetCurrentForm(*pForm1); pFrame->SetCurrentForm(*pMainListForm); // Draw and Show the form //REPLACED pForm1->Draw(); pMainListForm->Draw(); //REPLACED pForm1->Show(); pMainListForm->Show(); return true; }
5
Introduction to bada: A Developer's Guide - (draft preview, July 2010)
In this code, when our app launches, we: 1. Create the default Form we will display, add it to the application Frame, and set it to be the current Form. 2. Draw() and Show() the Frame; in two steps, this renders the Form (and any controls it contains) to the logical display; and then updates the physical frame buffer (which updates the phone display, so that you can see it). The AppRegistry& appRegistry parameter is passed to the method to save you having to make a method call to get it. Typical uses of the registry at initialization time are:
Look for some kind of signature to tell us whether this is the first time the app has ever run, if there are specific “first time” actions we want to perform, like inviting the user to register, or to provide default data like a nickname, or just so that we can say Hello!
If we find a signature, restore any saved preferences
In both cases it‟s a good idea to limit any code to simple, quick flag setting, to be actioned later, so that the Form we loaded can be drawn and the screen updated, and we can get on and launch; which we do by setting the return value: return true;
This is important; if the value is true, the framework will set our state to Running; otherwise, it will be set to Terminating.
3.1.4 Running If OnAppInitializing() returned true, our app will enter the Running state. There is no lifecycle method associated with this transition – so how do we code for it? The answer is that we don‟t need to manage the transition. Our default Form is being displayed; and our app is now the foreground application. User interaction will cause our GUI event handling code to run, for example we coded OnActionPerformed() to respond to the soft keys, option menu key, and option menu selections. 6
Introduction to bada: A Developer's Guide - (draft preview, July 2010)
It is essential to understand that in the Running state we differentiate between the two sub-states Foreground and Background. There are two methods associated with these states: OnForeground() and OnBackground(). OnForeground()is implicitly called when an app is started and the app is shown. A running app is sent to the background when the Home key is pressed or when a native application such as an incoming call or SMS is invoked. Then the OnBackground() method is called and it is recommended to stop resource intensive operations and release unneeded memory. Once your app moves into the foreground again you can proceed normally. Recall also the long list of listeners the UI Builder tool added to our MainListForm – key presses, touch and multi-touch events, and focus events will all cause our listener implementations (call-backs) to run, so that we can handle the events appropriately. And of course system events too will generate call-backs. As we‟ve seen, the minimum set of system events we should be prepared to handle is:
OnBackground()
OnLowMemory()
OnBatteryLevelChanged()
OnScreenOn()
OnScreenOff()
The two screen events, as you may have guessed, are the reason for deriving from IScreenEventListener. There are no hard and fast rules for how you should code for these events. But clearly, for example, if memory is low you should consider releasing memory you own; if the battery level becomes low, save power, and be prepared for sudden failure; if the screen is off, there is no point in updating the display, and so on.
3.1.5 Terminating Your app may be terminated by the user; typically in bada, apps do not have an Exit softkey or menu option, but instead are ended when the user presses the Power/End key. Your app may also be terminated 7
Introduction to bada: A Developer's Guide - (draft preview, July 2010)
by the system, but that will usually indicate a serious error of some kind. In either case, when your app transitions to terminating, its OnAppTerminating() method will be called, and you should prepare to close; release all resources, and possibly save state if relevant (but typically not user data – which should always be saved at the point of change). When your app next runs, it will launch into the Initializing state, which is the difference between its being terminated, and being put into background.
3.1.6 Terminated Your app is no longer running.
3.1.7 A note about frameworks The great thing about frameworks is that they enable your app to take advantage of ready-made behaviour. Because bada‟s language is C++, bada‟s frameworks use C++ inheritance to share behaviour between the frameworks and your app. If you know your C++, then you‟ll probably know (at least approximately) how that works, but it doesn‟t matter if you don‟t. The principle is simple: the frameworks declare certain methods that your app must implement; the frameworks will call these methods, and when they do, your implementations will run. The bada C++ frameworks use derivation and virtual functions to share responsibilities between the framework itself, and apps that use the frameworks. The framework base classes that apps derive from provide ready-made implementations of common behaviour that all apps will share, as well as behaviour defined in virtual methods that may optionally be overridden, and abstract behaviour defined in pure virtual methods for which the derived class must provide an implementation. Abstract classes are used extensively in bada, particularly to define interface classes. See Chapter 4 for more about interface classes and how to use them. Note: in C++, derivation (i.e. inheritance) is the generic mechanism that allows derived classes to share the behaviour of base classes; and specifically, virtual functions (dynamic binding) allow derived classes 8
Introduction to bada: A Developer's Guide - (draft preview, July 2010)
to extend the behaviour of base classes by overriding the base class behaviour. Overriding is not the same as overloading, in which methods with the same name but different signatures are allowed, and the references are resolved at compile time; virtual methods use the virtual keyword and have the same name and signature, and the references are resolved at runtime. In C++, pure virtual methods, also known as abstract methods, are declared with a special =0; syntax that indicates the method has a null body i.e. no implementation; code won‟t link until an implementation is provided. Pure virtual methods in the base class must be implemented by a derived class;1 other virtual methods of the base class have a base class implementation, but optionally may be reimplemented by a derived class to override the default behaviour.
3.2 Using the UI Framework Implementing the application lifecycle effectively and appropriately is one important aspect of making the best use of the bada frameworks. A second is using the GUI frameworks to create an effective, goodlooking, and easy-to-use GUI. TouchWiz on bada has a host of nice features, and the built-in apps showcase them well. In the following sections we take a deeper look at bada‟s control and graphics classes, which provide the building blocks for creating the app GUI.
1
More precisely, a derived class that will be instantiated must implement the pure virtuals of its base class(es). Chains of abstract classes are possible, but a class that does not implement an inherited pure virtual is itself an abstract class that cannot be instantiated.
9
Introduction to bada: A Developer's Guide - (draft preview, July 2010)
3.2.1 Control hierarchy The bada UI classes provide a useful set of ready-made Control types. All UI elements, including Frame and Form, derive from the Control class as shown in Figure 3.2 which shows the most important classes of the Control hierarchy.
Figure 3.2 The Control hierarchy Note that, for reasons of clarity, the diagram does not show all the UI controls which derive from Control, but it does show the relationship between Control and Container. Control is the base class for all GUI elements, and Frame and Form are the app‟s top level GUI objects.
10
Introduction to bada: A Developer's Guide - (draft preview, July 2010)
3.2.2 More about UI Controls Forms contain content. Content types include plain text, directly embedded images including backgrounds, and standard or custom Controls. Controls that derive from Container can also be containers for nested controls. As well as containing content, Controls are active and can respond to user events like touches, multi-touches, and gestures. As you would expect, bada provides a comprehensive set of standard Controls, like buttons, pickers, and edit areas, as well as more specialised controls including animations, Flash movies, and overlay panels that enable controls to be layered (for example to overlay player-like controls on a video frame). Applications can also derive and customise their own Controls, if there is no suitable standard Control that meets the application's needs. All Controls must be both drawn and shown in order to display, either synchronously using the Draw() and Show() methods, or asynchronously using RequestRedraw(). The synchronous methods should not be called from within a callback. Instead, use the asynchronous RequestRedraw() method, which returns immediately after queuing the redraw request. In this case your drawing code should be performed in the OnDraw() callback method, which will be called by the framework when your queued request is actioned. Note: a control only becomes displayable after it has been added to a displayable container. Whether a control is displayable will also determine whether its child controls, if any, are displayable. For this reason, a general rule is that no methods of the control should be called until after it has been added to its container, to avoid possible unexpected behaviour, for example related to displayability. Drawing requests cascade top-down through the control hierarchy until there is no further child to cascade to, when the first Draw() is performed. Drawing is then performed in a reverse, bottom-up cascade, from the most-nested control back towards the root of the hierarchy. Unexpected results can occur if a Draw() request higher up in the control hierarchy overwrites a Draw() lower down in the hierarchy. In practice, this is only likely to be an issue when a Canvas is being used. 11
Introduction to bada: A Developer's Guide - (draft preview, July 2010)
Draw() Show() RequestRedraw() OnDraw()
Draws the control to the canvas of the containing Window, which in all cases is the Window-derived Application Frame Copies the Window canvas content to the displayable frame buffer Asynchronous method that invokes Draw() and Show() and returns immediately Called by the framework when a control is requested to be drawn using RequestRedraw()
Shown below is a selection of some of the standard Controls provided by bada, organised by the kind of user interactions you‟ll need when you design your user interface.
Simple buttons Button CheckButton Label
This group of controls is for generic buttons, presenting the user with tick box choices and in the case of the Label control displaying non-editable text or images. Pickers ColorPicker
12
Introduction to bada: A Developer's Guide - (draft preview, July 2010)
DatePicker
RadioGroup
Slider
TimePicker
These are controls which let the user select a colour, a date or time or, in the case of a RadioGroup, make one choice from a list of options. The slider allows the user to choose a value from a range. Lists CustomList
ExpandableList
13
Introduction to bada: A Developer's Guide - (draft preview, July 2010)
GroupedList
IconList
bada gives you lots of choice when it comes to displaying lists, from lists of icons to a CustomList where individual items can have different layouts. We use a simple List in BuddyFix to display the list of buddies. Editable controls EditDate
EditField
These are input controls for text and date. You can also use EditTime and EditArea which are not shown above. Progress and popups Progress
14
Introduction to bada: A Developer's Guide - (draft preview, July 2010)
These are classes which display information to the user. Progress provides feedback to the user about how much time an operation will take to finish. A Popup provides a window that can be displayed on top of a Form or a Frame
Panels ScrollPanel
A panel is a Control which can contain other controls. A ScrollPanel provides a scrollable area (notice the scrollbar on the right of the control) which in the picture above contains a label and a button. The OverlayPanel control is used to for displaying video or camera previews. Animation and Flash Animation
The Animation control is designed for playing back a series of AnimationFrames. You can also use the Flash control to play back Flash Lite content embedded in an application.
3.2.3 More about Frame Every application has access to its Frame, which abstracts a drawable, full-screen-sized display window. Frame takes care of standard window behaviour for all of its contained controls, for example compositing drawn regions, marking regions invalid, clipping, capturing events and cascading them, and so on. 15
Introduction to bada: A Developer's Guide - (draft preview, July 2010)
Note: Frame derives from Control, Container, and Window. In most cases your app can happily let Frame take care of all these details. Rarely, if ever, will you need to think about window behaviour at all, and typically you will only ever use derived Window classes like Frame. Since the Frame is the root of your GUI hierarchy, getting hold of the Frame is the starting point for setting up the UI when an app initialises. Within any Form method, getting the Frame is easy: Frame *pFrame = GetAppFrame()->GetFrame();
Typically, a Form does not declare a Frame pointer member; instead, it dynamically allocates the Frame pointer, *pFrame in the example above, when it is required. Note: while Frame is at the top of the logical hierarchy of all GUI elements in an application, and has displayable properties – for example, its background and transparency – Frame itself is only displayed if no Form exists; what the user sees are the GUI elements that are contained by the application's Forms, or in the case of a full-screen app which does not use Forms, the user sees directly rendered graphics. It is important to remember that although Frame is Container-derived, it is a special case of a Container; the only Control type that can be added to a Frame is Form, using the AddControl() method, which is reimplemented from Osp::Ui::Container: Osp::Ui::Controls::Frame::AddControl ( const Osp::Ui::Control control ) [virtual] Osp::Ui::Controls::Frame::AddControl (const Osp::Ui::Control control) [virtual]
Frame includes a number of methods that enable Forms to be manipulated:
AddControl() RemoveControl() GetCurrentForm() SetCurrentForm()
An app that requires multiple screens should define multiple Forms, one Form per screen. The simplest architecture (but not the only one) for navigating between screens is to use tabbed Forms, allowing the 16
Introduction to bada: A Developer's Guide - (draft preview, July 2010)
user to select each Form by selecting the appropriate tab. Within the UI code, a Form manager should be implemented to handle tab selections and Form switching in response to user actions, using the “get” and “set “methods above. Frame can be used directly to create a non-standard GUI by rendering graphics to its Canvas, instead of populating it with a Form and controls – see Using Graphics, below. This approach is typically used for games and other full-screen applications.
17
Introduction to bada: A Developer's Guide - (draft preview, July 2010)
3.2.4 More about Form Except for the special case of a full-screen app (or what the App Wizard refers to as a Frame-based application), a Form is the starting point for GUI design. Like Frame, Form is a full-screen-sized container. Unlike Frame, Form can contain instances of any Control derived class (with the exception of Frame; Frame cannot be instantiated by the app), and Form itself (a Form cannot contain another Form). As we saw in the previous chapter, because it encapsulates the full screen, Form includes system areas like the Indicator and Title bars, and soft keys, as well as the application client area. In addition, the bada UI framework allows a Form to display an Option menu, which is launched from an Option key that displays at the bottom of the screen in the command area. In BuddyFix, for instance, we will use the Options menu to provide global options, like managing settings and adding and removing buddies. Because the Option and Soft Keys are Form properties, it‟s easy to add them just by updating Form properties in UI Builder. The change is trivial to make, but it‟s worth thinking through the intended interaction semantics. In BuddyFix, possible actions we might assign to a Soft Key are:
Adding or removing a buddy
Canceling an action in progress, for example when setting or changing settings
Backing out to the previous screen, which for a single-screen app means backing out to the phone's home screen
Pausing or unpausing location sharing for all buddies
„Nudging‟ a buddy with an update
A good rule of thumb is to reserve soft keys for actions that are used frequently, or that we want to make prominent. For now, „Add (buddy)‟ and „Nudge (buddy)‟ make a well-matched pair. Let‟s update the Form properties, save our resources, rebuild, and run:
18
Introduction to bada: A Developer's Guide - (draft preview, July 2010)
Figure 3.3 BuddyFix updated with the Soft keys and option menu key display. That's as far as UI Builder will take us. Adding menu items to the Option Menu, like adding list items to the buddy list, will require us to write some custom code.
3.3 Using graphics Using graphics effectively is an important part of creating a good GUI experience for users, and bada provides comprehensive graphical primitives for vector graphics (drawing), bitmaps, animations, and fonts, as well as directly supporting OpenGL ES.
19
Introduction to bada: A Developer's Guide - (draft preview, July 2010)
In bada:
all graphics are drawn to a Canvas object
at any time a global Canvas can be constructed that draws outside of the layout hierarchy
every Control owns a local Canvas that can be requested and drawn to, and that draws within the layout hierarchy
3.3.1 More about Canvas The Canvas class enables direct access to the device display for drawing. Whenever you want to do direct drawing using graphical primitives (like Line, Rectangle, Ellipse, Polygon, and so on, as well as TextElement for text and Bitmap for images, which are all members of the Osp::Graphics namespace), then you must use a Canvas. You can explicitly construct a normal (global) Canvas object from anywhere in your GUI: // Construct a "normal" or global canvas Canvas* pCanvas = new Canvas(); pCanvas->Construct();
Note that Canvas is always constructed in two-phases by allocating with operator new and initialising with Construct() (see Chapter 4, on two-phase construction). A normal Canvas overlays the application Frame and bypasses the window (and Control) hierarchy, providing direct access to the display and overwriting anything within its display rectangle (including your current Form and any Controls it contains). If no rectangle is specified in construction, a normal Canvas is full-screen size. This means that Canvas can be used to set a full-screen background image. (Recall that both Frame and Form allow their background colour to be set, but will not load an image as background.)
20
Introduction to bada: A Developer's Guide - (draft preview, July 2010)
Once Canvas is drawn, any subsquent Draw() calls will overwrite it, allowing Controls (for example) to be drawn on top of it. However, this will only be as robust as the sequence of Draw() calls in your code, so use this with care. The more typical way of using Canvas, which operates within the window and control hierarchy (and therefore does not risk unintended overwriting of other GUI elements) is to request a local “window” Canvas object. Every Control-derived object, from Form down through the Control hierarchy, owns a window Canvas object: // Get the window canvas Canvas* pCanvas = GetCanvasN();
In this case, the Canvas shares the context of its owning Control, including its display region and any other properties of the local graphics context that have been set. Typically, the caller then sets any desired display properties and draws, enabling a Canvas to be used to draw display primitives or background bitmaps directly to the screen within the context of a given Control, to create text or other graphics. Canvas is not part of the Control hierarchy, and in fact is not part of the Osp::UI namespace; instead, it derives directly from the root bada Object class Osp::Base::Object, and is a member of the Osp::Graphics namespace. Canvas has the following attibutes which you can set on any canvas, using methods such as SetForgroundColor(), SetLineWidth(), and so on: Foreground color
Drawing color for primitives
Background color
Background color for clearing
Line style
Line style (only Solid)
Line width
Line width for primitives with a line style
Font
Font used for text drawing
Note: if you are drawing from within the OnDraw() callback, then you should call GetCanvasN() on the parent container control to retrieve the canvas that the container is using, otherwise the control's local 21
Introduction to bada: A Developer's Guide - (draft preview, July 2010)
canvas will be overdrawn by the parent, since drawing is always performed bottom-up through the list of controls owned by the container.
22
Introduction to bada: A Developer's Guide - (draft preview, July 2010)
3.3.2 Graphics primitives As you would expect, bada provides a comprehensive set of graphics primitives. These are always drawn to a Canvas object. The Canvas supplies the graphics context for the primitives that are drawn to it, in the form of the settable Canvas attributes shown. You can set and reset these dynamically at any time in your drawing code. The Canvas you draw to may be either one you explicitly construct, or one you request from an appropriate Control. The Point, Dimension, and Rectangle classes are used to construct the various graphical primitives. Point A two dimensional point composed of X, Y coordinates Dimension An X, Y ordered pair of (width, height) Rectangle An rectangular region with a top-left point (X, Y) and a width and height.
Shapes are always constructed from the top left corner, which is the (0,0) point of the local coordinate space.
Simple shapes and text Note that for simple drawing of shapes and text, all the work is done by the Canvas. You do not need to explicitly create shape, line, or text objects; instead, set Canvas attributes and invoke a dedicated drawing method of the Canvas object, for example: 1. Construct a canvas: Canvas::Construct()
2. Clear the canvas: 23
Introduction to bada: A Developer's Guide - (draft preview, July 2010)
Canvas::Clear();
3. Set the line color to red: Canvas::SetForegroundColor(Color::COLOR_RED);
4. Draw a rectangle onto the canvas: Canvas::DrawRectangle();
5. Show the canvas to the display: Canvas::Show();
For shapes, like Ellipse, Polygon, Rectangle and so on, set the fill attributes by calling Fill methods instead of plain Draw methods, for example: Canvas::FillRectangle(const Color &color, const Rectangle &rect);
Text can be drawn to a Canvas in a similar way: 1. Construct a canvas. 2. Construct a font with style and size: Font::Construct(FONT_STYLE_ITALIC, 32);
3. Clear the canvas. 4. Set the Canvas font: Canvas::SetFont(font);
5. Draw “BuddyFix!” to the canvas: Canvas::DrawText(Point(55, 55), L”BuddyFix!”);
6. Show the canvas to the display. 24
Introduction to bada: A Developer's Guide - (draft preview, July 2010)
Note: text can also be drawn directly into most (but not all) types of control – most obviously Label, which is specifically provided as a container for non-editable text, and EditArea and EditField which are provided for editable text, as well as MessageBox, and the various List types and ListItem types. See the API reference for details.
EnrichedText EnrichedText gives you much greater control of text styles. Using simple Canvas text styles only allows Direction, Underline, and Strikeout styles to be set. Using EnrichedText you can fully specify text styles by combining overall styles for the complete EnrichedText block, for example alignment and wrapping, with individual styles set for each TextElement object in the blocks, for example font styles and sizes, colours, and so on.
Table: EnrichedText attributes Horizontalalignment Vertical alignment Text wrapping style Abbreviation Font size and style Text color Background colour Outlinecolour
Left, center, or right Top, middle, or bottom None, character wrap, or word wrap Whether the drawn text is abbreviated in case the text size exceeds the dimension of EnrichedText Thefont size and style: plain, bold or italic The foreground colour of the text element The background colour of the text element The outline colour of the text element
EnrichedText is still drawn using the Canvas, except that the text itself is explicitly created and passed as a parameter: pEnrichedText->Construct(Dimension(width, height)); pCanvas->DrawText(Point(left, top), *pEnrichedText);
25
Introduction to bada: A Developer's Guide - (draft preview, July 2010)
For example: 1. Create an EnrichedText: EnrichedText::Construct(dimension);
2. Set the attributes of the EnrichedText: EnrichedText::SetTextWrapStyle(TEXT_WRAP_CHARACTER_WRAP);
3. Create and add TextElements to the EnrichedText: TextElement::Construct(L"01234567890123“); EnrichedText::Add(TextElement&);
4. Set the attributes of the TextElement, e.g. color and font: TextElement::SetTextColor(Color::COLOR_BLUE); TextElement::SetFont(font);
5. Construct and clear a canvas. 6. Display the EnrichedText: Canvas::DrawText(Point(10, 10), *pEnrichedText);
7. Show the canvas on the display.
3.3.3 Bitmaps and images For many apps, the ability to display and manipulate images is an essential requirement:
Images may be used purely for GUI effects as background images, patterns, icons, and so on for display within (or as complete backgrounds to) GUI controls
Images may form part of the app's displayable data, for example thumbnail pictures of people, places, or things.
Images may be originated on the phone itself (by the camera, or by using a drawing or image editing app), uploaded from a memory card or via short link (Bluetooth) or cable connection, downloaded over the 26
Introduction to bada: A Developer's Guide - (draft preview, July 2010)
network (say, from Flickr), or embedded in the app by the developer at build time (background images used in the UI). In all of these cases, typically the image exists in the first instance as a data file.2 In file format it will be viewable by media player and browser apps, assuming the file is a supported format. Before it can be used within an application, image data must be loaded from file into memory. Image data that is held in memory on the phone should typically be saved into a file format before it is transferred off the phone, or before it can be shared with other apps on the phone. In bada, the Bitmap class encapsulates image data in memory, and the Image class is provided as a utility class to perform conversions both ways between files and Bitmaps, as well as directly between different file formats. Using the Image class, image data can be decoded into a Bitmap from a supported file format, or encoded from a Bitmap into a supported file format. A Bitmap object contains a (decoded) physical copy of the original file data, stored in a standard bitmap format (see below). This means that after decoding, the Image object and the original image file are no longer required. To create a Bitmap from an image file the steps are: 1. new and Construct() an empty Image object: Image* pImage = new Image(); pImage->Construct(); Bitmap* pBitmap = null;
2. Call the Image.DecodeN() method to decode the image data from the file. DecodeN() returns a Bitmap object: pBitmap = pImage->DecodeN(L"/Res/bada.png", BITMAP_PIXEL_FORMAT_ARGB8888);
3. Delete the Image object: delete pImage;
2
This is a simplification. Images can also be stored as binary data in byte buffers. See the SDK API Reference.
27
Introduction to bada: A Developer's Guide - (draft preview, July 2010)
4. Use the Bitmap object, and delete when no longer required, for example: pButton->SetNormalBitmap(Point(0,0),*pBitmap); delete pBitmap;
Specifically, the Image class contains utility methods for handling images:
Encoding and decoding image data to/from file
Converting Bitmap or file image data between image formats
Compressing JPEG images
Decoding image data supports the following file types:
JPEG
GIF
PNG
BMP
TIFF
WBMP
Encoding supports the following file types:
JPEG
PNG
BMP
Three different bitmap formats are supported by bada. The bitmap pixel format specifier defines the colour mode of the destination bitmap and accepts the following enumerated types: RGB565 pixel format ARGB8888 pixel format R8G8B8A8 pixel format for OpenGL
BITMAP_PIXEL_FORMAT_RGB565 BITMAP_PIXEL_FORMAT_ARGB8888 BITMAP_PIXEL_FORMAT_R8G8B8A8
28
Introduction to bada: A Developer's Guide - (draft preview, July 2010)
The pixel formats represent the following standard colour modes:
RGB565 specifies 16-bit RGB with 5 bits of red and blue, and 6 bits green
ARGB8888 specifies 32-bit Alpha RGB with 8 bits each
R8G8B8A8 is an alternative 32-bit, byte-based format preferred by OpenGL(R)
See FGrpBitmapCommon.h, the header file for all enumerations of the Bitmap class. As with the graphics drawing primitives, Bitmaps represent pixel data and are displayed by drawing the Bitmap into a region of a Canvas, and showing the Canvas. Note: Graphics provides the alpha blending functionality only for the Canvas which has an alpha channel. Because every image has a „real‟ size (the size at which it was created), which may or may not be the size at which you wish to display it on the phone, decoding from an image file supports image scaling. Other transformations, for example rotation, can be performed when the image is drawn to the Canvas. Bitmaps can also be clipped to regions of the Canvas, as a separate step from sizing and positioning the screen region (which must always be a rectangle) to which they are drawn. Create a bitmap from file FMedia.h is the header file for Media namespace which contains the Image class, while Bitmap is defined in the Graphics namespace in FGraphics.h. The required #include declaration is: #include FMedia.h #include FGraphics.h
FMedia is the required library to use the classes in the Media namespace, while FGraphics is required to use the classes, such as BitMap, defined in Graphics.
29
Introduction to bada: A Developer's Guide - (draft preview, July 2010)
The required namespace declaration is: using namespace Osp::Media; using namespace Osp::Graphics;
Privilege level is NORMAL. Privilege group is IMAGE. Image construction is performed as: result r = E_SUCCESS; Image *pImage = new Image; r = pImage -> Construct(); if (IsFailed(r)) { // handle error condition }
r contains E_SUCCESS if the method was successful, and an error status otherwise. More more about system error values see FBaseErrors.h which defines all framework error codes. Image provides four decoding methods:
Takes a source file image path string and destination bitmap pixel format specifier
No resizing performed
Original aspect ratio preserved
Bitmap* DecodeN(const Osp::Base::String& srcImagePath, BitmapPixelFormat colorFormat) const;
Takes a source file image path string and destination bitmap pixel format specifier, plus output image width and height
Resized as specified 30
Introduction to bada: A Developer's Guide - (draft preview, July 2010)
Bitmap* DecodeN(const Osp::Base::ByteBuffer& srcImageBuf, ImageFormat srcImageFormat, BitmapPixelFormat colorFormat, int destWidth, int destHeight) const;
Takes a reference to a source buffer and destination bitmap pixel format specifier
No resizing performed
Original aspect ratio preserved
Bitmap* DecodeN(const Osp::Base::ByteBuffer& srcImageBuf, ImageFormat srcImageFormat, BitmapPixelFormat colorFormat) const;
Takes a reference to a source buffer and destination bitmap pixel format specifier, plus output image width and height
Resized as specified
Bitmap* DecodeN(const Osp::Base::ByteBuffer& srcImageBuf, ImageFormat srcImageFormat, BitmapPixelFormat colorFormat, int destWidth, int destHeight) const;
Continuing the code fragment from above, with result r declared and pImage constructed: Bitmap* pBitmap = null; String path(L"/Res/Sample.jpg"); pBitmap = pImage->DecodeN( path, BITMAP_PIXEL_FORMAT_RGB565, SCREEN_WIDTH, SCREEN_HEIGHT ); if (null == pBitmap) { delete pImage; } //Your code goes here… //Finally, delete the image instance delete pImage;
31
Introduction to bada: A Developer's Guide - (draft preview, July 2010)
Note that we delete the Image object as soon as we have finished with it, or in case of error, we must delete it. Because pBitmap and String are not constructed (but are just declared as automatics), we should not call a destructor on them; they will simply be deallocated when they go out of scope when the method returns. In the code above we create a String object to store the path; more efficiently, we can use the L macro to create a string literal within the method call: pBitmap = pImage->DecodeN(L"/Res/Sample.jpg", BITMAP_PIXEL_FORMAT_RGB565, SCREEN_WIDTH, SCREEN_HEIGHT );
Draw a Bitmap onto a Canvas, into a specified rectangle inside a Form
After first doing: o
Create a new Image object
o
Use the Image to construct the Bitmap from a file e.g. PNG or JPEG
A Form has an underlying Canvas object: you request it, draw into a region of it and then Show() it. We will use the Rectangle initialising constructor to construct therectangle at the required size. Osp::Graphics::Rectangle::Rectangle (int x, int y, int width, int height);
We therefore supply the values x=20, y=80, width=440, height=440. Any play controls that we want must therefore appear in the screen area below the board (in portrait orientation, to which we will limit ourselves for now). Note: you can construct a Canvas larger than the device screen. In FGrpCanvas.h : result Construct(const Rectangle& rect); Now that we have created the bitmap we can use it. For example, to display the bitmap, we get the Canvas for the Form (or Frame if we have no Form), draw to the canvas and show.
32
Introduction to bada: A Developer's Guide - (draft preview, July 2010)
Continuing the code fragment: // Create a rectangle to draw into, gets the bounds of the client area Rectangle rect = TopBoardViewForm->
GetClientAreaBounds();
// Get a Canvas instance Canvas *pCanvas = null; pCanvas = pForm -> GetCanvasN(); // If we want to display directly in the app Frame then we get the Canvas instead with: pCanvas = GetAppFrame()->GetCanvasN(); r = pCanvas -> DrawBitmap(rect, *pBitmap); if (IsFailed(r)) { delete pCanvas; } r = pCanvas->Show(); if (IsFailed(r)) { delete pCanvas; } // Your further code … delete pCanvas;
To draw the bitmap to the canvas, we must create a rectangle to draw into. Note that the rectangle size, not the bitmap size, determines the size of the bitmap drawn. Note that we must delete the Canvas object in case of failure.
33
Introduction to bada: A Developer's Guide - (draft preview, July 2010)
3.3.4 Colours Finally, to complete this survey we will look briefly at the Color class. Although colour values may not seem to be as universally relevant as, say, String or Number types, most apps - in fact, all apps - are clients of the graphics classes which define colours, and every app developer shoud have at least a good, casual understanding of how colours are used and manipulated in bada. Mobile phones have come a very long way from the early, monochrome (or green-screen, text-based), devices that at least some of us remember from the early days of our careers in mobile development. In fact, Samsung is a technology leader in screen technology and has consistently driven phone specifications toward the high end, breaking new ground with HD (High Definition) and, recently, AMOLED technology (Organic Light Emitting Diode). Phones like Wave have physically big screens with high pixel density and bright, high-contrast, outdoor-readable screens with vibrant, dazzling colour. With the widespread availability of hardware graphics acceleration and shader support, UI effects like transparency, animation, and full-3D are now possible on phone displays, where just a few years ago they were unthinkable. Interestingly, AMOLED technology has brought device displays into the power-management equation in a surprising way. Unlike standard LCD technologies, OLED displays use active pixels for which power requirements vary depending on the hue being displayed by the pixel. Quite literally, darker colours are cheaper (in power usage) than lighter colours, meaning that UI designers can now add power-usage to the list of factors determining their design choices for app palettes and colour schemes.
34
Introduction to bada: A Developer's Guide - (draft preview, July 2010)
In bada, colours are defined using the ARGB colour model, which uses Alpha (i.e. transparency), Red, Green, and Blue values. Note: not all graphics objects have an alpha channel. Bitmap and Canvas both do, and both therefore support alpha blending. The Color class provides useful built-in functions including:
Setting and getting colour components for or from a Color object, with values for all ARGB or specific colour values (and alpha), as well as a 32-bit colour value
Predefined ten-colours
All colours are 32-bit entities supporting 24-bit "true-color" or "millions of colours" display, with 8 bits for each of red, green blue, and alpha data. If a device display supports a lesser physical bit depth, then colours are down-sampled, resulting in a loss of quality. Pixels, by the way, are always square on bada phones. Note: bada uses 32-bit ARGB color by default. Each channel (ARGB) occupies 8bits. However if the device supports only 16-bit for the colors, RGB occupies 5bits, 6bits, and 5bits respectively. This means colors are down-sampled.
35
Introduction to bada: A Developer's Guide - (draft preview, July 2010)
3.4 The BuddyFix UI revisited As we saw, UI Builder only gets us so far in creating a functional UI. In particular, to complete the basic UI for BuddyFix we will need to:
Implement the „Add‟ softkey
Implement the Option Menu
Also, before we can make any final decisions about the layout of the main list and its items, we will need to populate it.
3.4.1 Adding an OptionMenu The Option Menu is popped up when the user presses the Option soft key (also known as the handle) in the command area at the bottom of the screen, for a Form for which FORM_STYLE_OPTIONKEY is true. Each Form can choose whether or not to enable an Option Menu, and each Form can define its own Option Menu. The UI guide specifies some guidelines for designing an Option menu:
Soft key functions should not be duplicated in the option menu
The maximum number of menu items is 12, but the preferred limit is 8, and 4-6 items is probably better still
Menu items can have secondary items, for which the preferred limit is 4 sub items
The OptionMenu class derives from Control via Container. The principles for constructing and using an option menu are as follows:
36
Introduction to bada: A Developer's Guide - (draft preview, July 2010)
Construct an OptionMenu object dynamically, typically when initialising the Form that will display the menu
Set an event ID and a listener for the option key press action
Create the menu items and add an event ID for each item
Implement an action event handler that responds to the key and menu item event IDs
Delete the OptionMenu object, typically when terminating the Form that will display the menu
Event IDs are just integer values. Typically we assign 100 to the key event, 101 to the first top-level item, 201 to the first sub-item, and so on: static const int ID_OPTIONKEY = 100; static const int ID_OPTIONMENU_ITEM_1 = 101; static const int ID_OPTIONMENU_SUBITEM_1 = 201;
Once the event IDs have been set and the listener has been added, the framework will return event IDs corresponding to user actions performed on the menu. In BuddyFix we will implement the following top-level option menu items and sub-items: "Buddies" "Add Buddy" "Remove Buddy" "Pause sharing" (if active) or "Unpause sharing" (if paused) "Settings" "About"
Top-level item Sub-item, add a new buddy to the buddy list Sub-item, remove a buddy from the buddy list Top-level item, globally pause or unpause location sharing for all buddies Top-level item, launch a Settings pop-up Top-level item, launch an information pop-up providing app version and other information
Let's look at the code. Firstly in MainListForm.h, we add an OptionMenu pointer member pOptMenu, and event ID definitions: class MainListForm : public Osp::Ui::Controls::Form { // ...etc // Option Menu declarations
37
Introduction to bada: A Developer's Guide - (draft preview, July 2010)
protected: Osp::Ui::Controls::OptionMenu* pOptMenu; static const int ID_OPTIONKEY = 100; static const int ID_OPTIONMENU_ITEM_1 = 101; static const int ID_OPTIONMENU_ITEM_2 = 102; static const int ID_OPTIONMENU_ITEM_3 = 103; static const int ID_OPTIONMENU_ITEM_4 = 104; static const int ID_OPTIONMENU_ITEM_5 = 105; static const int ID_OPTIONMENU_SUBITEM_1 = 201; static const int ID_OPTIONMENU_SUBITEM_2 = 202; };
Next, in MainListForm.cpp, we add code to construct and assign the menu object. Event IDs are set by passing the ID to the item or sub-item constructor method. We must also invoke two Form methods: SetOptionkeyActionId(ID_OPTIONKEY); AddOptionkeyActionListener(*this);
The Form initialisation code now looks as follows. Notice the use of two-phase construction to separately allocate and initialise the OptionMenu object: bool MainListForm::Initialize() { Form::Construct(L"IDF_MAIN_LIST_FORM"); // Create the OptionMenu // Member in MainListForm Osp::Ui::Controls::OptionMenu* pOptMenu pOptMenu = new OptionMenu; pOptMenu->Construct(); pOptMenu->AddItem("Buddies",ID_OPTIONMENU_ITEM_1); pOptMenu->AddSubItem(0, "Add Buddy",ID_OPTIONMENU_SUBITEM_1); pOptMenu->AddSubItem(0, "Remove Buddy",ID_OPTIONMENU_SUBITEM_2); pOptMenu->AddItem("Pause Sharing",ID_OPTIONMENU_ITEM_2); pOptMenu->AddItem("Unpause Sharing",ID_OPTIONMENU_ITEM_3); pOptMenu->AddItem("Settings",ID_OPTIONMENU_ITEM_4);
38
Introduction to bada: A Developer's Guide - (draft preview, July 2010)
pOptMenu->AddItem("About Buddy Fix!",ID_OPTIONMENU_ITEM_5); // Invoked on the Form, not the menu SetOptionkeyActionId(ID_OPTIONKEY); AddOptionkeyActionListener(*this); return true; }
Since we have allocated the menu object, we are responsible for deleting it. In MainListForm.cpp: result MainListForm::OnTerminating(void) { result r = E_SUCCESS; delete pOptMenu; return r; }
Finally, we need to handle the events that menu actions generate. In MainListForm.cpp, we add handler code into the OnActionPerformed() method: void MainListForm::OnActionPerformed(const Control& source, int actionId) { switch (actionId) { case ID_OPTIONKEY: ShowOptionMenu(); break; // Menu items case ID_OPTIONMENU_ITEM_1: // Todo: insert your code here break; // ... etc
39
Introduction to bada: A Developer's Guide - (draft preview, July 2010)
// Menu sub-items case ID_OPTIONMENU_SUBITEM_1: // Todo: insert your code here break; case ID_OPTIONMENU_SUBITEM_2: // Todo: insert your code here break; default: break; } }
Our implementation is nearly complete. The final step is to add methods to dynamically show and hide the menu. Hiding the menu is performed by the framework, but showing it when the option key is pressed (or swiped) is our responsibility. In MainListForm.cpp: void MainListForm::ShowOptionMenu(void) { pOptMenu->SetShowState(true); pOptMenu->Show(); } // void MainListForm::HideOptionMenu(void) { pOptMenu->SetShowState(false); Draw(); Show(); }
Note the asymmetry in the use of Draw() and Show(). In ShowOptionMenu(), Show() is called on the option menu object. 40
Introduction to bada: A Developer's Guide - (draft preview, July 2010)
While there is nothing complex about the code we have had to write, implementation is not trivial. In an app that used multiple forms, we would probably choose to factor the option menu code out into a separate OptionMenuManager class, to be shared by all Forms, with each Form requesting its own subset of the available menu items and subitems.
3.4.2 Adding a Soft Key Adding a softkey is easy. The softkey behaves exactly like the option menu key. In the definition of MainListForm in MainListForm.h, we add a softkey ID as a protected member, just as we did for the option menu: static const int ID_LEFT_SOFTKEY = 900;
In the Initialize() method in MainListForm.cpp we add two lines, to set the softkey action ID and listener, just as we did for the option key: SetSoftkeyActionId(SOFTKEY_0,ID_LEFT_SOFTKEY); AddSoftkeyActionListener(SOFTKEY_0, *this);
That's it. To capture and handle the softkey event, in MainListForm.cpp we add a softkey case at the top of the OnActionPerformed() switch statement: switch (actionId) { case ID_LEFT_SOFTKEY: ShowOptionMenu(); break; case ID_OPTIONKEY: ShowOptionMenu(); // ... etc default: break; }
41
Introduction to bada: A Developer's Guide - (draft preview, July 2010)
}
3.4.3 Populating a List We still can't see how our app‟s buddy list looks or behaves until we have populated it with some contents. Since we are only interested in the UI behaviour, we will defer any other complexity and write a test method to populate the buddy list with dummy data. This will allow us to exercise the list functionality and validate the UI behaviour. To start with we would just like to add some data to the list so that we can see how it looks. To add an item, we will write a method TestAdditem(), and add it as a protected method of MainListForm. Recall that we chose the format: LIST_ITEM_DOUBLE_IMAGE_TEXT_FULLTEXT, to display a first line of image and text, and a second line of text. The parameters we will need to pass are those that will be needed by List.AddItem():
pText1 – the first line of our next, the buddy name string
pText2 – the second line of text, the buddy location stamp string
pBitmap1 – the first normal bitmap, the buddy picture
pBitmap2 – not used
itemId – an integer ID to allow us to identify this list item
This is the prototype we add to MainListForm.h: // Implementation protected: //Test method, add an item to the list result TestAdditem( const Osp::Base::String * aBuddyName, const Osp::Base::String * aLocationStamp,
42
Introduction to bada: A Developer's Guide - (draft preview, July 2010)
const Osp::Graphics::Bitmap * aBuddyPic );
This is the stubb implementation we add to MainListForm.cpp: /* * Test method, add an item to the main buddy list */ result MainListForm::TestAdditem(const Osp::Base::String * aBuddyName, const Osp::Base::String * aLocationStamp, const Osp::Graphics::Bitmap * aBuddyPic) { AppLog("TestAdditem()\n"); return E_SUCCESS; }
First of all, we will need to create a bitmap object to supply to this method. We can assume that in our final implementation, the bitmap and name string will be retrieved from the Contacts app. For now, we will need to supply the bitmap ourself. Because this is interim code we will make it part of the test method itself, and create a single dummy bitmap we can pass to every test item we create. (So that the prototype changes.) To use bitmaps and images, in manifest.xml:
IMAGE
You can modify the manifest with the Application Manager on developer.bada.com. To use bitmaps and images, in MainListForm.h: #include FGraphics.h #include FSystem.h
43
Introduction to bada: A Developer's Guide - (draft preview, July 2010)
#include FMediaImage.h
44
Introduction to bada: A Developer's Guide - (draft preview, July 2010)
To use bitmaps and images, in MainListForm.cpp: using namespace Osp::Graphics; using namespace Osp::Media;
Note: don't forget to add your link library! This now builds. We can now tweak the prototype to leave the image parameter out, since we create the dummy bitmap in the method. Now we can test calling the method. /* * Test method, add an item to the main buddy list */ result MainListForm::TestAdditem(const Osp::Base::String * aBuddyName, const Osp::Base::String * aLocationStamp)//, const Osp::Graphics::Bitmap * aBuddyPic ) { // First, get a pointer to the main list, by name List* mainlist = static_cast(GetControl(L"IDC_MAIN_LIST" )); if (mainlist) AppLog("Not null list\n"); else AppLog("Null list!\n"); // Create a dummy bitmap to put into buddy list entries result r = E_SUCCESS; Image* dummyimage = new Image; Bitmap* bitmap = null; r = dummyimage -> Construct(); if (IsFailed(r)) { // Handle error condition return r; } bitmap = dummyimage->DecodeN(L"/Home/94-novag.png", BITMAP_PIXEL_FORMAT_RGB565,
45
Introduction to bada: A Developer's Guide - (draft preview, July 2010)
52, 52); if (null == bitmap) { // Handle error condition } //Delete the image instance delete dummyimage; AppLog("TestAdditem() %s %s \n", aBuddyName, aLocationStamp ); // Okay, now make a list item // r = mainlist->AddItem(*aBuddyName, *aLocationStamp, bitmap, bitmap, 500); r = mainlist->AddItem(aBuddyName, aLocationStamp, bitmap, null, 500 ); return r; }
Invoked with: // Now initialise the list // Create the strings String dummyname(L"Elvis"); String dummylocstamp(L"Has left the arena"); result r = TestAdditem(&dummyname, &dummylocstamp ); // Log it! // Hm, how to do this properly!! AppLog("result =%n \n", r);
This is not what we want for out final UI, but now we can see the list item.
46
Introduction to bada: A Developer's Guide - (draft preview, July 2010)
Chapter 4: bada fundamentals This chapter starts with an overview of the bada platform – its origins and its architecture – and moves on to look at its programming idioms and conventions, and the bada class library and its platform-specific types. It concludes with some practical quick tutorials that run through the most important of bada‟s C++ programming idioms. What you will learn This chapter aims to give you the context you need to use bada effectively as a developer. It gives the bigger-picture view of what bada is. You will learn about: 1. The high-level system architecture 2. The bada class library and the platform specific types you'll be using in your apps, including collections, strings and numbers 3. The idioms and naming conventions you'll need to know to write, and read, bada code What you will need To get the most from this chapter we recommend - apart from the bada SDK and IDE - a cup of tea and an armchair - but any other refreshment will do quite nicely!
4.1 Architecture overview For more about bada platform architecture, please see the information available at developer.bada.com. The print version of this book will include an architecture overview. 47
Introduction to bada: A Developer's Guide - (draft preview, July 2010)
4.2 bada coding idioms 4.2.1 C++ and bada Of all current mainstream programming languages, C++ is the most powerful and flexible. That doesn't make it the most popular language. In fact, at the time of writing, C++ maintains a steady third place in popularity surveys, behind Java and C.3 There are good reasons why C++ is unlikely to win a popularity contest. Compared with more recent languages (Python, say, or even Java), it has a complex syntax. There are several reasons for that. One is its retention of C as a proper language subset. Another is the deliberate decision to favour terse and compact (and even cryptic) over verbose and transparent. Yet another is the breadth of the language - both high-level and low-level and everything in between; supporting procedural, OOP, and generic (templatebased) programming styles. And finally, while the previous point suggests maximalist goals (include everybody!), C++ takes a very minimalist view of what a programming language should aspire to be. Its built-in types are essentially those of C, and there (more or less) the language ends. There are no frameworks, or class libraries, included in the language proper. (Even the minimalist std.h and stdio.h are strictly optional.) For all of these reasons, C++ is not the kind of language that holds your hand. This probably gives it a more fearsome reputation than it deserves. But it also means that any platform based on C++ must tame the language to suit its own purposes.
3
E.g. according to the TIOBE Programming Community Index software survey, April 2010
http://www.tiobe.com/index.php/content/paperinfo/tpci/index.html. Intriguingly, in 2010 Java and C have swapped places in the top two places, with C now the most popular language, as Java's popularity share falls. Objective C meanwhile is roaring up the table. For comparison: C and Java score around 20%; C++ around 10%; and Objective C around 2%.
48
Introduction to bada: A Developer's Guide - (draft preview, July 2010)
4.2.2 The native system The bada platform itself is written in C++ (all frameworks, all higher level components, and of course the bada class library), with some low-level C-code (low level components, kernel interfaces). The bada UI, application, and application services frameworks, and the suite of native apps that are shipped on phones as part of the platform, are exclusively C++. And it's those frameworks and the class library that the app developer sees.
4.2.3 Alternatives to native On bada, then, native development means C++ development. However, there are other options open to application developers, for example runtimes like Flash and WebKit, so long as the (relative) penalty of non-native performance is acceptable. (Typically, the critical variable is the type of app - an app that is heavy on user input or that is file-centric is a poor candidate, content browers are usually good candidates.) These options are relevant when access to the complete native platform is not required, or when existing assets have been written using cross-platform technologies, or when cross-platform usage is the overriding requirement. There are plenty of possibilities on bada:
A Flash engine is completely integrated at a low level with the native graphics architecture, making Flash a perfect choice for graphics intensive apps (and in fact Flash is used as a system component by bada itself, enabling the phone's UI to be written in Flash, making it seamlessly portable across multiple different families of phones in Samsung's portfolio, across operating systems from Symbian to WinMo, to Android and LiMo).
WebKit is also fully supported. The bada native Dolfin browser is based on WebKit with support for HTML 4.0.1 and HTML 5.
49
Introduction to bada: A Developer's Guide - (draft preview, July 2010)
This makes bada rich with choice for app developers, whether as a target for porting an existing app, or as a target for new apps.
50
Introduction to bada: A Developer's Guide - (draft preview, July 2010)
4.2.4 C++ pitfalls Coming back to native development, the C++ environment is modern, straightforward, and comprehensive. It is supported by standard, open tools including the Eclipse IDE and GNU/CodeSourcery C++ compiler 4 The pitfalls of C++ on constrained devices are well-known. It's fair to ask if mobile platforms really can still be considered constrained, at least by the standards of the old definitions, in these days of 1 Ghz processors and multi-gigabyte memory. (See Wave specs). The answer is that mobile is certainly constrained relative to the desktop, in almost all respects from CPU capability to available RAM to screen size and network bandwidth. But also, there are absolute constraints with mobile. Let's not go through all the differences again (we looked at them in Chapter 1), but on mobile resources are critical in the following:
Memory - size and speed (e.g. flash, no HD)
CPU
ROM
Battery/power
Network bandwidth
The power and flexibility of C++ comes at a price. The most critical issues are:
Memory management, which the application must manage for itself, in contrast with languages that provide garbage collection to reclaim allocated memory that is no longer in use
4
From C http://www.codesourcery.com -- Sourcery G++
51
Introduction to bada: A Developer's Guide - (draft preview, July 2010)
Exception handling, where the C++ standard exception mechanism is expensive in terms of memory footprint and processor cycles
Lack of native string and array types
Most runtime failures (crashes) of C and C++ programs are caused by the same few common kinds of programming errors, specifically memory allocation errors and memory access errors, including pointer and array indexing errors. This simple fact is what motivates many of the distinctive features of Java. No pointers, true primitive types for arrays and strings, and automatic garbage collection. However, Java imposes a runtime cost that can be noticeable even on the desktop, and can be a showstopper on mobile; it also forces app developers into a sandbox in which access to native features is denied, reduces flexibility, and creates a barrier between apps and the native platform. On mobile, going native gives apps all the power of the underlying platform. However, the kind of tolerance for runtime failure that seems to have become a habit on the desktop is simply not acceptable on mobile. Mobile users will not accept data loss, calls hanging, or the other frustrations of buggy apps that crash or freeze. To offer the best of both worlds - robust apps that don't crash and a fully capable platform providing native performance - bada imposes some limitations on developers by limiting use of some C++ features. In particular: 1. Platform code in bada uses 2-phase construction (though it is not enforced for classes you define yourself) 2. A simple ownership policy is supported: an app is always responsible for deleting memory it allocates (every call to new must have a symmetrical call to delete), and an app must always delete platform allocated objects returned from a platform method named with a trailing N, for example SearchN(); in all other cases, the platform takes care of deleting the objects it allocates 52
Introduction to bada: A Developer's Guide - (draft preview, July 2010)
3. Native C++ strings are discouraged, the bada platform provides a dedicated string class 4. Native C++ arrays are discouraged, the bada platform provides a dedicated array class 5. Standard C++ exceptions are not supported, instead bada has its own lightweight exception model
4.2.5 Native idioms and types tutorial It's time to get practical again. When you read through bada code in the SDK tutorials and samples, you'll see the native types being used in real world contexts, and of course you'll need to use them in your own code. The following brief tutorials will get you up to speed with the things that bada does differently - and will be a useful reference to come back to as you explore the platform more deeply. You may want to bookmark these pages.
4.2.6 The problem of object construction In C++, like C, memory at runtime is divided between:
Static memory, which is assigned by the compiler and is part of the application binary at runtime
Stack memory, allocated and freed at runtime by the operating system as function activation frames for the running program are created and released
Heap memory, allocated and freed dynamically as requested by a program
Memory leaks are caused when programs allocate heap memory and fail to release it. Because mobile phones typically run for days or weeks or longer without being switched off, memory leaks can seriously compromise the phone's performance. The problem is compounded because (relative to the desktop), phones typically have much less RAM, and (in absolute terms), because of the power and physical size constraints of phones, memory technologies, e.g. Flash file systems, are slow.
53
Introduction to bada: A Developer's Guide - (draft preview, July 2010)
Unfortunately, in C++ the problem of ensuring that memory is not leaked is more complex than it is in C, and requires more than just discipline on the part of programmers (i.e. matching every allocation with a deallocation). In C++, allocating heap memory may be done either explicitly by the programmer with calls to operator new or new[], or implicitly by the compiler as part of C++ object creation.
Unlike C, in which every runtime construct is either static or on the stack or on the heap, the parts of a single C++ object may be allocated in one or more or all of those allocations, depending on how the class has been coded.5 Because a C++ class has only one destructor (which will be the default one generated by the compiler, if the programmer has not explicitly coded a destructor), while it may have many different constructors, destructors must be coded with care. The result of all of which is that naive coding in C++ can very easily result in memory leaks. There are two specific problems that make matters even worse. The first problem is that in C++, when a constructor fails, the class's destructor is not called. The problem of memory leaking is, as we have said, a problem with heap memory. (Static memory is never a problem, because it is allocated at compile time, and stack memory frames are automatically released when the functions with which they are associated return). A (heap allocated) C++ object is created when the new operator is called on a class constructor. The allocated memory must be released with a matching call to delete(), i.e. allocation and deallocation must always be symmetrical if memory is not to leak. delete() invokes the class destructor. Within the destructor, any futher memory allocated by the class should be released with appropriate calls to delete(). When the destructor returns, the final step performed by delete() is to release the memory
that was allocated for the object itself.
5
For an excellent discussion with examples, see Franek, 2004, Chapter 8.
54
Introduction to bada: A Developer's Guide - (draft preview, July 2010)
This is all straightforward enough. The problem arises if the class constructor attempts to allocate memory, for example calling new to create a class member that happens to be an object, and the allocation fails. In this case, the destructor cannot be called to delete the object, because the object pointer will be null (since construction failed), and trying to delete a null pointer will cause an exception. But meanwhile, if any allocations did succeed as part of construction, before the failed allocation occurred, there is no way for either the system of the program to free that memory, because no pointers exist to it. The allocated memory is orphaned. On mobile, low memory conditions should be assumed to occur as a matter of course. Multitasking, web browsing, playing music, recording and viewing images, playing or recording video, and downloading and trying out apps, are all part of the everyday use for a phone, and may occur in any dynamic pattern of usage. Any one may cause a memory usage spike, which if your own app is unlucky enough to encounter it, may cause memory to be unavailable to you. Worse, if any program running on the device is leaking memory, then over time, a low memory condition will become a certainty, and all apps on the device will effectively be compromised by the poorest quality app that the user has chosen to run. Let us assume we have a very simple class: class SimpleClass;
Then we have a more complex class that has objects of the SimpleClass as members. class ComplexClass { public: ComplexClass(void) { p1 = new SimpleClass(); p2 = new SimpleClass(); // Assume an Out-of-memory error occurs here. } ~ComplexClass(void) { delete p1; delete p2; } private:
55
Introduction to bada: A Developer's Guide - (draft preview, July 2010)
SimpleClass* p1; SimpleClass* p2; };
Then we have somewhere some method which instantiates an object of ComplexClass. void AnyClass::SomeMethod() { ComplexClass* pComplexClass = new ComplexClass(); // Calls the constructor, which could throw an exception. }
In doing so the constructor is invoked. But if an exception happens, the destructor is not called the allocated memory cannot be released resulting in a memory leak. Java developers are spared these scenarios, because all dynamic allocated memory is managed by the Java runtime (however, Java developers have plenty of other problems to make their lives hard). In fact, the scenario is not just a C++ problem. One of the most recognisable programming constructs in Objective C, on OSX for example, is two-phase object construction: id anObject = [[Rectangle alloc] init];
If you are familiar with the OSX idiom, or if you have programmed C++ apps on Symbian, then the bada solution should be immediately recognisable. Two-phase construction is just the rule that object creation and memory allocation for its members should be separated:
56
Introduction to bada: A Developer's Guide - (draft preview, July 2010)
class TwoPhaseClass { public: TwoPhaseClass(void) : p1(null), p2(null) {} ~TwoPhaseClass(void) { delete p1; delete p2; } result Construct(void) { p1 = new SimpleClass(); p2 = new SimpleClass(); // Out-of-memory error occurs. } private: SimpleClass* p1; SimpleClass* p2; };
Then we have somewhere some method which instantiates an object of TwoPhaseClass by using twophase construction. void AnyClass::SomeMethod() { TwoPhaseClass* pTwoPhaseClass = new TwoPhaseClass(); result r = pTwoPhaseClass.Construct(); }
In that case, no memory for members is allocated during the object creation. No memory can be leaking. We allocate memory in the Construct() method. If anything goes wrong an exception can be handled by querying the r variable of type result.
57
Introduction to bada: A Developer's Guide - (draft preview, July 2010)
The simple rule is that object should be created in two steps:
Allocate o
Dynamically allocate memory for the new object, this may include any simple value initialisation using the initialisation list syntax
Complete the construction o
This should include creation of all objects that require dynamically allocated memory
The object returned by the first step is not yet complete, and therefore cannot be used; but if memory allocation fails, since no memory has been allocated, there is nothing to clean up. If allocation succeeds, memory will have been allocated for all class members. Where members are simple values then there is no more work to be done, if default values have been set using compile-time values, or at runtime using initialisation list syntax or (simple valued) passed parameters. Where members are themselves objects requiring dynamic allocation, then memory for the member pointers will have been allocated, but not the objects themselves. The second step of object construction should now make any further allocations (and of course should also use two-step construction for those objects where necessary). Used systematically, this is an easy convention to follow, and classes become self-documenting; wherever a Construct() method is present in the class, then two-step construction should be used.
4.2.7 Object ownership responsibilities A further small but important, complication relating to memory allocation and object construction is that sometimes framework methods require the framework to allocate and return a new object to the calling
58
Introduction to bada: A Developer's Guide - (draft preview, July 2010)
app. However, once the object is returned by the framework, and the object is passed into the ownership of the caller, the framework no longer knows when the object is finished with. In this case, the simple rule that allocating and freeing memory should always be done symmetrically, no longer holds. The problem for the app programmer is, then, to know whether or not the app, or the framework, should be responsible for cleaning up a given object. This problem is solved almost trivially in bada by a simple naming convention, and the associated rule: Convention Trailing 'N', for example Sometype SomethingN; Rule The caller is always responsible for deleting objects returned by the framework that are named with a trailing 'N'
To give an example, the interface IRemoteLandmarkStoreListener which is part of the Osp::Locations namespace defines a method OnLandmarksReceivedN(). This method is called when an application queries a remote server about its stored landmarks. If there are landmarks available that match the search criteria they are stored in one of the parameters of the method. This parameter is local to the calling application, hence, the object owner ship changes. The following code should exemplify this. void OnLandmarksReceivedN(RequestId reqId, IList* pResults, int pageNo, int countPerPage, int totalPageCount, int totalCount, result r, const String& errorCode, const String& errorMsg) { if (!IsFailed(r) && pResults) { // Do something with the results stored in pResults… pResults->RemoveAll(true); // You have to explicitly delete the object !!!
59
Introduction to bada: A Developer's Guide - (draft preview, July 2010)
delete pResults; } }
4.2.8 Exception handling Exception handling arrived in C++ not exactly as an afterthought, but a long time after the first release6. Efficiency was an important design goal7 in particular avoiding adding time or space cost to code that doesn't use exceptions. That goal was certainly achieved, but quantifying the cost for code that does use exceptions is more controversial. At least in the unoptimised case, "turning on" standard C++ exception handling can add as much as a 10% code size increase to a system, 8with a measurable runtime performance penalty when exceptions are thrown and handled. For those reasons, as well as for reasons of simplicity, bada does not support native C++ exceptions, but instead implements a simple error handling mechanism. In bada:
All exceptions are caught and returned as a simple type-defined result value
Framework methods that can fail return a result value, and app developers are encouraged to do the same in their own code
Framework methods are provided to get and set the "last result", and get error messages, which assists simplistic propagation of exceptions
6
See Stroustrup green book, 1.0 released 1986, exceptions included 1992.
7
Stroup p.385.
8
Morris. The example is Symbian.
60
Introduction to bada: A Developer's Guide - (draft preview, July 2010)
This provides a minimal framework for propagating exceptions within application code, and a simple mechanism for returning and checking for exceptions. Significantly, it forces responsibility for exception handling onto the app developer. Looked at positively it means that app developers are encouraged to "try to understand and handle problems"9 rather than bouncing them into an exception handling mechanism that, by convention, emphasises terminating programs upon exceptions, rather than gracefully recovering. This is an important point to make, and interestingly, it is one that differentiates mobile from more conventional desktop platforms. As Stroustrup himself explains, an important part of the design philosophy of C++ is to support the development of systems that execute „where no programmer is present,‟10 for example telephone exchanges and ATMs. In those contexts, the recommended response of an application to an exception is termination.11 In a scientific or academic context this approach to correctness is entirely appropriate, and it is indeed the kind of behaviour we have become accustomed to in (say) wordprocessor or spreadsheet applications on the desktop. But if my phone behaves like that, it will go straight back to the shop. The point to make about exceptions on mobile is not simply that they must be handled, but that they must be expected. As we wrote elsewhere,12 low memory, low power, sudden loss of power, loss of connectivity and intermittent connectivity, and even the sudden loss of a file system (for example when removeable media is abruptly removed from a device without first unmounting), are all everyday occurrences on mobile, and apps that respond to such events by promptly terminating will not be popular with users.
9
In the (these days possibly unfashionable) words of Doug McIlroy, quoted by Stroustrup (green), p.384.
10
P107 green
11
7 For example, see Franek p.52: "We therefore suggest immediate program termination in the event of memory allocation failure." As he goes on to say, „of course‟ some helpful message should also be reported to the user „so that the nature of the error can easily be determined if necessary.‟ 12
Morris p75
61
Introduction to bada: A Developer's Guide - (draft preview, July 2010)
On mobile, then, exception handling mechanisms do not just differ from the desktop in the degree to which any overhead they add may be aceptable, they have a genuinely different purpose, and express different design philosophies and user expectations. If formality and correctness, as evident in abrupt termination, are most important on large systems, on mobile the values are opposite, and graceful degradation, or user friendliness, is the primary virtue. Exceptions in practice on bada On bada, errors can be caught and handled, or propagated, by either:
Returning a result using the return type with an enumerated value, enabling a caller to test for a possible exception
Setting a result using an enumerated value, enabling a possible exception to be handled in a decoupled way by a method other than the immediate caller
Jumping to local handler label after testing a returned type for an enumerated value, enabling the exception to be handled immediately and locally, in the method in which the exception is detected
Returning a result value and testing it has the advantages of immediacy and simplicity, where handling by the caller is appropriate; result r = E_SUCCESS; // ... // Case 1: The method returns a result. r = list.Construct(...); if (r != E_SUCCESS) // identical to 'if (IsFailed(r))' { // Process the error condition. }
Querying for the „last result‟ is less direct, and runs the risk that the last caller of Set was not the expected caller, but may be useful where a more decoupled error handling is required within an app: 62
Introduction to bada: A Developer's Guide - (draft preview, July 2010)
// Case 2: The method sets the result in the method body or returns null. pObj= list.GetAt(...); if (GetLastResult() != E_SUCCESS) // or 'if (pObj== null)' { // Process the error condition. }
Jumping to a local label enables the error to be handled immediately and locally, which is the only recommended behaviour in the case that locally allocated resources require clean up due to the exception: // Case 3 result r = E_SUCCESS; r = pList->Construct(..); TryCatch(r == E_SUCCESS, delete pList, "[%s] Some message.", GetErrorMessage(r)); // ... CATCH: SetLastResult(r); Return null;
As the macro name implies in the third case above, this is really just a simple and local, and cheap, way of providing something like the familiar behaviour of try: catch: exception handling. As a final note, all exceptions are logged in the simulator to the Output pane, making it easy to trace errors without any explicit coding being required.
4.2.9 Interfaces C++ allows multiple inheritance, but bada does not. There is nothing very new or surprising in that. The arguments about multiple inheritance, and whether it is a good thing or a bad thing, go all the way back to the dawn of object oriented programming. Allowing multiple inheritance fits with the non63
Introduction to bada: A Developer's Guide - (draft preview, July 2010)
prescriptive philosophy of C++, as well as with its goal of being a true modelling and simulation language. In C++, the ability to model the real world closely is a requirement, and in the real world, objects can belong to multiple categories. Restricting inheritance therefore implies a loss of flexibility, and even inefficiency. The counter arguments - in the C++ context at least - mostly centre on precedence and ambiguity (what if multiple base classes have identically named methods? Which one will get called in the derived class?); efficiency and the „evil diamond‟ pattern12 which can cause code to be duplicated; and complexity (to use it well, programmers must understand it, which means yet another language feature to master). The compromise solution, which bada adopts, like some other mobile platforms, and like the Java language, is to promote the use of interfaces to solve the kinds of design problems that tempt programmers towards multiple inheritance, and allow multiple interface inheritance, but only single inheritance from any concrete base class. Interface classes are very natural to use, and allow simple and expressive design. They also have the advantage of being familiar to developers through the Java language. In bada for example, Frame access, listeners of all kinds, interactions with base applications, collections and collection comparators and enumerators, are just some of the behaviours which can be implemented using interface classes. Java raises the concept of interfaces into a language feature, with the interface keyword. In C++ there is no built-in language convention, and therefore bada introduces its own convention of naming interface classes with a leading I (for example IList, IEnumerator, IEventListener, and so on).
In bada, in common with many other platforms:
An interface class is always abstract i.e. it contains only pure virtual methods, which means that it cannot be instantiated directly (you cannot new an interface class), it can only be inherited from
The deriving class is therefore responsible for implementing the behaviour of interface methods 64
Introduction to bada: A Developer's Guide - (draft preview, July 2010)
And you must implement all of the methods of the interface class
And in bada specifically:
Interface classes are always named ISomething
Derived classes should avoid using the virtual keyword in the inheritance declaration, so for example this:
public class MyClass : public Osp::Ui::IActionEventListener { … };
is preferred to this: public class MyClass : virtual public Osp::Ui::IActionEventListener { //... };
Let's look at a real world example. The following code declares a Form class that displays a waiting animation while waiting to get a first GPS position fix. class WaitingForm : public Form, public IAnimationEventListener, public IActionEventListener, public ILocationListener { public: // ... Constructor/Destructor and other public methods public: // handle softkey press on the form (to stop animation)
65
Introduction to bada: A Developer's Guide - (draft preview, July 2010)
void OnActionPerformed(const Control& source, int actionId); // be informed when the animation has stopped void OnAnimationStopped(const Osp::Ui::Control& source); // manage requested location data virtual void OnProviderStateChanged(LocProviderState newState); virtual void OnLocationUpdated(Location& location); // ... Other methods and properties };
Here, methods are inherited from three different interface classes that enable the Form to respond to softkey presses by the user, the animation event, and location events. With the animation event, the IAnimationEventListener interface class, defined in ../Include/FUiIAnimationEventListener.h, defines the following listener method as a pure virtual (abstract) method: virtual void OnAnimationStopped(const Osp::Ui::Control& source) = 0;
Because the method has no implementation in the base class, we are responsible for providing an implementation, so our WaitingForm source code .cpp file will contain the following code: void WaitingForm::OnAnimationStopped(const Osp::Ui::Control& source) { // ... Implementation goes here }
In this case we don't want to implement any specific behaviour; we have stopped the animation, so the notification is just a confirmation of our request. But in the case of the other events this example listens for, we definitely do want to provide an implementation. For example, suppose we want to stop the animation when a specific softkey is pressed: void WaitingForm::OnActionPerformed(const Control& source, int actionId)
66
Introduction to bada: A Developer's Guide - (draft preview, July 2010)
{ switch(actionId) { case SOFTKEY_ACTION_ID_STOP: mp_Animation->Stop(); mp_Frame->RemoveControl(*this); break; default: break; } }
To summarise, these are the rules for using interface classes in your apps:
Derive the class for which you want to inherit interface behaviour from the relevant interface class or classes -- there is no limit on the number of classes
Use the public, but not the virtual, keyword in the inheritance declaration13
Implement the interface methods in your derived class. Note that you must implement all the methods of the interface class
If the interface class is a listener class, then your derived class becomes a listener itself; and it can be added as a listener to the control that should have focus when the listened-for event occurs
Finally, note that bada provides the dedicated comparison interface class IComparer.
4.2.10 File system and default locations on bada phones As well as a privilege model (see 4.4 below), bada enforces data caging for apps. To implement the policy, bada defines a number of well-known locations in the file system on a per-application basis, each of which can be accessed by an app using a virtual path prefix.
13
At the time of publication, the virtual keyword may cause problems with the compiler; only use it if absolutely necessary.
67
Introduction to bada: A Developer's Guide - (draft preview, July 2010)
Virtual path prefixes on bada phones Path
Description
Permissions
/Home
Home directory for an
r/w
application /Home/Share
Used to share temporary
r/w
data with other applications /Share/[appid]
Used to read temporary
r
data of other applications /Res
Used to read
r
resourcefiles, such as the icon file that was shipped with the app. package. /Share/AppControl/[appcontrol-name]
Used to read data
r
provided by an app controlby its name. /Media/{Images,Sounds,Videos,
Used to read mediadata
Themes,Others}
likeimage, sound, video,
r
theme,and so on. /Storagecard/Media/{Images,Sounds,
Used to read media data
Videos,Themes,Others}
in external memory like
r
image, sound, video, theme,and so on.
The paths are
defined by the Osp::Io namespace as part of the data caging policy which is enforced for bada apps, and ensures that an app's private files cannot be read or written by others apps, and that files stored in readonly locations cannot be over written (even by the owning application).
68
Introduction to bada: A Developer's Guide - (draft preview, July 2010)
These well-known locations are important to developers too. When you create a bada project, your code is organised into several directories under the project's root directory. Some of these locations correspond to permanent locations in the filesystem on bada phones, and to the virtual path prefixes.
4.3 bada basic functionality 4.3.1 Native types The Base namespace in the bada class library defines a variety of essential classes that you will become familiar with as you go deeper into developing your apps for bada. To get you started, this section provides a quick overview, and shows some examples of those classes in use. The native types include classes for:
Basic types, including Object, which is the root class of the bada class library, and wrapper classes for familiar native C++ types including Boolean and Character
Number, from which all numeric types derive, and wrapper classes for a complete set of numeric value types, from Short to LongLong
BufferBase, from which all array types derive, and Buffer and ByteBuffer, which wrap C++ native byte arrays
String, representing a Unicode string
DateTime and TimeSpan which represent dates and date differences
UuId, a Universal Unique Identifier.
69
Introduction to bada: A Developer's Guide - (draft preview, July 2010)
As well as these wrapper classes, bada also includes a complete set of collection classes, which are defined in the Base::Collection namespace.
Finally, the Base namespace also includes useful Comparer classes for many of the types above, and Base::Utility provides utilities for managing URIs, the math library and string functions.
Object, by the way, provides two useful built-in methods:
Equals tests for equality, which by default is interpreted as identity, i.e. true if and only if the two tested objects share the same address. However, it can be overridden to support value equality, in which case it returns the same value as the equality operator. The SDK Sample and Example code includes several examples of overriding and using Equals.
GetHashCode(), which generates a hash value for the current instance (note that the default implementation simply returns the object's address , as a simple way of returning a random but unique number).
Object does not provide additional functionality like zeroing memory when an Object is instantiated.
4.3.2 Using Strings, Characters, and Unicode It should be no surprise that bada is thoroughly Unicode enabled, and takes non-Western alphabet and writing systems seriously. In fact, bada is designed to allow a complete, alternative windowing set to be used, for example to support Samsung's home market in Korea, with a complete look and feel. This is not just a matter of providing good localisation support (which bada includes), it really is complete support for an alternative calligraphic system. The Character class wraps the mchar built-in multibyte character type. In bada, multibyte means, more precisely, UTF8.
70
Introduction to bada: A Developer's Guide - (draft preview, July 2010)
A string in bada is a mutable sequence of 2-byte Unicode characters of type Character, and supports a familiar set of string operations including Append(), Insert(), Remove(), IndexOf(), and so on, as well as equality, comparison, sizing and resizing, and IsEmpty() methods. Strings default to 16 bytes length if no length is specified, and grow at 1.5 times the current length, rounded to the nearest multiple of 4, so for example 16, 24, 36, 54, 80. Note that the size of a string in bytes is not a guide to the length in Characters. bada also includes an L macro which is used to create a literal String object from the specified character sequence, for example L"Hello string!". The L macro generates wide characters and long strings (unicode strings). The String class, or the L macro, should always be used in preference to native C++, C-style strings.
To create a new String with set text, use: String str(L"Set text!");
To create a string from a numeric value, use: String str((int) 100);
The bada platform also provides some useful utility classes for use with strings, specifically: StringTokenizer Makes simple String parsing easy based on default or specified delimiters, and provides GetNextToken() and HasMoreTokens() methods to perform and control token extraction from strings Length getting and String conversion Simple conversions to and from multi-byte mchar and UTF-8 primitive types
71
Introduction to bada: A Developer's Guide - (draft preview, July 2010)
URI handling URI-specific String handling, that allow URIs to be constructed and decomposed easily Text and Unicode Unicode is a universal character encoding that aims to support all living languages (and most dead ones too, not to mention some made-up ones) Fonts by providing codepoints for the individual characters of some 90 alphabets, scripts, ideographic, and hieroglyphic writing systems. The list of supported scripts includes everything from ASCII and Western Latin and no-Latin languages like Greek and Cyrillic, all the way through the Semitic and Indic scripts and other scripts of the Indian sub-continent, to the ideographic character sets of the Far East including Chinese, Japanese, and Korean hangul. Unicode is vast. Like most modern platforms, whether mobile or desktop, bada includes comprehensive Unicode support. Most importantly, bada supports multi-way conversion between the most common encoding schemes (many of which Unicode includes as subsets within its global character space), including: Encoding scheme
Description
UTF-8
The encoding used by XML, and therefore increasingly the standard for web-based textual resources
Latin1
Western alphabets i.e. ISO-8859-2
UCS2 ASCII GSM Encoding and decoding between different schemes can either be done per-String (or per ByteBuffer or MCharBuffer) using a GetBytes() or GetChars() method of the encoded string, or by constructing an Encode or Decoder, which you should do for large blocks of text, or where you have sequential data, for example if you are reading text in from an external source. Natively, all character strings are Unicode by default. 72
Introduction to bada: A Developer's Guide - (draft preview, July 2010)
Note: you can query a device for supported encodings with the method: IList* Encoding::GetAvailableEncodingsN(void) And you can query for the encoding of a text string with: Encoding* Encoding::GetEncodingN(const String &encodingType) Encoding and decoding support is provided by the Osp::Text namespace classes, while Osp::Base classes provide the unerlying support for native Unicode, including the Mchar wide-character data type wchar_t. Note: MChar is supported at compiler level as a native type by the Sourcery G++ GNU Toolchain, which is used for target and Simulator builds in the bada SDK. Be aware that for the sake of efficiency, the bada MChar type is defined with a two-byte size i.e. 16-bits. On most GNU-based platforms, MChar is defined with a four-byte size. Therefore any code that depends on the physical size of an MChar will not behave correctly if ported to bada without change. Of course, programming best practice would say that code should not depend on the phsyical size of a data type. And by the way, bada also provides comprehensive support for localisation generally, and not just for writing language. Support includes date, time, and timezones, number, currency, and other localesensitive information types, including conversions and formatting.
4.3.3 Using Buffers Just as Strings should always be used instead of native C-style null-terminated character arrays (because Strings are inherently Unicode, and size-checking means that they cannot overflow), the Buffer class is preferred to native, C-style arrays. Buffers are container classes that wrap arrays (sequences) of C++ primitive types, for example int, long, double, and char. (Compare with strings -- which are sequences of non-primitive type, Character.) Buffers provide absolute and relative indexing, as well as a mark that stores an index.
73
Introduction to bada: A Developer's Guide - (draft preview, July 2010)
ByteBuffer is a wrapper class for sequences of 8-bit unsigned int
BufferType is provided to enable ready-made template classes of double, float, int, long, longlong, mchar, and short primitive types
Note: a DoubleBuffer is a Bufferdouble object, not to be confused with the "double buffering" buffer management technique!
4.3.4 Collection classes An essential ingredient of any well-designed class library is a good set of collection classes. In keeping with its minimalist design philosophy (it's a language for object-oriented programming, not an objectoriented programming framework), C++ goes no further than providing native types, which are in essence identical to those of the C language that C++ includes as a proper subset. bada supports the STL (Standard Template Library), which is a rich class library, but does not use it in the platform. STL was not designed for mobile (although there are mobile implementations: as used, for example, in Symbian, as well as on Windows CE.) There are other objections to it: it is big, like the kitchen sink, with a maximalist philosophy. It almost certainly imposes a runtime performance penalty; and template-bsed programming, also known as generic programming, which is strictly speaking not at all the same as object-oriented programming, adds another layer of complexity to the programming task. 14 In summary, objections to the STL are:
Complex syntax
Complex design and usage
Code size, lots of copying of objects
Not so well understood, usage of the library has to be learned
14
See the GOF comment, "Dynamic, highly parameterized software is harder to understand than more static software." (Gang of Four 1995:21)
74
Introduction to bada: A Developer's Guide - (draft preview, July 2010)
Bigger binaries (though it can be faster at runtime)
Not optimised for efficiency
Instead, bada focuses on providing a small number of versatile collection types, with highly optimised implementations speciifically designed for mobile. In summary, the bada class library includes the following collection types: HashMap, MultiHashMap, and MapEntry Key-value pair collections hashed on the key value, where MultiHashMap allows duplicate keys (values of duplicate keys must be different), and where MapEntry is a key-value pair ArrayList and LinkedList Index-addressed and sequentially addressed lists Stack and Queue LIFO and FIFO collections, respectively
For each collection type, a templated type is available, e.g. StackT, QueueT, HashMapT, etc. As well as the concrete and template classes, bada provides interface classes that allow collections to be manipulated: ICollection Defines the collection size, enumerator, and synchronnisation method IEnumerator, IMapEnumerator, IBidirectionalEnumerator Enable iteration over Collection and Map types IList Indexable list
75
Introduction to bada: A Developer's Guide - (draft preview, July 2010)
IComparer Enables comparison of two individual objects IHashCodeProvider A hash map Again, exactly as with the concrete collection classes, a templated version of each of the interface classes is provided for use with the templated collection classes: for example ICollectionT representing a templated collection, IListT, IMapT, and so on. Here is the difference between the object based classes and the template based classes:
Object based collections derive from ICollection, and store objects that derive from Object
Template-based collections derive from ICollectionTType, and should typically be used to store C++ primitive types
Note: object-based collections don't collect copies of objects (for obvious reasons of efficiency), instead they collect pointers. So any object you want to put into a collection class must be allocated using operator new (or an overload). Otherwise, if your collection stores a pointer to an automatic variable, its lifetime is unpredictable, and it likely will not exist when the collection comes to use it. Your app will crash, unpredictably.
4.3.5 Using dates and times Dates and times and calculations from dates and times occur so frequently in almost any kind of application, that having convenience classes to make using them easy is essential on any platform. The DateTime class in bada hides all the complexity of creating and manipulating dates and times. A DateTime represents a value to the nearest second between 12:00:00 a.m. (midnight) on January 1, 1 A.D, and 11:59:59 a.m. (one second before midnight) on December 31, 9999 A.D. In other words, a 76
Introduction to bada: A Developer's Guide - (draft preview, July 2010)
DateTime is a single, specified, instant. Since a DateTime is an instant, there is no meaningful concept of differencing (adding, subtracting) DateTime values, but there are meaningful concepts of comparison. In contrast, a TimeSpan is a time period i.e. duration, internally represented in ticks (milliseconds). Durations do support meaningful concepts of differencing, as well as comparison. A DateTime can also be added to (or subtracted from) using built-in add and subtract methods, for example: dt.AddYears(10); dt.AddDays(-3);
More complex manipulation of dates and times typically involves using DateTime objects and TimeSpans: TimeSpan ts(1, 1, 1); // 1 day, 1 hour, 1 second dt.Add( ts ); dt.Subtract( ts );
A DateTime and a TimeSpan can be added or subtracted
A TimeSpan and a TimeSpan can be added or subtracted
The parts of a DateTime can be extracted, and a DateTime can be queried with IsLeapYear()
A DateTime can be added to or subtracted from using the built-in methods AddYears(), AddDays(), and so on
A TimeSpan can be negated, converted into and between time units, hashed, compared, etc
A DateTime can be converted from, or to, seconds
77
Introduction to bada: A Developer's Guide - (draft preview, July 2010)
4.3.6 Using numbers In bada, both wrapper and comparison classes are defined for each of the C++ primitive numeric types of short, char (8-bit integer), int (32-bit integer), double, long, longlong, and float. This makes number comparisons and number-to-string and string-to-number conversions, as well as hashing, trivial. It also adds robustness to the platform (and to your apps) by ensuring that overflows (whether accidental or deliberate) are impossible when numeric classes are used for number handling instead of primitive numeric types. App developers are encouraged to use the numeric types when handling numeric data, and not to rely on primitive C++ types.
4.4 Security and the privilege model in bada All platforms need to protect end-users against malicious (or just badly designed) software that might disrupt the device; corrupt, steal, or destroy private data; or spoof users or the system into performing billable actions that incur unwanted costs, for example, making premium-rate voice or expensive data calls. In some respects, mobile phones have an advantage over desktop systems:
Because they are ROM-based, all system software and data can be restored by rebooting
Their network connection model ensures that they are permanently behind an operator firewall
Their intermittent and mobile connection model makes them continuously moving IP address targets
Both of the above, together with their (relatively) low-bandwidth makes them poor targets for bot networks and other infections
Shortlink connectivity typically requires user acceptance. Bluetooth attacks are mostly mythical.
78
Introduction to bada: A Developer's Guide - (draft preview, July 2010)
At the same time, phones are potentially an attractive target to malware because they are a rich source of personal data, and the pay-to-connect model theoretically creates opportunities for rogue software to exploit. In practice, viruses of the kind that plague desktop systems are almost unknown on phones, partly for the reasons mentioned, partly also because phones require greater programming skills and partly because mobile platforms have designed-in security. For mobile app developers, like it or not, and regardless of platform, security considerations will always be present, and will always create overhead in term of effort. In this respect, bada is no different from other mobile platforms. All impose security limitations of some kind. However, unlike sandboxed systems (for example mobile Java, Windows Mobile .NET, Android), bada offers native API access for apps – and therefore layers a security model on top of its APIs.
Privileges in bada In bada, sensitive APIs are protected by privileges. Privileges have two dimensions: 1. A privilege group is a category that typically applies to related methods of a class or namespace. When you are granted access to the group, you have access to all methods requiring that privilege 2. Every privilege group belongs to one of two privilege levels – NORMAL or SYSTEM The goal of the privilege model in bada is to protect app users against malicious code, and to protect bada services against abuse. Because bada includes network-based, service-centric features in its API set, there is clearly scope for those with malicious intent to attempt to subvert or break the services. Because those services potentially hold private user data, protecting them is essential. Not all bada APIs are protected, and in fact the majority require no privileges. To access privileged APIs, you must have the required privilege level, and your app must declare the required privilege group in its manifest file.
79
Introduction to bada: A Developer's Guide - (draft preview, July 2010)
Declaring privileges is easy. Privileges are metadata, not code: you simply add the required privilege group while defining your app profile on the developer.bada.com site (as explained in Chapter 2). Privilege groups map quite closely to namespaces (currently there are more than thirty privilege groups, compared to twenty-something top-level namespaces, and thirty-something namespaces in total if you include nested namespaces), and so in general, adding a new namespace implies checking to see whether privileges are required. The unusual dimension to privileges is the privilege level, which interprets access to privileges in terms of the app developer, instead of the app itself. Access to privileges is therefore controlled based on developer status, defined as membership level in the bada ecosystem – for which currently there are only two values, ordinary members and strategic partners. The unfortunate side-effect of this in current versions of bada, is that access to privileges is severely restricted. Almost half of the privilege groups, and in many ways the most interesting ones, are placed out of the reach of ordinary third-party developers and are available only to strategic partners. This is a reflection of the newness of the platform as much as anything, and will change. Keep an eye on developer.bada.com for news.
In practice Privilege level restrictions aside, using privileges in your app is straightforward.
Where no privilege group is required, which is the case for most of the bada class library, no special declarations or other action is required
All developers automatically have NORMAL privileges, which means that their apps can use any APIs that are marked as requiring NORMAL privileges. Simply declare the required group in your manifest file
If you only have NORMAL privilege and you want to access APIs requiring SYSTEM level privilege, the only solution is to apply to become a bada partner developer. Realistically, this option is bound to be restricted compared to the number of developers who would like partner access.
80
Introduction to bada: A Developer's Guide - (draft preview, July 2010)
You will notice that we‟ve listed any privilege groups required for each namespace in the namespace descriptions in Chapter 6. For more details of privileges at the API level, please see the SDK documentation.
81
Introduction to bada: A Developer's Guide - (draft preview, July 2010)
Part 3
0
Introduction to bada: A Developer's Guide - (draft preview, July 2010)
Chapter 5: Exploring bada server In this chapter, we will explore some of features provided by the bada server. As you may know, the bada platform is not limited to providing features only on devices, but also server associated features. These are key and unique features compared with other mobile platforms on the market. The bada platform provides its devices with a remote server infrastructure as a means of easy integrating web services. And it provides a full mobile application eco-system to its developers. This chapter is dedicated to these service-centric features. This chapter is divided into three sections: the first section gives overview of all services; the second section gives the big picture of communication between devices and the server; the last section is a practical section with some examples of using these services. Through this chapter, you will learn how to utilize these features in your own applications.
5.1 What are the services? When you downloaded the bada SDK, you may come cross some namespaces such as Osp::Commerce::Store, Osp::Locations::Services, Osp::Social::Services and Osp::Content. Actually they are referring to services provided via the bada server. There are some other namespaces which also contain features provided by the bada server, such as Osp::Security. These are the services we will discuss in this chapter. Let‟s look into each of these services.
1
Introduction to bada: A Developer's Guide - (draft preview, July 2010)
5.1.1 Location Service The location service allows developers to utilize features such as displaying a map, geo-coding an address, finding points of interest (POI) and searching routes from one place to another. The bada platform provides developers with easy to use APIs to integrate different location service providers.1 There are also some other nice features available from the bada location service that are social related. It is possible to request location data in the form of GPS measurable parameters. This positioning data can be for yourself or for fellow individuals who have allowed their position to be monitored by you, via the bada server. In addition, it is possible to finely tune this data to allow for location reporting when subject either enters or leaves a specified region. Users can store their personal landmarks on the server. We will explain these features in detail on chapter 5.3. Note: during the time of writing of this book only deCarta is integrated as map provider in the bada platform.
5.1.2 Social Service Social networking has become a popular feature of current mobile applications. Without exception, the bada platform also provides fully functioning social services including profile management, buddy management, privacy management, messaging and Social Network Service (SNS) Gateway. The Social service allows applications to create, share and manage information from bada user profiles. Applications can also manage buddies between bada users. The relationships between buddies are stored on the server. bada apps that use the buddy service can make use of these relationships.
1
For latest information, please check the latest statues from developer.bada.com.
2
Introduction to bada: A Developer's Guide - (draft preview, July 2010)
Profiles Profiles can contain data such as names, gender and marital status. More data can be added, but may be subject access controls for privacy. The owner of a private profile must grant permission for another to view it. Custom profiles can be created to hold specific data. Communication and collaboration can exist between profile „associates‟ through the use of messaging exchange services. Buddy lists A buddy describes the confirmed relationship between users of the bada server. The relationship is initiated by a request and is only established following acceptance of the recipient. A bada app, for instance, can fully manage and categorize the buddies of an individual based on the closeness of the relationship. It is also possible to communicate your buddies via the bada messaging server using messaging APIs. Finally you can integrate existing 3rd party social services into your bada applications utilizing the unique feature of the bada SNS gateway.
5.1.3 Content Service When we mention the word „content‟ here, we are referring to the media content such as images, audio and videos. There are two types of contents described in Osp::Content namespace, content on device side and content on server side. As this chapter is dedicated to bada service-centric features, so we will only explain the server side contents. Basically bada content service allows developers to create, read, update and delete (CRUD) contents on the server. It is also possible to search contents and set the access level on the server remotely. By using the content service, developers can not only manage content itself, but also manipulate the metadata of contents, such as thumbnail information, geo-tag information, and basic file information.
3
Introduction to bada: A Developer's Guide - (draft preview, July 2010)
Note: to use the Content service, you have to sign up the Amazon Simple Storage Service (Amazon S3). Your data will be stored on the Amazon server instead of the Samsung server.
5.1.4 Commerce Service The Commerce service allows end users to browse and purchase items through bada applications. Items can be everything that can be purchased out of a bada app. Developers can set up their own online store, manage items on the store and track purchase statistics. As a developer, you can utilize this service to create an application with functionalities such as retrieving selling item information and purchasing them in your application. Purchases are made simple as buyers are required to pre-register their credit cards when they sign up with the SamsungApps site. So there is no need for developers to handling any credit card information from buyers. The SamsungApps store maintains the buyer‟s credit card details and associates it with a buyer ID. Purchases are then a simple matter of entering the buyers ID and a password. Note: to sell your items, you always need to register at SamsungApps seller office at seller.samsungapps.com
5.1.5 Single Sign On bada services are not limited to the ones mentioned above. There are some other services which are located in other namespaces. Such as single sign on (SSO) application control from the Osp::App::AppControl namespace, and the weather sensor service from the Osp::Uix namespace. The bada server can manage identities by associating a single login and password with all of its services. This single sign on (SSO) method utilizes an authentication token provided by the server to validate and sign into all the services that a user may have on the bada server.
4
Introduction to bada: A Developer's Guide - (draft preview, July 2010)
5.2 How it works For most mobile application developers, the biggest problem for them is to choose the development language. It is even more difficult when development involves communications between web components, such as map providers (Google, NavTeq), social service providers (Facebook, Twitter etc) or content server (Flickr, Picasa). So how does the bada platform handle these types of communications?
5.2.1 Device-to-server interaction – bada APIs When you develop applications to access server associated services, you do not need to consider which language to use, whether it is Javascript, Python or HTML. On bada platform, all communications between devices and servers are in native or wrapped C++ APIs. Let‟s take an example of verifying your Twitter account with Twitter server using Open authentication method. Using Javascript and oauth Javascript plug-in (http://oauth.googlecode.com/svn/code/javascript/), you can write following lines of code: var url = "..."; var accessor = { token: "...", tokenSecret: "...", consumerKey : "...", consumerSecret: "..." }; var message = { action: url, method: "GET", parameters: {...} }; OAuth.completeRequest(message, accessor); OAuth.SignatureMethod.sign(message, accessor);
5
Introduction to bada: A Developer's Guide - (draft preview, July 2010)
url = url + '?' + OAuth.formEncode(message.parameters); // send request to 'url'
But on the bada platform, all you need to program is: Osp::Social::Services::SnsAuthenticator* pAuthenticator; pAuthenticator->Authenticate(L“twitter”, L”YourConsumerKey”,L”consumerSecretKey”);
From the above example, you can grab a glimpse of bada C++ API for server communication. For services such as Social, Remote Landmark Store and Content, developers are directly communicating with the bada server. For some other services such as SNS Gateway and Location service, the bada backend server is acting as a mediator between the device and 3rd party servers.
5.2.2 bada Server and 3rd party server interaction with open APIs On the bada platform, the bada server uses set of open APIs to communicate with 3rd party servers. Through open APIs, the bada server can make seamless connections to 3rd party servers to both retrieve and manage contents. Developers can use simplified bada native APIs to interrogate popular search engines and handle buddy lists for popular SNS sites such as Twitter, Facebook and MySpace. The bada server does the hard work of handling the specifics of connecting to each SNS service. Being scaleable, scope exists to add further services in the future. Note: currently the SNS Gateway is mainly used for retrieve the buddy information from the 3rd party social network provider. For other functions, such as follow and un-follow from Twitter, you have to use the HTTP connection and XML parser provided by bada.
Figure 5.1 illustrates the big picture of bada server associated services. All application developers need to know is the bada native C++ APIs.
6
Introduction to bada: A Developer's Guide - (draft preview, July 2010)
Figure 5.1: bada Server
Now let‟s look at how open APIs work on the bada server. Normally client applications use Representational State Transfer (REST) APIs to communicate with web servers, which means that calls are made over HTTP (GET, POST etc.) to the server.2 As we mentioned in the previous section, different web server implement with different sets of RESTful APIs. It is very difficult for a client application to interoperate with different servers. By using the bada server as a mediator, you are not required to use any specific RESTful APIs, instead you use native C++ APIs. The bada server takes care of making calls to specific 3rd party servers. Through 3rd party map server - deCarta, bada can provide your applications rich mapping services that include route calculation, geo-coding and directory service.
With the original design of HTTP protocol, it is stateless which means server does not keep any information about client. The disadvantage for this design is it may increase the repetitive data and decrease the network performance. Adding the caches on server side could make HTTP protocol stateful.
7
Introduction to bada: A Developer's Guide - (draft preview, July 2010)
5.3 Services in detail You should now have a general understanding of bada server associated services. It is time to understand how to use these features. Let‟s start with location services.
5.3.1 Location as a service A key distinction between the mobile application and the convention application is the location feature. Majority of modern smartphones are equipped with GPS transceivers. Devices are aware of location changes all the time. Mobile developers could utilize the real time location data to make function-rich applications, such as FourSquare, Loopt. The bada platform provides several types of Location based service discussed at the beginning of this chapter. So now we will examine each of them, and give you a deeper view. Before we start, let‟s think of a user case: imagine you want to make an application to give directions to a user‟s nearest Starbucks based on their current location, and show it on a map. Simple, right? To search a particular landmark, you can use the directory services or remote landmark store provided by bada. In this chapter we show how to use the directory service. As mentioned in the previous chapter, all development on bada is related to: service provider (e.g. IDirectoryServiceProvider interface), listener (e.g. IDirectoryServiceListener interface) and handler (e.g. OnDirectoryRequestReceivedN method). Step 1: Instantiate DirectoryService provider object String providerName = L”deCarta”; String extraInfo = L”ClientName=usernmae;ClientPassword=pwd; HostUrl=http://developer.kr.dz.decarta.com:80/openls”; IDirectoryServiceProvider *pProvider = dynamic_cast(ProviderManager::ConnectToServiceProviderN( providerName, LOC_SVC_PROVIDER_TYPE_DIRECTORY, extraInfo) );
8
Introduction to bada: A Developer's Guide - (draft preview, July 2010)
The above code is self explanatory. To instantiate the provider object, you have to specify the client name, client password and the host URL of the map provider. But remember to request your own user account (client name) and password from deCarta developer site for using deCarta as your service provider. There is a Getting Start guide for the bada platform available from the deCarta developer zone. Also you can find the Features, Testing and Going Commercial information from dedicated bada sections on the deCarta developer zone website. Step 2: Get preferences of DirectoryService provider object, and set preference properties DirectoryServicePreferences *pPreferences = null; pPreferences = static_cast( pProvider->GetServicePreferencesN(false) ); //if set to true, using default values from provider pPreferences->SetSortBy(&String(L”Name”)); pPreferences->SetSortOrder(Osp::Base::SORT_ORDER_ASCENDING);
After getting the DirectoryService object, you can set its preference by using above code snippet. For example, you can set the sorting criteria by using a name. And you can also set the sorting order to be ascending mode or descending mode. In this example, we use ascending mode. Step 3: Get directory filter and add search keywords DirectoryFilter is the criteria for searching. From above example code, we use GetFilterN() to get the criteria object from the provider object, and then we can set the criteria to use specific keywords, such as Starbucks in our example. DirectoryFilter *pFilter = null; pFilter = pProvider->GetFilterN(); pFilter->AddFilter(DirectoryFilter::SEARCH_FILTER_KEYWORD, L”Starbucks”);
Note: deCarta POI search also matches substrings. A search for “Star” would find “Star Donuts”, “Nightstar restaurant”, and any POI containing “star” in its name. 9
Introduction to bada: A Developer's Guide - (draft preview, July 2010)
Step 4: Implement listener for handling results class MyDirectoryServiceListener; //results returned as a list of landmarks MyDirectoryServiceListener::OnDirectoryRequestResultReceivedN(RequestId requestId, const IDirectoryServiceProvider& provider, IList* pLandmarks, result r, const String& errorCode, const String& errorMsg) { switch(r) { //handle different situation here if(pLandmarks) { IEnumerator* pEnumerator = pLandmarks->GetEnumeratorN(); While(!IsFailed(pEnumerator->MoveNext()) { const Landmark* item = static_cast( pEnumerator->GetCurrent()); String name = item->GetName(); AppLog(“Landmark Retrieved(%s)”, name.GetPointer()); } } delete pEnumerator; pLandmarks->RemoveAll(true); delete pLandmarks; } }
To be able to get the result of a directory request, you have to also implement the callback function OnDirectoryRequestResultReceivedN() which is a virtual method. The above code snippet demonstrates a common implementation of this method. Because the results are returned as a list of landmarks, you need to iterate the pLandmarks to display the directory information.
10
Introduction to bada: A Developer's Guide - (draft preview, July 2010)
Step 5: Define the search area To define search area, use the class called GeographicArea under the Osp::Location namespace. This class is an abstract class and provides common methods to different shapes of geographic area. In our example, we will use the CircleGeographicArea. To get updated location information, we have to first implement the ILocationListener interface class to receive the location information. Class MyListener : public ILocationListener { public: MyListener(); ~MyListener(); virtual void OnLocationUpdated(Location& location); virtual void OnProviderStateChanged(LocProviderState newState){}; }; void MyListener::OnLocationUpdated(Location& location) { LocationProvider* pLocationProvider; const QualifiedCoordinates* pCoordinate = location.GetQualifiedCoordinates(); if(pCoordinate != null) { CircleGeographicaArea* pArea; //We declare it here as local for better understanding. In your project it is advisable to have it as a member variable. pArea = new CircleGeographicArea(); pArea->Set(*pCoordinate, 2000); } // Stop the location updating pLocationProvider->CancelLocationUpdates(); };
11
Introduction to bada: A Developer's Guide - (draft preview, July 2010)
Now what we need to do is to get our LocationProvider object and update the current location. LocationProvider* pLocationProvider; pLocationProvider = new LocationProvider(); MyListener* pLocationListener = new MyListener(); result r = pLocationProvider->Construct(LOC_METHOD_HYBRID); if(!(IsFailed(r))) { int interval = 5; pLocationProvider->RequestLocationUpdates(*pLocationListener, interval, false); }
What the above code does is to instantiate a LocationProvider object using a hybrid approach, and request the updated location with the interval value equal to 5 seconds. Once the location is updated, it will invoke the OnLocationUpdated() method which you implemented in MyListener class. Step 6: Send search request RequestId reqId; MyDirectorServiceListener *pListener; //You have to implement by yourself per step 5 CircleGeographicArea *pArea; Coordinates center; //Normally it is your current coordinates from GPS pArea = new CircleGeographicArea(); pArea->Set(center, 2000); pFilter->AddFilter(DirectoryFilter::SEARCH_FILTER_KEYWORD, L”Starbucks”); result r = pProvider->Search(*pFilter, *pArea, pPreferences, *pListener, reqId);
To send the search request, you can use Search() method defined in DirectoryServiceProvider class declared at Step 1. You have to pass five parameters when calling this method: the preference of received search results pPerferences declared at Step 2, the search criteria pFilter that you just set at Step 3, the listener pListener for receiving replies from 12
Introduction to bada: A Developer's Guide - (draft preview, July 2010)
the server that defined at Step 4, the request ID reqId that identifies this search request and the search area pArea. The parameter pArea is the given area where you will search for landmarks. In this example, we are using a circle type of area that has the current location as the centre coordinates. The centre coordinate center is updated constantly within a given interval. The implementation is described at Step 5. Now you learned how to implement necessary classes and how to send the search request. Having found the preferred Starbucks location, you probably would also like to know how to get there. In this case, you will need the route service to help you find the route. Now let‟s see how we can find a route by using the bada Route Service. Again, we will break down the implementation into individual steps. Some steps are very similar to the directory service we described above. For example, the first two steps are almost exactly the same except you have to change the service name to LOC_SVC_PROVIDER_TYPE_ROUTE in step 1. And in step 2, you will set the preference dedicated for route service. String providerName = L”deCarta”; String extraInfo = L”ClientName=username;ClientPassword=pwd; HostUrl=http://developer.kr.dz.decarta.com:80/openls”; IRouteServiceProvider *pProvider = dynamic_cast( ProviderManager::ConnectToServiceProviderN(providerName, LOC_SVC_PROVIDER_TYPE_ROUTE, extraInfo) );
You can just use the default preference from deCarta using following lines of code. RouteServicePreferences *pPreferences = null; pPreferences = static_cast(pProvider->GetServicePreferencesN(true)); //if set to false if you want to use your own settings
13
Introduction to bada: A Developer's Guide - (draft preview, July 2010)
Then next step is to request the route from your current location (coordinate) to the location of Starbucks that you received from ILocationListener class in Step 5. //pLandmark is the variable defined in Step4 Coordinates *pPerferredStarbucksLocation = pLandmark->GetQualifiedCoordinates(); //location is the parameter used in Step 5 Coordinates *pCurrentLocation = location.GetQualifiedCoordinates(); ArrayList* pWaypoints = null; pWayPonints = new ArrayList(); pWaypoints->Construct(2); pWaypoints->InsertAt(*pCurrentLocation, 0); pWaypoints->InsertAy(*pPerferredStarbucksLocation, 1); pProvider->GetRoute(*pWaypoints, pPreferences, *pListener, reqId);
To receive the route results, you have to implement the IRouteServiceListener interface class and overwrite the pure virtual method defined in this class. Class MyListener : public IRouteServiceListener { public: MyListener(); ~MyListener(); virtual void OnRouteReceived(RequestId reqId, const IRouteServiceProvider& pProvider, IList* pRoute, result r, const String& errorCode, const String& errorMsg); }; void OnRouteReceived(RequestId reqId, const IRouteServiceProvider& pProvider, IList* pRoute, result r, const String& errorCode, const String& errorMsg) { //For a detailed implementation, you can refer to the bada example code provided with bada SDK };
14
Introduction to bada: A Developer's Guide - (draft preview, July 2010)
Note: the results returned from OnRouteReceived() method is a list of calculated routes. If the calculation of alternative routes is not available, only one route is included in the list. Once you find the route to your Starbucks, you would like to invite your friends to meet there. Let‟s see what kind of features we can get from the social service.
5.3.2 Social network service – all connected Mobile users connect with each other all the time, update and share their status information, exchanging messages. At the beginning of this chapter, we mentioned five different services under Osp::Social namespace. Now we will explain more details in buddy service, profile management and privacy management. We have our location sample from the location service. Let‟s take the same user case from last section and make it even more sociable. Assume we want to share our current locations with another bada user, how could we make this happened? Before you share or request any information from your friends, there are several things you have to do.
Action 1: Make User A’s profile searchable Figure 5.2 shows the sequence diagram of setting profile exposure level.
15
Introduction to bada: A Developer's Guide - (draft preview, July 2010)
Figure 5.2 UML sequence diagram – User A There are two classes used in this use case: PrivacyManager and MyListener. Let‟s start from User A‟s PrivacyManager class that allows user to send privacy control related event to the bada server, such as set profile exposure level (PEL). The code snippet below demonstrates how to use PrivacyManager class to set User A‟s profile searchable, and how to assign the listener object to this class. MyListener* pMyListener pMyListener = new MyListener(); pMyListener->Consturct(); pMyPrivacyManager = new PrivacyManager(); pMyPrivacyManager->Construct(*pMyListener); //Register/assign the listener to PrivacyManager RequestId reqId; pMyPrivacyManager->SetProfileExposureLevel(PROFILE_SEARCHABLE, reqId);
16
Introduction to bada: A Developer's Guide - (draft preview, July 2010)
Another class from User A side is the MyListener class, which is the essential class for handling the asynchronous event sent by the bada server. The following code snippet shows you how to implement MyListener class. // implementation of MyListener class class MyListener : public IPrivacyManagerListener { }; void MyListener::OnProfileExplosureLevelUpdated(RequestsId reqId, result r, const String &errorCode, const String &errorMsg) { //Your implementations for this virtual method }
As you can see, MyListener class is derived from the interface classes called IPrivacyManagerListener. It defines virtual methods started with „On‟ postfix. You have to implement them by yourself. From the sequence diagram, the On-methods mainly display or notify the user when results received from the bada server. From now, User A‟s profile is searchable. Other bada users can search her or request her as their buddy.
Action 2: User B sends buddy request to User A Next we will take a look at the User B‟s side. User B is the person trying to find her friend‟s (User A) profile and request to become buddies. Again, we will first start from the sequence diagram of User B.
17
Introduction to bada: A Developer's Guide - (draft preview, July 2010)
Figure 5.3 UML Sequence diagram - User B Figure 5.3 illustrates the sequence for User B to search a profile and add as a buddy upon on a successful search. Compared with Figure 5.2, there are two more types of class involved called ProfileService and BuddyService. ProfileService class accesses profiles on the bada server and sends different types of request to the server. And BuddyService class sends the buddy request to the bada Server. User B‟s MyListener class has to implement two virtual method called OnProfileResultsReceivedN() which will handle the results returned by the server and OnBuddyRequestSent() which will be invoked when a response of the buddy request received from the server. Let‟s take a look how to implement the class in this case.
18
Introduction to bada: A Developer's Guide - (draft preview, July 2010)
// implementation of MyListener class class MyListener : public IProfileServiceListener, public IBuddyServiceListener {}; void MyListener::OnProfileSearchResultsReceivedN(RequestsId reqId, IList *pRequestList, int PageNo, int countPerPage, int totalPageCount, int totalCount, result r, const String &errorCode, const String &errorMsg) { //Your implementations } //invoked when server sends response void MyListener::OnBuddyRequestSent(RequestId reqId, result r, const String &errorCode, const String &errorMsg) { //Your implementation }
Action 3: Response to buddy request sent by user B There are several steps User A has to consider when she or he receives the User B‟s request from bada server. User A can reject, ignore or accept the request. Figure 5.4 shows how User A‟s receives the buddy requests and responses them.
19
Introduction to bada: A Developer's Guide - (draft preview, July 2010)
Figure 5.4 UML Sequence chart - Response Buddy Requests This time, User A‟s listener has inherited one more interface classes called IBuddyServiceListener. The IBuddyServiceListener allows the users to receive the buddy service related results from the bada Server. The code snippet below demonstrates the virtual methods MyListener class has to implement. // implementation of MyListener class class MyListener : public IProfileServiceListener, public IBuddyServiceListener {}; void MyListener::OnReceivedBuddyRequestsReceivedN(RequestsId reqId, IList *pRequestList, int PageNo, int countPerPage, int totalPageCount, int totalCount, result r, const String &errorCode, const String &errorMsg) { //Your implementations
20
Introduction to bada: A Developer's Guide - (draft preview, July 2010)
} void MyListener::OnBuddyResponseSent(RequestsId reqId, result r, const String &errorCode, const String &errorMsg) { //Your implementations for this virtual method }
The OnReceivedBuddyRequestsReceivedN() callback function is invoked when User A has some buddy requested received from the bada Server. And OnBuddyResponseSent() callback function is invoked when User A sends the reponse to a particular buddy request. Compare with Figure 5.2, User A has one more class called BuddyService this time. The BuddyService class is defined by the bada application framework. It directly handles the user interactions such as GetReceivedBuddyRequests() and RespondToBuddyRequest(). The following code snippet shows how to use this class. BuddyService* pMyBuddyService; pMyBuddyService = new BuddyService(); pMyBuddyService->Construct(*pMyListener); pMyBuddyService->GetReceivedBuddyRequests(reqId, 1, 20); pMyBuddyService->RespondToBuddyRequest(*pRequest, RESPONSE_ACCEPT, reqId);
User A can also get the details of the request using ProfileService::GetProfile() by passing the user Id in the returned RecievedBuddyRequest instance. Action 4: Sharing location information So far we have learned how to set the profile exposure level, how to send the buddy request, and how to handle the asynchronous event from server using listeners, such as when receiving the results of the buddy request or the profile search request. The final step is to share the location information.
21
Introduction to bada: A Developer's Guide - (draft preview, July 2010)
The bada server allows users to share personal data. The user can set their personal information to be sharable, for example location information using PrivacyManager. In our case, from User A‟s side, the application has to implement the following code: User A has to get her/his location by using a new class called LocationProvider, it will constantly update the location data from GPS transceiver. Then User A has to report the location data to the bada server by using another class called RemoteLocationProvider. //Set your location information can be accessed by your buddy myPrivacyManager->SetUserInfoPrivacy(INFO_LOCATION, ACCESS_BUDDY,reqId); //Create and initialize location provider pLocationProvider->RequestLocationUpdates(); //Report location information to bada server RemoteLocationProvider::StartLocationReport();
Note: in bada, there are two type of location information. One is the local location information which indicates the current location of the device. Another is the remote location information that is stored on the bada server. It is a record of multiple local locations.
Once User A sets her/his location information sharable and start to reports to bada server, User B can now request to receive the updates of User A‟s location because they are buddies. User B‟s side implementation looks like: //Add User A to target list ArrayList targetInfoList; TargetInfo targetInfo(userAId); TargetInforList.Add(targetInfo); //Request last known location list pRemoteLocationProvider = new RemoteLocationProvider(); pRemoteLocationProvider->RequestLastKnownLocationList(…,targetInfoList, …);
22
Introduction to bada: A Developer's Guide - (draft preview, July 2010)
The sequence chart of location sharing is shown in Figure 5.5. Note that there are multiple instances of MyListener and RemoteLocationProvider class which indicate both User A and User B have their own instances of these two classes.
Figure 5.5 UML sequence chart - share location
5.3.3 Content Service – content is king As we described at the beginning of this chapter, content management on bada is divided into two categories: local content management and remote content management. In this section, we explain how to use the Remote content manager to upload and create the content on the server.
23
Introduction to bada: A Developer's Guide - (draft preview, July 2010)
Step 1: Implement the sign in form To be able to use the content service, the user has to sign in on the bada server with a valid bada account. This requires your application has to have a sign in form before they use the content service. This step can be very easy using the sign in application control. AppControl* pAppControl = AppManager::FindAppControlN(APPCONTROL_SIGNIN, OPERATION_SIGNIN); if(pAppControl) { pAppControl->Start(null, pListener); delete pAppControl; }
This code will automatically generate the sign in or sign up form for you. Once the user signs in, he or she can use the content service. Note: the Sign in process is necessary for some of the bada services like Social service, Location services and the content management service. Step 2: Transfer the content to the server After a successful sign in, the user is ready to transfer content to the server. To implement this function, you have to use the ContentTransfer class provided by bada. First we will explain how to implement the IContentTransferListener interface that you will need for check the results from the server. class MyListener : public Osp::Content::IContentTransferListener { public: MyListener(); ~MyListener(); virtual void OnContentDownloadCompleted(RequestId reqId, ContentId contenteId, result r, const String &errorCode, const String &errorMsg);
24
Introduction to bada: A Developer's Guide - (draft preview, July 2010)
virtual void OnContentDownloadToBufferCompleted(RequestId reqId, ByteBuffer *pBuf, result r, const String &errorCode, const String &errorMsg); virtual void OnContentTransferCanceled(RequestId reqId, result r, const String &errorCode, const String &errorMsg); virtual void OnContentTransferProgress(RequestId reqId, int totalTransferredSize); virtual void OnContentUploadCompleted(RequestId reqId, result r, const String &errorCode, const String &errorMsg); virtual void OnContentDescriptorReceived(RequestId reqId, const DownloadDescriptor &descriptor); };
Once the server receives the completed content, it will invoke OnContentUploadCompleted() method to inform the end user results. You can also check the uploading progress by implementing OnContentTransferProgress() method. The following code snippet is the sample implementation of OnContentUploadCompleted() method. void MyListener::OnContentUploadCompleted(RequestId reqId, result r, const String &errorCode, const String &errorMsg) { if(IsFailed(r)) { AppLog(“Content Upload failed! Reasone (%s)”, errorMsg.GetPointer()); } }
To upload the content, you can just simply call Upload() method from ContentTransfer class. pContentTransfer = new ContentTransfer(); pContentTransfer->Construct(myListener); //Defined in step 2 Osp::Base::Utility::Uri uri; RequestId reqId; pContentTransfer->Upload(L”/Media/Images/sourceImg.jpg”, L”/Image/destinationImg.jpg”, true, uri, reqId);
//The four parameters indicate: serFilePath, destFilePath,
replace the exisiting file, request id.
25
Introduction to bada: A Developer's Guide - (draft preview, July 2010)
Once the content is uploaded to the server, you have to create the content on the server with its information (metadata). Without its remote content information, the content is not created. In the next step we will start to manipulate the remote server. pRemoteContentInfo = new RemoteContentInfo(); Osp::Base::Utility::Uri uri; uri.SetPath(L”Image.jpg”); r = pRemoteContentInfo->Construct(L”Image”, uri, 123345); AppAssert(IsFailed(r)); r = pRemoteContentInfo->SetContentName(L”My photo”); AppAssert(IsFailed(r), “Set content name failed!”); r = pRemoteContentInfo->SetProvider(L”My name”); AppAssert(IsFailed(r), “Set content provider failed!”);
Step 3: Set the remote content information To set the remote content information, you have to use the RemoteContentInfo class from Osp::Content namespace.
Step 4: Implement the RemoteContentManagerListener class MyListener : public Osp::Content::IRemoteContentManager { public: MyListener(); ~MyListener(); virtual void OnContentCreated(RequestId reqId, result r, const String &errorCode, const String &errorMsg); virtual void OnContentDeleted(RequestId reqId, result r, const String &errorCode, const String &errorMsg); virtual void OnContentInfoReceivedN(RequestId reqId, RemoteContentInfo *pInfo, result r, const String &errorCode, const String &errorMsg);
26
Introduction to bada: A Developer's Guide - (draft preview, July 2010)
virtual void OnContentStatusReceived(RequestId reqId, RemoteContentStatus contentStatus, const String &errorCode, const String &errorMsg); virtual void OnContentUpdated(RequestId reqId, result r, const String &errorCode, const String &errorMsg); };
void MyListener::OnContentCreated(RequestsId reqId, result r, const String &errorCode, const String &errorMsg) { if(IsFailed(r)) { AppLog(“Failed to create content on server! Reason(%s)”, errorMsg.GetPointer()); } else { AppLog(“Content Created successfully!”); } }
In the same way as other services provided on bada platform, the service listener class has to be implemented by the developer in order to receive the replies sent by the server. The code snippet above demonstrates the header file of your implementation. There are five virtual methods defined in IRemoteContentManagerListener interface class. You have to implement them according to your own requirements. For instance, if you want to create the content on the server side, and also want to know whether the create request is successful or not, then you will need to implement the OnContentCreated() method. The following code snippet gives you a rough ideas about how to implement the OnContentCreated() method.
27
Introduction to bada: A Developer's Guide - (draft preview, July 2010)
Step 5: Create the content To create the content on the remote server, you have to use RemoteContentManager class. MyListener* myListener; myListener = new MyListener(); RequestId reqId; pRemoteContentManager = new RemoteContentManager(); pRemotecontentManager->Construct(pMyListener); pRemoteContentManager->CreateContent(*pRemoteContentInfo, reqId);
The above code snippet demonstrates how to create the content on the remote server. The parameter pRemoteContentInfo is the one we defined in Step 3. And MyListener class is the class we defined in Step 4.
5.3.4 Commerce Service – make your own business The thing that makes the bada platform most unique and interesting is the commerce service. With commerce service developers can not only sell their applications on SamsungApps store, but also sell inapp items. The essential part of commerce service is SamsungApps, where you set up your own items for sale. Bear in mind that all items you sell have to be set from the seller site of SamsungApps. It is slightly different from a normal application, because your items are not listed in the SamsungApps client on device (COD). Figure 5.6 shows you how you can set the items using your SamsungApps account. Let‟s start with how to set up the items on the seller site. Every item listed on store has its own properties, such as name, description, price, currency, image URL, download URL and two preserved fields for future use.
28
Introduction to bada: A Developer's Guide - (draft preview, July 2010)
Step 1: Set up items on SamsungApps Seller Office Here is how you can define and register items: First, go to Samsung Apps Seller Office (http://seller.samsungapps.com/) and, in the menu, select Applications > Item Management to submit your items for possible inclusion. Create an item group and add your items to it. Note that you must remember the item group ID to use it as a parameter for the APIs later on. Before registering the application in Samsung Apps (Applications > Add New Application), you can test purchasing items in your application without actual payment (test mode). When you add your application, you can register your items to the application by selecting the item group ID. Not all items are accepted. Please read the terms and conditions at Samsung Apps for more information.
Figure 5.6 SamsungApps Seller Site 29
Introduction to bada: A Developer's Guide - (draft preview, July 2010)
Step 2: Using in-App purchase API There is a good example from the bada SDK explained purchasing items from SamsungApps. Two classes are related with in-app purchase activities: ItemService and PurchaseService. We will now examine how to use these two classes to implement your own application. The ItemService class only has one method called GetItemList(). You can use it to send a request to SamsungApps server to get an item list. You should also specify the item group ID that is a String type. This ID has to match the one you set up on your store on seller site. It is always the case that the application is hard coded with item group ID. When an application is launched, it will display the items only from this group. Osp::Commerce::Store::ItemService* pItemService; ItemServiceListener *pItemServiceListener; pItemService = new ItemService(); pItemService->Construct(*pItemSerivceListener); //Getting the items start from index 1 to index 2 from the item group with group ID “0x1000000a7” pItemService->GetItemList(L“Ox1000000a7”, 1, 2, reqId);
Meanwhile you also have to implement the listener for catching the replies from the server that is needed when you construct the pItemService object. class ItemServiceListener : public Osp::Commerce::Store::IItemServiceListener { public: ItemServiceListener(); ~ItemServiceListener(); void OnItemListReceivedN(RequestId reqId, Osp::Base::Collection::IList* pItemInfoList, result r, const Osp::Base::String & errorCode, const Osp::Base::String &errorString); };
30
Introduction to bada: A Developer's Guide - (draft preview, July 2010)
31
Introduction to bada: A Developer's Guide - (draft preview, July 2010)
void ItemServiceListener::OnItemListReceivedN(RequestId reqId, Osp::Base::Collection::IList* pItemInfoList, result r, const Osp::Base::String & errorCode, const Osp::Base::String &errorString) { if(IsFailed(r)){ //print error message} else {//display item information} if(pItemInforList != NULL) {pItemInfoList->RemoveAll(true); delete pItemInfoList;} }
The PurchaseService class is another class that allow users to purchase items and get purchase information such as the payment history on the device. Following the same pattern from the ItemService class, you have to implement both the IPurchaseServiceListener interface class and PurchaseService class. It is very similar to IItemServiceListener mentioned above. Both classes need to have the companion listener interface class to handle the response and results from the SamsungApps server. class PurchaseServiceListener : public Osp::Commerce::Store::IPurchaseServiceListener { public: PurchaseServiceListener(); ~PurchaseServiceListener(); void OnItemPurchaseCompleted(RequestId reqId,const PaymentId& paymentId, const ItemId& itemId, const String& itemName, double price, String& currency, const DateTime& purchaseDate, result r, const String& errorCode, const String& errorMsg); void OnItemPurchaseInfoReceivedN(RequestId reqId, IList* pPurchaseInfoList,result r, const String& errorCode, const String& errorMsg); };
32
Introduction to bada: A Developer's Guide - (draft preview, July 2010)
To purchase the item, you can use following code snippet: pPurchaseService = new PruchaseService(); pPurchaseService->Construct(pPurchaseServiceListener); result r; RequestId reqId = INVALID_REQUEST_ID; String itemGroupId(L”0x1000000a7”); String purchaseItemId(L”000000000517”); r = pPurchaseService->PurchaseItem(itemGroupId, purchaseItemId, reqId);
5.3.5 Component setup We explained how to setup the sale items on the SamsungApps Seller Office in case you are using the commerce service. Actually there are some other services require you to setup the component via the bada developer site (http://developer.bada.com) too. The most common one is the Remote Content management service. Before you actually start to write your code, you have to setup the Amazon S3 workspace for your application. In this section, we will give you the step-by-step guide for setup the necessary server components.
33
Introduction to bada: A Developer's Guide - (draft preview, July 2010)
Step 1: Set basic application information This is the first step when you generate a new application. During this step you need to give your application a name, and some simple descriptions and the version information. Figure 5.7 is the screen shot of Step 1 from the developer site.
Figure 5.7: Create Application Profile Once you filled in the information, The Application Manager will lead you to the next step when you click the next button.
34
Introduction to bada: A Developer's Guide - (draft preview, July 2010)
Step 2: Select Privileged API groups Once you decided an application name and gave the description of your application. You then need to select the privilege group which includes APIs used by your application. In case you want to use the content management features, you need to click at least one of privileged API group from CONTENT_TRANSFER, LOCAL_CONTENT or REMOTE_CONTENT shown in the figure below. If you want to use content service only in your device, select LOCAL_CONTENT. If you want to use remote content service which is the service-centric feature, select CONTENT_TRANSFER or REMOTE_CONTENT.
35
Introduction to bada: A Developer's Guide - (draft preview, July 2010)
Figure 5.8 Select Privileged API Groups Step 3: Set up components After you decided the privileged API groups, you can now set the components for your application. This step covers both Social components, Content components and Workspace shown as Figure 5.9. The workspace (Amazon S3) is the actual storage space for your physical content files, such as image, video and audio. When you click the Content Type Management option from Content section, you can create new content types. There are four predefined content types in bada: image, video, audio and others.
36
Introduction to bada: A Developer's Guide - (draft preview, July 2010)
Figure 5.9 Setup Components
37
Introduction to bada: A Developer's Guide - (draft preview, July 2010)
Step 4: Set up Amazon S3 workspace As we mentioned in Step 3, within the same web page, you can also set the workspace. Amazon S3 workspace is the place where your physical contents are stored. Your content information (such as Content Type, attributes information) is stored on the bada Server. That is why it always involves two steps when you create the content in the bada platform: transfer the physical content to the Amazon S3 workspace, and create the content information on the bada Server. bada Developer Site provides a simple authentication process for your bada application and the Amazon S3 workspace. Once you click the “Setup workspace” option, you can setup your Amazon S3 Access Information. To authenticate your Amazon S3 workspace, you have to obtain yourself the Access key, Secrete key and Bucket name from Amazon. If you do not have one, you can always register an account from http://aws.amazon.com/s3/. After filling in all the necessary information, you can click the Connection Check button to verify the access to the Amazon S3 server.
38
Introduction to bada: A Developer's Guide - (draft preview, July 2010)
Chapter 6: bada Namespaces Namespaces in C++, like packages in Java, or import modules in Python for example, are a languagelevel mechanism for partitioning the global program namespace. In C++, namespaces can be thought of as a top-level encapsulation mechanism. In bada, namespaces provide a means for structuring the system at a programming level into well-defined, logically coherent, functional subsets. Each namespace declares a discreet subset of the classes that make up the bada class library.
In all, bada contains twenty primary namespaces within the top-level Osp namespace, which encapsulates all bada third-party APIs. Around half of the primary namespaces contain one or more nested namespaces, for a total of over thirty namespaces beneath the Osp root namespace. The rest of this chapter summarises each individual namespace. What you will learn This chapter walks through the bada namespaces to highlight the most important features of each, and to place each in the bigger context of the platform as a whole. It will provide you with: 1. an overview of how the bada platform is partitioned into major functional areas 2. an understanding of what contribution to the overall system is made by each namespace You'll know where the interesting functionality is, and how to access it. 39
Introduction to bada: A Developer's Guide - (draft preview, July 2010)
What you will need To get the most from this chapter, keep your editor open and browse the header files which are mentioned, which in almost all cases contain useful commentary and code examples.
6.1 using directives and declarations If you are not familiar with namespace syntax in C++, don't despair; it is very straightforward. To use the classes and other definitions from a given namespace in C++, you must include either a using directive to declare all names from the namespace that you want to be available in a given source file, or qualify the names of individual identifiers as they occur in your code using declarations.
Where somenamespace is a namespace, a directive has the form:
using namespace somenamespace;
And where someidentifier is an identifier (a class name, say, or enumeration), a declaration has the form:
using somenamespace::someidentifier;
For example:
using namespace Graphics;
40
Introduction to bada: A Developer's Guide - (draft preview, July 2010)
makes the Graphics namespace available to all code that follows it, allowing access to Graphics classes like Canvas and Bitmap.
41
Introduction to bada: A Developer's Guide - (draft preview, July 2010)
In contrast:
using Graphics::Canvas;
makes the Canvas class from the Graphics namespace available, but not the Bitmap class, for which you would need to make a separate declaration:
using Graphics::Bitmap;
To include a nested namespace, for example Ui::Controls, you must explicitly include the nested namespace, and not just the containing namespace. To use a Button object, for example, the following would appear in your code:
using namespace Ui; using namespace Ui::Controls;
6.2 How this chapter is organized In this book we’ve divided the functionality of bada into 9 groups - it’s the same way the recipes (in the print publication) are organized, for example. Figure 6.1 shows how each namespace maps to each area of functionality. Some namespace features apply to more than one of the functional groups, such as Locations and Locations::Services, but it should provide a starting point for identifying which namespace contains the functionality you need.
42
Introduction to bada: A Developer's Guide - (draft preview, July 2010)
Section 6.3 describes each of the namespaces in alphabetical order, so once you've identified the functionality you need, it's easy to find out more details. We've also pointed you towards which of the recipes in Part 2 are appropriate to each namespace.
Figure 6.1 How namespaces fit into the functional groups used in this book
43
Introduction to bada: A Developer's Guide - (draft preview, July 2010)
Included in the description of most namespaces in this Chapter are one or more UML diagrams, designed to show the most important classes in each namespace and the relationship between them. We have included as many classes as possible in the diagrams, but for clarity in some cases we have just focused on the key classes within a particular namespace. In a few cases, there is no UML diagram at all, not because the namespace isn’t interesting, but because the classes are mostly self contained and a diagram will not add much to the description. If you’re not a UML aficionado, there’s no need to panic. We’ve used just enough UML in this chapter to show how the important classes in each namespace fit together. For a refresher on UML syntax, please see the appendix for a UML primer. Libraries, headers and privileges At the beginning of most of the namespace descriptions you‟ll also find a privilege table, specifying the privilege groups required to use certain functionality within that namespace. You‟ll notice some of the functionality requires privileges at the SYSTEM level which may not be available to all developers, mainly those functions which work together with the bada server. Check out the developer site at developer.bada.com for the latest information about how your application can obtain this privilege level. More information about obtaining privileges can be found in Chapter 2 and Chapter 4 covers the bada security model in detail, including privileges. We‟ve also listed the library and header files required to use each namespace. The individual libraries only need to be included when building for the simulator, when building your application for the device FOsp is the only library required. To add a library to your project, in the IDE choose Properties | C/C++Build |Settings |Bada C++ Linker |Libraries and add the required library by name.
44
Introduction to bada: A Developer's Guide - (draft preview, July 2010)
In bada, typically each namespace is associated with a single header file containing the namespace declaration and an #includes list of all the individual header files that contribute declarations to the namespace. You can find the header file that you need to include at the beginning of each namespace description. At the beginning of each namespace summary we‟ve also listed a selection of the most important classes within that namespace, although more classes will be explained in detail in the summary text.
6.3 Namespaces in detail
Osp Declared in: Framework.h
Summary The top level namespace that includes all other namespaces in bada. A reference to the original bada project name of Open Service Platform.
Osp::App Declared in: FApp.h Library: FApp Privileges required: Most functionality in this namespace requires no privileges. Some specific application features require the following privileges: 45
Introduction to bada: A Developer's Guide - (draft preview, July 2010)
Privilege group
Privilege level
Description
NOTIFICATION
NORMAL
Providing user notifications
TELEPHONY
NORMAL
Using the Call application
WEB_SERVICE
NORMAL
Using the Browser application
Note: to use APPCONTROL_SIGNIN, to allow the user to sign in to the bada Server, you must have one of the SYSTEM level privilege groups from CONTENT, LOCATIONS::SERVICES or MESSAGING specified for your application. Prerequisites: To use notifications, you must ensure that an icon is specified for Ticker and QuickPanel in the project properties in the IDE.
Summary Selected important classes:
Application AppControl AppManager NotificationManager
The App namespace contains the classes which form the basis of application development. Every application must derive from the Application base class which implements the features necessary to create the application, handles initialisation and termination and provides handlers for system events. As shown in Figure 6.2, your application must implement a factory method that returns your application instance, MyApplication in the diagram.
46
Introduction to bada: A Developer's Guide - (draft preview, July 2010)
Figure 6.2 The main classes in the App namespace Application contains two pure virtual functions which the application developer has to implement: OnAppInitializing and OnAppTerminating. In OnAppInitializing, the application loads in any state information from the registry and initialises user interface components such as forms and UI controls. In OnAppTerminating the application should write any relevant state information back to the registry and deallocate any resources it is using. You can also implement other system event handlers to take action when the application moves to the background, is moved to the foreground, when the battery state changes and when memory is so low that
47
Introduction to bada: A Developer's Guide - (draft preview, July 2010)
the application is about to be terminated, giving you a last chance to free resources and write state information back to the registry. The AppControl class provides access to features exported by bada base applications such as dialling, access to the camera and calendar entries. The AppManager class finds the specified control (the dialling control, for example) and returns it as an object type AppControl for use by the application. The NotificationManager class includes methods to provide the user with notifications if a new message is received or something requires their attention. A notification can be displayed in the ticker and quickpanel, particularly useful when the application is running in the background, as a result of the user taking a call, for example. You can also implement other system event handlers to take action when the application moves to the background
Related recipes: - Creating an AppControl to interact with a base application
Osp::Base Declared in: FBase.h Library: FBase Privileges required: None
Summary Selected important classes:
Object Number 48
Introduction to bada: A Developer's Guide - (draft preview, July 2010)
Contains the classes and interfaces around which bada is built. The Object class is the root class of bada and most bada classes derive from this class or its descendants. The namespace also provides wrapper classes for representing and manipulating primitive data types such as char, short, double and bool as well as string handling classes as shown in Figure 6.3. There are also classes to represent date and time and number and string comparisons.
Figure 6.3 The core classes deriving from base::Object Base also includes wrapper classes for the numeric types defined by bada. The number classes are shown in Figure 6.4.
Figure 6.4 Numeric types deriving from base::number 49
Introduction to bada: A Developer's Guide - (draft preview, July 2010)
Osp::Base::Collection Declared in: FBaseCol.h Privileges required: None
Summary Selected important classes:
ICollection IComparer IEnumerator LinkedList Stack Queue
This is the namespace for handling various collections such as arrays, lists and stacks. It contains methods to make it easy to create and manipulate these collections. Collections are either object or template based. Object based collections, derived from ICollection are used to store objects, while template based collections, deriving from ICollectionT are used to store interface pointers and primitive types such as integers. For the sake of clarity, Figure 6.5 just shows the derivation and relationships between the non-template versions of the classes in the namespace, but for each collection class shown in the diagram there is also a version of the class that takes a templated type- LinkedList and LinkedListT, for example.
50
Introduction to bada: A Developer's Guide - (draft preview, July 2010)
Figure 6.5 Collections deriving from ICollection and related classes From the Collection classes shown in Figure 6.5, you just need to choose an appropriate collection class to match the way you want to manage your data. Stack and Queue are simple collections of objects organized in last in first out (LIFO) order and first in first out (FIFO) order respectively. ArrayList and LinkedList implement a list of objects which can be accessed by index, whereas HashMap and MultiMap manage a list of key/value pairs, represented MapEntrys. You can iterate through the elements in both of these collections, to perform an operation on each element, for example, by using the IEnumerator derived class returned by the GetEnumeratorN() method of the collection you‟re using.
51
Introduction to bada: A Developer's Guide - (draft preview, July 2010)
Note: ArrayList and LinkedList are used in the same way, but the implementation of each class is subtly different. ArrayList items are stored in a contiguous area of memory, making accessing the list faster, but adding elements slower than a LinkedList since the entire block of memory may need to be resized as a new item is added. The LinkedList is slower to access, but faster to resize. So if you have a fixed list and you don‟t plan on adding or removing items frequently, then choose an ArrayList. If the number of items in the list is likely to change more often, then use a LinkedList. IComparer derived classes can also be used to Sort() the list, in the case of ArrayList and LinkedList or for key comparison for key/value pair lists. There are number of comparers provided by bada to compare specific types, including IntegerComparer and StringComparer but for more complex object comparisons, you could derive your own comparison class from IComparer. Note: object-based collections don't collect copies of objects, instead they collect pointers. So any object you want to put into a collection class must be allocated using operator new. Otherwise, if your collection stores a pointer to an automatic variable, its lifetime is unpredictable, and it likely will not exist when the collection comes to use it. Your app will crash, unpredictably.
Osp::Base::Runtime Declared in: FBaseRT.h Privileges required: None
Summary Selected important classes:
Monitor Thread Timer
52
Introduction to bada: A Developer's Guide - (draft preview, July 2010)
This namespace includes classes which implement the runtime environment of an application, including threads, synchronization objects and timers as shown in Figure 6.6.
Figure 6.6 The main classes in the base::runtime namespace bada applications can have several threads and the synchronization objects: mutexes, semaphores and monitors are used to control access to shared resources, so that, for example, only one thread at a time has exclusive access to a particular piece of code or shared resource on the device. Timers are used to schedule execution of a particular piece of code.
Osp::Base::Utility Declared in: FBaseUtil.h Privileges required: None
53
Introduction to bada: A Developer's Guide - (draft preview, July 2010)
Summary Selected important classes:
Math StringUtil Uri
This namespace provides some useful utility classes. The Math class is a wrapper to the math library providing access to logarithmic functions other common maths functions and the other classes provide string handling utilities and a class for creating and analyzing URIs.
Osp::Commerce::Store Declared in: FCommerce.h Library: FOsp Prerequisites: To use functionality such as In App Purchases you need to have a seller account on the SamsungApps store. Privileges required: To use the functionality in this namespace requires the following privilege: Privilege group
Privilege level
Description
COMMERCE_STORE
NORMAL
Connecting to SamsungApps to enable In App Purchases
Summary Selected important classes: 54
Introduction to bada: A Developer's Guide - (draft preview, July 2010)
ItemInfo ItemService PurchaseService
The Store namespace provides classes and methods to allow applications retrieve information and make In App Purchases from SamsungApps. These items might be In App Purchases such as new application services or new levels within a game, for example. The actual purchasing process is handled by the SamsungApps servers, so all the application needs to do is to allow the user to choose an item to purchase and pass this request onto the server. Figure 6.7 shows the Commerce::Store namespace is organized. There are two main classes: ItemService for retrieving item information and PurchaseService for actually buying an item. Information for each available item, such as description, price and currency is represented by the ItemInfo class while applications handle ItemService events by implementing the IItemServiceListener. Similarly for purchases, the PurchaseInfo class includes details of the purchase, while responses, such as item successfully purchased or a purchasing error should be handled by the application‟s implementation of the IPurchaseServiceListener.
Figure 6.7 Classes implementing the ItemService and PurchaseService in Commerce::Store
55
Introduction to bada: A Developer's Guide - (draft preview, July 2010)
Osp::Content Declared in: FContent.h Library: FContent Privileges required: To manipulate content on the device or server requires the following privilege groups to be set: Privilege group
Privilege level
Description
LOCAL_CONTENT
Normal
For handling device content
CONTENT_TRANSFER
System
REMOTE_CONTENT
System
Uploading and downloading content to and from a server Manipulating content on a server
Prerequisites: For manipulating remote content the user will need an account on the bada server. While the information about the remote content is stored on the bada server, the physical content is stored on an Amazon S3 workspace which you will need to set up and link to your application. You can set up the Amazon workspace from the Application Manager on the bada developer site, in the “Set Up Components” section.
Summary Selected important classes:
ContentInfo ContentManager ContentSearch
The Content namespace contains classes and methods which are used to search and manage content both locally on the device and remotely on the server. Content is the logical representation of various media types including: images, audio and video, containing content information such as date and time 56
Introduction to bada: A Developer's Guide - (draft preview, July 2010)
captured, GPS information, description and the location of the actual content itself. This information can be used to search for content using an SQL-like syntax. Creating, reading, updating and deleting content is handled by the ContentManager and RemoteContentManager classes. Information in the content database on the device is accessed through specialised classes deriving from ContentInfo: AudioContentInfo, ImageContentInfo and VideoContentInfo all of which contain information about their particular media types while OtherContentInfo is used to represent content such as PDFs. As shown in Figure 6.8, these classes are used to hold content information returned by these searches.
Figure 6.8 The classes responsible for managing and searching for content on a bada device Content searches on the device and server are provided by the ContentSearch and RemoteContentSearch classes. Local searches return items deriving from ContentInfo, while remote searches return information in the more flexible RemoteContentSearch class as shown in Figure 6.9. Once you have the content, use Osp::Media::Player to play it, in the case of audio and video, or for an image, use Osp::Media::Image to decode it into a bitmap and the Osp::Graphics::Canvas to draw the bitmap using the information in ContentInfo.
57
Introduction to bada: A Developer's Guide - (draft preview, July 2010)
Figure 6.9 Content can also be stored and managed remotely using the bada server The Content namespace also provides classes to transfer content between the device and the bada server, useful for sharing information in social networking applications, backing up content or syncing it with the cloud. The functionality for uploading and downloading content to and from a server is provided by the ContentTransfer class.
Osp::Graphics Declared in: FGraphics.h Library: FGraphics Privileges required: None
58
Introduction to bada: A Developer's Guide - (draft preview, July 2010)
Summary Selected important classes:
Bitmap Canvas EnrichedText
The graphics namespace contains classes for drawing 2D and 3D graphics, text and images. All graphics are rendered into a Canvas and the Canvas class contains the methods for drawing basic shapes and the graphic settings such as foreground and background color, line style and font information for text drawing. You can create your own Canvas, but in most cases you will draw into the area of a control. Note: to get a Canvas with the bounds of the whole application frame, use the Osp::App::Application::GetAppFrame method to get the frame control and then Osp::Ui::Control::GetCanvasN to return the Canvas to draw into. Common graphic shapes drawn using the methods of the Canvas class include arcs, lines, rectangles, polygons and text as well as bitmaps. Take a look at Figure 6.10 to see the relationship between Canvas and the other Graphics classes.
59
Introduction to bada: A Developer's Guide - (draft preview, July 2010)
Figure 6.10 The classes in the Graphics namespace. Notice the importance of Canvas The Bitmap class contains methods for creating and scaling bitmaps, but bitmaps are actually rendered using the Canvas::DrawBitMap method. Bitmaps are also used to store the images decoded by Osp::Media::Image before the bitmap containing the image is drawn to the canvas. The namespace also contains some core classes used for drawing shapes: Dimension, Point and Rectangle. More advanced 2D and 3D drawing is provided by the OpenGL subnamespace.
Osp::Graphics::Opengl Declared in: FGraphicsOpengl.h (for OpenGL ES 1.1) Declared in: FGraphicsOpengl2.h (for OpenGL ES 2.0) Libraries: FGraphicsOpengl, FGraphicsEgl 60
Introduction to bada: A Developer's Guide - (draft preview, July 2010)
Privileges required: None Prerequisites: Note that not all hardware running the bada platform will support OpenGL.
Summary This namespace provides support for the OpenGL ES 2D and 3D graphics library. OpenGL ES is a cross platform standard for embedded graphics and provides full functionality for 3D games. By supporting OpenGL ES, bada allows developers to make use of graphics code originally written for other mobile platforms. The EGL library provides the rendering surfaces into which OpenGL draws and connects the OpenGL calls to bada‟s underlying windowing system. Note: support is provided for both OpenGL ES 1.1 and Open GL ES 2.0, which version is available to you depend on whether the device‟s hardware will support it.
Osp::Io Declared in: FIo.h Library: FIo Privileges required: none
Summary Selected important classes:
Database Directory File
As shown in Figure 6.11, the Io namespace includes wrapper classes to handle files, directories, databases and registries. The File class provides support for creating, deleting, writing to and reading 61
Introduction to bada: A Developer's Guide - (draft preview, July 2010)
from files using raw buffers and strings. To get information about files and directories, use the FileAttributes class. Applications only have write access to files in their home or shared directory- which is used to share data with other applications.
Figure 6.11 Core classes in the Io namespace The Database class provides support for basic database functions, creating and deleting databases and executing SQL commands. It also includes support for transactions and rollback, which are very useful functions when using SQL databases. The SQL used by the Database class is SQLLite (www.SqlLite.org). Note: that database is for storage on the local device only, there is no support for connecting to remote databases. The Registry class supports creating, writing to and reading from registry files, which an application typically uses to store settings. This is different from the registry managed by App::AppRegistry which only the application can access. An application could store a file created by Io::Registry in its shared directory and grant read only access to its settings information to a group of applications, for example.
62
Introduction to bada: A Developer's Guide - (draft preview, July 2010)
Osp::Locales Declared in: FLocales.h Library: FLocales Privileges required: none
Summary Selected important classes:
Calendar DateTimeFormatter LocaleManager NumberFormatter
Locales contains classes which make it easy for you to localize your application for international markets, ensuring that numbers, dates and currencies are all displayed in a way consistent with the setting for a particular Locale. A Locale contains a language code and a country code, as well as a variant, a setting which may be used to differentiate between language settings such as simplified and traditional Chinese, for example. Most of the work of formatting numbers and dates for a specific Locale is the responsibility of the DateTimeFormatter and NumberFormatter classes which are shown in Figure 6.12.
63
Introduction to bada: A Developer's Guide - (draft preview, July 2010)
Figure 6.12 The classes which make up the Locales namespace To format a number for a particular locale, you need to use a static factory function, such as NumberFormatter::CreateNumberFormatter or NumberFormatter::CreateCurrencyFormatterN to create a NumberFormatter object and use this to format a number with the correct groupings, decimals and currency symbols for the specified locale. You can also choose to customize the format by using a pattern language very similar to that used on other platforms. The following listing shows how to format a number for the current system locale: LocaleManager localeManager; localeManager.Construct(); Locale
systemLocale = localeManager.GetSystemLocale();
64
Introduction to bada: A Developer's Guide - (draft preview, July 2010)
NumberFormatter* pNumberFormatter= NumberFormatter::CreateNumberFormatterN(systemLocale); String formattedString; double num = 12345.67; pNumberFormatter->Format(num, formattedString);
Formatting dates is a similar process, just call DateTimeFormatter::CreateDateTimeFormatterN and use the DateTimeFormatter to format a date for the specified locale. The current date can be obtained by using System::SystemTime::GetCurrentTime and for more control over the date and time you can use the Calendar class. Calendar represents the date as a series of TimeFields, and provides an AddTimeField function allowing you to perform calculations on dates- moving forward or back a certain number of minutes, days or months, for example. The localized day and month names are stored in the DateTimeSymbol class, which can be retrieved from DateTimeFormatter or constructed on its own. For support for various text encodings, see the Osp::Text namespace.
Osp::Locations Declared in: FLocations.h Library: FLocations Privileges required: Using the features of Locations requires the following privilege levels be set to access the specified areas of functionality:
65
Introduction to bada: A Developer's Guide - (draft preview, July 2010)
Privilege group
Privilege level
Description
LOCATION
NORMAL
LANDMARK
NORMAL
REMOTE_LANDMARK REMOTE_LOCATION REMOTE_TRACE
SYSTEM
Accessing location information on the device Accessing the landmark store on the device Accessing location services using the bada server.
Summary Selected important classes:
IAreaListener ILocationListener LocationProvider Landmark LandmarkStore
This namespace has classes and interfaces for acquiring the location of local and remote devices. Subnamespaces supply the classes to handle map services and map display. The starting point for processing location information is the LocationProvider class, as shown in Figure 6.13. An application can implement listener methods of this class to be notified of the device location at regular intervals, or when the device location crosses a specified area boundary. In both cases a Location object is sent to the listener method containing information about location, speed and the time the data was collected.
66
Introduction to bada: A Developer's Guide - (draft preview, July 2010)
Figure 6.13 The role of the LocationProvider class in the Locations namespace Server supported services Using the bada server, together with the RemoteLocationProvider class, developers can also access information about remote devices, periodically report the last location of the local device to the server and use the SubscribeToTraceService method and ITraceServiceListener class to record a path of travel. Reporting device location to the bada server is done using the StartLocationReport method, together with the ILocationReportListener class. This causes location information to be uploaded to the bada server periodically, information which will then be available for other authenticated devices to read. To retrieve the last known locations of remote devices, use the RequestLastKnownLocationList method, passing in a list of TargetInfo objects which identify a device from the user‟s bada server userID. You can also narrow down the results to devices with last known locations inside a given area using the RequestLastKnownLocationListInCircle and RequestLastKnownLocationListInRectangle methods. 67
Introduction to bada: A Developer's Guide - (draft preview, July 2010)
Landmarks The Landmark class represents a named geographical location that has a name and contains extra information such as a description and a URL. Applications can create their own landmarks, from a user selected location on a map, for example, or use pre-defined landmarks provided by other applications or third party content providers. Landmark information is stored in a database on the device managed by the LandmarkStore class which contains classes to create, modify, delete and search for landmarks within a specified area or with a given name or category (such as a restaurant or theatre), for example. The landmark functionality becomes a lot more powerful when used with the bada server and the RemoteLandmarkStore class which allows landmark information to be shared between applications using the bada server. Information in remote landmark stores consists of user created stores, where the landmark information can be shared between all devices that use the same application, or pre-defined stores which are handled by third party content providers and available to all applications. Note: landmarks are usually drawn on a map in the overlay layer as markers of the class Locations::Controls::MapOverlayMarker. See the discussion of the way that maps are drawn in the Locations::Controls namespace description.
Osp::Locations::Controls Declared in: FLocations.h Privileges required: None
Summary Selected important classes:
IMapOverlay IMapEventListener Map 68
Introduction to bada: A Developer's Guide - (draft preview, July 2010)
Provides classes and methods for rendering maps and UI controls to allow the user to customise the way a map is displayed and to interact with it. Maps are drawn in 5 layers, with the map layer drawn first, each layer adding its own set of graphical information. The main classes used to render each layer of the map are shown in Figure 6.14.
Figure 6.14 Classes for rendering a Map within a UI control The purpose of each layer and the related classes and methods for manipulating this information is as follows: Zoom The top layer containing user interface controls for zooming. The application implements IMapEventListener::OnMapZoomingStarted and OnMapZoomingEnded to be notified when the user zooms the map.
69
Introduction to bada: A Developer's Guide - (draft preview, July 2010)
Info window Word bubbles that display useful information about locations and businesses. This may include a brief description of a business and their contact details, for example. Info windows are created using the NativeMapInfoWindow class for pre-defined windowns and IMapInfoWindow classes for user defined windows.
MyLocation Displays the current location on the map, together with a circular bounds showing the margin of error. The application can choose whether to display this information by using the Map::SetMyLocationEnabled method. Overlay An interactive layer with shapes marking out locations on the map and markers that can be moved by the user like pins on a physical map. Shapes: polygons, circles and rectangles can be added to a map by adding objects deriving from the MapOverlayShape class, while movable markers derive from MapOverlayMarker as shown in Figure 6.15. Applications implement the IMapOverlayEventListener to handle the events received when the user moves the markers around. Map The basic map graphic as provided by the map service provider and encapsulated by the Map class. Methods of this class provide lots of control over how the map is displayed, including its size and bounding rectangle.
70
Introduction to bada: A Developer's Guide - (draft preview, July 2010)
Figure 6.15 Classes for adding overlays to a Map Related recipes: - Getting geographic information from a service provider and showing a map
Osp::Locations::Services Declared in: FLocations.h Prerequisites: An account with a geographic services provider. Required privileges: LOCATION_SERVICE
71
Introduction to bada: A Developer's Guide - (draft preview, July 2010)
Summary Selected important classes:
IDirectoryServiceProvider IMapServiceProvider IRouteServiceProvider ProviderManager
This namespace provides support for geographic information services: maps, geocoding, directory and route services. The starting point for implementing these services is the ProviderManager class which retrieves information about the service providers available to the device and allows the application to choose the one that provides the appropriate services. Support for map services is provided by a set of interface classes called to get map information and render the map. The IMap interface implements dynamic maps from the service provider, supporting features such as panning and zooming, the user interface to which is handled by classes in the Locations::Controls namespace. Route and directory services The Route Service is implemented by the IRouteServiceProvider and IRouteServiceListener and allows the application to request a route, given a set of waypointswhich must consist of at a minimum a start and destination- and parameters such as mode of transport and whether the route is the fastest or shortest. The application is returned a list of Routes, which contains a set of coordinates representing the route and information such as length, estimated travelling time and a set of RouteSegments. The application could then display this information on a map, to provide services such as turn by turn directions. The classes which provide the Route Service are shown in Figure 6.16.
72
Introduction to bada: A Developer's Guide - (draft preview, July 2010)
Figure 6.16 Classes which manage the functionality of service providers in Locations::Services The Directory Service allows application developers to implement a user friendly search for products and services within a specified geographic area - coffee shops within a certain city, for example. Developers put together their search request with the methods of IDirectoryServiceProvider and process the response asynchronously using IDirectoryServiceListener. The search results are returned as a list of Landmarks. Underpinning these services is the Geocoding service, which converts an address into geographic coordinates and vice versa. Note: to make use of these services, you‟ll need an account with a geographic information services provider such as DeCarta (www.decarta.com), which is the currently supported map provider by bada. However, you can provide access to maps within an application by using the Web::Control class and websites such as www.googlemaps.com.
73
Introduction to bada: A Developer's Guide - (draft preview, July 2010)
Osp::Media Declared in: FMedia.h Library: FMedia Privileges required: Using the features of this namespace requires one or more of the following privilege groups depending on the functionality you're making use of: Privilege group
Privilege level
Description
CAMERA
NORMAL
Accessing the camera
IMAGE
NORMAL
Manipulating images
RECORDING
NORMAL
Recording audio and video
DRM_CONTENT
NORMAL
Manipulating DRM content
Summary Selected important classes:
Camera Player AudioRecorder VideoRecorder
This namespace contains classes for audio, video and image processing, playing and capturing. Note: the Image class is used for encoding, decoding and converting images, but to draw an image will also require classes from other namepaces. For example, to draw an image you need to decode the image into a bitmap container defined in Osp::Graphics::Bitmap, create a rectangle to act as the image bounds and then use of method of Osp::Graphics::Canvas to actually draw the image. 74
Introduction to bada: A Developer's Guide - (draft preview, July 2010)
The other important media handling classes are shown in Figure 6.17 and described below.
Figure 6.17 Core classes in the Media namespace Player is used for playing audio and video stored locally on device or streamed across the network. AudioRecorder and VideoRecorder classes are used to capture audio and video on the device. Camera contains methods to provide a live preview and capture a still image from the camera. The application has a lot of control over the camera and can modify settings such as contrast, effects, zoom and flash from Camera class methods. Note: you can test out Camera functionality using the Simulator on a PC with a webcam, although depending on the hardware, not all Camera settings will be available.
75
Introduction to bada: A Developer's Guide - (draft preview, July 2010)
Media format support A wide variety of standard audio playback formats are supported: MP3, AAC, WMA, M4A, XMF, 3GA, MMF, MIDI, WAV and AMR. Audio can be recorded in AMR or WAV formats. The range of video playback formats is also wide: WMV, ASF, AVI, MP4 and 3GP while video can be recorded in MP4 and 3GP formats. The following image formats can be decoded by the Image class: BMP, GIF, JPEG, PNG, TIFF and WBMP. Images can be output in BMP, JPEG and PNG formats. Audio and Video files protected by the OMA and Windows Media Digital Rights Management (DRM) formats can also be played.
Osp::Messaging Declared in: FMessaging.h Library: FMessaging Privileges required: Sending a message using the classes in this namespace requires at least the first of the privilege groups listed in the table below:
Privilege group
Privilege level
Description
MESSAGING
SYSTEM
Sending SMS, MMS and eMail messages
Summary Selected important classes:
EmailManager MmsManager SmsManager 76
Introduction to bada: A Developer's Guide - (draft preview, July 2010)
This namespace provides access to the message handling capabilities of the device. An application can send SMS, MMS or email messages. In order to check on the status of messages being sent, developers implement a listener for each type of message to receive status information asynchronously. Figure 6.18 shows the SmsManager, the RecipientList and the SmsMessage, together with the ISmsListener which is implemented to receive message state information. MMS and email message sending is organized in a similar way with a recipient list, a class to represent the message and a listener which is implemented to receive information about message status.
Figure 6.18 The Messaging::SmsManager and related classes Note: Push messages are not supported by version 1.0.0b3 of the bada SDK which is the current version at the time of writing.
Osp::Net Declared in: FNet.h Library: FNet Privileges required: You will need at least one of the privilege groups listed below to use the features of this namespace and possibly more depending on what features you're using: 77
Introduction to bada: A Developer's Guide - (draft preview, July 2010)
Privilege group
Privilege level
Description
NET
NORMAL
NET_STATISTICS
NORMAL
NET_ACCOUNT
SYSTEM
Manipulating netaccount information Accessing information on a data call Creating and deleting net accounts
Prerequisites: You may need to use a proxy server if you are behind a Firewall.
Summary Selected important classes:
NetAccountInfo NetAccountManager NetConnection
This namespace is responsible for accessing the data communications capabilities of bada. It contains classes for establishing, maintaining and monitoring the connections required to send and receive data over a network. It also provides methods to retrieve information about a specific host using the internet Domain Name System (DNS). Sub namespaces are providing for managing Wi-Fi and Bluetooth connections and sending and receiving data using HTTP or using low level socket functions.
Figure 6.19 Creating and managing connections using the classes in the Net namespace As shown in Figure 6.19, the main classes used to create a network connection are NetAccountManager and NetAccountInfo which encapsulates the configuration information 78
Introduction to bada: A Developer's Guide - (draft preview, July 2010)
necessary to establish a remote connection, such as a Wi-Fi access point name, DNS and authorisation information. The NetConnection class then uses this information to establish a connection and data can then be sent to and received from the remote host.
Osp::Net::Bluetooth Declared in: FNetBluetooth.h Privileges required: You will need the following privilege group to make use of the features of this namespace: Privilege group
Privilege level
Description
BLUETOOTH
NORMAL
Creating connections, sending and receiving data
Prerequisites: Bluetooth must be activated on the device. Note that it is not possible to test the features of Bluetooth using the Simulator.
Summary Selected important classes:
BluetoothDevice BluetoothManager
This sub-namespace provides classes and methods for implementing Bluetooth data protocols. It provides methods for pairing (creating connections), and sending and receiving data over a Bluetooth connection.
79
Introduction to bada: A Developer's Guide - (draft preview, July 2010)
Figure 6.20 Some of the main classes in the Bluetooth namespace Facade classes are also provided for Bluetooth profiles: -
-
GAP (General Access Profile), OPP (Object Push Profile) and SPP (Serial Port Profile).
Osp::Net::Http Declared in: FNetHttp.h Privileges required: You will need at least the first of the privileges listed in the table below to make use of the features of this namespace. Privilege group
Privilege level
Description
HTTP
NORMAL
Setting up HTTP sessions
COOKIE
SYSTEM
Removing stored cookies from a HTTP session
80
Introduction to bada: A Developer's Guide - (draft preview, July 2010)
Summary Selected important classes:
HttpHeader HttpSession HttpTransaction
The Http sub-namespace provides a set of classes that support the HTTP protocol, allowing an application to act as an HTTP 1.1 compliant client, with support for standard features such as pipelining and chunking, communicating with HTTP servers on the internet. Secure connections using HTTPS, with the SSL 3.0 and TLS 1.0, protocols are also supported. The main classes in the Http namespace are shown in Figure 6.21.
Figure 6.21 Classes in the Net::Http namespace implement the HTTP protocol
81
Introduction to bada: A Developer's Guide - (draft preview, July 2010)
To send HTTP requests, you must first set up a HttpSession which includes the connection type (the default is to send plain text over a TCP/IP connection), a proxy server (if any) and the URL of the host server that you‟re sending HTTP requests to. To send a HTTP request and receive a response, you use a HttpTransaction which manages the interaction between client and server. Clients support one or more sessions while a session can consist of many transactions. Messages are packaged up to be sent using the HttpRequest class, while the response is received as a HttpResponse. Adding a header to a request or reading one or a whole list of headers in a response is made easy in bada by using HttpHeader. Like the rest of the communications features of bada, Http requests are dealt with asynchronously, so to receive a responses to a Http request, and to upload messages which are divided into chunks, you need to implement a IHttpTransactionEventListener. For those websites that require a name and password, you can specify this information when you open a HttpTransaction by wrapping the login information up in a HttpAuthentication object.
Osp::Net::Sockets Declared in: FNetSockets.h Privileges required: You will need the following privilege to make use of the features of the Sockets sub namespace. Privilege group
Privilege level
Description
SOCKET
NORMAL
Creating a socket connection, sending and receiving data
82
Introduction to bada: A Developer's Guide - (draft preview, July 2010)
Summary Selected important classes:
SecureSocket Socket
Sockets implements socket data communications protocols, similar to the standard BSD socket library. A socket is described as an endpoint, one side of the communication between two applications running on a network. bada supports TCP/IP, UDP and secure sockets and the stream and datagram protocols. Applications should implement the ISocketEventListener to process socket events asynchronously. The various classes for implementing Socket functionality are shown in the Figure below. Notice that both standard and secure sockets are supported in bada.
Figure 6.22 Net::Sockets implements functionality similar to the BSD sockets library 83
Introduction to bada: A Developer's Guide - (draft preview, July 2010)
Osp::Net::Wifi Declared in: FNetWifi.h Privileges required: You will need at least the first privilege group in the table below to make use of the features of this namespace. Privilege group
Privilege level
Description
WIFI
NORMAL
WIFI_MANAGER
SYSTEM
Setting up an adhoc network, getting information on local WiFi devices Establish a connection to a specific access point
Prerequisites: WiFi must be activated on the device and you must be connected to a wireless network. Note that it is not possible to test Wifi functionality using the Simulator.
Summary Selected important classes:
AdhocService WifiManager WifiNetAccountInfo
This namespace contains classes and methods to get information about an active WiFi connection, allowing developers to gain access to the SSID and securityinfo by using the methods of the WiFiNetAccountInfo class. To control the current WiFi connection, use the WiFiManager class which contains methods for activating and deactivating connections, joining a specified WiFi network and returning information about the WiFi status of the device. The WifiManager and related classes are shown in Figure 6.23.
84
Introduction to bada: A Developer's Guide - (draft preview, July 2010)
Figure 6.23 The main classes in the Net::Wifi namespace, used for managing WiFi devices Wifi also contains classes for creating and managing an adhoc WiFi network, so bada users can connect with their friends and play multiplayer games, for instance. This functionality is managed by the AdhocService class.
Osp::Security Declared in: FSecurity.h Library: FSecurity Privileges required: none
85
Introduction to bada: A Developer's Guide - (draft preview, July 2010)
Summary Selected important classes:
PrivateKey PublicKey SecretKey SecretKeyGenerator AesSecureRandom, DesSecureRandom, DesEdeSecureRandom
The Security namespace provides a platform wide security system and advanced security services such as: cryptographic functions, certificate management services, key management and user authentication with single sign on. bada supports generating pseudo random numbers using the following algorithms: AES using the AesSecureRandom class, DES using DesSecureRandom and 3DES using DesEdeSecureRandom. These functions generate cryptographically secure random numbers (CSPRNG) which can be used in bada to generate secret keys using the SecretKey, SecretKeyGenerator and related interface classes. A secret key could be used for password protecting a file, for example.
86
Introduction to bada: A Developer's Guide - (draft preview, July 2010)
Figure 6.24 The Security classes for generating a SecretKey Public/Private key pairs for use in RSA standard PKI (Public Key Infrastructure) protected messages are generated by using the KeyPair and KeyPairGenerator and related interface classes. PKI is used for creating digital certificates to verify message senders and ensure a message has not been tampered with. (a message in this context could refer to an email or document or a stream, for example). Adding digital signatures to messages and verifying signed messages are handled by the Crypto and Cert sub namespaces.
Osp::Security::Cert Declared in: FSecCert.h Privileges required: none
Summary 87
Introduction to bada: A Developer's Guide - (draft preview, July 2010)
Selected important classes:
X509Certificate
This namespace provides classes for getting information from X509 standard security certificates used to validate a message. The X509Certificate class represents a certificate which contains methods to return information about the certificate and a Verify method which takes a IPublicKey as a parameter and checks to see if the certificate was signed using the corresponding private key. This can be used to check if a message has been tampered with, for example.
88
Introduction to bada: A Developer's Guide - (draft preview, July 2010)
Osp::Security::Crypto Declared in: FSecCrypto.h Privileges required: none
Summary Selected important classes:
IHash IHmac RsaCipher RsaSignature
Contains classes and methods to support various types of encryption and decryption. There are four basic types of encryption supported: one way encryption using hashing, encryption using a secret key, encryption using a public and private key and the use of digital signatures. Public/Private key pairs are used in two ways, to encrypt a message with a public key so that only the person with the corresponding private key can read it and to use a private key to digitally sign a document. Anyone with the public key can read the message, but signing it with a digital signature provides proof that it has not been tampered with. The RsaCipher and RsaSignature classes provide support for encrypting and signing with public/private key pairs.
Osp::Social Declared in: FSocial.h Library: FSocial (In order to use the Lifelog, you must also link the FSocialLifelog library.) 89
Introduction to bada: A Developer's Guide - (draft preview, July 2010)
Privileges required: Using the features of this namespace will require at least one of the privileges listed in the table below, depending on what functionality you implement: Privilege group
Privilege level
Description
ADDRESSBOOK
NORMAL
CALENDARBOOK
NORMAL
LIFELOG
SYSTEM
Access the address book on the device Access the calendar on the device Access the lifelog
Summary Selected important classes:
Addressbook Calendarbook Lifelog
The Social namespace contains classes to maintain the user‟s personal data, address book, calendar and lifelog on a device. The lifelog is a log of activities over a certain period of time including calling and messaging, together with cell-based location information. You can think of this namespace as providing the tools to write applications to help users interact with each other. It includes classes which are responsible for getting, manipulating and sharing data and a set of server assisted features which are implemented by the Social::Services namespace. The most important classes within the Social namespace are Addressbook, Calendarbook and Lifelog. The Addressbook class allows access to the address book database on the device providing methods for adding and deleting categories and contacts and searching for contact information. Addressbook and the classes which it uses is shown in Figure 6.25.
90
Introduction to bada: A Developer's Guide - (draft preview, July 2010)
Figure 6.25 Addressbook and related classes Calendarbook provides methods to allow the application to create, edit and modify events and to-do lists store in the device‟s calendar, set up reminders and recurring events and respond when event information is changed. Calendarbook and the classes for implementing features like to dos and reminders are shown in Figure 6.26.
91
Introduction to bada: A Developer's Guide - (draft preview, July 2010)
Figure 6.26 Calendarbook and related classes Lifelog lets an application analyse the most frequently called numbers, list the callers between a range of dates or from a cell-based locations and many other types of processing of the lifelog database.
Osp::Social::Services Declared in: FSocial.h Privileges required: All of the features of this namespace work together with the bada server and SYSTEM level privileges are required for all of the services it implements:
92
Introduction to bada: A Developer's Guide - (draft preview, July 2010)
Privilege group
Privilege level
Description
BUDDY_SERVICE
SYSTEM
Buddy Service
MESSAGING_SERVICE
SYSTEM
Message Service
PRIVACY_SERVICE
SYSTEM
Privacy Service
PROFILE_SERVICE
SYSTEM
Profile Service
SNS_SERVICE
SYSTEM
SNS Gateway
Summary Selected important classes:
BuddyService MessagingService ProfileService Profile SnsGateway
The Services namespace provides different ways for users to interact using the features of the bada server. There are features provided to build social relationships between bada users and a social networking aggregation service (SNA) which provides built in support for social networking services such as Facebook and Twitter all from within the application. As you can see from the table, the functionality of Services can be broken into five groups: Profile, Privacy, Messaging and Buddy management work with the features of the bada server to connect bada users, while the SNS Gateway provides the link from the application through the bada server and onto social networking sites. The ProfileService class is used to manage profiles. A user‟s profile actually consists of several different parts: a BasicProfile, which is public by default and other profiles such as ContactProfile and SocialProfile which are available across the device to all permitted users, but which are set as private when stored on the bada server. Users must choose to be listed in the public directory on the bada server and can also choose which of their other profiles are available to be accessed by all or a specified group of users. You need to implement IProfileServiceListener to respond 93
Introduction to bada: A Developer's Guide - (draft preview, July 2010)
to request initiated from the ProfileService. The ProfileService and the various types of Profiles are shown in Figure 6.27.
Figure 6.27 How the ProfileService manages the different kinds of Profiles Access to a user‟s profile and other information such as their location is handled by the PrivacyManager class. This controls which parts of a user‟s profile information can be searched by other users and who has access to that information- buddies, for example. Developers need to implement the IPrivacyManagerListener class to implement this functionality. Users of the bada server can be connected as Buddys- a mutually confirmed relationship between two users. Sending and responding to buddy requests is handled by the BuddyService class and since, as with most other requests in the Services namespace these requests are handled asynchronously, you need to implement the IBuddyServiceListener. The classes which are used to implement the BuddyService are shown in Figure 6.28.
94
Introduction to bada: A Developer's Guide - (draft preview, July 2010)
. Figure 6.28 The classes which go to make up the BuddyService The MessagingService is used for applications to send text messages between devices to one or a group of users. Messages are send via the bada server and you need to implement IMessageServiceListener and IMessageServerEventListener to take advantage of this functionality. Note: the MessagingService can only be used to send messages between the same application on different devices, not between different applications. SNSGateway The SnsGateway class manages one of the most powerful features of the Services namespace, allowing you to create applications that can easily communicate with social networking sites such as Facebook, Myspace and Twitter and retrieve information such as pictures and status updates all from within your application. All you need to do is use the SnsGateway class and related classes such as SnsAuthenticator and the low level work of connecting to and retrieving information from the various social networking sites is taken care of for you by the bada server.
95
Introduction to bada: A Developer's Guide - (draft preview, July 2010)
The organization of the classes making up the functionality of the SnsGateway is shown in Figure 6.29.
Figure 6.29 Classes which allow access to social networking sites, as provided by the SnsGateway SnsGateway helps to present a unified view of all the information from various sites, representing the retrieved information in classes such as SnsPhotoInfo and SnsStatusText which you can then display in whatever way you want. Note: a Buddy as managed by the BuddyService refers to another user of the bada server and is different from the concept of a buddy as returned by the SnsGateway::GetMyBuddies method. The latter refers to a buddy in a social networking service such as Facebook or MySpace and represented by a SnsProfile.
Osp::System Declared in: FSystem.h Library: FSystem Privileges required: To access any of the functions of this namespace, you need the following privilege group: 96
Introduction to bada: A Developer's Guide - (draft preview, July 2010)
Privilege group
Privilege level
Description
SYSTEM_SERVICE
NORMAL
For accessing the features of the utility classes provided by this namespace
Summary Selected important classes:
Alarm Battery SystemTime
The system namespace provides access to device level information including system time, the alarm service, operating the vibrator device, battery levels and charge status and power management. The system time can be returned as UTC (Coordinated universal time) and local time with or without any adjustment for daylight saving time. The classes which provide the functionality of the System namespace are shown in Figure 6.30.
Figure 6.30 System consists of a group of self contained utility classes Note: applications should check the battery level before starting a particularly power intensive function such as playing multimedia content. Osp::App::Application::OnBatteryLevelChanged is called whenever the battery level changes.
97
Introduction to bada: A Developer's Guide - (draft preview, July 2010)
Osp::Telephony Declared in: FTelephony.h Library: FTelephony Privileges required: To use the features of this namespace you need the following privilege group: Privilege group
Privilege level
Description
TELEPHONY
NORMAL
Getting network and SIM information
Summary Selected important classes:
CallManager NetworkManager SimInfo
This namespace provides classes to access the telephony features of the device and contains methods for getting information about the current call, network information and access to information from the SIM card.
Figure 6.31 Accessing the Telephony features of the device 98
Introduction to bada: A Developer's Guide - (draft preview, July 2010)
Osp::Text Declared in: FText.h Library: FText Privileges required: none
Summary Selected important classes:
Decoder Encoder Encoding
This namespace contains classes to handle various text encodings including Unicode, ASCII, GSM and UTF-8 as shown in Figure 6.32. Classes are also provided to convert text between formats. Those interested in localizing their applications should also review the Osp::Locales namespace which is used for handling number, date and currency formats.
99
Introduction to bada: A Developer's Guide - (draft preview, July 2010)
Figure 6.32 Text encoding and decoding as provided by the Text namespace
Osp::Ui Declared in: FUi.h Library: FUi Privileges required: none
100
Introduction to bada: A Developer's Guide - (draft preview, July 2010)
Summary Selected important classes:
Container Control Window
The Ui namespace together with the Controls sub namespace provide the classes and methods to implement a graphical user interface. The Ui namespace provides common base classes for all controls as well as interfaces for event handlers. An application UI is divided into layers of a frame, forms and controls. The frame is the top level window of an application and an application can have only one. Within that are forms- there can be many forms within an application and within forms are controls which are handled by the Controls sub namespace.
Osp::Ui::Controls Declared in: FUiControls.h Privileges required: none
Summary Selected important classes:
Form Frame
The Controls sub namespace contains control classes and other methods for displaying and interacting with the user interface: creating controls, control layout and responding to control events.
101
Introduction to bada: A Developer's Guide - (draft preview, July 2010)
Controls are graphical user interface components that are displayed inside an application frame. Controls are divided into two types: containers such as forms, panels, popups and pickers that can contain other controls and standard controls such as buttons, lists and sliders. Container controls will typically have a parent/child relationship with the controls that it contains. Figure 6.33 shows the main UI controls. Note: when you delete a container control, you must not delete the controls that it contains since this will be done automatically for you by the system
Figure 6.33 UI controls. Notice which ones are Container controls Related recipes:
Adding a form to a Frame based application Adding a simple Button control to a Form Adding softkeys to a Form Adding an options Menu to a form 102
Introduction to bada: A Developer's Guide - (draft preview, July 2010)
Displaying a MessageBox
103
Introduction to bada: A Developer's Guide - (draft preview, July 2010)
Osp::Uix Declared in: FUix.h Library: FUix Privileges required: none
Summary Selected important classes:
FaceDetector Haptic Motion
This namespace contains classes to implement user interface extensions- unconventional user interface features which are not covered by basic UIs. While conventional applications interact with the user via menus and physical buttons, the UI extensions provided by bada provide ways of using the device in unconventional ways and give the application developer access to built-in sensors. The classes which represent the user interface extensions are shown in Figure 6.34.
Figure 6.34 User interface extensions provided by the UIX namespace 104
Introduction to bada: A Developer's Guide - (draft preview, July 2010)
The FaceDetector is the class used to locate a face in a still image or camera preview, while the FaceRecognizer will analyse this image and try and identify it from a list of already identified faces. A device can contain many sensors available to application developers, including acceleration, GPS, magnetic, proximity and tilt sensors. The SensorManager class is used to determine if a sensor is available and to add or remove the sensor event handlers, while the SensorData class is used to retrieve information from that sensor. The classes which handle the functionality of these sensors are shown in Figure 6.35.
Figure 6.35 Sensors provided by the UIX namespace Note: sensor monitoring methods like ISensorEventListener::OnDataReceived are called from a separate thread to the main thread, in order not to be slown down by the API calls in the main thread. This means that if you implement monitoring of a sensor you should minimise what you do in the OnDataReceived method and do any drawing in the main thread. This also applies to the weather services classes which are used to retrieve and store a one day weather forecast for a given location.
105
Introduction to bada: A Developer's Guide - (draft preview, July 2010)
Osp::Web Declared in: FWeb.h Library: FWeb Privileges required: Some of the functions of this namespace require privileges, as explained in the table below: Privilege group
Privilege level
Description
WEB_PRIVACY
NORMAL
Accessing the web history
Summary Selected important classes:
HistoryItem WebHistory
This namespace contains classes and methods to interact with the browser engine. It contains classes which track browsing history. The functionality for displaying a web browser inside a window is handled by the Controls sub namespace.
Osp::Web::Controls Declared in: FWebControls.h Privileges required: To use the features of this namespace, you must have the following privilege group: Privilege group
Privilege level
Description
WEB_SERVICE
NORMAL
Construct a web control 106
Introduction to bada: A Developer's Guide - (draft preview, July 2010)
Summary Selected important classes:
Web
This sub namespace provides web browsing functionality to an application. A full web browser can be embedded in an application window just like any other control. This control can be used to download web content to the device and run Javascript (using the EvaluateJavaScriptN method of Web). The web control is based on the WebKit standard.
Osp::Xml Declared in: FXml.h Library: FXml Other header files: Privileges required: None
Summary Contains classes and methods to manipulate XML documents using the standard libXml2 library for parsing document content.
107
Introduction to bada: A Developer's Guide - (draft preview, July 2010)
Part 4: Recipes
Introduction ............................................................................................................................................... 1 2.1 Adding a Form .................................................................................................................................... 3 2.2 Adding a button to a Form .................................................................................................................. 8 2.3 Adding softkeys to a Form ................................................................................................................ 15 2.4 Adding an option menu to a Form .................................................................................................... 19 2.5 Display MessageBox to confirm an action ....................................................................................... 25 2.6 Using a keypad control ..................................................................................................................... 29 2.7 Get touch events................................................................................................................................ 39 2.8 Using base applications..................................................................................................................... 47 2.9 Get magnetic field from Compass Sensor......................................................................................... 56 2.10 Get geographic data from provider and show map ......................................................................... 62
0
Introduction to bada: A Developer's Guide - (draft preview, July 2010)
Introduction Note: in this draft, pre-publication, and downloadable version of the book, we present the first 10 recipes only, as a taster of what's to come. The recipes as well as this book and further resources can be accessed on our website http://developer.bada.com. In Part 2 of the book we‟ll present 70 C++ recipes, organized into 9 functional groupings, that explore the bada APIs and provide you with ready-made code solutions for common *how-to-do-it?* questions. These are questions you are likely (in fact, certain!) to meet in the course of your own projects. By providing you with ready-made solutions, we want to help speed you on your way to your finished apps. Just as importantly, by solving these basic problems for you, we hope we will clear the way for you to focus on the interesting problems that your apps present - the kinds of features that differentiate your great idea from everyone else's.
What's in the recipes 1. UI and extended UI Basic recipes to get you started, demonstrating how to work with common UI elements including Frames, Forms, Controls, and Popups. These recipes also include application input types, including keyboards, keys, touch, multi-touch, and gestures. These recipes also include managing sensor and other hardware input including from the camera. 2. Fundamentals Application basics, recipes that demonstrate how to work with the app lifecycle and with app state, and that demonstrate the use of bada idioms for C++, as well as common basic types from the bada class library, including Strings, Dates and Times, and Numbers. 1
Introduction to bada: A Developer's Guide - (draft preview, July 2010)
These recipes also include using base (built-in) applications from your own apps. 3. Multimedia content Essential multimedia recipes. 4. Networking Recipes that demonstrate common networking, phone, messaging, and similar techniques. 5. Service-centric features Recipes that demonstrate interaction with server-based content. 6. Maps and locations Recipes that demonstrate how to use maps and location in your own apps. 7. Social networking and commerce Recipes that demonstrate how to use social networking services, including Facebook and Twitter, and other server-based content from within your own apps. 8. Security Recipes demonstrating security features and use. 9. Internationalization Recipes demonstrating internationalization features and use. .
2
Introduction to bada: A Developer's Guide - (draft preview, July 2010)
2.1 Adding a Form Problem description You want to add a Form to a Frame-based application.
The recipe The following configuration is required for this recipe: Namespaces used: Osp::Ui, Osp::Ui::Controls Header files to #include: FUi.h, FUiControls.h Required libraries: FUi, FUiControls [.lib | .so] Required privilege level: Normal Required privilege groups: None The top level window of an Application is called a Frame. A Frame is the ultimate parent object of all controls that an application possesses. A Frame can contain one or many Forms. A Form is the highest level container. It is a full screen container which can contain user-created controls and system UI components to help provide functionality for an application. The Frame and Form classes are provided by the Osp::Ui::Controls namespace. This recipe shows two different methods that can be used to create a Form and add it to the Application‟s Frame. Each method details the steps required to add a Form to a Frame and provides some sample code snippets. 3
Introduction to bada: A Developer's Guide - (draft preview, July 2010)
Figure 2.1.1 A blank Form Method 1: Adding a Form to the Frame using the Osp::Ui::Controls::Form class This simple recipe creates a new Form object using the system‟s Osp::Ui::Controls::Form class and adds it to the Application‟s Frame. The Form should be created and added to the Application‟s Frame during the application initialization phase (OnAppInitializing()). 1. Create an instance of a Form and initialize it with the style parameters required to display a normal Form containing a title bar and an indicator bar. 2. Set the name of the Form and the text to be displayed in the Form‟s Title area. 3. Add the Form to the Application Frame. 4. Set the Form as the current form of the Frame. 5. Draw and Show the Form. The following code snippet is an example of code that would be added to the Application‟s OnAppInitializing() method:
4
Introduction to bada: A Developer's Guide - (draft preview, July 2010)
// Create a Form Form* pForm = new Form(); pForm->Construct (FORM_STYLE_NORMAL|FORM_STYLE_TITLE|FORM_STYLE_INDICATOR); pForm->SetName(L"MainForm"); pForm->SetTitleText(L"MainForm"); // Get a frame pointer and add the Form to the Frame Frame* pFrame = GetAppFrame()->GetFrame(); pFrame->AddControl(*pForm); // Set the current Form pFrame->SetCurrentForm(*pForm); // Call Draw & Show to display Form pForm->Draw(); pForm->Show();
Method 2: Adding form to the Frame using a user-defined Form class This recipe creates the same results as in Method 1, but does it using a newly created Form class. This method may be more suitable for applications which contain multiple forms, as the creation of the Form‟s controls and its logic is implemented by the Form rather than in the Application code. In this recipe the MainForm class is inherited from the base class Osp::Ui::Controls::Form. The following code snippet shows an example of the MainForm class definition: class MainForm : public Osp::Ui::Controls::Form { // Construction public: MainForm(void); ~MainForm(void); bool Initialize(void); // Call-back functions public: result OnInitializing(void); result OnTerminating(void); };
5
Introduction to bada: A Developer's Guide - (draft preview, July 2010)
The Form should be created and added to the Application‟s Frame during the application initialization phase (OnAppInitializing()). 1. 2. 3. 4.
Create an instance of the MainForm type and initialise it. Add the Form to the Application Frame. Set the Form as the current form of the Frame. Draw and Show the Form.
The following code snippet is an example of code that would be added to the Application‟s OnAppInitializing() method: // Create a form MainForm* pForm = new MainForm(); pForm->Initialize(); // Add the form to the frame Frame* pFrame = GetAppFrame()->GetFrame(); pFrame->AddControl(*pForm); // Set the current form pFrame->SetCurrentForm(*pForm); // Draw and Show the form pForm->Draw(); pForm->Show();
The Form‟s style parameters and title text should be defined during initialization of the MainForm (Initialize()): 1. Call the base class constructor with the style parameters required to display a normal Form containing a title bar and an indicator bar. 2. Set the text to be displayed in the Form‟s Title area. The following code snippet is an example of code that would be implemented in the MainForm‟s Initialize() method:
6
Introduction to bada: A Developer's Guide - (draft preview, July 2010)
Form::Construct(FORM_STYLE_NORMAL|FORM_STYLE_TITLE|FORM_STYLE_INDICATOR); SetTitleText(L"Main Form");
Hints, pitfalls, and related topics All containers, including the Form container, must be created on the heap memory. However, once the Form has been attached to the Frame, the application framework is responsible for its deletion when the application terminates. If the developer deletes the controls, it will cause a problem.
7
Introduction to bada: A Developer's Guide - (draft preview, July 2010)
2.2 Adding a button to a Form Problem description You want to add a Button control to a Form.
The recipe The following configuration is required for this recipe: Namespaces used: Osp::Ui, Osp::Ui::Controls, Osp::Media1, Osp::Graphics25 Header files to #include: FUi.h, FUiControls.h, FMedia.h, FGraphics.h25 Required libraries: FUi, FUiControls, FMedia25, FGraphics25 [.lib | .so] Required privilege level: Normal Required privilege groups: IMAGE25
A Button is a control provided by the Osp::Ui::Controls namespace. A Button can vary in size and can contain either text or an image. In order to handle the Button control‟s events, a listener must be used. The IActionEventListener is the interface class that should be implemented by any class interested in receiving a button‟s action events. This recipe details the steps to add a Button control to a Form and describes the code that needs to be implemented for the Form to receive and handle a Button press event. Examples are provided for a button containing text and a button containing an image.
1
For Button control displaying an image
8
Introduction to bada: A Developer's Guide - (draft preview, July 2010)
This recipe assumes the steps detailed in method 2 of the „Adding a Form‟ recipe [2.1] have been followed to add a Form to the Application‟s Frame. As shown in the „Adding a Form‟ recipe the MainForm class is inherited from the Form base class. In order for this form to handle events from a control such as a button, an event listener interface has to be implemented. So in this recipe the MainForm class must implement the Osp::Ui::IActionEventListener interface class. Because the IActionEventListener is shared by many controls, each control that uses this listener must be assigned a unique action ID. The action ID is used to identify the relevant control when handling events in the OnActionPerformed() event handler. The following code snippet highlights the changes made to the MainForm class in order to handle a button control‟s events: class MainForm : public Osp::Ui::Controls::Form, public Osp::Ui::IActionEventListener { // Construction public: MainForm(void); ~MainForm(void); bool Initialize(void); // Implementation protected: static const int ID_BUTTON_OK = 101; public: result OnInitializing(void); result OnTerminating(void); void OnActionPerformed(const Osp::Ui::Control& source, int actionId); };
In order to handle the Button control action events the IActionEventListener class‟s pure virtual function OnActionPerformed() needs to be implemented in the MainForm class. In this event 9
Introduction to bada: A Developer's Guide - (draft preview, July 2010)
handler the control‟s event is identified by its action ID, which is registered when the control was created, and the relevant processing can be implemented. The following code snippet is an example of the MainForm’s OnActionPerformed() method: void MainForm::OnActionPerformed(const Osp::Ui::Control& source, int actionId) { switch(actionId) { case ID_BUTTON_OK: { // Add button handling functionality here } break; default: break; } }
Example 1: Creating a button containing text In this example a button control with a text label is created on the Form.
Figure 2.2.1 Button with text
10
Introduction to bada: A Developer's Guide - (draft preview, July 2010)
The Button control should be added to the Form during initialization of the MainForm (OnInitializing()): 1. 2. 3. 4.
Create a button object and initialize it by setting its size and position using a Rectangle instance. Set the text string to be displayed on the button control. Assign a unique action ID for the button control. Register the IActionEventListener implemented by the MainForm class with the button control. 5. Add the button control to the form. The following code snippet is an example of code that would be added to the MainForm’s OnInitializing() method, in order to add a button control to the form: // Create Button Button* pButton = new Button(); // Set button size and position pButton->Construct(Rectangle(10, 100, 460, 60)); // Set button text pButton->SetText(L"Ok"); // Set button Action identifier pButton->SetActionId(ID_BUTTON_OK); // Register an event listener pButton->AddActionEventListener(*this); // Add the button control to the Main Form AddControl(*pButton);
11
Introduction to bada: A Developer's Guide - (draft preview, July 2010)
Example 2: Creating a button containing an image In this example a button control with an image is created on the Form.
Figure 2.2.2 Form with image The Button control should be added to the Form during initialization of the MainForm (OnInitializing()): 1. Create a Button object and initialize it by setting its size and position using a Rectangle instance. 2. Create an Image object and initialize. 3. Decode the image file into the decoded bitmap container, passing the local file path of the image file and colour format parameters. 4. Set the „Normal‟ and „Pressed‟ button images and position them at a Point relative to the top left corner of the Button Rectangle. 5. Assign a unique action ID for the button control. 6. Register the IActionEventListener implemented by the MainForm class with the button control. 7. Add the button control to the form. The following code snippet is an example of code that would be added to the MainForm’s OnInitializing() method, in order to add a button control to the form: 12
Introduction to bada: A Developer's Guide - (draft preview, July 2010)
// Create Button Button* pButton = new Button(); // Set button size and position pButton->Construct(Rectangle(140, 100, 200, 200)); // Create a Bitmap and decode image Bitmap* pBitmap = new Bitmap(); Image* pImage = new Image(); pImage->Construct(); pBitmap = pImage->DecodeN(L"/Res/bada.png", BITMAP_PIXEL_FORMAT_ARGB8888); delete pImage; // Set button images pButton->SetNormalBitmap(Point(0, 0), *pBitmap); pButton->SetPressedBitmap(Point(0, 0), *pBitmap); delete pBitmap; // Set button Action identifier pButton->SetActionId(ID_BUTTON_OK); // Register an event listener pButton->AddActionEventListener(*this); // Add the button control to the Main Form AddControl(*pButton);
Hints, pitfalls and related topics All controls must be created on the heap memory. However, once a control has been added to the container, and the container attached to the Frame, the application framework is responsible for its deletion when the application terminates.
13
Introduction to bada: A Developer's Guide - (draft preview, July 2010)
If a control is not added to a container, the programmer must explicitly delete it on termination of the application. Controls, such as buttons, can be added and removed during run-time depending on UI context, to preserve memory. The methods AddControl() and RemoveControl() are provided to add and remove controls from a container.
Related recipes 2.1 Adding a Form recipe
14
Introduction to bada: A Developer's Guide - (draft preview, July 2010)
2.3 Adding softkeys to a Form Problem description You need to add softkeys to a Form.
The recipe The following configuration is required for this recipe: Namespaces used: Osp::Ui, Osp::Ui::Controls, Osp::Media2, Osp::Graphics26 Header files to #include: FUi.h, FUiControls.h, FMedia.h26, FGraphics.h26 Required libraries: FUi, FUiControls, FMedia26, FGraphics26 [.lib | .so] Required privilege level: Normal Required privilege groups: 26 IMAGE
A Form is composed of an indicator area, tab and title areas, a client area, and a softkey area. Depending on the style of a form, it is determined whether an indicator, a tab, a title, an options key or the softkeys are shown. A softkey can either display text or a bitmap. The softkey generates an action event when it is pressed. If an application wants to handle the action event generated by the softkey, it should implement an action event listener and register it to the softkey using AddSoftkeyActionListener() method.
2
For softkey displaying an image
15
Introduction to bada: A Developer's Guide - (draft preview, July 2010)
This recipe details the steps to create the left and right softkeys for a Form, and describes the code that needs to be implemented for the Form to receive and handle the softkey action events. In this recipe the left softkey contains an icon and the right softkey contains text.
Figure 2.3.1 A Form with softkeys This recipe assumes the steps in method 2 of the „Adding a Form‟ recipe (2.1) have been followed to add a Form to the Application‟s Frame. It also assumes the steps described in the “Adding a button” recipe (2.2) have been followed to implement the Osp::Ui::IActionEventListener interface class. To display the softkey area with a left and right softkey, the Form constructor needs to be called with the FORM_STYLE_SOFTKEY_0 (related to left softkey) and FORM_STYLE_SOFTKEY_1 (related to right softkey) style parameters set. The following code snippet is an example of code that would be implemented in the MainForm‟s Initialize() method: Form::Construct(FORM_STYLE_NORMAL|FORM_STYLE_TITLE| FORM_STYLE_INDICATOR|FORM_STYLE_SOFTKEY_0|FORM_STYLE_SOFTKEY_1);
Action IDs need to be added to the MainForm for each of the softkeys, so that the softkey action events can be identified when handling events in the OnActionPerformed() event handler: 16
Introduction to bada: A Developer's Guide - (draft preview, July 2010)
static const int ID_SOFTKEY_LEFT = 101; static const int ID_SOFTKEY_RIGHT = 102;
In the OnActionPerformed() event handler the softkey action events are identified by the action ID, which is registered when the softkey is created, and the relevant processing can be implemented. The following code snippet is an example of the MainForm’s OnActionPerformed() method: void MainForm::OnActionPerformed(const Osp::Ui::Control& source, int actionId) { switch(actionId) { case ID_SOFTKEY_LEFT: { // Add left softkey handling code here } break; case ID_SOFTKEY_RIGHT: { // Add right softkey handling code here } break; default: break; } }
The softkeys should be created during initialization of the MainForm (OnInitializing()): 1. Create an Image object and initialize. 2. Decode the image file into the decoded bitmap container, passing the local file path of the image file and colour format parameters. 3. Set the left softkey to display an icon and assign the „Normal‟ and „Pressed‟ images. 4. Set the right softkey to display a text string. 5. Assign unique action IDs for both softkeys. 6. Register IActionEventListener implemented by the MainForm class with the softkeys. The following code snippet is an example of code that would be added to the MainForm’s OnInitializing() method, in order to create the left and right softkeys: 17
Introduction to bada: A Developer's Guide - (draft preview, July 2010)
// Create left softkey (SOFTKEY_0) // Create a Bitmap and decode image Bitmap* pBitmap = null; Image* pImage = new Image(); pImage->Construct(); pBitmap = pImage->DecodeN(L"/Res/bada.png", BITMAP_PIXEL_FORMAT_ARGB8888); SetSoftkeyIcon(SOFTKEY_0, *pBitmap, pBitmap); delete pImage; delete pBitmap; // Create right softkey (SOFTKEY_1) SetSoftkeyText(SOFTKEY_1, "Right"); // Assign action IDs for both the softkeys SetSoftkeyActionId(SOFTKEY_0, ID_SOFTKEY_LEFT); SetSoftkeyActionId(SOFTKEY_1, ID_SOFTKEY_RIGHT); // Register event listener AddSoftkeyActionListener(SOFTKEY_0, *this); AddSoftkeyActionListener(SOFTKEY_1, *this);
Hints, pitfalls and related topics If both an icon and text are set for the same softkey at the same time, the text takes precedence over the icon.A softkey can be enabled or disabled using the SetSoftkeyEnabled() method, with the enable parameter set to either true or false.
Related recipes 2.1 Adding a Form recipe 2.2 Adding a Button recipe
18
Introduction to bada: A Developer's Guide - (draft preview, July 2010)
2.4 Adding an option menu to a Form Problem description You want to add an options menu to a Form and get the user‟s selections.
The recipe The following configuration is required for this recipe: Namespaces used: Osp::Ui, Osp::Ui::Controls Header files to #include: FUi.h, FUiControls.h Required libraries: FUi, FUiControls [.lib | .so] Required privilege level: Normal Required privilege groups: None A Form is composed of an indicator area, tab and title areas, a client area, and a softkey area. Depending on the style of a form, it is determined whether an indicator, a tab, a title, an options key or the softkeys are shown. An Option Menu is a menu control activated from an Option Key located in the command area of the display. It can be used to present multiple options to the user, and is displayed over the content of the form. It is a hierarchical menu, which can contain up to 2 levels, consisting of main items and sub items. The menu items can only be presented as text strings, bitmaps cannot be displayed.
19
Introduction to bada: A Developer's Guide - (draft preview, July 2010)
An Option Menu control does not get added to a container, so it must be explicitly deleted when it is no longer required. The Application Framework will not delete the Option Menu when the application terminates. This recipe details the steps to create the Option Key and add a 2-level Option Menu to a Form, and describes the code that needs to be implemented for the Form to receive and handle the Option Key and Option Menu action events.
Figure 2.4.1 Option Menu with 2-levels This recipe assumes the steps detailed in method 2 of the „Adding a Form‟ recipe (2.1) were followed to add a Form to the Application‟s Frame. It also assumes the steps described in the „Adding a button‟ recipe (2.2) have been followed to implement the Osp::Ui::IActionEventListener interface class. To display the Option Key in the softkey area of the display, the Form constructor needs to be called with the FORM_STYLE_OPTIONKEY style parameter set. The following code snippet is an example of code that would be implemented in the MainForm‟s Initialize() method:
20
Introduction to bada: A Developer's Guide - (draft preview, July 2010)
Form::Construct(FORM_STYLE_NORMAL|FORM_STYLE_TITLE| FORM_STYLE_INDICATOR|FORM_STYLE_OPTIONKEY);
An Action ID needs to be added to the MainForm for the Option Key, so that its action event can be identified when handling events in the OnActionPerformed() event handler: static const int ID_OPTIONKEY = 100;
Similarly, each Option Menu main item and sub item requires an Action ID to identify it in the OnActionPerformed() event handler: static const int ID_OPTION1 = 103; static const int ID_OPTION2 = 104; static const int ID_OPTION3 = 105; static const int ID_OPTIONA = 106; static const int ID_OPTIONB = 107;
In the OnActionPerformed() event handler the Option Key and Option Menu item action events are identified by the action ID, which are registered when the Option Key and Option Menu are created, and the relevant processing can be implemented. When the event with the action ID associated with the Option Key is received, the Option Menu is activated and displayed using the SetShowState() and Show() methods. The following code snippet is an example of the MainForm’s OnActionPerformed() method: void MainForm::OnActionPerformed(const Osp::Ui::Control& source, int actionId) { switch(actionId) { case ID_OPTIONKEY: { // Display the OptionMenu __pOptionMenu->SetShowState(true); __pOptionMenu->Show();
21
Introduction to bada: A Developer's Guide - (draft preview, July 2010)
} break; case ID_OPTION1: // Because this item has sub items attached, you // don't need to do any additional event handling here break; case ID_OPTION2: // Add event handling code here break; case ID_OPTION3: // Add event handling code here break; case ID_OPTIONA: // Add event handling code here break; case ID_OPTIONB: // Add event handling code here break; default: break; } }
The Option Key and Option Menu should be created during initialization of the MainForm (OnInitializing()): 1. 2. 3. 4.
Set the Action ID of the Form‟s Option Key control. Register the IActionEventListener implemented by the MainForm class. Create an Option Menu and initialize. Add the main items to the Option Menu, specifying the text string to be displayed and the item‟s action IDs. 5. Add any sub items to the Option Menu, specifying the index of the main item to attach the sub item to, the text string to be displayed and the item‟s action IDs. 6. Register the IActionEventListener implemented by the MainForm class, with the Option Menu object. 22
Introduction to bada: A Developer's Guide - (draft preview, July 2010)
The following code snippet is an example of code that would be added to the MainForm’s OnInitializing() method, in order to create the Option Key and Option Menu: // Create an OptionKey SetOptionkeyActionId(ID_OPTIONKEY); AddOptionkeyActionListener(*this); // Create an OptionMenu __pOptionMenu = new OptionMenu(); __pOptionMenu->Construct(); __pOptionMenu->AddItem("Option1",ID_OPTION1); __pOptionMenu->AddItem("Option2",ID_OPTION2); __pOptionMenu->AddItem("Option3",ID_OPTION3); // Add a sub items to the first item in the options menu @ index 0 __pOptionMenu->AddSubItem(0, "Sub item1", ID_OPTIONA); __pOptionMenu->AddSubItem(0, "Sub item2", ID_OPTIONB); // Register an event listener __pOptionMenu->AddActionEventListener(*this);
Hints, pitfalls and related topics The example shown in this recipe has a 2-level fixed structure for the Option Menu‟s menu hierarchy. It is also possible to dynamically add, change and delete items during runtime. If you want to change the content of the Option Menu there are several methods that can be used to add, change and delete both main items and sub items. These methods are: AddItem(), AddSubItem(), SetItemAt(), SetSubItemAt(), RemoveItemAt() and RemoveSubItemAt(). If you need to determine if there are any sub items associated with a main item, and how many there are, the GetSubItemCount() method can be used. In the example, the first main item in the menu (ID_OPTION1) has sub items associated with it. In this scenario no code needs to be implemented in the OnActionPerformed() event handler for this Action ID, as the display of the sub items is automatically performed by the Option Menu object. But, 23
Introduction to bada: A Developer's Guide - (draft preview, July 2010)
if there is code for this Action ID in the OnActionPerformed() event handler, it will get executed after the sub items are displayed. When a sub item, or main item with no associated sub item is selected by the user, the Option Menu object will generate the appropriate event for the form to handle and the menu will be removed from the display. Because of the way in which the Option Menu is removed from the display when it has no sub items to display, it is not recommended to dynamically create any sub items for a main item on selection of that main item. If the items text string is too long, it will be truncated when displayed:
A main item will get truncated at 2 lines of text (in English) and „…‟ will be added to the end of the string A sub item will get truncated at 1 line of text (in English) and „…‟ will be added to the end of the string.
Related recipes 2.1 Adding a Form recipe 2.2 Adding a Button recipe
24
Introduction to bada: A Developer's Guide - (draft preview, July 2010)
2.5 Display MessageBox to confirm an action Problem description You want to prompt the user for confirmation of an action, outside the fixed view or menu structure of your application.
The recipe The following configuration is required. Namespaces used: Osp::Ui, Osp::Ui::Control Header files to #include: FUi.h, FUiControls.h Required libraries: FUi [.lib | .so], FUiControls [.lib | .so] Required privilege level: Normal Required privilege groups: None This recipe shows how to launch and display an acknowledgement MessageBox that displays a message to the user and an OK button, and waits for the user to confirm by pressing OK. A MessageBox can also have no button, in which case the message is simply displayed, or two or three buttons. Buttons have fixed text, set by the MSGBOX_STYLE parameter. Handling the user response is easy – it is set in the argument passed to the launch method. Unlike other Control-derived classes which are used as building blocks to populate the Forms from which an application‟s UI is constructed, a MessageBox is a so-called modal control; a MessageBox is instantiated, initialized, and displayed outside the normal event flow of the currently displayed Form and any Controls the Form owns. 25
Introduction to bada: A Developer's Guide - (draft preview, July 2010)
Unlike other controls, MessageBox derives from the Window class, via the derivation chain: Object -> Control -> Container -> Window -> [ MessageBox | Popup ] A MessageBox therefore is drawn directly into the window area it defines, on top of the current Form. Conceptually therefore a MessageBox defines an additional mode of interaction outside the fixed infrastructure of the application‟s Forms; a MessageBox is direct and immediate. To use a MessageBox, #include the following header files and declare the appropriate namespace: #include #include #include using namespace Osp::Ui::Controls;
The code to instantiate and launch a MessageBox is almost trivial: /* * Giving a title and message for the popup windows showing to the user */ void Utils::showMessage(const String &title, const String &message) { MessageBox messageBox; messageBox.Construct(title, message, MSGBOX_STYLE_OK, 3000); // Call ShowAndWait - draw, show itself and process events int modalResult = 0; messageBox.ShowAndWait(modalResult); switch(modalResult) { case MSGBOX_RESULT_OK: // TODO break; default: break; } }
26
Introduction to bada: A Developer's Guide - (draft preview, July 2010)
The MessageBox constructor is used to set values for the title, message, style, and timeout period of the instance; and then the ShowAndWait(result) method is called, which instantiates and displays the MessageBox, sets the user response in the result argument, and manages destruction and cleanup.
Hints, pitfalls, and related topics Forms and menus create the fixed architecture of an interactive application. But a typical application also requires the more dynamic kinds of interaction provided by prompts, alerts, messages and notifications based on the specific context of the moment. The MessageBox class is almost trivial to use, but is rather limited in the options it provides; in particular, only a small selection of preset buttons is provided: MSGBOX_STYLE_NONE MSGBOX_STYLE_OK MSGBOX_STYLE_CANCEL MSGBOX_STYLE_OKCANCEL MSGBOX_STYLE_YESNO MSGBOX_STYLE_YESNOCANCEL MSGBOX_STYLE_ABORTRETRYIGNORE MSGBOX_STYLE_CANCELTRYCONTINUE MSGBOX_STYLE_RETRYCANCEL
Contains no buttons Contains one button: OK Contains one button: CANCEL Contains two buttons: OK and CANCEL Contains two buttons: YES and NO Contains three buttons: YES, NO and CANCEL Contains three buttons: ABORT, RETRY, and IGNORE Contains three buttons: CANCEL, TRY and CONTINUE Contains two buttons: RETRY and CANCEL
Where more flexibility is required, the Popup class enables a similar style of dynamic interaction, and is fully customizable – but also requires explicit construction, initialization, display, and cleanup. Popups can also contain buttons, labels, and other simple controls to enable capturing a richer variety of user choices or selections. On return of the ShowAndWait() method (which is a synchronous function), the result argument contains the result of the call.
27
Introduction to bada: A Developer's Guide - (draft preview, July 2010)
The following results are returned by a MessageBox: MSGBOX_RESULT_CLOSE MSGBOX_RESULT_OK MSGBOX_RESULT_CANCEL MSGBOX_RESULT_YES MSGBOX_RESULT_NO MSGBOX_RESULT_ABORT MSGBOX_RESULT_TRY MSGBOX_RESULT_RETRY MSGBOX_RESULT_IGNORE MSGBOX_RESULT_CONTINUE
The message box was closed The OK button was selected The cancel button was selected The Yes button was selected The No button was selected The Abort button was selected The Try button was selected The Retry button was selected The Ignore button was selected The Continue button was selected
The MessageBox class is easy to use, but it has one important limitation.
The call to launch a MessageBox is synchronous and blocking; the MessageBox is not dismissed until the user response is received or until it times out.
For this reason a MessageBox should never be launched from a listener callback method, since it will block the callback‟s return and disrupt the asynchronous event flow. Therefore, inside a callback method, always use a Popup instead.
28
Introduction to bada: A Developer's Guide - (draft preview, July 2010)
2.6 Using a keypad control Problem description You want to pop up a Keypad and get input from it.
The recipe The following configuration is required for this recipe: Namespaces used: Osp::Ui, Osp::Ui::Controls, Osp::Base Header files to #include: FUi.h, FUiControls.h, FBase.h Required libraries: FUi, FUiControls, FBase [.lib | .so] Required privilege level: Normal Required privilege groups: None A Keypad is a UI control which provides a means for the user to input alphanumeric text. A Keypad can either be used within an application as a stand-alone keypad or as part of an Edit Field or Edit Area input control. For a stand-alone keypad, only a full screen keypad is available. For a keypad automatically created by the system for an Edit Field or Edit Area control, both full screen and overlay keypads are supported This recipe shows two different methods that can be deployed to make use of the Keypad control. Each method details the steps required to create and use the Keypad, and provides some sample code snippets.
29
Introduction to bada: A Developer's Guide - (draft preview, July 2010)
Both methods in this recipe assume the steps detailed in method 2 of the „Adding a Form‟ recipe have been followed to add a Form to the Application‟s Frame. Method 1: Using the stand-alone keypad control This recipe creates a stand-alone keypad using the Osp::Ui:Controls::Keypad class and displays it in the Application Frame. Any text events generated by the keypad, can be processed by the application by implementing the Osp::Ui::ITextEventListener interface class.
Figure 2.6.1 Stand-alone keypad When a stand-alone keypad is used, it is not added to any container, so it must be explicitly deleted when it is no longer required. The Application Framework will not delete the Keypad when the application terminates. The ITextEventListener interface receives text events. In order for the application to retrieve any text that has been entered by the user using the Keypad control, this interface must be implemented. The following code snippet shows an example of the MainForm class definition: 30
Introduction to bada: A Developer's Guide - (draft preview, July 2010)
class MainForm : public Osp::Ui::Controls::Form, public Osp::Ui::ITextEventListener { // Construction public: MainForm(void); ~MainForm(void); bool Initialize(void); private: Osp::Ui::Controls::Keypad *__pKeypad; public: result OnInitializing(void); result OnTerminating(void); void ShowKeypad(bool show); void OnTextValueChanged(const Osp::Ui::Control& source); void OnTextValueChangeCanceled(const Osp::Ui::Control& source); };
The Keypad control can be created during initialization of the MainForm (OnInitializing()): 1. Create a keypad object. 2. Set the required style and input mode category parameters e.g. normal style with alphabetic input mode. 3. Register the ITextEventListener implemented by the MainForm class to the Keypad control. The following code snippet is an example of code that would be added to the MainForm’s OnInitializing() method, in order to create a Keypad control: // Create the Keypad member object __pKeypad = new Keypad(); // Initialize with specified style and category __pKeypad->Construct(KEYPAD_STYLE_NORMAL, KEYPAD_MODE_ALPHA);
31
Introduction to bada: A Developer's Guide - (draft preview, July 2010)
// Register an event listener __pKeypad->AddTextEventListener(*this);
As the Keypad control is not explicitly added to the Form container, it will not automatically be displayed. The keypad‟s Show() method must be called to display the keypad. For example, the display of the keypad could be triggered by a press of a softkey invoking the ShowKeypad() method: void MainForm::ShowKeypad(bool show) { if(true == show) { __pKeypad->Show(); } else // call the Form’s Show() method { Show(); } }
The stand-alone keypad displays „Done‟ and „Cancel‟ command buttons in the softkey area. Although they look like softkeys, they are not softkeys and do not behave in the same way as softkeys. When the „Done‟ button is tapped, a ITextEventListener action event is triggered and the MainForm’s OnTextValueChanged() method is invoked. When the „Cancel‟ button is tapped, a ITextEventListener action event is triggered and the MainForm’s OnTextValueChangedCanceled() method is invoked. These methods can be used by an application to retrieve the data that has been entered by the user using the Keypad control. For example the OnTextValueChanged() method can be implemented to retrieve the text string from the keypad object: void MainForm::OnTextValueChanged(const Osp::Ui::Control& source) { String string(__pKeypad->GetText());
// Retrieve text from Keypad object
}
32
Introduction to bada: A Developer's Guide - (draft preview, July 2010)
Method 2: Using an overlay style keypad within an edit field This recipe creates an edit field, which displays one line of editable text to the user. It is implemented in the overlay style, so that when the user taps on the edit control, an overlay keypad is launched and the edit control is automatically scrolled so that it does not overlap with the overlay keypad, below.
Figure 2.6.2 Edit Field with overlay keypad In order to use the overlay style of keypad, the Form must contain a scroll panel and the edit field control must be added to the scroll panel. This recipe creates a scroll panel container using the Osp::Ui::Controls::ScrollPanel class and creates an edit field control using the Osp::Ui::Controls::EditField class. The IScrollPanelEventListener interface must be implemented in order to handle the events generated when the keypad is opened or closed, e.g. for retrieval of the edited text string. The ITextEventListener interface must be implemented if the application needs to be aware of when the cursor moves within the edit field. The IActionEventListener interface must be implemented if the edit field is created with the optional keypad command button controls, in order to handle the events generated when these buttons are tapped. 33
Introduction to bada: A Developer's Guide - (draft preview, July 2010)
The following code snippet shows an example of the MainForm class definition: class MainForm : public Osp::Ui::Controls::Form, public Osp::Ui::IActionEventListener, public Osp::Ui::ITextEventListener, public Osp::Ui::IScrollPanelEventListener { // Construction public: MainForm(void); ~MainForm(void); bool Initialize(void); // Implementation protected: static const int ID_BUTTON_EDITFIELD_DONE = 100; static const int ID_BUTTON_EDITFIELD_CANCEL = 101; private: Osp::Ui::Controls::EditField* __pEditField; Osp::Ui::Controls::ScrollPanel* __pScrollPanel; Osp::Base::String* __pEditFieldText; public: result OnInitializing(void); result OnTerminating(void); void OnActionPerformed(const Osp::Ui::Control& source, int actionId); void OnTextValueChanged(const Osp::Ui::Control& source); void OnTextValueChangeCanceled(const Osp::Ui::Control& source); void OnOverlayControlCreated(const Osp::Ui::Control& source); void OnOverlayControlOpened(const Osp::Ui::Control& source); void OnOverlayControlClosed(const Osp::Ui::Control& source); void OnOtherControlSelected(const Osp::Ui::Control& source); };
34
Introduction to bada: A Developer's Guide - (draft preview, July 2010)
The ScrollPanel container and the EditForm control can be created during initialization of the MainForm (OnInitializing()): 1. Create ScrollPanel object and initialize it by setting its size and position using a Rectangle instance. 2. Create EditField object and initialize it with its size, position, edit field style, input style, title, input length limit and table view style parameters. 3. Register the IActionEventListener implemented by the MainForm class with the EditField control. 4. Register ITextEventListener implemented by the MainForm class with EditField control. 5. Register the IScrollPanelEventListener implemented by the MainForm class with the EditField control. 6. Add the EditField’s left and right command buttons. 7. Create a String object to store the edited text. 8. Add the EditField control to the ScrollPanel container. 9. Add the ScrollPanel container to the MainForm. The following code snippet is an example of code that would be added to the MainForm’s OnInitializing() method, in order to create a overlay style edit field control: // Create ScrollPanel __pScrollPanel = new ScrollPanel(); __pScrollPanel->Construct(Rectangle(0, 0, 480, 712)); // Create EditField __pEditField = new EditField(); __pEditField->Construct(Rectangle(0, 300, 480, 80), EDIT_FIELD_STYLE_NORMAL, INPUT_STYLE_OVERLAY, true, 20, GROUP_STYLE_SINGLE); __pEditField->SetGuideText(L"Edit Field"); // Register event listeners __pEditField->AddActionEventListener(*this); __pEditField->AddTextEventListener(*this); __pEditField->AddScrollPanelEventListener(*this); // Add command buttons __pEditField->SetOverlayKeypadCommandButton( COMMAND_BUTTON_POSITION_LEFT, L"Done", ID_BUTTON_EDITFIELD_DONE); __pEditField->SetOverlayKeypadCommandButton(
35
Introduction to bada: A Developer's Guide - (draft preview, July 2010)
COMMAND_BUTTON_POSITION_RIGHT, L"Cancel", ID_BUTTON_EDITFIELD_CANCEL); // Create String to store entered text __pEditFieldText = new String(); // Add an EditField to the Scroll Panel __pScrollPanel->AddControl(*__pEditField); // Add a ScrollPanel to the Form AddControl(*__pScrollPanel);
When the user taps on the edit field control the overlay keypad is launched. In order to receive and process any changes to the overlay keypad, the following IScrollPanelEventListener methods should be implemented: OnOtherControlSelected(),OnOverlayControlClosed(),OnOverlayControlCrea ted()and OnOverlayControlOpened(). The following code snippet shows an example of how the edit field‟s text string can be stored in a string member variable when the keypad is opened, in the OnOverlayControlOpened() method: void MainForm::OnOverlayControlOpened(const Osp::Ui::Control& source) { __pEditFieldText->Clear(); __pEditFieldText->Append(__pEditField->GetText()); }
When the overlay keypad is active and the user taps either of the edit field control‟s command buttons, an action event is generated and is handled in the OnActionPerformed() method. The following code snippet is an example of the command button event handling in the MainForm’s OnActionPerformed() method:
36
Introduction to bada: A Developer's Guide - (draft preview, July 2010)
void MainForm::OnActionPerformed(const Osp::Ui::Control& source, int actionId) { switch(actionId) { case ID_BUTTON_EDITFIELD_DONE: __pScrollPanel->CloseOverlayWindow(); __pEditField->Draw(); __pEditField->Show(); break; case ID_BUTTON_EDITFIELD_CANCEL: __pEditField->SetText(*__pEditFieldText); __pScrollPanel->CloseOverlayWindow(); __pEditField->Draw(); __pEditField->Show(); break; default: break; } }
When the „Done‟ button is tapped the overlay keypad is closed and the Edit Field is redrawn. When the „Cancel‟ button is tapped the original text string, which is stored in the member variable __pEditFieldText, is loaded into the edit field, the overlay keypad is closed and Edit Field redrawn.
Hints, pitfalls and related topics The ITextEventListener interface receives text events, but the type of text events it receives will differ depending on what type of UI control it is registered with. For example, in method 1 the OnTextValueChanged() method is invoked when the „Done‟ button is tapped, but in method 2 it is invoked each time the cursor moves within the edit field. By default an overlay style keypad is not displayed with any command buttons. If these buttons are required they must be created using the SetOverlayKeypadCommandButton() method. When initializing a ScrollPanel object for the EditField to be placed within, the location and size parameters for the ScrollPanel should be set relative to the top left of the Form‟s available client 37
Introduction to bada: A Developer's Guide - (draft preview, July 2010)
area. So if a Form contains an indicator area and/or a title area, the heights of these areas should be taken into account when setting the ScrollPanel‟s height parameter. If these values are not set correctly the overlay keypad will not be displayed in the correct position. To clear any previous text entered in the stand-alone keypad, the SetText() method can be called with an empty string parameter.
Related recipes 2.1 Adding a Form recipe
38
Introduction to bada: A Developer's Guide - (draft preview, July 2010)
2.7 Get touch events Problem description You want to retrieve touch events from the user input.
The recipe The following configuration is required for this recipe: Namespaces used: Osp::Ui, Osp::Ui::Controls, Osp::Graphics3 Header files to #include: FUi.h, FUiControls.h, FGraphics.h27 Required libraries: FUi, FUiControls, FGraphics27 [.lib | .so] Required privilege level: Normal Required privilege groups: None The bada platform supports both single-point and multi-point touch user input. This recipe details the steps to enable single-point touch user input within a Form and describes the code that needs to be implemented for the Form to receive and handle touch events. This recipe assumes the steps detailed in method 2 of the „Adding a Form‟ recipe have been followed to add a Form to the Application‟s Frame.
3
For graphics canvas drawing in the recipe
39
Introduction to bada: A Developer's Guide - (draft preview, July 2010)
In this recipe the touch screen user input is handled by the application and is used to draw lines on a graphics canvas. A line is drawn on the graphics canvas following the motion of the users touch input. The double-tap touch input is used to clear the canvas.
Figure 2.7.1 Drawing lines with touch screen input
As shown in the “Adding a Form” recipe the MainForm class is inherited from the Form base class. In order for this form to handle events from the touch screen, an event listener interface has to be implemented. So in this recipe the MainForm class must implement the Osp::Ui::ITouchEventListener interface class. The following code snippet shows an example of the MainForm class definition: class MainForm : public Osp::Ui::Controls::Form, public Osp::Ui::ITouchEventListener { public:
40
Introduction to bada: A Developer's Guide - (draft preview, July 2010)
MainForm(void); ~MainForm(void); bool Initialize(void); private: Osp::Graphics::Canvas* __pDrawingCanvas; Osp::Graphics::Point* __pStartPoint; public: result OnDraw(void); result OnInitializing(void); result OnTerminating(void); void OnTouchPressed(const Osp::Ui::Control& source, const Osp::Graphics::Point& currentPosition, const Osp::Ui::TouchEventInfo & touchInfo); void OnTouchLongPressed(const Osp::Ui::Control& source, const Osp::Graphics::Point& currentPosition, const Osp::Ui::TouchEventInfo & touchInfo); void OnTouchReleased(const Osp::Ui::Control& source, const Osp::Graphics::Point& currentPosition, const Osp::Ui::TouchEventInfo & touchInfo); void OnTouchMoved(const Osp::Ui::Control& source, const Osp::Graphics::Point& currentPosition, const Osp::Ui::TouchEventInfo & touchInfo); void OnTouchDoublePressed(const Osp::Ui::Control& source, const Osp::Graphics::Point& currentPosition, const Osp::Ui::TouchEventInfo & touchInfo); void OnTouchFocusIn(const Osp::Ui::Control& source, const Osp::Graphics::Point& currentPosition, const Osp::Ui::TouchEventInfo & touchInfo); void OnTouchFocusOut(const Osp::Ui::Control& source, const Osp::Graphics::Point& currentPosition, const Osp::Ui::TouchEventInfo & touchInfo); };
In order to receive touch events, the MainForm must register the touch event listener using the AddTouchEventListener() method.
41
Introduction to bada: A Developer's Guide - (draft preview, July 2010)
The creation of the canvas and the registration of the touch event listener should be performed during initialization of the MainForm (OnInitializing()): 1. 2. 3. 4. 5. 6. 7.
Create a graphics canvas and set its size and position based on the available client area. Set the background colour of the MainForm. Set the background colour and foreground colour of the drawing canvas. Set the line width for the drawing canvas. Clear the drawing canvas. Create a Point object, to store the touch start position when drawing. Register the ITouchEventListener implemented by the MainForm class.
The following code snippet is an example of code that would be added to the MainForm’s OnInitializing() method, in order to create a graphics canvas and enable the handling of touch events: // Create a member canvas object, and set its size to the // Form's client area __pDrawingCanvas = new Canvas; __pDrawingCanvas->Construct(GetClientAreaBounds()); // Set background colour of the Form SetBackgroundColor(Color::COLOR_WHITE); // Set the bg, fg colour and line width of canvas __pDrawingCanvas->SetBackgroundColor(Color::COLOR_WHITE); __pDrawingCanvas->SetForegroundColor(Color::COLOR_RED); __pDrawingCanvas->SetLineWidth(3); __pDrawingCanvas->Clear(); // Create an instance of a Point to store the touch start position __pStartPoint = new Point(); // Register touch event listener AddTouchEventListener(*this);
Because this recipe is using the touch events to create a custom drawing on a graphics canvas, the OnDraw() method must be implemented. The GetCanvasN() method is used within the OnDraw() implementation to retrieve the canvas the MainForm is using, otherwise the default Draw() method of the MainForm will overwrite the custom drawing. 42
Introduction to bada: A Developer's Guide - (draft preview, July 2010)
In this recipe the OnDraw() method copies the contents of the drawing canvas to the window canvas; this is necessary because the drawing operations are not actually being performed directly on the MainForm’s canvas in the OnDraw() method:
result MainForm::OnDraw(void) { result r = E_SUCCESS; // Retrieve the window canvas Canvas* pWindowCanvas = GetCanvasN(); if (pWindowCanvas) { // Copy the contents of the drawing canvas (where the drawing // operations have been performed) to the window canvas pWindowCanvas->Copy(Point(GetClientAreaBounds().x, GetClientAreaBounds().y), *__pDrawingCanvas, GetClientAreaBounds()); delete pWindowCanvas; } return r; }
The display will be updated when the MainForm’s Show() method is called; this occurs automatically following the OnDraw() callback. In order to handle the touch events when they occur the following methods have to be implemented by the MainForm: OnTouchDoublePressed(), OnTouchFocusIn(), OnTouchFocusOut(), OnTouchLongPressed(), OnTouchLongPressed(), OnTouchMoved(), OnTouchPressed(), or OnTouchReleased(). Each method is passed information about the source of the event, the current position, the start position and the status of the event.
43
Introduction to bada: A Developer's Guide - (draft preview, July 2010)
In this recipe only the OnTouchPressed(), OnTouchMoved() and OnTouchDoublePressed() methods have been implemented. The TOUCH_PRESSED event occurs when the user touches the screen. This event is handled in the MainForm by the OnTouchPressed() method. In this recipe the OnTouchPressed() method is used to set the touch start position Point object to the current position touched by the user:
void MainForm::OnTouchPressed(const Osp::Ui::Control& source, const Osp::Graphics::Point& currentPosition,const Osp::Ui::TouchEventInfo & touchInfo) { // Set the touch start position to the current position __pStartPoint->SetPosition(currentPosition); }
This touch start position is used in the OnTouchMoved() method for the line drawing. The TOUCH_MOVED event occurs when the user is touching the screen and they have moved their finger across the screen. The first event is sent after the user has moved 22 pixels in either the x or y direction, and thereafter events are sent for every movement of 2 pixels or more in either direction. This event is handled in the MainForm by the OnTouchMoved() method. In this recipe the OnTouchMoved() method is used to draw a line from the stored touch start position to the current position: void MainForm::OnTouchMoved(const Osp::Ui::Control& source, const Osp::Graphics::Point& currentPosition, const Osp::Ui::TouchEventInfo & touchInfo) { // Draw a line from stored touch start point to current position __pDrawingCanvas->DrawLine(*__pStartPoint, currentPosition);
44
Introduction to bada: A Developer's Guide - (draft preview, July 2010)
// Draw the Form RequestRedraw(); // Set the current position to the touch start point __pStartPoint->SetPosition(currentPosition); }
After the line is drawn, the touch start position is set to the current position. This is necessary to draw a line that correctly represents the user‟s motion across the screen. The start position passed into this function cannot be used because it is the start position of when the user touched the screen, not the start position of the last movement. The TOUCH_DOUBLE_PRESSED event occurs when the user double taps on the screen. This event is handled in the MainForm by the OnTouchDoublePressed() method. In this recipe the OnTouchDoublePressed() method is used to clear the graphics canvas: void MainForm::OnTouchDoublePressed(const Osp::Ui::Control& source, const Osp::Graphics::Point& currentPosition,const Osp::Ui::TouchEventInfo & touchInfo) { // Clear the canvas __pDrawingCanvas->Clear(); // Draw the Form RequestRedraw(); }
Hints, pitfalls and related topics As would be expected, the TOUCH_PRESSED and TOUCH_RELEASED events occur in pairs when the user touches the screen. These events also occur in conjunction with the TOUCH_MOVED,
45
Introduction to bada: A Developer's Guide - (draft preview, July 2010)
TOUCH_LONG_PRESSED and TOUCH_DOUBLE_PRESSED events. These event sequences need to be taken into account when designing an application‟s event processing. The sequence of events for a movement touch event is: 1. TOUCH_PRESSED 2. TOUCH_MOVED (multiple times) 3. TOUCH_RELEASED The sequence of events for a long press touch event is: 1. TOUCH_PRESSED 2. TOUCH_LONG_PRESSED 3. TOUCH_RELEASED The sequence of events for a double-tap touch event is: 1. 2. 3. 4.
TOUCH_PRESSED TOUCH_RELEASED TOUCH_DOUBLE_PRESSED TOUCH_RELEASED
It might be suitable for an application to only process a TOUCH_PRESSED event when its corresponding TOUCH_RELEASED event has been received. Or alternatively, the application may be designed so that any processing done in the OnTouchPressed() method is reversed if the TOUCH_MOVED, TOUCH_LONG_PRESSED or TOUCH_DOUBLE_PRESSED event is received in the sequence afterwards. In both these cases it would be necessary to store the status of the previous event(s). It is advisable not to do too much processing in the OnTouchMoved() method, as the sensitivity (2 pixels) of movement can result in this method being called many times. In this recipe, the GetCanvasN() method is used in the OnDraw() method to retrieve the MainForm‟s canvas. To prevent memory leaks, if a method has an „N‟ postfix, the caller must delete the returned instance after the caller is finished with the instance.
Related recipes 2.1 Adding a Form recipe 46
Introduction to bada: A Developer's Guide - (draft preview, July 2010)
2.8 Using base applications Problem description You want to launch a base application from a bada application using the Application Control.
The recipe The following configuration is required for this recipe: Namespaces used: Osp::Ui, Osp::Ui::Controls, Osp::App, Osp::Base::Collection Header files to #include: FUi.h, FUiControls.h, FApp.h, FBase.h Required libraries: FUi, FUiControls, FApp, FBase [.lib | .so] Required privilege level: Normal Required privilege groups: WEB_SERVICE4 Base applications are those which are stored in the built-in memory of the device and are not removable via the Application Manager. Base applications export features which are commonly required by other applications e.g. playing a video, or retrieving a contact. Access to these features is provided through Application Control. The Application Manager is used to find the base application that provides the feature required by an application, and an instance of the Application Control is returned. The Application Control is then used to start a base application and control specific behavior. Once the Application Control is started, the application goes to the background and the target application control UI is displayed.
4
Required for example 1 only.
47
Introduction to bada: A Developer's Guide - (draft preview, July 2010)
This recipe shows two different examples of accessing functionality from a base application. Each example details the steps required to use the Application Control to access the necessary functionality, and provides some sample code snippets. Both examples in this recipe assume the steps detailed in method 2 of the „Adding a Form‟ recipe (2.1) have been followed to add a Form to the Application‟s Frame. Example 1: Launching the browser application This recipe uses Application Control to launch the base application Browser with a specific URI. The relevant data to be delivered to the Application control, in this case the URI, is constructed using a collection of type Osp::Base::Collection::ArrayList.
Figure 2.8.1 Application Control – launching the browser
As the Browser Application control does not return any status information or data, no callback listener is required. 48
Introduction to bada: A Developer's Guide - (draft preview, July 2010)
The WEB_SERVICE group privilege is required to use the Browser Application control. The following steps are necessary to launch the Browser base application with the specified URI: 1. Use the Application Manager to find the Application Control for launching the Browser. 2. Create an instance of an ArrayList collection to store the application control data in. 3. Create an instance of a String and initialise it with the “url:” tag and the URI for the Browser Application control to launch. 4. Start the Browser Application control, passing in the URI data in an ArrayList. The following code snippet is an example of a method that would be added to the MainForm‟s class, in order to launch the browser to a specified URI: result MainForm::LaunchBrowser(void) { result r = E_SUCCESS; // Find the required Application Control based on the application // control id and the type of operation required AppControl* pAc = AppManager::FindAppControlN(APPCONTROL_BROWSER, OPERATION_MAIN); if(pAc != null) { // Create an ArrayList and initialise ArrayList* pDataList = null; pDataList = new ArrayList(); pDataList->Construct(); // Create String for URI and add to the ArrayList String* pData = null; pData = new String(L"url:http://www.bada.com"); pDataList->Add(*pData); // Start the required application with the relevant data. // As the BROWSER does not provide any callback data, no listener is required. r = pAc->Start(pDataList, null); delete pAc;
49
Introduction to bada: A Developer's Guide - (draft preview, July 2010)
pDataList->RemoveAll(true); delete pDataList; } else { r
= E_OBJ_NOT_FOUND;
} return r; }
Once the Application control Start() method has been called the application goes to the background and the Browser UI is displayed. When the user exits the Browser application, the application returns to the foreground. Example 2: Retrieving phone numbers from the contacts list This recipe uses Application Control to launch the Contact application and allows the user to select multiple phone numbers from the list of contacts. The relevant data to be delivered to the Application control, in this case the selection mode and the return type, is constructed using a collection of type Osp::Base::Collection::ArrayList.
Figure 2.8.2 Application Control - select items from Contact application 50
Introduction to bada: A Developer's Guide - (draft preview, July 2010)
In order to allow the user to select phone numbers from the Contact application it is launched with the PICK operation. This operation results in some data being returned from the Contact Application Control when it is exited. This data is the result of the operation and the value strings of the selected contacts. In order to receive data from the Contacts Application control the application needs to implement the Osp::App::IAppControlEventListener interface. The following code snippet shows an example of the MainForm class definition: class MainForm : public Osp::Ui::Controls::Form, public Osp::App::IAppControlEventListener { // Construction public: MainForm(void); ~MainForm(void); bool Initialize(void); public: result OnInitializing(void); result OnTerminating(void); void OnAppControlCompleted(const Osp::Base::String& appControlId, const Osp::Base::String& operationId, const Osp::Base::Collection::IList* pResultList); result GetContact(void); void DisplayContact(String* number); };
The following steps are necessary to launch the Contact base application: 1. Use the Application Manager to find the Application Control for launching the Contact application with the PICK operation. 2. Create an instance of an ArrayList collection to store the application control data. 3. Create an instance of a String, initialize it with the “selectionMode:” tag and the selection mode for the Contact application (in this example multiple selection mode is defined) and add it to the ArrayList. 51
Introduction to bada: A Developer's Guide - (draft preview, July 2010)
4. Create an instance of a String, initialise it with the “returnType:” tag and the return type for the Contact application (in this example the phone number value string is requested) and add it to the ArrayList. 5. Start the Contact Application control, passing in the application control data in an ArrayList and a pointer to the Application Control callback listener. The following code snippet is an example of a method that would be added to the MainForm’s class, in order to launch the Contact application for the required operation: result MainForm::GetContact(void) { result r = E_SUCCESS; // Find the required Application Control based on the application // control id and the type of operation required AppControl* pAc = AppManager::FindAppControlN(APPCONTROL_CONTACT, OPERATION_PICK); if(pAc != null) { // Create an ArrayList and initialise ArrayList* pDataList = null; pDataList = new ArrayList(); pDataList->Construct(); // Create String for selection mode and add to the // ArrayList String* pData1 = null; pData1 = new String(L"selectionMode:multiple"); pDataList->Add(*pData1); // Create String for return type and add to the ArrayList String* pData2 = null; pData2 = new String(L"returnType:phone"); pDataList->Add(*pData2); // Start the required application with the relevant data // As the CONTACTS app is going to return phone numbers, // the callback listener must be sent to the
52
Introduction to bada: A Developer's Guide - (draft preview, July 2010)
// application control. r = pAc->Start(pDataList, this); delete pAc; pDataList->RemoveAll(true); delete pDataList; } else { r
= E_OBJ_NOT_FOUND;
} return r; }
The IAppControlEventListener interface receives notification events from the Application Control when it is done (i.e. the operation has completed or has been cancelled). The type of notification data received depends on the type of Application control started and the operation type used. For this example, the implementation of the OnAppControlCompleted() method must handle both Application status results and multiple items of Contact data. The following steps describe the functionality that would be implemented in the OnAppControlCompleted() method: 1. Retrieve the number of result elements in the IList collection returned from the Contact application. 2. Check the application control ID and the operation ID match those requested when the application control was started (APPCONTROL_CONTACT and OPERATION_PICK respectively). 3. If they match, determine if the request was successful by retrieving the first result item from the IList collection and comparing it with the APPCONTROL_RESULT_SUCCEEDED result. 4. If it matches, determine if the correct return type has been set by retrieving the second result item from the IList collection and comparing it with the string “phone”. 5. If it matches, retrieve all the data values by looping through the list until the last element is reached. The following code snippet is an example of the Application Control event handling in the MainForm‟s OnAppControlCompleted() method:
53
Introduction to bada: A Developer's Guide - (draft preview, July 2010)
void MainForm::OnAppControlCompleted(const Osp::Base::String& appControlId, const Osp::Base::String& operationId, const Osp::Base::Collection::IList* pResultList) { String* pPickResult = null; int loopCount = 0; int elementCount = pResultList->GetCount(); if(appControlId.Equals(APPCONTROL_CONTACT) && operationId.Equals(OPERATION_PICK)) { pPickResult = (String*)pResultList->GetAt(0); if(pPickResult->Equals(APPCONTROL_RESULT_SUCCEEDED)) { pPickResult = (String*)pResultList->GetAt(1); if(pPickResult->Equals(String(L"phone"))) { // Result is a phone number, // so retrieve numbers from the list for (loopCount=2; loopCountGetAt(loopCount); DisplayContact(pPickResult); } } } } }
In this example a DisplayContact() method can be implemented to display the phone numbers retrieved from the Contact application. Once the Application control start method has been called the application goes to the background and the Contact UI is displayed. When the user selects required items or exits the Contact application, the application returns to the foreground. 54
Introduction to bada: A Developer's Guide - (draft preview, July 2010)
Hints, pitfalls and related topics The WEB_SERVICE group privilege must be set in the Application‟s manifest file in order to use the Browser Application control.
When using the Contact application control it is not possible to request the return of multiple items of data related to a single contact (e.g. both the phone number and the Email address). If this functionality is required the following steps should be performed instead: 1. Use the Contact application control for the user to select the required contact, but request the return type from the operation to be the contact ID. 2. Use the Osp::Social::Addressbook class‟s GetContactN() method to retrieve all the contact details associated with the contact. The ADDRESSBOOK group privilege must be set in the Application‟s manifest file in order to use this Address book functionality. When selecting multiple items from the Contact application, they may not be added to the IList collection in the same order as they are presented in the Contact application. They will be returned in the order of ascending contact ID (i.e. in the order in which the information was saved in the Contact application).
Related recipes 2.1 Adding a Form recipe
55
Introduction to bada: A Developer's Guide - (draft preview, July 2010)
2.9 Get magnetic field from Compass Sensor Problem description You want to obtain data from the magnetometer (compass sensor) to interpret that information for various applications (e.g., determine device orientation or metal detection).
The recipe The following configuration is required. Namespaces used: Osp::Uix Header files to #include: FUixSensorManager.h, FUixSensorTypes.h Required libraries: FUix[.lib | .so] Required privilege level: Normal Required privilege groups: none. This recipe is related to the namespace Osp::Uix. Uix stands for UI extension, which provides additional novel ways for the user to interface with a device. These are not covered in basic UIs. Traditional UI approaches mostly depend on oral or visual in- and output for providing information, or they take commands or information from the user through buttons. UI extension is intended to improve the user's experience in interacting with a mobile phone.
This recipe covers one particular part of that namespace. We make use of the magnetometer (magnetic sensor). This sensor is a 3-axis electronic compass. It can also be used for determining the orientation. The magnetic sensor measures the magnetic field strength. The measurements are split into the X, Y, and Z axis and the unit is Micro-Tesla (µT). Note that several factors can have an impact on the data coming 56
Introduction to bada: A Developer's Guide - (draft preview, July 2010)
from this sensor: weather, your current location on the planet, and most influentially nearby magnetic fields, such as magnets or electric coils. The magnetic sensor uses the phone as a fixed frame of reference as indicated in the figure below and models this into the 3-axis Cartesian space coordinate system.
Figure 2.9.1 Magnetic field related to the device For this example we use the SensorManager class and the ISensorEventListener interface both from the namespace Osp::Uix. The SensorManager class provides the functionality for adding and removing sensor listeners, checking if a sensor is available, setting intervals and getting the max and min intervals. A bada device can have various physical sensors (for example, an acceleration sensor, GPS sensor, or proximity). The SensorManager supports simple access of built-in sensors in a device. By registering a listener to the SensorManager, an application can get sensor data with a timestamp based on definable intervals. In our example we define a class that inherits from the ISensorEventListener interface. Below you can find a sample header file that contains all the signatures of the methods we will show in this recipe. 57
Introduction to bada: A Developer's Guide - (draft preview, July 2010)
//… class YourClassName : public Osp::Uix::ISensorEventListener { private: Osp::Uix::SensorManager __sensorMgr; // … public: // … bool RegisterSensor(); bool UnRegisterSensor(); void OnDataReceived(Osp::Uix::SensorType sensorType, Osp::Uix::SensorData& sensorData, result r); private: void DrawArrow(); float GetDegree(float rad); float CalculateAngle(float f1, float f2); };
Because we inherit from an interface, we need to overwrite the respective method with the following signature: void OnDataReceived(Osp::Uix::SensorType sensorType, Osp::Uix::SensorData& sensorData, result r);
The implementation of our class also provides two methods that help to resister and unregister a sensor type. bool RegisterSensor() {
58
Introduction to bada: A Developer's Guide - (draft preview, July 2010)
result r = E_SUCCESS; // Construct the sensor manager instance r = __sensorMgr.Construct(); if(IsFailed(r)) { return false; } long interval = 0; // Activate the sensor type SENSOR_TYPE_MAGNETIC r = __sensorMgr.GetMinInterval(SENSOR_TYPE_MAGNETIC, interval); if(IsFailed(r)) { return false; } if (interval < 50) { interval = 50; } // Register our listener to this sensor r = __sensorMgr.AddSensorListener(*this, SENSOR_TYPE_MAGNETIC, interval, false); if(IsFailed(r)) { return false; } return true; }
bool UnRegisterSensor() { result r = E_SUCCESS; // Deactivate our compass sensor
59
Introduction to bada: A Developer's Guide - (draft preview, July 2010)
r = __sensorMgr.RemoveSensorListener(*this); if(IsFailed(r)) { return false; } return true; }
In the body of the overwritten OnDataReceived() method we get the X, Y, and Z values and can process them as needed. In this example we simply calculate the 3D vector of the earth‟s magnetic field (assuming that there are no other sources of severe inferences). For this purpose we defined a member of type float called __magField into which we store the length of this vector. Void OnDataReceived(Osp::Uix::SensorType sensorType, Osp::Uix::SensorData& sensorData, result r) { float x=0 ,y=0 ,z=0; AppLog("DataReceived: Get Magnetic Sensor Data"); sensorData.GetValue((SensorDataKey)MAGNETIC_DATA_KEY_X, x); sensorData.GetValue((SensorDataKey)MAGNETIC_DATA_KEY_Y, y); sensorData.GetValue((SensorDataKey)MAGNETIC_DATA_KEY_Z, z); // Calculate the length of our vector determined by the three axis __magField = Math::Sqrt((Math::Pow(x,2)+ Math::Pow(y,2)+ Math::Pow(z,2))); }
Hints, pitfalls, and related topics Once your code compiles without errors you can run it in the simulator. A very convenient feature of the bada simulator is the Event Injector tool. To get this, right-click on the simulator screen, select the Event Injector, and there choose the Sensors tab. In the row below choose the Magnetic tab. There you can 60
Introduction to bada: A Developer's Guide - (draft preview, July 2010)
freely choose the µT values per X, Y, and Z axis. By clicking on the Send button these are then sent as events to your application running on the bada simulator. This tool is very useful for testing. For some use cases you might be interested in getting the angle between two vectors. The following code snippet should help. float CalculateAngle(float f1, float f2) { float angle = 0; // angle in rad if (f1==0 && f2==0){ angle = 0; return angle; }else{ angle = Math::Asin(f1 / Math::Sqrt((Math::Pow(f1,2) + Math::Pow(f2,2)))); } return angle; }
The SDK calculates the angle in rad. For converting this into degrees you may find the following code useful. float GetDegree(float rad) { return Math::Abs(rad * 180/Math::GetPi()); }
61
Introduction to bada: A Developer's Guide - (draft preview, July 2010)
2.10 Get geographic data from provider and show map Problem description You want to obtain geographic information and display it in form of a map on your bada device. In addition you want to show the current position of a user on that map.
The recipe The following configuration is required. Namespaces used: Osp::Locations, Osp::Locations::Services, Osp::Locations::Controls, Osp::Graphics Header files to #include: FLocations.h Required libraries: FLocations, FLocationControls[.lib | .so] Required privilege level: Normal Required privilege groups: LOCATION, LOCATION_SERVICE The namespace Osp::Locations contains among others the classes LocationProvider and Location, which we will use in our recipe. With the LocationProvider class you can define where you want to get a position from (e.g. from the GPS sensor). This class also implements the interface ILocationListener, which gives you information about location updates. The class Location representing the location information is a part of LocationProvider.
62
Introduction to bada: A Developer's Guide - (draft preview, July 2010)
The namespace Osp::Locations::Services provides a number of useful services that can be exploited by the developer. An essential service that we will also introduce is what is encapsulated in the IMapServiceProvider interface. Finally, the last namespace presented here is Osp::Locations::Controls, which allows users to pan, zoom and interact with maps as is generally expected. We simply show how a map can be displayed on screen that has an overlay additionally showing the users current position. Our sample code presents snips from two C++ source files and their corresponding header files:
MapVisualisation.cpp (covers code for presenting geographic data as a map)
MapInteraction.cpp (covers code for obtaining locations)
In order to be able to display maps we need access to a geographic data provider. For this example we use deCarta as our map provider. You can sign up at deCarta (http://developer.decarta.com) and request a key for free. Once you have your key, you can link your deCarta account in the application by creating a map provider object. We do this in our MapVisualisation class. // Define a name for the provider String providerName = L"deCarta"; // Set a map key for deCarta (insert your username/pwd instead of XXX/YYY) static const String extraInfo = L"ClientName=XXX;ClientPassword=YYY;" "HostUrl=http://developer.kr.dz.decarta.com:80/openls/openls"; // Create a map provider IMapServiceProvider* pProvider = static_cast( ProviderManager::ConnectToServiceProviderN(L"deCarta", LOC_SVC_PROVIDER_TYPE_MAP, extraInfo));
63
Introduction to bada: A Developer's Guide - (draft preview, July 2010)
After that, construct a Map control and configure it according to your display requirements. // Create Map control Map* pMap = new Map(); // Construct the map pMap->Construct(Osp::Graphics::Rectangle(0, 0, GetCanvasN()->GetBounds().width, GetCanvasN()->GetBounds().height), *pProvider); // Configuration: allow panning pMap->SetPanEnabled(true); // Configuration: define the center of the map // These are the coordinates of Staines, UK, around which we center the map double lat = 51.433315; double lon = -0.497382; pMap->SetCenter(lat, lon, false); // Configuration: Show my location pMap->SetMyLocationEnabled(true);
It is important to set the configuration value for the selected map area. The default value is „globalmobile‟. Other area codes can be found on the deCarta website. For demonstration purposes we will use this string to access global map data. This is done by invoking SetPreferencePropertyValue() method which is a member of the map class. Further map configuration settings can be obtained from the deCarta developer site. // Set configuration values static const String CONFIGURATION_VALUE(L"global-mobile"); // Configuration: Set the maps to this area pMap->SetPreferencePropertyValue(String(L"configuration"), &CONFIGURATION_VALUE);
Now we switch to the MapInteraction class. Create and construct a LocationProvider by adding in your location source. We‟re using the GPS receiver. Here you can also configure the update rate, which we set to 5 seconds in the RequestLocationUpdate() method.
64
Introduction to bada: A Developer's Guide - (draft preview, July 2010)
// Create a LocationProvider LocationProvider *locProvider = new LocationProvider(); // Construct the LocationProvider by using GPS as its locating mechanism locProvider->Construct(LOC_METHOD_GPS); // Configure the time interval for updates locProvider->RequestLocationUpdates(*this, 5, false);
In order to receive location updates you need to override the OnLocationUpdated() method which is declared in the ILocationListener interface. //Called when a location event is received void MapInteraction::OnLocationUpdated(Location& location){ if(location.GetQualifiedCoordinates()!=null) { const QualifiedCoordinates *q = location.GetQualifiedCoordinates(); // The lat and lon values double longitude = q->GetLongitude(); double latitude = q->GetLatitude(); // Center the map around these new values pFormMap->SetCenter(latitude, longitude, true); // Redraw and show the map pFormMap->Draw(); pFormMap->Show(); } }
Hints, pitfalls, and related topics Once your code compiles without errors you can run it in the emulator. A very convenient feature of the bada emulator is the Event Injector tool. To get this, right-click on the emulator screen, select Event Injector, and choose the Location tab. You can drag and drop the pointer on the map, or directly enter 65
Introduction to bada: A Developer's Guide - (draft preview, July 2010)
latitude and longitude values. These are then sent as events to your application running on the bada emulator. This tool is very useful for testing.
Figure 2.10.1 Event Injector for simulating location changes If no map is shown on the emulator screen, you might first check whether you have any spelling errors in username and password which you got from your geographic data provider. Another reason might be that you are in a proxy environment. Then you have to set the proxy information in the emulator. Go to menu – settings – connectivity – network – bada.
66
Introduction to bada: A Developer's Guide - (draft preview, July 2010)
Example use in BuddyFix In BuddyFix we used this recipe to connect to deCarta as our geographic data provider, displayed a map and on top of the map indicated the current position of our Buddies.
67
Introduction to bada: A Developer's Guide - (draft preview, July 2010)
Appendix A: A UML primer Here’s an explanation of the subset of UML notation that we’ve used in Chapter 6:
1. Class diagrams Interface inheritance Queue derives from and implements the interface defined by ICollection. See Chapter 4, “bada fundamentals” for more information about interfaces. Inheritance Both AudioContentInfo and VideoContentInfo derive from ContentInfo
Dependencies LocationProvider uses IAreaListener and ILocationListener to provide location updates.
Simple Association CurrentWeather and WeatherForecast are connected to IWeatherEventListener in some way, the classes work together. The application requests a list of WeatherForecast or the CurrentWeather and this will be returned using the IWeatherEventListener. 68
Introduction to bada: A Developer's Guide - (draft preview, July 2010)
Composition Route contains one or more RouteSegment. If the diamond is not filled in, this represents aggregation, a „has a‟ relationship. Note: the UML class diagrams in Chapter 6 were created using the excellent free online tool yUML, available at: http://yuml.me/.
2. Sequence diagrams Sequence diagrams show how objects and processes interact with each other over a timeline- the vertical line shown on the diagrams in Chapter 5, representing the lifetime of an object. In Chapter 5, we use sequence diagrams to show how the application interacts with the bada server in response to user requests, such as to make their profile searchable, and how messages are sent between the objects involved in handling the request. A process or object. In this case the object MyBuddyService of class BuddyService.
A message sent between objects.
A response to a request.
A process performed in response to a message
Note: the sequence diagrams used in Chapter 5 were created using the free online web tool at http://www.websequencediagrams.com/
69
Introduction to bada: A Developer's Guide - (draft preview, July 2010)
Appendix B: A software engineering process model for mobile app development As we mentioned early in the book (see Chapter 1), in order to successfully develop a mobile software solution you should follow an engineering process the helps you address the specific characteristics of mobile software. We refer to this as mobile software engineering. Such a process ideally is highly agile incorporating several macro and micro iterations. Of course, you can follow any process you prefer or develop your software without following any process at all. There is a range from strict waterfall model to cowboy coding. As a rule of thumb the more complex a project is and the more coordination it requires the more formalization in terms of processes is advisable. Experience showed that so called agile processes are very appropriate with software for fast paced markets, which definitely is the case in mobile app development. From a high-level point of view, it might not make a difference if software for desktops, servers, the Web or for mobile devices is developed. It is all software engineering and the basic steps are always the same: requirements, design, programming, testing and deployment. However, it is the detail that makes the difference. From experience we can tell that it is not possible to simply transfer the techniques of traditional software engineering one-to-one to mobile software engineering without significant modifications. Since in this book we are talking about the bada platform for mobile applications, our prime interest in this chapter, naturally, is the mobile software engineering process. In the following pages we will introduce one such agile mobile software engineering process that subsumes several recommended bestpractices. Of course, you are free to choose whichever engineering process you want to follow and whether you comply with all the phases we introduce, pick out the most relevant for your needs or don‟t 70
Introduction to bada: A Developer's Guide - (draft preview, July 2010)
use it at all. We will also show where and how the bada platform and its tools support the described phases and best-practices. Some mobile software engineering best-practices For developing mobile software, we recommend deploying ideas from agile development initiatives (stated in the agile manifesto) such as adaptability, iterations, and making heavy use of prototyping and diversified testing as early as possible in the process. Prototypes can be exploited nearly in any phase of the engineering of a mobile software solution. They are primarily helpful in eliciting requirements or to get a common understanding with various stakeholders early in the project. Testing surely is not unique to mobile software engineering but must be treated and executed differently as we will argue throughout this chapter. The mobile software engineering process that we introduce here is subdivided into three major phases: 1. Feasibility and economic efficiency analysis phase 2. Software product realization phase 3. Distribution phase The following sections discuss each of these phases in detail and the figure below gives an illustration of the whole process. The phases of this mobile software engineering process mainly interweave with the concept, market entry, development, and evolution phases of software product management, where clearly the strongest overlap can be mapped to the development phase.
71
Introduction to bada: A Developer's Guide - (draft preview, July 2010)
Figure A.1 A software engineering process model Phase 1: Feasibility and economic efficiency analysis This first phase should help all the stakeholders to get a better picture about the feasibility, the acceptance, and the potential economic success of a mobile software solution. With economic efficiency analysis we mean that very early in the project lifetime it can be determined whether it is worth to pursue a mobile software development project. This first phase is composed of the four stages requirements engineering, design drafting, early prototyping, user acceptance testing, and a milestone at the end of the phase. Stage 1.1: Requirements engineering The first step in this analysis phase is the elicitation and understanding of the requirements. The business requirements cover considerations about the business model and distribution policy. This is input which usually originates from the product management process that embeds our mobile software engineering process.
72
Introduction to bada: A Developer's Guide - (draft preview, July 2010)
User requirements are the starting point and represent what users need and what they expect from a mobile software. These requirements must be collected and can be maintained in form of use cases or user stories. Early prototypes can already be exploited for this elicitation because users can get a more tangible impression about the future system. Such early prototypes can be low-fidelity ones such as drawings on a paper. More advanced ones can be done by electronic images that can actually allow showing a sequence and simple interactions. Even more advanced is the use of simple UIs that can be created fairly easy and quickly by using the UI builder provided by the bada IDE. The envisioned application can be sketched and simple user interaction (clicking on buttons or exploiting multi-touch) can be modeled and even deployed and shown on a real hardware device. This helps the user even more to think of the future use of an application, which is directly reflected in the quality of the users‟ feedback. Chapter 2 shows the usage of the bada UI builder. For mobile applications we recommend to focus on addressing a clearly defined problem or need with as little functionality as required. Many applications seem overloaded and as a result are difficult to use. Focus on the core and address rather less needs. We are not talking about desktop applications. We outlined the differences between mobile and desktop apps above. As mentioned the cognitive resources and the attention time span is substantially more limited. Traditional software engineers tend to underestimate the impact that a mobile setting will have on application usage patterns. Stage 1.2: Design drafting The drafting of the design deals with two aspects. The first one being the draft of the dialog flow logic and the user interface (UI) design. This is the only part of the software that is exposed to the user and hence, the only part she can experience. From user workshops and feedback to our applications we know that it is tremendously important to provide a simple yet attractive user interface. If an application is too complex to understand within the first minute or it is ugly looking, the user will most probably not launch it a second time. The second aspect deals with preliminary software component architecture considerations. The UI design activities are conducted in various micro iterations with feedback from stakeholders.
73
Introduction to bada: A Developer's Guide - (draft preview, July 2010)
Stage 1.3: Early prototyping Early prototypes embody the requirements gathered and the design developed so far. They are a good means to get a common understanding. Experience showed that some rudimentary functionality should be in place such that minimal interaction is possible. That can be achieved by paper prototypes, an interactive slide show or a click-able UI mock-up. The goal is to find a good balance between a fast and cost effective prototype and providing a user experience which comes close to the final product. As mentioned above, the bada tools give an ideal support for building good prototypes fast. A further advantage is that these prototypes can be re-used for the later programming as is without the need of entirely re-doing all the work for the UI. This is a result from the clear separation of UI design and programming brought to you by bada. Stage 1.4: User acceptance testing This is an optional stage. However, we recommend to plan and execute tests with users that are not involved in the project. These tests can be short in length but should be as close to the real-world context as possible. This way, many problems that will go unnoticed in a lab environment will become apparent, such as bad readability under sunlight or overly complex and confusing user interfaces. These kinds of trials will almost always yield highly valuable feedback about the future acceptance by users and thus the potential success on the market. After a test session there may be one or more iterations back to requirements engineering stage depending on available time, quality and cost targets. The first phase is ended with the milestone Decision for Continuation, which entails the decision to pursue or abandon the software project. With the knowledge gained in this phase – particularly arising from the early acceptance tests – the potential success of a mobile solution can be estimated much clearer, which helps to assess the economic efficiency. Phase 2: Software product realization The second main phase deals with realizing the software solution. It bases on the works of the first phase where as many results as possible should be reused. To follow this agile engineering process, also this 74
Introduction to bada: A Developer's Guide - (draft preview, July 2010)
phase is characterized by many iterations, incremental development („first things first‟), and a high degree of internal and external communication. This phase is composed of the six stages requirements reviewing, design detailing, defining test cases, programming, testing, user acceptance testing, and a milestone at the end of the phase. Again, we would like to emphasis that we present a complete mobile software engineering. Due to our advice about working in an agile way, which implies adaptability, you are free of choosing which ever stages you want to deploy in your software project. Stage 2.1: Requirements reviewing Prior to starting with the detailed software design, programming, and testing the requirements should be reviewed and revised – ideally together with all stakeholders. Stage 2.2: Design detailing In this step the available UI and architecture designs of the first phase are detailed into much more finegrained levels – down to element and component level. Although, mobile software engineering is a comparatively young discipline, some (mostly vendor-driven) initiatives emerged that provide guidelines about user interface design. Although you are not bound to use these, we strongly recommend complying with such guidelines because it simply increases the usability of your product and the acceptance. Also the bada platform introduced such guidelines. These are implicitly used when you use the open APIs for the UI and extended UI controls. Apart from that the IDE ships with a help document that gives further information about best-practices for ideal UI design. Stage 2.3: Defining test cases Testing is absolutely necessary in any software engineering endeavor. In mobile software engineering it is more multifaceted and more variables need to be taken into consideration. The definition of test cases is the first activity related to testing. The cases can be derived from the requirements. Stage 2.4: Programming
75
Introduction to bada: A Developer's Guide - (draft preview, July 2010)
This stage means transforming the designs into program code that can finally successfully pass all test cases. Although, mobile devices get more and more powerful, we nevertheless it is highly recommendable to write efficient code with an eye on conservative computation in order to conserve as much battery capacity as possible. Stretching availability of battery power is crucial as we argued in chapter 1 earlier. The bada IDE ideally supports you with all you need for writing your program code such as syntax highlighting, code completion, comprehensive documentation and example material, and all the necessary compiling, linking, deploying, and running functionalities. Important is also to understand that every mobile application is subject to a „technical‟ application lifecycle, which subsumes initializing, running, terminating, and terminated. The bada platform and its shipped IDE to access it provides the support to easily deal with this app lifecycle and to do the right things in the appropriate stages (through well-defined methods). Stage 2.5: Testing In the mobile software engineering process, much emphasis must be placed on this stage: testing. We must differentiate between the testing platform and the real platform. The testing platform is usually a desktop computer that runs an emulation of the mobile device. Unfortunately, emulators per se exhibit a great discrepancy compared to the real mobile devices. Emulator tests are tests in ideal lab environments where context factors such as position or light conditions are either not considered or simulated. Hence, it is necessary to test software on the real target mobile device and in the real world environment where the software is intended to be used. All the “controllable” variables must be caught by the software such as behavior according to device capabilities, adapting to screen size, masking network disconnections or loss of GPS signal. The last three stages (2.3 defining test cases, 2.4 programming, and 2.5 testing) are characterized by many micro iterations and in reality are partly also executed in parallel. Particularly testing naturally iterates with the test case definition and programming stages. It usually also iterates with the design detailing and the requirements reviewing steps. Stage 2.6: User acceptance testing 76
Introduction to bada: A Developer's Guide - (draft preview, July 2010)
User acceptance tests at the end of the second phase are again optional but recommended. By this, engineers can make sure to really meet users‟ requirements with a software version that more and more approaches a final state. This type of testing can be repeated and the outcomes can be fed back into earlier steps of this phase. Human-computer interaction techniques such as audio/video recordings, questionnaires, cooperative evaluations, focus groups, or controlled experiments can be deployed and are beneficial. After stakeholders accept the existing version of the mobile software, it can be denoted as a release. This means that the milestone Version Released is fulfilled, and the next iteration of the same phase (to realize a further increment) or the successive phase can start. Phase 3: Distribution This phase mainly deals with bringing the mobile software product into the market to the users. This phase is less iterative than the other two. The phase is composed of the three stages marketing, preparing for deployment, product maintaining, and a milestone at the end of the phase. Stage 3.1: Marketing The marketing stage exemplifies where and how the processes of mobile software engineering and product management overlap and complement one another. This stage serves for the finalization of the business model and distribution policy and for preparation of the actual market entry of the software product. Marketing is partly in parallel to other steps and already starts during earlier phases as suggested by the product management process. Stage 3.1: Preparing for deployment In this step, the software must be prepared (i.e. signed) such that the needed functionality of a mobile device can be accessed appropriately. It must be decided which components and contents are packaged together and which parts may be downloaded or installed on-demand. Also the distribution channel must be prepared which usually involves requesting an account and getting familiar with the according policies. Finally, the mobile software is physically distributed and installed on the end users‟ devices. Stage 3.1: Product maintainance 77
Introduction to bada: A Developer's Guide - (draft preview, July 2010)
Maintenance covers support, bug fixing, and feedback integration. This step – depending on the significance of the reported issue and the policy of the application provider – can lead to an additional iteration with the preparing-for-deployment step. Also the level of maintenance and the commitment to it depends on the provider and can range from 24/7 service to no support at all. The mobile software engineering process ends with the end event (milestone: Project End) which was defined by the stakeholders and the project manager.
78