Categories
Android iOS Mobile REST Source Code webinar

Mobile Summer School 6: REST & BaaS

Here are the slides and downloads from my mobile summer school session on REST & BAAS. If you just want the slides they are on Slide Share. I’ll post the video and more details here later.

For more information on BaaS, check out Sarina’s excellent series of blog posts.

Categories
Android Components gadgets iOS Source Code

Parrot AR.Drone 2.0 Delphi Component

githubI took my code I previously used to control the Parrot AR.Drone and turned it into a reusable component. I added some more functionality to it as well, although there is a lot more to cover. The component is available on GitHub.

It should work with Delphi, C++Builder, Appmethod and RAD Studio on iOS, Android, Windows and OS X. I’d love to hear how it works for you and what you use it for!

Categories
Android Graphics iOS Mobile Source Code

OpenGL ES Support on Mobile with XE6

OpenGL ES logoAppmethod, RAD Studio, Delphi and C++Builder XE6 all make it really easy to work with OpenGL ES on mobile devices. Under the covers FireMonkey is implemented with OpenGL ES on mobile (iOS & Android), OpenGL on OS X and DirectX on Windows. It provides a number of useful abstractions for working with 2D and 3D graphics, but sometimes you just want to get down to a lower level.

Here is all you need to access an OpenGL ES rendering context in your FireMonkey mobile application. This example is in Object Pascal, but should be easy enough to adapt to C++.

  1. Create a new FireMonkey Mobile application
  2. Select 3D application
  3. Add FMX.Types3D to the Interface uses clause
  4. In the Object Inspector, create a new event handler for the OnRender event for your form
  5. You now have access to the OpenGL render context.

You can work with the TContext3D that is passed in via a parameter, and your code will work across platforms automatically. If you want to work with the OpenGL ES APIs directly you can do that too with the following uses clause in your Implementation section:

uses
  // Gives you access to the FMX wrappers for GLES
  FMX.Context.GLES, 
{$IFDEF ANDROID}
  // Direct access to the Android GLES implementation
  Androidapi.Gles, FMX.Context.GLES.Android;
  // More useful units for Android
  //, FMX.Platform.Android, Androidapi.Gles2, Androidapi.JNI.OpenGL,
  // Androidapi.Glesext, Androidapi.Gles2ext;
{$ENDIF}
{$IFDEF IOS}
  // Direct access to the iOS GLES implementation
  iOSapi.OpenGLES, FMX.Context.GLES.iOS;
  // More useful units for iOS
  //, iOSapi.GLKIT, FMX.Platform.iOS;
{$ENDIF}

And here is an example event handler with a couple calls to the OpenGL ES APIs:

procedure TForm1.Form3DRender(Sender: TObject; Context: TContext3D);
begin
  glClearColor(1, 1, 0, 1);
  glClear(GL_COLOR_BUFFER_BIT);
end;

This accesses the iOS and Android equivalents of the same OpenGL ES APIs. Thanks to the compiler directives, and the cross platform nature of OpenGL ES, this code just works. I’m not an OpenGL expert, but I looked through the OpenGL ES API and all the routines I tested worked, but I never did anything interesting with them.

Categories
Android iOS webinar

Revisiting Google Glass

Few weeks ago I posted about how to launch a Google Glass app with a voice command. The app I built used buffered sensor data from the accelerometer and smooth animation to show a level. The video below is from our Making the Connection: Programming Devices and Gadgets with RAD Studio where I put all the pieces together.

Google Glass is an exciting new platform and form factor. Éric Bonilha from Digifort joined us to show interfacing IP Controllers and streaming video from IP Cameras.

Something we didn’t get to show is Éric built a prototype app for streaming video to Google Glass. His plan is to build a version of his camera surveillance app for Google Glass that will stream surveillance video to security guards on patrol. Additionally it will stream the video from Google Glass back to the security system.

It was so cool how fast Éric used Delphi XE5 to prototype accessing the camera on Google Glass and streaming video from his system to it.

The source code for my Google Glass app, and Éric’s code for accessing IP Camera & IO Controllers is available along with the replay from our RAD-In-Action Webinar. I’m looking to pick up a PTZ IP Camera and streaming it to my Google Glass next.

Categories
Android Components iOS Tools

Scanning Barcodes with RAD Studio XE5

Turns out there are a few ways to scan a barcode with RAD Studio XE5, and no sooner do I make a video about it then TMS releases a component to scan barcodes, and then Thomas Krampe sends me his component that combines them all together.

