I thought I’d share a few pointers about developing OPC UA on Android, since our Prosys OPC UA Java SDK has supported Android from version 1.3 onwards. In recent times we’ve had a surge of interest from Android users, who have helped us in understanding some typical use cases of developers on mobile platforms. In this vein, we’ve already shared some of our Android development effort in the form of our Christmas special that was available for a limited time as a preview for our full Android client. It allowed connecting to a Beckhoff programmable logic in our office via OPC UA (the PLC is running Beckhoff’s OPC UA server for Windows CE) and controling a signal light column, which was viewable via a webcam.
This tutorial will concentrate on development for Android phones, so we will be using Android 2.3, but everything here also applies to the tablet world (Android 3.x) pretty well. Haven’t tested on 4.0 yet, but should run okay there as well.
To begin, you will need the Prosys OPC UA Java SDK. You can request an evaluation edition or purchase it on our website. With the same credentials, you can download the demo project from here.
In addition, you’ll need Eclipse and the Android SDK respectively. Install Eclipse and the Android SDK after that. The ADT plugin for Eclipse is also very useful, please see instructions for installing it. I assume here that you have some level of familiarity with Eclipse and Java in general. Also check out the SDK tutorials (especially the Client tutorial) to get a grip on how the SDK is meant to be used. Of course, you could also just dive right in and start off by examining the demo project, which is a simple GUI client for reading the time off a server.
Creating your project
After installing the Android SDK, Android projects are added to the New Project wizard in Eclipse. When you create your project, you will need to specify the version of Android you’re developing for. If you have an Android device available for testing, try to match its version, otherwise you can just select 2.3.1 (API version 9). If you want to use an emulator (handy even if you have a real device you’re developing for), you can create one using the SDK Manager that comes with the Android SDK. Select New… and simply enter a name and a target, you can leave the rest of the parameters as they are.
You will need to add the four .jars (bcprov, log4j, Opc.Ua.Stack and the SDK jar itself) in the Java SDK to your project’s build path. Optionally, in order to use SDK’s inbuilt logging, you can also add log4j-over-slf4j. The SDK uses log4j, whereas Android uses slf4j and thus this kind of bridge is needed. This way you can view the SDK’s output in DDMS along with other Android logging. log4j-over-slf4j is available at www.slf4j.org as part of the slf4j download package.
You’ll also need to modify the Android manifest to allow your application to create a connection. This is done by modifying AndroidManifest.xml, you can insert
just below uses-sdk in the manifest file. Similarly, if your application at some point requires file write permissions, position data etc. they all have to be declared here. When installing the application, the user gets notified of these required permissions and so this is a nice security and transparency feature in Android.
Writing an OPC UA Client
Now that you’ve created your project and added the necessary libraries, it’s time to write your app. I won’t go through every detail here, see the (well-commented) example project for those, but rather share some general pointers and insight for Android development. I suggest you go through the example code, copy things to your own project and change details here and there and just play around with it. The main parts of creating an Android application are
- Creating an UI
- Creating your application logic
- Binding these two together
I’ll go through each of these steps shortly to get you on your way.
Creating an UI
Using Eclipse it’s very easy to design the layout of your application using the WYSIWYG editor. Layout files are at res/layout, and one file has been pre-generated for you, main.xml. Using the editor, you can simply drag and drop components to the layout, or if you prefer, edit the XML file directly.
For the sample app, one textfield and one button should be enough. Remember to give some good ids for the components, you can do this in the component tree view by right-clicking and selecting “Edit ID…”. I gave them ids “timeBox” and “readButton”, and also changed the text on the button to “Read” by selecting “Edit text”. Create a new string resource by clicking “New String…” and give it an id like “read_button” and a value of “Read”. String resources are stored in res/values/strings.xml, if you want to edit them directly without the GUI.
That’s it for the UI part, easy, isn’t it!
Creating your application logic
This is the part where you get to use our SDK and see how simple it really can be to use OPC UA.
Since reading the time is a long-running activity, we won’t be doing it on the UI thread to avoid freezing up the UI. Instead, we want to run it in the background and just present the results once they are available. To achieve this, we’ll be creating a class that inherits from AsyncTask (see the example project for the exact syntax). The two methods that interest us are doInBackground() and onPostExecute(). doInBackground() will do the heavy lifting in the background, and once it’s done, it’ll store the results in a field. Upon completion of the task, onPostExecute() will be called using the UI thread of the application, allowing us to modify UI components (by calling setUITime() on our Activity) and display the result.
You’ll need to set some information into the UaClient object, but as you can see in the sample project, it’s not too hard. And besides, once that’s done, you can simply start communicating!
Doing the binding
Now we have our UI and the logic for reading the time, but we still need to make the magic happen. For this, we’ll need to make the button start up the read task and also write an implementation for setUITime(). We can get handles to the UI components by calling findViewById in the onCreate method of our activity. The ids for the UI components are listed in R.id, so you can get a handle to readButton by calling (Button)findViewById(R.id.readButton). You can store them as fields in your Activity. After this, it’s easy to write an implementation for setUITime() – but remember, you’ll have to ensure that it’s only called from the UI thread, otherwise you’ll get an exception.
At this point, all we’ll have to do is make the Read button work. We’ll do this by making a click listener for it and making it create a ReadTask. We’ll pass our Activity along as a parameter, so the task can update the time field once it’s done.
That’s it, we’re done! Now you can test the application by firing it up in an emulator. The example project is configured to connect to SampleConsoleServer on the host machine, so simply start that up before firing up your Android app.
Good to know
One important bit here is that if you’re running the application in an Android emulator, you can connect to the host machine (your computer) using the IP address 10.0.2.2. So, if you want to connect to the SampleConsoleServer provided with the SDK, you can use the URI opc.tcp://10.0.2.2:52520/OPCUA/SampleConsoleServer. On the other hand, if you’re developing on a device and don’t have an OPC UA server handy, you can connect to our demo server at opc.tcp://uademo.prosysopc.com:52520/OPCUA/SampleConsoleServer.
The source code for the app is available from the link mentioned earlier, so you can double-check on the details or simply just jump in and start making your own app using the example as a base. All in all, Android is a very good platform to develop on (even if you’re not doing OPC UA :)) and I expect that there will be interesting UA applications especially on tablet hardware in the future. We’ll keep on developing our SDK and also we’ll be releasing the full version of the Android handset client soon, so do check back often!
You must also define the libraries that you use in the Order & Export section of the Build Path editor – and make sure that they are defined before the Android libraries.