This content has been archived.

Developing custom Pega Mobile Client modules for the Android platform

This tutorial describes how you can extend your custom mobile apps by using custom Pega® Mobile Client modules. You develop custom modules in Java and expose their functionality through the JavaScript API. The modules enable features and functions that are available to native Android applications in Pega Platform mobile apps, for example allowing the use of an embedded laser scanner to scan and recognize barcodes.

To learn what you can accomplish by extending the custom mobile app, see Custom Pega Mobile Client modules.

For a technical introduction and definitions of terms used in this tutorial, see Custom Pega Mobile Client modules for the Android platform.

To develop custom Pega Mobile Client modules for the Android platform, complete the following tasks.

Prerequisites

To develop custom modules for Android, do the following tasks:

  • Download and configure the following items:
    • An up-to-date Android development environment: Android Studio
    • Java Runtime Environment (JRE) 7 x64 or 8 x64
    • A code-signing key (see Sign Your App article in the User Guide for the Android Studio)
  • Obtain the distribution package for your intended platform. To do this, contact your Pegasystems Global Customer Support representative.
  • Review the documentation in the doc folder of the distribution package to become familiar with the native custom module API and JavaScript API.

The instructions in the following sections assume the use of a sample library that validates phone numbers. When you create a custom module for production, you can replace it with a library of your choice.

Importing the Android custom module template

  1. Extract the distribution package into a local directory of your choice.
  2. Navigate to the resources directory and copy the customModuleExamples/PhoneValidator subdirectory to the modules directory.
  3. Rename the PhoneValidator directory to the name of your target custom module, for example, MyCustomModule.
  4. At the command prompt, navigate to the root directory of the distribution package and run the following command:
    ./gradlew :app:assembleDebug
  5. When the "BUILD SUCCESSFUL" message is displayed, run Android Studio and import the project:
    1. Click Import project.
    2. Navigate to the distribution package's root directory.
    3. Select the build.gradle file, and click OK.
  6. Confirm the default options on the next screen, and click OK to start the import.
  7. When the project import finishes and the MyCustomModule folder is visible in the Modules folder of the Project View pane, navigate to the MyCustomModule folder.
  8. Modify your custom module's AndroidManifest.xml file to match the functionality and requirements of your application, for example, set the package name value to my-custom-module.
  9. Review the PhoneValidatorPlugin.java and phoneValidator.js files. You can modify them to create your custom module by adding plug-in classes and activity plug-in classes, as described below.

Adding third-party dependencies

If you use an external library to extend Pega Mobile Client, you must add third-party dependencies to the project by following these steps:

  1. Create a libs directory in the root directory of your custom module.
  2. Paste third-party *.jar files in the libs directory.
  3. Display the Gradle Projects tab in Android Studio, and click the Refresh icon.
  4. Optional: To build your application by using the release build type (by clearing the Build debuggable app check box on the Mobile tab), you must create a proguard-rules.pro file in the custom module directory. This file lists the rules that are needed to preserve all the required classes, interfaces, or enums that are used in your third-party libraries, for example:
    - keep class com.samsung.** {*;}

The ProGuard tool, which is part of Android Studio, removes obsolete classes by determining whether they are directly referenced. It does not detect classes that are loaded through reflection. Therefore, you must include the following lines in the proguard-rules.pro file:

 

-keep class * implements com.pega.mobile.plugin.JavaScriptPlugin { *; }
-keep class * implements com.pega.mobile.activity.plugin.ActivityPlugin { *; }

Extending Pega Mobile Client with JavaScript plug-in classes