Not that we need another barcode scanning app on our smartphones, but it can be a useful feature for an app that performs another purpose to be able to scan a barcode too.

This video was part of our Making the Connection: Programming Devices and Gadgets with RAD Studio webinar. Check out the on demand replay to get the source code.

Categories
Android Brain Computer Interface devices gadgets iOS Mobile

Connecting to the Parrot AR.Drone 2.0 from Delphi XE5

My first thought when I see cool technology is to figure out how to connect to it with Delphi. So the day I got the Parrot AR.Drone 2.0 quadricopter I started working on Delphi interface. By the time evening rolled around the batteries were dead (after a couple recharges), but I had a basic interface working. The official developer guide seemed to be a little out of date, or I was reading it wrong, but once I got my facts staight, connecting was really easy. http://www.youtube.com/watch?v=aaGe2aERwgI The Parrot AR.Drone has it’s own access point. Once you’ve connected to it, then it is simply a matter of sending UDP packets for the basic controls. To accomplish that I simply used the Indy UDP Client: TIdUDPClient. Each command is sent with an increasing sequence number, so I initialize my interface as follows:

  udp := TIdUDPClient.Create(nil);
  udp.Host := '192.168.1.1';
  udp.Port := 5556;
  seq := 1;

The AR.Drone is always at 192.168.1.1 since it is the access point, and the port for communication is 5556 (one of a few ports, but the one we need for now.) It is worth pointing out that if you’ve previously flown your AR.Drone with the FreeFlight mobile app then you may need to reset your drone to unpair it. Otherwise it is paired to only that device. The commands are formatted with an AT* prefix, and a series of arguments. For example, to take off, the command is AT*REF=1,290718208 where AT*REF is the command, 1 is the sequence number (always the first argument) and 290718208 is a bitmask that means take off. I created a SendCommand routine that looks like:

procedure TARDrone.SendCommand(cmd, arg: string);
var
  full: string;
begin
  if not udp.Active then Connect;

  full := Format('%s=%d,%s' + Chr(13), [Cmd, Seq, arg]);
  Seq := Seq + 1;
  udp.Send(full);
end;

