Categories
News

What About Blackberry?

One of the most common questions we get when we talk about new features in Delphi, C++Builder and RAD Studio is “What about Blackberry?” which is almost as common as similar questions about Windows Phone or Linux. iOS and especially Android rule the smartphone OS market, but Blackberry still has a place on most charts (unlike Symbian and some others).

IDC: Smartphone OS Market Share 2013, 2012, and 2011 ChartWell, now RAD Studio XE6, Delphi, C++Builder and Appmethod support 96.8% of the shipping platforms thanks to the latest update to Blackberry 10 (10.2.1 or later), it now supports running Native Android APK apps without needing to port. I tested on a Z10 developer device, but it should work on Q10, Q5, Z30, or others. To be clear, Blackberry still runs their own OS, but that OS is able to run Native Android Apps.

Our IDE doesn’t recognize the Blackberry device, again because it is not running Android. But once you build your APK you can transfer it to the Blackberry device using whatever method is most convenient for you. I used Dropbox. Once you have the APK on the Blackberry you simply need to install it.

I built a few samples, including one that takes a picture, and they all more or less worked as expected. When the ShareSheet came up, the usual suspects like Facebook and Twitter were not there, but I didn’t have those set up yet on my test device, so that is to be expected.

You can take things a step further and repackage and sign your app to distribute through the Blackberry store, but that isn’t necessary. You can deploy your APK directly to the Blackberry, or distribute it through the Amazon App Store. Crackberry has a guide on installing APKs too, with a little more detail.

The Blackberry Developer site has useful pages:

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.

Mobile Summer School Lesson 5: App Tethering Round-Up

I substituted for David I. yesterday for Developer Direct Mobile Summer School on Lesson 5: Connecting Mobile and Desktop together using App Tethering. The Summer School landing page and David’s blog maintain a list of downloads for all the previous lessons, but here are the resources from my session in the meantime.

I’ll post the replay videos here when they are available too.

You can download my slides and code samples from Code Central. I believe I fixed the issue where some people were not able to download it.

cc.embarcadero.com/item/29907

Here are the links to more information on App Tethering:

Here is the Developer Skill Sprint I did previously on App Tethering

And this is Al Mannarino’s C++ Mobile Day session on the topic

And some blog posts on the topic too:

There was some interest in the code sample that bypasses App Tethering’s autodiscovery to connect directly to a specific IP address. I’m working on getting that tested before posting it. Leave a comment if you are interest and I’ll see that you are notified when it is ready.

Skill Sprint: Android Voice – Speech Recognition and TTS

Androids can talk and listen!For my Developer Skill Sprint I was originally scheduled to show how to do a Google Glass Voice Trigger. That is pretty cool because it allows you to launch a Google Glass app with your voice, but I decided to expand on that to also show how the Google Glass app can be launched with the results of additional voice input, as well as how to take dictation and do text to speech everywhere else in Android.

I’ve still got a lot of work to do on the components, but they work as is for now. If you want to modify the component code then take a look at my Skill Sprint and blog post on the Android JNI Bridge.

 

Categories
News

Android JNI Bridge and Custom Classes.dex

By creating a custom Classes.dex you can get access to 3rd party Java JAR APIs from your application. For my Integrate More Android with a JNI Call to your Android App Developer Skill Sprint I created a demo app that demonstrates creating a custom Classes.dex. This is a new feature in XE6 and Appmethod 1.14. [Download the demo] [Download the slides] The Demo app uses the Base64Coder JAR file (included). To build the demo:

  1. Examine the createdex.bat file to make sure it refers to the correct location for your dx.bat utility and the fmx.jar & android-support-v4.jar files.
  2. Run the createdex.bat file to create the classes.dex file which includes the two jar files above, plus the base64coder.jar file.
  3. Double check that the Deployment Manager references the new classes.dex and not the old ones, and that the remote path is “classes\”
  4. Notice that the android.JNI.Base64Coder.pas file wraps and exposes the methods of the base64coder class.
  5. Run the app on your Android device and verify that it works as expected.

The Base64Coder.JAR is Android specific, so it will not work on iOS or Windows. Some additional notes from the Developer Skill Sprint: Some useful units for making JNI calls

  • Androidapi.Jni – Java Native Interface type definitions
  • Androidapi.JNIBridge – The JNI Bridge
  • Androidapi.JNI.JavaTypes – JString and other common types.
  • Androidapi.Helpers – JStringToString and other useful conversions.
  • FMX.Platform.Android– Useful platform methods like GetAndroidApp, MainActivity and ConvertPointToPixel
  • Others useful units: Androidapi.AppGlue, Androidapi.JNIMarshal, Androidapi.JNI.Embarcadero
  • For more see: C:\Program Files (x86)\Embarcadero\Studio\14.0\source\rtl\android (Object Pascal) and C:\Program Files (x86)\Embarcadero\Studio\14.0\include\android\rtl (C++)

You will want to make use of Conditional Defines in Object Pascal and Predefined Macros in C++. In my blog post on Android Settings I showed how to make a JNI call with Object Pascal, but you can also look at the DeviceInfo Mobile Code Snippet in both C++ and Object Pascal. To create your own JNI Bridge wrappers, look at the source code in C:\Program Files (x86)\Embarcadero\Studio\14.0\source\rtl\android (Object Pascal) and C:\Program Files (x86)\Embarcadero\Studio\14.0\include\android\rtl (C++). You can also consider the following 3rd party utilities:

If you just want to include standard Android APIs then check out the FMXExpress (also an Embarcadero MVP) project on GitHub that includes all the Android APIs. Here is the video replay of my skill sprint

Also, check out Brian Long’s video on accessing the Android API with XE5

Categories
News

BlueTooth Remote Control Car

How to use BlueTooth is one of the most common requests with Delphi. During our Devices and Gadgets webinar David I. showed how to browse paired BlueTooth devices and connect to them.

But wait, there’s more! Daniele Teti & Daniele Spinetti of bit Time Software created an Android client app to control a BeeWi – BBZ201 – Mini Cooper S Bluetooth Car. It may work with other BeeWi Bluetooth remote control vehicles, but has not been tested with any (that I know of).

The Multitouch code is Copyright (c) 2006-2014 Iztok Kacin, Cromis and used under the BSD license.

It currently doesn’t have BlueTooth discovery, so once you pair your device you need to update the source code with the MAC address of your car.

I’ve created a GitHub repository for the project. It should work with XE5 or AppMethod just fine. I’ve got a version updated to XE6 that exposes the controls via App Tethering too, which I will upload later.

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.

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.

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?

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