Skip navigation

Tips and Tricks

12 posts

A few people have asked how it is possible to start RxLogger automatically using AirWatch.

 

This is possible by doing the following

 

1) Go to Products->Files and Actions and create a new one

2) In the manifest section and a new item under Run Intent

3) Add the following parameters to the Intent mode=implicit,broadcast=true,action=com.symbol.rxlogger.intent.action.ENABLE

4) Add this to a product and deploy to the devices

 

For other intents the following documentation is available

 

RunIntent action

Overview

The runIntent action is used to cause an Android intent to be launched. An Intent provides a facility for performing late runtime binding between the code in different applications. Its most significant use is in the launching of activities, where it can be thought of as the glue between activities. It is basically a passive data structure holding an abstract description of an action to be performed. The runIntent action supports both explicit and implicit intents.

Depending on the arguments used, the AirWatch agent will use either of the following to launch the specified intent:

  • android.content.Context.startActivity(Intent intent)
  • android.content.Context.sendBroadcast(Intent intent) to launch the specified intent.

RunIntent Syntax

The argument syntax changes depending on whether explicit or implicit mode is specified:

mode=explicit, broadcast=[true|false] , action=< action>, package=<package>, class=<class> [, data=<data>][, extraString=<stringname>=<string value>[,...]][, extraInt=<int name>=<int value>[,…]]

mode=implicit, broadcast=[true|false] , action=<action> [,category=<category>][, uri=<uri>] [, data=<data>] [, extraString=<string name>=<string value>[,...]][, extraInt=<int name>=<int value>[,…]]

Arguments

ArgumentExplanation

mode=[explicit|implicit]

Specifies whether the intent to be launched is explicit or implicit.

broadcast=[true|false]

Specifies whether the intent to be launched using startActivity() or sendBroadcast().

action=<action>

action specifies the Android action string for the intent. An example of an Android action string is android.intent.action.MAIN.

package=<package >

package specifies the Android package name of the java class to be explicitly launched. Android package names are generally of the format com.mycompany.myapplication.

class=<class>

class specifies the java class in the specified package that is to be explicitly launched.

uri=<uri>

uri optionally specifies the URI that is to be passed with the implicitly launched intent.

category =<category >

category optionally specifies the Android category string that is to be passed with the implicitly launched intent. An example of an Android category string is android.intent.category.DEFAULT

data=<data>

data optionally specifies the value of the Android data parameter that is to be passed with the explicitly or implicitly launched intent.

extraString=<string name>=<string value>

string name optionally specifies the name of an extra string parameter that is to be passed with the explicitly or implicitly launched intent. string value specifies the value of the extra string. The extraString argument can be used multiple times to specify additional extra string name/values.

extraInt=<int name>=<int value>

int name optionally specifies the name of an extra int parameter that is to be passed with the explicitly or implicitly launched intent. int value specifies the value of the extra int. he extraInt argument can be used multiple times to specify additional extra int name/values.

 

The following table indicates which arguments are required, optional, or not applicable for the explicit and implicit modes:

mode

explicit

implicit

broadcast

required

required

action

required

required

package

required

n/a

class

required

n/a

uri

n/a

optional

category

n/a

optional

data

optional

optional

extraString

optional

optional

extraInt

optional

optional

Example RunIntent

mode=explicit,broadcast=false,action=android.intent.action.MAIN,package=com.examples.myappl,class=com.examples.myappl.MainActivity

Some earlier Android builds did not come preloaded with the EMDK runtime and as such this will need to be installed before making use of any of the EMDK features on the device.

 

The runtime can be installed with a simple PC side script that comes as part of the EMDK installation or it can be pushed down to multiple devices at once through an MDM like AirWatch.

 

Since the EMDK runtime installer is packaged as an application and the installer is removed after a successful install, this can create complications for some MDMs that enforce that apps remain installed.  The following steps allow you to add the installer as a managed application in Airwatch and ensure that the install runs only once:

 

1.Add EMDKOSUpdate as a managed application in Airwatch
2.Create a product to install the application only (don’t send the intent to start it)
3.Add a new Files/Actions item to only run the intent for installation: mode=explicit,action=android.intent.action.MAIN,package=com.symbol.emdkosupdater,class=com.symbol.emdkosupdater.MainActivity
4.Create a separate product to run the intent action and list the EMDKOSUpdate application product as a dependency.
5.Activate both products

 