Notice the command is terminated with a carriage return (#13). The documentation says line-feed (#10), it is wrong. Supposedly you can send multiple commands in the same message, if they are separated by the carriage return. I haven’t tested that. Then I can send the some common commands like this:

  SendCommand('AT*REF','290718208'); // Takeoff
  SendCommand('AT*REF','290717696'); // Land
  SendCommand('AT*CONFIG', '"control:altitude_max","10000"'); // unlimited altitude
  SendCommand('AT*CONFIG', '"control:altitude_max","5000"'); // restrituded altitude - unsure what units 500-5000.
  SendCommand('AT*PCMD','1,0,0,0,0'); // Hover (stop movement)

PCMD is the move command. It takes 5 arguments (after the sequence number.) The first is the controller type, which we are leaving 1 for now. The next 4 are phi, theta, gaz, yaw and they are floating point numbers in an integer representation. This is where it gets interesting. The documentation says:

The number –0.8 is stored in memory as a 32-bit word whose value is BF4CCCCD(base 16), according to the IEEE-754 format. This 32-bit word can be considered as holding the 32-bit integer value –1085485875(base 10).

The first way I thought of to access the same memory as two different types is a variant record. So I came up with the following helper routine:

function IEEEFloat(const aFloat: Single): Integer;
type
  TIEEEFloat = record
    case Boolean of
      True: (Float: Single);
      False: (Int: Integer);
  end;
var
  Convert: TIEEEFloat;
begin
  Convert.Float := aFloat;
  Result := Convert.Int;
end;

Using that I built a move routine that takes 4 singles (32-bit floats) and sends them as integers:

procedure TARDrone.Move(const phi, theta, gaz, yaw: Single);
begin
  SendCommand('AT*PCMD',Format('1,%d,%d,%d,%d',
    [IEEEFloat(phi), IEEEFloat(theta), IEEEFloat(gaz), IEEEFloat(yaw)]));
end;

Now if I want the drone to go up I can call:

  Move(0,0,5.6,0); // positive gaz is upward acceleration

Now it is just a matter of figuring out how to the rest of the movements map to the physical worked and building a user interface on Android, iOS, Windows or Mac. Maybe all 4! Once I build up the API a little bit more I’ll share some full working apps and libraries. Let me know if you are interested in collaborating on such.

Categories
Android Delphi Projects iOS Mobile

Learning from Digifort

You’ve probably seen Éric Fleming Bonilha videos showing off his Digifort mobile applications developed with Delphi XE5. The videos don’t mention it, but the back end server and client applications are all written in Delphi too. Just in case you haven’t see the videos, here they are again:

Earlier version, but on a lot of different devices:

Embarcadero just completed a case study with him too, which is really informative. I spoke with him down in Brazil and he said they previously developed mobile clients with both Java and Objective-C, and found Delphi let them develop their projects much faster, and they get both Android and iOS from one project. Also, and perhaps more importantly he said the performance of the Delphi client was just as good, plus they found it more flexible for building a user interface that looks great and is easy to use.

Digifort Mobile Client

Digifort may be based in Brazil, but their clients are all over the world and are a mix of government agencies and business of various sizes. Eric arranged a trip to meet me in Scotts Valley this last week. He showed me some pictures of some of the walls of monitors his clients have, all powered by Digifort. Some really impressive installations.

A big part of his trip was to pick up a his very own Google Glass to start developing a Digifort mobile app for Google Glass. In just a couple short sessions he was capturing images from the built in camera, connecting to his remote server, and streaming live video from Brazil to the glass display. The use case for security personal to view cameras while on patrol, while sharing what they see with everyone else is a great one.

David, Eric and Jim

Eric also had a chance to visit with some people from R&D and product management and share his experiences working with Delphi XE5 and FireMonkey. Here are some best practices he found for making a really smooth user interface.

  • FireMonkey handles PNG images really well. He makes a lot of use of transparent and semitransparent PNG images in TImage components. Layering, animating and zooming those images is what he uses to create some of those really great effects, like the joystick control for camera control.
  • The TFloatAnimation and other animation effects are really powerful. He uses those extensively for smooth animations.
  • He created the drawer interface using TFrames (he uses a lot of frames). The main (center screen) has a Pan Interactive Gesture on it. He looks at the gesture to see if it is horizontal (comparing the gesture start to a later gestsure event) and has traveled at least 10 pixels in that direction. Once that happens then he moves the edge of it with the current finger position from the gesture. He also tracks the speed of the movement, so if you let go then he uses another TFloatAnimation to smoothly finish the movement at the same speed.
  • When the drawer starts to open he pauses all the video and other animations. This really increases the performance of the drawer animation.
  • Anything that is not currently shown on the screen has its visibility set to false. So if the drawer is closed, then everything in the drawer is invisible (since it is in a frame he just sets the frame to invisible). This keeps it from rendering and gives what is visible all the processing power. This is a common suggested optimization with many mobile development tools.
  • It is important to think about a mobile app’s interface as a mobile app. Don’t try to squeeze a desktop app onto a mobile device. That will only frustrate you and your users.
  • In his lists of cameras he uses a TVertScrollBox and fills it with a custom component that contains TImages and TLabels. That gives him maximum flexibility for the drag to reorder (again a Pan Interactive Gesture). He did find that the TLabel has better performance than drawing the text manually inside his custom control.

There were a lot of things he shared where he spent a little extra time to get things just right, and that is what makes the difference for a really smooth user interface. When asked about the learning curve to move from Desktop VCL to FireMonkey Mobile he said there was just a little learning curve, but now he really likes FireMonkey better than VCL. There was talk about having him collaborate for a user interface webinar, which I’m sure will be very informative.

You can catch Eric’s appearance in our Devices and Gadgets webinar on the webinar replay (posting any day now). And download his sample code (along with the rest of the code from the webinar).

What are some tips and best practices you’ve found in your FireMonkey mobile development?

Categories
Android iOS Mobile webinar

Buffering Sensor Data

Working with sensors on devices can often lead to large amounts of data coming to you really fast. For example the TMotionSensor’s OnDataChange event fires 100 times a second on my Nexus 5. When I was building my level app for Google Glass the level bar was bouncing all over the place because of the sensitivity and sample rate.

My first thought was to only take every 10th sample, but I wasn’t happy with that either because the specific sample it pulled could be the one when there was a jitter.

Example: 1,2,1,1,2,1,2,3,1,3,12,2,3,1

If I just looked at sample 1 and 11 then I would see a lot of movement, but in reality it was relatively stable most of the time.

What I ended up doing was buffering the data and taking an average. I just created a generic TList of the appropriate type, and during the OnDataChange event I would simply store the sample data. When it came time to update the display I took an average sample, which I found gave a much smoother and more representational display.

Although it was still possible the line could jump erratically if I really moved a lot. So I decided to use an animation for the movement. This keeps the line movement smooth, even if there is a lot of movement (it interpolates the positions between the current line position and the new position). I used a TFloatAnimation and set the StartFromCurrent property to true.

When the animation is finished I set the StopValue to the the average of the values, then enable again. It is important to always clear the sample values after taking an average. Otherwise the movement will continue to get slower and slower as it becomes more and more stable (averaging a large enough sample of numbers results in a smaller range of results.)

I was really pleased with how smooth things looked with a 0.1 second duration on the animation. With 100 samples a second, this translates into each animation covering the average of 10 samples. The built in animations made it really easy, and the final display looked great.

I’ll include the source code with the downloads from the Making the Connection: Programming Devices and Gadgets with RAD Studio webinar coming up next week!

RAD-in-Action Webinar Making the Connection: Programming Devices and Gadgets with RAD Studio Wednesday, January 22, 2014

Categories
Android design iOS Mobile

Skeuomorphic No More?

Skeuomorph is compounded from the Greek: skéuos (container or tool), and morph (shape). It describes something that possess additional ornamentation indicative of its inspiration. It is used to describe both physical objects as well as digital designs.

In the physical world we frequently see it as something made of plastic that is styled to look like leather, wood, etc. In the digital world it shows up when a button or other digital element contains textures, shading, etc. to make it look like the physical element that inspired it. From a design point of view in digital assets it is useful in that the user recognizes what an object represents by its physical familiarity (called an affordance).

Apple’s platforms used to be full of a great examples of Skeuomorphism. On iOS all the default icons had a glare that made them look 3D. Many apps, had a extra details to make them look lifelike. Take the Notes app, it was full of torn bits of paper, leather borders, stitching, paper lines, etc. The new version doesn’t have any of that (although it does have a slight paper texture).

iOS6 vs iOS7 Notes

iOS 7 didn’t lead the move to non-skeuomorphic design. Windows Phone 7 (the predecessor to WP8 and Windows 8) and the Metro design eschewed skeuomorphism completely. (If you are keeping score, iOS 7’s features were inspired by Android and design inspired by Microsoft.) Android has always been been straddling the proverbial skeuomorphic fence. Although with the the other two mobile plays moving away from skeuomorphism I expect Android to follow.

iOS7’s move away from skeuomorphism really highlights how most apps design no longer tries to mimic the platform’s design completely. Users are creative with their apps, and often times bring their own design with their app across all platforms. That is the great thing about building your cross platform apps with Delphi. You can use the standard platform styles so your app looks like a standard app on each platform, or just as easily switch to a premium or custom style and have your app stand-out and look consistent across platforms.

Now you need to ask yourself if I only wrote this post so I could use words like eschew, skeuomorphic, proverbial and affordance.

Categories
Android iOS Mobile News webinar

FireDAC is the Recommended Database Access Library

I got a great call the other morning. A Delphi developer from a few versions back was considering upgrading to XE5, but he wanted to know if FireDAC was recommended for database access, or if he would need a 3rd party library.

I remember working on some data driven Delphi applications when the drill was you always bought a 3rd party database access library. There are lots of great database access libraries to choose from, which is one of the great things about Delphi: all the technology partners!

In XE5 the BDE is officially deprecated (and has been for a while), but it still ships (maybe not for much longer though). dbExpress is still there, and so is dbGo and IBX, and they are all good, specialized database access libraries. But with the full integration of FireDAC in XE5, it is the recommended database access library, and for good reason.

FireDAC is a universal data access library: you use the same components to connect to a huge variety of databases. The usage pattern is similar to the BDE, and it is fully bidirectional. It also has a large collection of specialized features for dealing with specific databases, and local, in memory data.

If you are still on the BDE, check out the FireDAC migration guide or any of the other great FireDAC documentation. Cary Jensen just did a fabulous webinar on FireDAC including a fabulous 70 page whitepaper.

Of course you are still welcome to continue using 3rd party libraries, and some of them may offer some other specialized features. That is one of the great things about Delphi, C++Builder and RAD Studio: It comes with great features in the box, but you can expand on those with 3rd party libraries.

If you still aren’t on XE5, you still have a little time to take advantage of the special offers.