Links may not function; however, this content may be relevant to outdated versions of the product.
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
- Importing the Android custom module template
- Adding third-party dependencies
- Extending Pega Mobile Client with additional JavaScript plug-in classes
- Extending Pega Mobile Client with activity plug-in classes
- Requesting a permission to perform an action
- Enabling the logger API
- Testing the custom module
- Packaging the custom module
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
- Extract the distribution package into a local directory of your choice.
- Navigate to the resources directory and copy the customModuleExamples/PhoneValidator subdirectory to the modules directory.
- Rename the PhoneValidator directory to the name of your target custom module, for example, MyCustomModule.
- At the command prompt, navigate to the root directory of the distribution package and run the following command:
./gradlew :app:assembleDebug
- When the "BUILD SUCCESSFUL" message is displayed, run Android Studio and import the project:
- Click
- Navigate to the distribution package's root directory.
- Select the build.gradle file, and click
- Confirm the default options on the next screen, and click to start the import.
- 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.
- 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
. - 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:
- Create a libs directory in the root directory of your custom module.
- Paste third-party *.jar files in the libs directory.
- Display the Gradle Projects tab in Android Studio, and click the icon.
- 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:
- Create the JavaScript plug-in class:
- 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 > , and enter the name of the JavaScript plug-in class, for example: MyCustomJavaScriptPlugin. - Edit the Java class file.
Annotate every class that extends theDefine the method implementations, for example:
JavaScriptPlugin
class with@JavaScriptPluginImpl
.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() {} }
- In the Project View pane of Android Studio, create the following subfolder: modules/MyCustomModule/src/main/java/com/organization/custom/javascriptplugin.
- Implement the JavaScript side of the custom module by following these steps:
- Create a myCustomModule.js file in the modules/MyCustomModule/src/main/assets/js directory.
- Edit the resource.
The name of the JavaScript plug-in class used in theCreate code that is similar to the following example:
bridge.call
method must be the same as the one that was defined at the beginning of this procedure.(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); } }; })();
- Optional: Test and package your custom module by following these steps:
- Place any additional resources that are required by your module, such as JavaScript files and graphics, in the modules/MyCustomModule/src/main/assets directory.
- 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:
- 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 > , and enter the name of the activity plug-in class, for example: "MyCustomActivityPlugin". - Edit the Java class file.
Annotate every class that extends theDefine the method implementations that are similar to the following example:
ActivityPlugin
class with@ActivityPluginImpl
.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.
- Obtain a reference to the
PermissionRequestor
object by calling theContainerProvider.get(PermissionRequestor.class)
method. - Call the
permissionRequestor.requestPermissions(),
passing an array of permission names, as defined in the Android developer's reference, and aResultHandler
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 theDeniedPermission
object, from which you can retrieve the permission name and the Boolean value of theshouldShowRequestPermissionRationale
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:
- Import the
com.pega.commontools.androidlogger.ALog
class. - Use the
ALog
class in your code. In terms of use, it is identical to the android.util.log class.
Testing custom modules locally
- Modify the app.properties file, which is in the root directory of the distribution package:
- Uncomment the
bootstrap.config.dir = resources/pega7OfflineBootstrap
line. - Set the value of the
bootstrap.string.applicationURL
to your intended instance of the Pega Platform, for example:http://test.server.com:8243/prweb/
. - Optional: To debug the JavaScript code, change the value of the
container.webContentsDebugging
parameter to true. - Set the other parameters as necessary (read the inline comments for details).
- Uncomment the
- 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. - Optional: To test a custom module that has already been built, for example, when it comes from a different developer, do the following steps:
- 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.
- Run the
ant
command at a command prompt. The APK file is created in the out directory.
- 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)
- 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.
- Optional: To package your custom module in a binary form:
- 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/") } }
- Navigate to the root directory of your distribution package and run the following command:
./gradlew :MyCustomModule:assemble :MyCustomModule:uploadArchives
- Locate the modules-android folder and place it in the custom-module-assets.zip file.
- Open the build.gradle file, which is in your custom module directory, and modify paths in the following code to match your environment:
- Optional: To package your custom module in a source-code format:
- 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 thewebContentsDebugging
parameter to true, consider reverting it to false and repeating the build procedure.- Copy your custom module directory and place it in the modules-android folder of the custom-module-assets.zip file.
- Upload your custom module to Pega Platform. For more information, see Uploading custom modules.