It is key that the dependency be set so that the intent is not fired before the application is installed.  By following these steps the installer application will be installed, and then the intent will be fired to kick off the install.  The device will reboot into recovery, perform the update, remove the installer, and reboot.  After the reboot Airwatch will detect that the app is no longer there and re install it however since the Action only runs once, the install will not be restarted.

Our Compatible and Validated programs are targeted at testing application interoperability and functionality with Motorola Solutions’ devices.  For the best user experience in enterprise environments we also recommend the following best practices when it comes to testing your application and also your interaction with Zebra printers.  Suggested test cases related to the best practices are also supplied below.

 

For more information on our Compatible and Validation programs including promotional benefits of each, please refer to: https://developer.motorolasolutions.com/community/global-solution-center

For participation, please fill out the nomination form:

   For our Validated program: https://partnercentral.motorolasolutions.com/resources/development/val_solu.aspx

   For our Compatible program: https://partnercentral.motorolasolutions.com/resources/development/compat_solu.aspx

About RxLogger

 

RxLogger is a comprehensive AndroidTM diagnostic tool that provides application and system metrics.  It is a simple to use tool that was designed for flexibility – it allows for custom plug-ins to be created and work seamlessly with this tool.  RxLogger is targeted for partner, customer, and technical support usage in diagnosing device and application issues.  Its information tracking includes the following, but is not limited to: CPU load, memory load, memory snapshots, battery consumption, power states, wireless logging, cellular logging, TCP dumps, Bluetooth logging, GPS logging, logcat, FTP push/pull, ANR dumps, etc.  All logs and files generated are saved onto flash storage on the device (internal or external).  RxLogger is intended to be utilized for diagnostic purposes only.

 

The main RxLogger features are:

     • Simple user interface
       The user interface based configuration allows for ease of use without a learning curve.
     • Silent configuration and easy mass deployment
       A single configuration file can be deployed to multiple devices without the need for user intervention.
     • Remote configuration and remote log retrieval
       Reduce delays in acquiring and transferring log files
     • Pluggable interface
       Allows for 3rd party development and seamless add-ons without the need for user intervention.

 

Main User Interface

Screen1.png Screen2.png


Supported Devices

Supported on Motorola Solutions AndroidTM Gingerbread and Jelly Bean devices such as ET1, MC40, and TC55.

 

Demonstration Download

Use of the RxLogger tool is for diagnostic purposes only.

 

RxLogger_barcode.jpg

 

 

Contact Information

Motorola Solution Center
Web site: http://www.motorola.com/business/solutioncenter/
Email: SolutionCenter@motorolasolutions.com

By default, when the screen is rotated your Activity is killed and restarted.  See the sample code below to save the state

 

Source:  http://stackoverflow.com/questions/5123407/losing-data-when-rotate-screen

 

//Use onSaveInstanceState(Bundle) and onRestoreInstanceState

@Override
public void onSaveInstanceState(Bundle savedInstanceState) {

 
// Save UI state changes to the savedInstanceState.  
 
// This bundle will be passed to onCreate if the process is 
 
// killed and restarted.

  savedInstanceState
.putBoolean("MyBoolean", true); 
  savedInstanceState
.putDouble("myDouble", 1.9); 
  savedInstanceState
.putInt("MyInt", 1); 
  savedInstanceState
.putString("MyString", "Welcome back to Android");   
 
// etc. 
 
super.onSaveInstanceState(savedInstanceState); 
} 
//onRestoreInstanceState 
   
@Override 
public void onRestoreInstanceState(Bundle savedInstanceState) { 
 
super.onRestoreInstanceState(savedInstanceState); 
 
// Restore UI state from the savedInstanceState. 
 
// This bundle has also been passed to onCreate. 
 
boolean myBoolean = savedInstanceState.getBoolean("MyBoolean"); 
 
double myDouble = savedInstanceState.getDouble("myDouble"); 
 
int myInt = savedInstanceState.getInt("MyInt"); 
 
String myString = savedInstanceState.getString("MyString"); 
}

It is important to note that when pairing with BSP44 that you must enter PIN number quickly otherwise it will not pair. 

 

WIth BSP44 and the RS507 with firmware PAAACS00-005-R02D0 the procedure is as follows:

 

1.  Load the follwing as a reg file into the Application Folder

; BT Scanner settings for 41.400 / 44.00

[HKEY_LOCAL_MACHINE\Drivers\BuiltIn\BarcodeReaderBT]
"Flags"=dword:00000000

