I recently received a request from a Customer to produce an application that would allow updating of multiple devices without requiring the update to be transferred via their network. Their reasoning was simple: transferring a large (1.5GB~) update file via the network would take up a considerable amount of bandwidth and subsequently slow other business functions as a result. To meet this request I’ve developed a utility application (Local Updater) which facilitates the updating of a device from an external storage device (in this case a USB attached to a TC75x cradle) bypassing the need to transfer the file via the network.


What Does the Utility Do?

Local Updater will copy one or more update files from an external storage device to the internal SD Card of the target device. Once copied & validated, the Utility will invoke PowerManager to trigger the update directly from the device, using the file (files) copied from the external storage.


How does it work?

Local Updater is controlled using Intents which can be sent via an MDM. These intents are used to specify what type of update to perform (either upgrade or downgrade) and which files should be applied to the device to perform the upgrade or downgrade. The Utility also supports the chaining of these operations (for example applying a base OS update followed by several LG patches) without requiring multiple invocations of the application.


How do I use it?

Firstly, you need to source the OS & LG update files from the relevant support page for your device. Once you’ve sourced these files, they need to be placed onto an external storage device (E.g. USB or Micro SD etc..) which then needs to be connected to your target device.

Having set up the external storage and connected it to your device, you can now invoke the Utility application by sending an Intent. There are several intents which can be used to trigger either singular upgrade/downgrades or to chain these actions.


Note: Ensure the application has been installed and is running (either in the background or foreground) before sending any intents.


Applying a single package

To apply a single update package to the device, use the following intent:


adb shell am broadcast -a <INTENT_TYPE> --es package "<PACKAGE_NAME>"

where <INTENT_TYPE> is either com.zebra.UPGRADE or com.zebra.DOWNGRADE and <PACKAGE_NAME> is the fully qualified name of the file.


For example, an update intent may look like this:


adb shell am broadcast -a com.zebra.UPDATE --es package "FULL_OSUPDATE_13_20_U00.zip"


Chaining packages

To chain packages the same intent is used, however, the extra data passed is slightly different:


adb shell am broadcast -a <INTENT_TYPE> --es package-0 "package-name.zip" --es package-1 "package-name.zip"


Here, we define two packages by using the format:




Where <PACKAGE_NUMBER> is the order in which the package should be applied (0 indexed) and <PACKAGE_NAME> is the fully qualified name of the file.


For example, an update intent which applies a base OS update file, followed by two LG patches may look like this:


adb shell am broadcast -a com.zebra.UPDATE --es package-0 "FULL_OSUPDATE_13_20_U00.zip" --es package-1 "CFE_ATLAS_02-13-15.00-OG-U11-STD.zip " --es package-2 "CFE_ATLAS_02-13-15.00-OG-U12-STD.zip"


Where can I find it?

The source code for the application is available on my GitHub & the APK can be found at the bottom of this post.