Version 2021

Add Custom Logic During the Authentication Process in Android

MicroStrategy Mobile SDK authentication APIs for Android let you insert custom logic at different points during the authentication process. You can do this by overriding and implementing the methods in the classes that are part of the authentication process.

Add Custom Logic from Scratch

One of the most common customizations is to add custom logic during project authentication. The steps and code snippets below illustrate how to do this.

  1. Create a new Java client named CustomAuthenticationFragment that extends MobileLoginFragment and add it to the desired targets. The following code snippet shows a sample header file for this class.

    Copy
    package com.microstrategy.android.custom.afip;

    import com.microstrategy.android.ui.controller.authentication.module.MobileLoginModule;
    import com.microstrategy.android.ui.fragment.MobileLoginFragment;
    import com.microstrategy.android.ui.view.authentication.MobileLoginView;

    import java.util.Map;

    public class CustomAuthenticationFragment extends MobileLoginFragment {
        @Override
        public void mobileLoginDidSucceed(MobileLoginModule mobileLoginModule, Map map) {
            // do something after login success
        }

        @Override
        public void mobileLoginDidFail(MobileLoginModule mobileLoginModule, Map map) {
           // do something after login failure
        }

        @Override
        public void willHandlePreMobileLogin(MobileLoginModule mobileLoginModule, Map map) {
            // do something before login request is sent
        }

        @Override
        public void willHandlePostMobileLogin(MobileLoginModule mobileLoginModule, Map map) {
            // do something after dealing with login request, this means this function is called after mobileLoginDidSucceed or mobileLoginDidFail is called.
        }

        @Override
        public void loginPromptViewDidInputAuthenticationParameters(MobileLoginView mobileLoginView, Map map) {
            // do something after login button is tapped and before login request is sent. This function is called before willHandlePreMobileLogin is called
        }

        @Override
        public void loginPromptViewDidCancel(MobileLoginView mobileLoginView) {
            // do something after cancel button is tapped
        }
    }

  2. Override the View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) method to add custom behavior to the fragment, if necessary. Make sure this implementation calls its parent implementation before adding custom logic. A code snippet with a sample implementation is shown below.

    Copy
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState){
        View view = super.onCreateView(inflater,container,savedInstanceState);
        // add custom view fragment logic if needed
        return view;
    }

Reuse MicroStrategy Internal Logic to Add Custom Login Logic

If you don't need to implement everything from scratch, you can allow your custom fragment to extend from AuthenticationFragment, instead of MobileLoginFragment. Reusing MicroStrategy's internal logic is a good choice if you only need to use willHandlePostMobileLogin.

Override the delegate and call methods implemented by the parent class. The code snippet below shows a full implementation Java file of the custom class. The customization implemented by this file forces a programmatic logout five minutes after the user signs in successfully.

Copy
package com.microstrategy.android.custom.afip;

import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;

import com.microstrategy.android.infrastructure.SessionManager;
import com.microstrategy.android.ui.controller.authentication.module.MobileLoginModule;
import com.microstrategy.android.ui.fragment.AuthenticationFragment;
import com.microstrategy.android.ui.view.authentication.MobileLoginView;

import java.util.Map;
import java.util.Timer;
import java.util.TimerTask;

public class CustomAuthenticationFragment extends AuthenticationFragment {
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState){
        View view = super.onCreateView(inflater,container,savedInstanceState);
        // add custom view fragment logic if needed
        return view;
    }

    /*
     Hook to add custom logic when the authentication process succeeded
    */
    @Override
    public void mobileLoginDidSucceed(MobileLoginModule loginModule, Map map) {
        super.mobileLoginDidSucceed(loginModule,map);
    }

    /**

      Called when mobile login module failed to login.

      @param loginModule the mobile login module that sends the message

      @param _failureInfo The information mobile login module returns to MobileLoginModuleListener

      */
    @Override
    public void mobileLoginDidFail(MobileLoginModule loginModule, Map _failureInfo) {
        super.mobileLoginDidFail(loginModule,_failureInfo);
    }

    /**

      Called when mobile login module starts login.

      @param loginModule the mobile login module that sends the message

      @param _preLoginInfo The information mobile login module returns to MobileLoginModuleListener

      */
    @Override
    public void willHandlePreMobileLogin(MobileLoginModule loginModule, Map _preLoginInfo) {
        super.willHandlePreMobileLogin(loginModule,_preLoginInfo);
    }

    /**

      Called when mobile login module finishs login.

      @param loginModule the mobile login module that sends the message

      @param _postLoginInfo The information mobile login module returns to MSIMobileLoginModuleDelegate

      */
    @Override
    public void willHandlePostMobileLogin(MobileLoginModule loginModule, Map _postLoginInfo) {
        super.willHandlePostMobileLogin(loginModule,_postLoginInfo);
        Timer timer = new Timer();
        timer.schedule(new TimerTask() {
            @Override
            public void run() {
                SessionManager.getInstance().cleanSavedSessions();
            }
        },500*1000);

    }

    /*

     Hook to add custom logic when the view notifies the view controller that the user provided the credentials, one example use case would be

     to replace the credentials provided dynamically or adding a dynamic token if needed.

    */
    @Override
    public void loginPromptViewDidInputAuthenticationParameters(MobileLoginView mobileLoginView, Map parameters) {
        super.loginPromptViewDidInputAuthenticationParameters(mobileLoginView,parameters);
    }
}

Register the Class

Register the custom login view controller class in MobileLoginManager, so it is used for the prompt type for which it was designed. You can register the class by either rewriting the .json file or registering it programatically.

The code snippet below illustrates how to register the class by modifying the authentication_customization.json file.

Copy
{
    "UserDefinedComponent": [
        {
            "PromptType": 0,
            "View":"com.microstrategy.android.custom.afip.CustomAuthenticationView",
            "Fragment":"com.microstrategy.android.ui.fragment.AuthenticationFragment",
            "Module":"com.microstrategy.android.ui.controller.authentication.module.AuthenticationModule"
        },
        {
            "PromptType": 1,
            "View":"com.microstrategy.android.ui.view.authentication.CustomizableAuthenticationView",
            "Fragment":"com.microstrategy.android.ui.fragment.ChangePasswordFragment",
            "Module":"com.microstrategy.android.ui.controller.authentication.module.ChangePasswordModule"
        }
    ]

}

The code snippet below illustrates how to register the class programmatically.

Copy
MobileLoginManager.sharedLoginManager().setUserDefinedComponents(
"com.microstrategy.android.custom.afip.CustomAuthenticationView",
"com.microstrategy.android.ui.fragment.AuthenticationFragment",
"com.microstrategy.android.ui.controller.authentication.module.AuthenticationModule",
0);

When registering the class programatically, a PromptType of 0 represents AuthenticationPromptType. A PromptType of 1 represents ChangePasswordPromptType. View/Fragment/Module provides the class name with the full package name. MobileLoginManager finds and initializes the class with reflection.