[HKEY_LOCAL_MACHINE\Drivers\BuiltIn\BarcodeReaderBT\Settings]
"PortName"="\$device\COM7"

2.  Click on the .reg file -> click on it to merge it.

3.  Warm boot the MC65

4.  Clean boot the RS507 - procedure -hold down the button on the back right and place battery in it until it beeps several times.

5.  To avoid having to enter a Pin number please scan Disable Bluetooth Authentication.

 

Bluetooth Authentication.png

6.  On the MC65 tap on the MotoBtui and turn on Bluetooth. 

7.  Click on Pairing barcode icon -  This must be down after the RS507 is on

8.  Scan the pairing barcode.

 

If you want to pair it with having to enter a PIN then follow

1.  Load the follwing as a reg file into the Application Folder

; BT Scanner settings for 41.400 / 44.00

[HKEY_LOCAL_MACHINE\Drivers\BuiltIn\BarcodeReaderBT]
"Flags"=dword:00000000

[HKEY_LOCAL_MACHINE\Drivers\BuiltIn\BarcodeReaderBT\Settings]
"PortName"="\$device\COM7"

2.  Click on the .reg file -> click on it to merge it.

3.  Warm boot the MC65

4.  Clean boot the RS507 - procedure -hold down the button on the back right and place battery in it until it beeps several times.

6.  On the MC65 tap on the MotoBtui and turn on Bluetooth. 

7.  Click on Pairing barcode icon -  This must be down after the RS507 is on

8.  Scan the pairing barcode

9.  Enter the PIN (12345) very quickly prior to the light flashing on the RS507 going off

Are you a beginner Android programmer?  Interested in learning the basics of Android programming?   This presentation provides the fundamentals of Android programming covering topics such as Android architecture, activity, service, broadcast receiver, and intents. 

 

For additional information, refer to: http://developer.android.com/training/index.html

Handheld devices in enterprise environments typically don't use a single network connection for communication.  The devices can be connected through wireless LAN, cellular, Bluetooth, and even wired Ethernet.  To add to that, these can be connected independent of each other or all at the same time.  Windows Embedded HH 6.5 allows multiple interfaces to be up simultaneously and will allow the device to have multiple IP addresses.  The Microsoft Connection Manager (http://msdn.microsoft.com/en-us/library/ms849587.aspx) is responsible for handling connection requests from applications and automatically deciding the "least cost" interface to use.  Typically it will prefer wired Ethernet to wireless LAN and wireless LAN to cellular.  This works well in most cases however there can be situations where the best suited connection for the customer is not the "least cost" connection as decided by Connection Manger.  There are also power considerations when dealing with multiple radios.  Leaving all radios active at all times can have a detrimental effect on battery performance with little to no gain.  In this blog I will explain some best practices when dealing with multiple connections and then provide some details on implementation.

 

Suggested Practices

 

  • Control power to radios that aren't needed or aren't in use.  By powering off the radios that you do not want to use, Connection Manager is forced to use only the connection that remains.  This method had the added benefit of saving battery power by turning off radios when they aren't needed.
  • Consider using power notifications to suggest that terminal is in or out of WiFi coverage.  In some situations, devices are out in cellular coverage during the day and are only in WiFi coverage when they are brought back to a central depot to charge following a shift.  In this case a notification that the device is charging could be a good indicator for the application to power on the WiFi radio.
  • Periodically power on the WiFi radio to check if a known network is available.  If no network is available, shut down the radio and increase the time until the next check to prevent frequent power cycles when out of WiFi coverage long periods of time.
  • Use Microsoft's Connection Manager when multiple connections exist.

 

Wireless LAN - Power Control

  • Use Fusion Public API (FAPI) to enable and disable radio power.
  • Call OpenFusionAPI() with COMMAND_MODE.
    • Note: Command mode can only be open by a single application at any given time.  It is recommended only to open command mode for the time necessary to send the command.  Applications should not hold an open command mode context for an extended period to ensure interoperability with other applications.
  • Call CommandFusionAPI()
    • POWER_CONTROL_WLAN_DISABLE_POWER
    • POWER_CONTROL_WLAN_ENABLE_POWER
  • Alternate Method
    • Call DevicePowerNotify(L"WLP1:", D0, 1);
      • D0 - On
      • D4 - Off

 

