Android App & Web App Development for Hartwood Services
Hartwood Services' 125 qualified engineers have been helping maintain the UK's mobile infrastructure for the past 14 years.
Their field-based engineers look after the main switching centres and data hubs of leading mobile telcos such as T-Mobile, Orange, 02 & Three.
Hartwood Services asked App Developer for Android to develop some bespoke applications with the following requirements:
- Develop a bespoke Android app to install on 7" Android tablets to allow field engineers real-time access to site surveys and installations allocated to them by Hartwood Services project managers.
- Develop a secure web-based Project Management System where Hartwood Services project managers could set up site surveys and installations and allocate these to the 150 engineers in the field. The project data would then appear automatically on the relevant field engineer's Android app and the data entered on the Android app by the technician (site survey answers, photos, geo-data, barcode data and signatures) would be stored locally on the
Android tablet and sent in real-time (or as soon as an Internet connection is
established) to the Project Management System in the cloud.
- Develop a secure Customer Portal where customers (e.g. T-Mobile, Orange, 02 etc.) can
login and enter their requirements and be able to track the staus of their projects.
- Develop a secure website with bespoke CMS (Content Management System) based on the look and feel of their existing website.
Key Features of the Bespoke Android App
Pulling Survey & Project Data from the Cloud
Here we use the XmlPullParser class to pull a list of projects, surveys and materials assigned to the technician by project managers in the web app cloud.
Passing Device Longitude and Latitude to the Cloud
Using the phone or tablet's GPS, the Android app uses the LocationManager object which provides access to the system location services. These services allow applications to obtain periodic updates of the device's geographical location, or to fire an application-specified Intent when the device enters the proximity of a given geographical location.
The LocationListener represents a listener that receives events associated with a particular LocationProvider. Applications implement this interface and register it with a LocationProvider to obtain regular position updates.
We use a TimerTask to update the project and survey list from the web app cloud data. Timers are used to schedule jobs for execution in a background process.
Updating the Cloud with Data and Photos Saved on the Android App
Here we use the HttpPost class in our Android app to post data to a data-handling process on the web-based Project Management System which in turn updates the Cloud database.
We use a FileOutputStream class to save photos as an image on the Android tablet (or smartphone) and then we use Android's BitmapFactory class to compress the image and then a ByteArrayOutputStream to convert the image data into a byte array.
We convert the byte array into a Base64 string and post that to the web server. There we create the image and save to the web server and update the web-based Project Management System.
Base64 encoding schemes are commonly used when there is a need to encode binary data that needs be stored and transferred over media that are designed to deal with textual data. This is to ensure that the data remains intact without modification during transport. Base64 is used commonly in a number of applications including email via MIME, and storing complex data in XML.
See below some more details on how we use the tablet's or smartphone's in-built camera as part of the app.
Using the Android tablet's camera
Hartwood Services wanted engineers to take photos through the Android app so these were automatically assigned to the relevant projects and uploaded to the cloud-based Project Management System in real-time. Directly controlling a device camera requires a lot more code than requesting pictures or videos
from existing camera applications. However, if you want to build a specialised camera application or
something fully integrated in your app UI (User Interface), this is how we do it.
Open the Camera Object
Getting an instance of the Camera object is the first step in the
process of directly controlling the camera. As Android's own Camera application does, the
recommended way to access the camera is to open Camera on a separate thread
that's launched from onCreate(). This approach is a good idea
since it can take a while and might bog down the UI thread. In a more basic implementation,
opening the camera can be deferred to the onResume() method to facilitate code reuse and keep the flow of
control simple.
Calling Camera.open() throws an
exception if the camera is already in use by another application, so we wrap it
in a try/catch block.
Since Android API level 9, the camera framework supports multiple cameras. If you use the
legacy API and call open() without an
argument, you get the first rear-facing camera.
Create the Camera Preview
Taking a picture usually requires that your users see a preview of their subject before clicking
the shutter. To do so, you can use a SurfaceView to draw previews of what the
camera sensor is picking up.
Preview Class
To get started with displaying a preview, you need a preview class. The
preview requires an implementation of the android.view.SurfaceHolder.Callback interface, which is used to pass image
data from the camera hardware to the application.
The preview class must be passed to the Camera object before the live
image preview can be started.
Set and Start the Preview
A camera instance and its related preview must be created in a specific
order, with the camera object being first. The
process of initializing the camera is encapsulated so that Camera.startPreview() is called by the
setCamera() method, whenever the user does something to change the
camera. The preview must also be restarted in the preview class surfaceChanged() callback method.
Set the Preview Orientation
Most camera applications lock the display into landscape mode because that is the natural
orientation of the camera sensor. This setting does not prevent you from taking portrait-mode
photos, because the orientation of the device is recorded in the EXIF header. The setCameraDisplayOrientation() method lets you change
how the preview is displayed without affecting how the image is recorded. However, in Android prior
to API level 14, you must stop your preview before changing the orientation and then restart it.
Take a Picture
Use the Camera.takePicture()
method to take a picture once the preview is started. You can create Camera.PictureCallback and Camera.ShutterCallback objects and pass them into Camera.takePicture().
If you want to grab images continously, you can create a Camera.PreviewCallback that implements onPreviewFrame(). For
something in between, you can capture only selected preview frames, or set up a
delayed action to call takePicture().
Stop the Preview and Release the Camera
Once your application is done using the camera, it's time to clean up. In
particular, you must release the Camera object, or you risk crashing other
applications, including new instances of your own application.