The module template includes a sample JavaScript plug-in class. You can use additional JavaScript plug-in classes to implement a custom module.following these steps:

  1. Create the JavaScript plug-in class:
    1. In the Project View pane of Android Studio, create the following subfolder: modules/MyCustomModule/src/main/java/com/organization/custom/javascriptplugin.
      Right-click the Folder icon, click New > Java Class, and enter the name of the JavaScript plug-in class, for example: MyCustomJavaScriptPlugin.
    2. Edit the Java class file.
      Annotate every class that extends the JavaScriptPlugin class with @JavaScriptPluginImpl.
      Define the method implementations, for example:
      package com.organization.custom.javascriptplugin;
        
      import android.webkit.JavascriptInterface;
      import com.pega.mobile.plugin.*;
      import java.util.Timer;
      import java.util.TimerTask;
        
      @JavaScriptPluginImp
      public class MyCustomJavaScriptPlugin extends JavaScriptPlugin {
        package com.organization.custom.javascriptplugin;
        
        import android.webkit.JavascriptInterface;
        import com.pega.mobile.plugin.*;
        import java.util.Timer;
        import java.util.TimerTask;
        
        @JavaScriptPluginImpl
        public class MyCustomJavaScriptPlugin extends JavaScriptPlugin {
          private static final String EVENT_NAME = "myCustomPlugin";
          private static final String ON_TIMER_TICK = "onTimerTick";
        
          private EventLauncher eventLauncher;
          private int counter = 0;
          private Timer timer;
          private TimerTask timerTask;
        
          public MyCustomJavaScriptPlugin(JavaScriptPluginContext context) {
            super(context);
            this.timer = new Timer();
            this.eventLauncher = context.getEventLauncher();
          }
        
          @Override
          public String getName() {
            return "MyCustomPlugin";
          }
        
          @Override
          public void appendJavascript(JavaScriptAppender assetLoader) {
            assetLoader.appendFile("js/myCustomPlugin.js");
          }
        
          @SuppressWarnings("unused")
          @JavascriptInterface
          public void startTimer(Object data, JavaScriptCallback callback) {
            if (timerTask != null) {
              callback.call("onFailure", null);
              return;
            }
            String message = (String) data;
            timerTask = new TimerTask() {
              @Override
              public void run() {
                eventLauncher.fireEvent(EVENT_NAME, ON_TIMER_TICK, counter++);
              }
            };
            timer.schedule(timerTask, 0, 1000);
            String outputMessage = my.third.party.library.Capitalize.capitalize(message) + " : " + counter;
            callback.call("onSuccess", outputMessage);
          }
        
          @SuppressWarnings("unused")
          @JavascriptInterface
          public void finishTimer(Object data, JavaScriptCallback callback) {
            callback.call("onFinished", null);
            timerTask.cancel();
            timerTask = null;
          }
        
          @Override
          public void onPageLoaded() {}
        
          @Override
          public void onReload() {}
        
          @Override
          public void onDestroy() {}
        }
  2. Implement the JavaScript side of the custom module by following these steps:
    1. Create a myCustomModule.js file in the modules/MyCustomModule/src/main/assets/js directory.
    2. Edit the resource.
      The name of the JavaScript plug-in class used in the bridge.call method must be the same as the one that was defined at the beginning of this procedure.
      Create code that is similar to the following example:
      (function() {
        window.launchbox.MyCustomPlugin = {
          startTimer: function(message, callback) {
            bridge.call("MyCustomPlugin", "startTimer", message, {
              onSuccess: callback.onSuccess, onFailure:
              callback.onFailure });
            },
            finishTimer: function(callback) {
            bridge.call("MyCustomPlugin", "finishTimer", undefined, {
              onFinished : callback});
            },
            registerListener : function(listener) {
              var wrapper = {
                onTimerTick : listener
              };
              bridge.registerForEvent("myCustomPlugin", wrapper, false,
              listener);
            }
          };
        })();
  3. Optional: Test and package your custom module by following these steps:
    1. Place any additional resources that are required by your module, such as JavaScript files and graphics, in the modules/MyCustomModule/src/main/assets directory.
    2. To avoid build errors, remove all the attributes in the application section of the AndroidManifest.xml file in the custom module folder.

Extending Pega Mobile Client with activity plug-in classes

The module template does not contain any activity plug-in classes. Activity plug-in classes can be used, for example, to grant the custom mobile app access to activity life cycle events. Create an activity plug-in class by following these steps:

  1. In the Project View pane, go to the following subfolder of the custom module:
    modules/MyCustomModule/src/main/java/com/organization/custom/activityplugin.
    Right-click the Folder icon, click New > Java Class, and enter the name of the activity plug-in class, for example: "MyCustomActivityPlugin".
  2. Edit the Java class file.
    Annotate every class that extends the ActivityPlugin class with @ActivityPluginImpl.
    Define the method implementations that are similar to the following example:
    package com.organization.custom.activityplugin;
      
    import android.content.Context;
    import android.os.Bundle;
    import com.pega.commontools.androidlogger.ALog;
    import com.pega.mobile.activity.plugin.ActivityPlugin;
    import com.pega.mobile.activity.plugin.ActivityPluginContext;
    import com.pega.mobile.activity.plugin.ActivityPluginImpl;
      
    @ActivityPluginImpl
    public class MyCustomActivityPlugin extends ActivityPlugin {
      
      private Context activityContext;
      
      public MyCustomActivityPlugin(ActivityPluginContext context) {
        super(context);
        this.activityContext = context.getActivityContext();
      }
      
      @Override
      public void onCreate(Bundle bundle) {}
      
      @Override
      public void onStart() {}
      
      @Override
      public void onRestart() {
        ALog.d("MySampleExtension", "On Restart callback invoked!");
      }
      
      @Override
      public void onResume() {}
      
      @Override
      public void onPause() {}
      
      @Override
      public void onStop() {}
      
      @Override
      public void onDestroy() {}
    }

Requesting a permission to perform an action

If you want your custom module to perform an action that requires a permission in Android 6 and later, you can use a simplified API that supports the new permission mechanism.

  1. Obtain a reference to the PermissionRequestor object by calling the ContainerProvider.get(PermissionRequestor.class) method.
  2. Call the permissionRequestor.requestPermissions(), passing an array of permission names, as defined in the Android developer's reference, and a ResultHandler handler, which contains actions that are performed when the permission request result is retrieved.

When the result is retrieved:

  • If all permissions are granted, the onPermissionsGranted callback is called.
  • If any permissions are denied, the onPermissionsDenied is called, with a list of permissions that are not granted.
    Each permission is represented by an instance of the DeniedPermission object, from which you can retrieve the permission name and the Boolean value of the shouldShowRequestPermissionRationale parameter. This parameter passes the user's requirement to provide a justification for the permission. If the user refused the permission before, the value of this parameter is true.

Enabling the logger API

You can test the operation of your custom module by sending the log output to Android Studio. You can use the Logger API, which is superior to an Android's original Log API. By using this API, you can access the logs or set a logging level. To use the Logger API in the custom module's native code, do the following steps:

  1. Import the com.pega.commontools.androidlogger.ALog class.
  2. Use the ALog class in your code. In terms of use, it is identical to the android.util.log class.

Testing custom modules locally

  1. Modify the app.properties file, which is in the root directory of the distribution package:
    1. Uncomment the bootstrap.config.dir = resources/pega7OfflineBootstrap line.
    2. Set the value of the bootstrap.string.applicationURL to your intended instance of the Pega Platform, for example: http://test.server.com:8243/prweb/.
    3. Optional: To debug the JavaScript code, change the value of the container.webContentsDebugging parameter to true.
    4. Set the other parameters as necessary (read the inline comments for details).
  2. Optional: To test your own custom module, build a binary Pega Mobile Client package that includes your custom module. To do this, run the following command:
    ./gradlew :app:assembleDebug
    The APK file is created in the app/build/outputs/apk directory.
  3. Optional: To test a custom module that has already been built, for example, when it comes from a different developer, do the following steps:
    1. Paste your custom module files, either in source-code or compiled format, in the modules directory of the distribution package. For additional information, see the README.txt file in the modules directory.
    2. Run the ant command at a command prompt. The APK file is created in the out directory.
  4. Test the APK file that contains a native application by installing the file and debugging the application on a device or an emulator.

Packaging the custom module

When your custom module is ready and has been tested, prepare it for packaging by creating a .zip file, for example custom-module-assets.zip file. To obtain a sample custom module package that you can rename and use as a template for your package, right-click and save the following link:

custom-module-assets.zip (0.1 MB)

To bundle custom modules from different developers within one *.zip file, avoid conflicts between modules from different sources by doing these steps:
  • Place all binary modules from one developer in a subfolder with a unique folder name and combine their individual proguard-rules.pro files into one.
  • Ensure that all source-code modules have unique names.
  1. Optional: To package your custom module in a binary form:
    1. Open the build.gradle file, which is in your custom module directory, and modify paths in the following code to match your environment:
      apply plugin: 'maven'
        uploadArchives {
        repositories.mavenDeployer {
          pom.groupId = 'com.pega.'
          pom.artifactId = 'my-custom-module'
          pom.version = '1.0.0'
          repository(url: "file:///home/user/Documents/modules-android/")
        }
      }
    2. Navigate to the root directory of your distribution package and run the following command:
      ./gradlew :MyCustomModule:assemble :MyCustomModule:uploadArchives
    3. Locate the modules-android folder and place it in the custom-module-assets.zip file.
  2. Optional: To package your custom module in a source-code format:
    1. If you tested your custom module by doing the steps in the Testing the custom module section, navigate to your custom module directory, for example, MyCustomModule, and remove the build folder that is created there as part of the testing process.
    When you build an app for production, and you have set the value of the webContentsDebugging parameter to true, consider reverting it to false and repeating the build procedure.
    1. Copy your custom module directory and place it in the modules-android folder of the custom-module-assets.zip file.
  3. Upload your custom module to Pega Platform. For more information, see Uploading custom modules.

Related Content

Have a question? Get answers now.

Visit the Pega Support Community to ask questions, engage in discussions, and help others.