Wireless LAN - Getting Status

  • Use Fusion public API (FAPI) to get WLAN status
  • Call OpenFusionAPI() with STAT_MODE
  • Call CommandFusionAPI()
  • The following commands provide useful information from the WLAN radio:
    • ADAPTER_INFO_WLAN
    • RF_SIGNAL_STRENGTH_WLAN_GET
    • RF_SIGNAL_QUALITY_WLAN_GET
    • WLAN_ADAPTER_STATISTICS_GET
    • FUSION_DIAG_LOG_SAVE

 

Cellular - Power Management

  • Use Microsoft TAPI commands to Enable/Disable the WAN radio
  • lineSetEquipmentState with:
    • LINEEQUIPSTATE_FULL – On
    • LINEEQUIPSTATE_MINIMUM – Off
  • See WANSample in the Motorola Solutions EMDK for C for more information

 

Cellular - Getting Status

  • The following TAPI calls provide useful information from the WAN radio:
  • lineGetCurrentSystemType – GSM, CDMA, IDEN, etc
    • lineGetRegisterStatus – Registration status (roam, home)
    • lineGetLineDevStatus – Signal strength
  • See WANSample in the Motorola Solutions EMDK for C for more information

 

Bluetooth - Power Management

  • When using the Stonestreet One BT stack, the recommended way to enable/disable Bluetooth is by using the OEMBthSetMode exposed by SS1PWMGR.dll:

          hInstance = LoadLibrary(L"SS1PWMGR.dll");

          // If the lib was found, try and find the OEMBthGetMode/OEMBthSetMode functions

          if(hInstance)

          {

                     pBthGetMode = (int (*)(DWORD *pdwMode))GetProcAddress( hInstance,    L"OEMGetBthPowerState");

                     pBthSetMode = (int (*)(DWORD dwMode))GetProcAddress( hInstance, L"OEMSetBthPowerState");

                     if(pBthGetMode) // be sure to check the ptr before using it

                     {

                         pBthGetMode (&pdwMode);

                     }

                     if(pBthSetMode)

                     {

                         pBthSetMode (dwNewState);

                     }

          };

 

  • Note:  For WM devices, the Microsoft API BthSetMode() will also work

 

Bluetooth - Getting Status (Stonestreet One stack)

  • Use BTExplorer (provisioning) API to enumerate connections:
    • BTPFindFirstConnection
    • BTPFindNextConnection
    • Use BTP_Connection_Query_t structure to filter types of connections to return (Active, All, etc.)

 

  • Returns BTP_Connection_Info_t structure:

typedef struct

{

          BTP_Connection_ID            ConnectionID;

          BD_ADDR_t                            BD_ADDR;

          unsigned int                         RFCOMMPort;

          int                                       LocalCOMPort;

          unsigned char                       MajorVersion;

          unsigned char                       MinorVersion;

          Word_t                                ConnectionAttributes;

          BTP_Profile_Type               ProfileType;

} BTP_Connection_Info_t;

 

Using Microsoft Connection Manager

  • Connection Manager exposes functionality to explicitly request a certain interface be used for the requested connection:
    • ConnMgrMapConRef() will return a destination network GUID when given the name of a network connection (ex. My Connection).
    • Calling ConnMgrEstablishConnectionSync() with the GUID from ConnMgrMapConRef() will ensure the supplied connection path is used even if it is not the “least cost”
  • If a cellular connection had an entry in the "Connections" settings applet, it can be referred to by its name when calling ConnMgrMapConRef.  Other adapters (like WiFi or ethernet) must be added to Connection Manager by means of XML provisioning.  The following example shows how to add a network connection called "Wifi Connection" that will correspond to the Wifi adapter named "NPME\JEDI10_1".  Note that the adapter name will change based on the specific WiFi adapter in the device.  You can use GetAdaptersInfo() to retrieve all of the adapter names in the system.

 

<wap-provisioningdoc>

          <characteristic type="CM_NetEntries">

                    <characteristic type="Wifi Connection">

                              <parm name="DestId" value="{436EF144-B4FB-4863-A041-                                                            8F905A62C572}"/>

                              <parm name="Adapter" value="NPME\JEDI10_1"/>

                    </characteristic>

          </characteristic>

</wap-provisioningdoc>

 

Additional Information

Additional information on using Connection Manager can be found here: http://msdn.microsoft.com/en-us/library/bb840031.aspx .

Setting the Date and Time on an SB1.  There are many ways to set the date and time
on an SB1.  One way is to set it with the Fusion settings.  When you create a
Fusion Profile in MSP the Fusion Option is set by default.  This will set the date and time based off the
Wireless infrastructure.  If you are using Motorola Solutions Infrastructure it will set the date and time.

 

On the device to set the date and time manually the user will need to set it through the GUI in advanced  settings under Set Date and Time.

Over the last several years most partners have had multiple instances of their application running on the device which has
caused some issues for them.  It has been my experience that the partners need to check for this in their apps.  There are several ways to check for this
depending on what programming language is used.  Here are some links and snippets of code:

 

int _tmain(int argc, _TCHAR* argv[])

  {

  
// CREATE A SINGLE INSTANCE MUTEX

   
HANDLE hMutex = CreateMutex(NULL, FALSE, L"ApplicationNameSingleInstanceMutex");

       if (hMutex != NULL)

       {       
if (GetLastError() == ERROR_ALREADY_EXISTS)

          
{

                 
// MUTEX ALREADY EXISTS, EXIT APPLICATION

              
CloseHandle(hMutex);

               
return -2;

         
}

       }

       else

       {

         
// ERROR CREATING MUTEX

         
return -1;

       }

      
// NORMAL APPLICATION PROCESSING HERE

        // CLOSE HANDLE TO MUTEX

   CloseHandle(hMutex);   

       return 0;

  }

 

  Also please check this post out :

  http://social.msdn.microsoft.com/Forums/en-us/netfxcompact/thread/18b8ec06-89e2-4318-8eb9-d26bd42ac1b2

     I have included another link here: 

  
http://www.nesser.org/blog/archives/56
and a copy of his code:  The below was needed because users were not patient : Most users are not.  Here is some sample code:  This is for C#

 

 

 

using System;

  using System.Windows.Forms;

  using System.Runtime.InteropServices;

  namespace SomeNameSpace

 

{

  static class SingleInstance

  {

  [MTAThread]

  static void Main()

  {

  // Check if we have a duplicate
instance of the program running

  if (
IsInstanceRunning() )

 

{

  // Perhaps log the fact a duplicate
program was shut down

  return;

  }

  /*

  * Continue with your normal program here

  */

  try

  {

  Application.Run( YourFormClass );

  }

  catch ( Exception
e )

  {

  // Log an exception that caused the
application to close here

  MessageBox.Show( "See log file
for details.\r\nClosing this application.", "Fatal Application
Error"
);

 

}

  }

  #region OpenNETCF native interface
to mutex generation (version 1.4 of the SDF)

  public const Int32
NATIVE_ERROR_ALREADY_EXISTS = 183;

 

#region P/Invoke Commands for
Mutexes

  [DllImport(
"coredll.dll", EntryPoint="CreateMutex", SetLastError=true
)]

  public static extern IntPtr
CreateMutex(

  IntPtr lpMutexAttributes,

 

bool InitialOwner,

 

string MutexName
);

  [DllImport(
"coredll.dll", EntryPoint="ReleaseMutex", SetLastError=true
)]

 

public static extern bool ReleaseMutex(
IntPtr hMutex );

 

 

#endregion

 

 

public static bool IsInstanceRunning()

 

 

{

 

 

IntPtr hMutex = CreateMutex(
IntPtr.Zero, true, "ApplicationName"
);

 

 

if ( hMutex == IntPtr.Zero )

 

 

throw new ApplicationException(
"Failure creating mutex: "

  +
Marshal.GetLastWin32Error().ToString( "X"
) );

 

if (
Marshal.GetLastWin32Error() == NATIVE_ERROR_ALREADY_EXISTS )

  return true;

  else

  return false;

  }

  #endregion

  }  

}

In MSP under settings ->  Click on Create and in the Setting Type drop down select FILE.SETTINGS.XML and then select the registry file and place it in the Application directory as shown below.
After creating the setting The user will need to create a staging barcode with just the setting selected.

 

msp1.png

 

msp1.png

 

Click on the Staging – Barcode in MSP and you will get the Barcode Below. The barcode below will set the MTU to 1300 on the SB1. It is a standalone barcode not requiring a backend.
The user must cold boot the device for the setting to take effect.

 

The below barcode wil set the MTU setting on an SB1 to 1300 as long as the user cold boots the device.

msp1.png

The registry key is below:

     [HKEY_LOCAL_MACHINE\Comm\NPME\XWING10_1\Parms\TcpIp]

       ; Set MTU to 1300

          "MTU"=dword:514

A registry file will need to be created and placed in the User drive or the Application Folder to configure the setting

Filter Blog

By date:
By tag: