Citrix.Xamarin.Forms.MAMSDK 22.11.0.3

Prefix Reserved
dotnet add package Citrix.Xamarin.Forms.MAMSDK --version 22.11.0.3                
NuGet\Install-Package Citrix.Xamarin.Forms.MAMSDK -Version 22.11.0.3                
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="Citrix.Xamarin.Forms.MAMSDK" Version="22.11.0.3" />                
For projects that support PackageReference, copy this XML node into the project file to reference the package.
paket add Citrix.Xamarin.Forms.MAMSDK --version 22.11.0.3                
#r "nuget: Citrix.Xamarin.Forms.MAMSDK, 22.11.0.3"                
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
// Install Citrix.Xamarin.Forms.MAMSDK as a Cake Addin
#addin nuget:?package=Citrix.Xamarin.Forms.MAMSDK&version=22.11.0.3

// Install Citrix.Xamarin.Forms.MAMSDK as a Cake Tool
#tool nuget:?package=Citrix.Xamarin.Forms.MAMSDK&version=22.11.0.3                

Xamarin MAM SDK

This SDK is useful for developing Xamarin Native (Android) and Xamarin Forms apps with Citrix Endpoint Management's MAM SDK.

Getting Started

The Citrix Endpoint Management (CEM) Xamarin MAM SDK libraries are designed to allow a per-app VPN connection without requiring mobile device management (MDM). These libraries enables the creation of the Web SSO network tunnel for a Xamarin app. <b>With the Xamarin MamSdk, apps are no longer required to be wrapped with the MDX Toolkit.</b>

Why use the Micro VPN SDK

Current MDX provides an app wrapping approach that modifies the original apk file and generates a wrapped apk file that causes different kinds of compatibility issues for the app wrapping. Also, it provides lot of lower level hooking that breaks often with OS changes. Citrix Xamarin MAM SDK starts secure per-app VPN tunnel and enable objects for network tunneling. This gives app developers more control over establishing a network tunnel and they can avoid all the above mentioned app wrapping issues. Also it will help to avoid several OS compatibility issues.

Supported Platforms

  • Android (Xamarin Android MAM SDK currently supports Android Enterprise platform only. <b>Legacy Device Admin (DA) platform is not supported</b>)

<b>Note: Currently Xamarin MAM SDK doesn't support iOS platform</b>

Currently Xamarin.MAMSDK libraries for Android platform supports tunneling for the following Xamarin components.

  • Xamarin Android WebView
  • Xamarin Forms WebView
  • Xamarin HttpClient

Prerequisites

  1. Microsoft Visual Studio 2019 or later and Visual Studio for Mac 8 or later
  2. Latest Secure Hub App from Google Play Store
  3. Keystore for MDX file generation or signing apk file
  4. Android SDK
  5. Xamarin Forms 4.x

How-to Guides:

Installing the Xamarin MAM SDK Plugin:

For the latest Xamarin MAM SDK and examples, see the download page.

Setting up the Xamarin MAM SDK:

Step-1:

Unzip Xamarin.MAMSDK-<MAM SDK Version Number>.zip. This will have the following directory structure.<br><br>

Directory Structure

NugetPackage folder will contain all the necessary nuget libraries required to build Xamarin Android and Xamarin Forms App using Citrix MAM SDK.

Step-2:

Add nuget sources to your project to point to MAM SDK nuget libraries. Example,

nuget sources Add -Name Xamarin.MAMSDK.Android -Source <Enter Xamarin MAM SDK Location Here>/NugetPackage/Android
nuget sources Add -Name Xamarin.MAMSDK.Forms -Source <Enter Xamarin MAM SDK Location Here>/NugetPackage/Forms

Step-3:

Change Dex compiler to 'd8' for your Xamarin project by adding below element under 'PropertyGroup' node in your .csproj file.

<AndroidDexTool>d8</AndroidDexTool>
Step-4:

Change minSdkVersion and targetSdkVersion in your Androidmanifest.xml

<uses-sdk android:minSdkVersion="24" android:targetSdkVersion="29" />
Step-5:

Add Nuget Packages in your Xamarin project. Change the "Version" value with latest Xamarin MAM SDK version number.

For Xamarin Forms project add the following packages:

<PackageReference Include="Citrix.Xamarin.Android.MAMSDK">
  <Version>22.11.0.x</Version>
</PackageReference>
<PackageReference Include="Citrix.Xamarin.Forms.MAMSDK">
  <Version>22.11.0.x</Version>
</PackageReference>

If you are not using Xamarin Forms and your project is just using Xamarin.Android (Native) then add only Citrix.Xamarin.Android.MAMSDK nuget library.

<PackageReference Include="Citrix.Xamarin.Android.MAMSDK">
  <Version>22.11.0.x</Version>
</PackageReference>
Step-6: Using SDK: Refer(#Using Xamarin MAM SDK) sections below.
Step-7:

Generate MDX file corresponding to your Xamarin App APK file using command line tool.

export KEYSTORE_PATH=<Enter Keystore Location Here>
export KEYSTORE_PASSWORD=<Enter Store Password Here>
export KEY_PASSWORD=<Enter Key Password Here>
export KEY_ALIAS=<Enter Keystore Alias Here>
export PACKAGE_NAME=<Enter App Package Name Here>
export INPUT_APK_PATH=<Enter APK Location Here>
export OUTPUT_MDX_PATH=<Enter Output MDX Location Here>
export ANDROID_SDK_HOME=<Enter Android SDK Path Here>
export PATH=$ANDROID_SDK_HOME/tools:$ANDROID_SDK_HOME/build-tools/29.0.3:$ANDROID_SDK_HOME/platform-tools:$PATH

java -jar <Enter Xamarin MAM SDK Location Here>/Tools/AndroidTools/managed-app-utility.jar wrap -in $INPUT_APK_PATH -out $OUTPUT_MDX_PATH -appType sdkapp -storeUrl https://play.google.com/store/apps/details?id=$PACKAGE_NAME -keystore $KEYSTORE_PATH -storepass $KEYSTORE_PASSWORD -keyalias $KEY_ALIAS -keypass $KEY_PASSWORD

Step-8:

Publish signed APK file to your enterprise. Citrix Endpoint Management cloud customers can use XMS console to publish APK file for their enterprise. Follow the below steps to use Enterprise App publishing feature for private app publishing.<br><br> Enterprise App Publishing 1<br><br> Select Platform as "Android Enterprise"<br><br> Enterprise App Publishing 2<br><br> Enterprise App Publishing 3<br><br> Enterprise App Publishing 4<br><br> Once uploaded, it takes sometime before it gets approved by Google. You can verify if it got approved from https://play.google.com/work console.<br><br> Enterprise App Publishing 5

Step-9:

Once Enterprise App is approved then upload the MDX file to XMS console. This will allow the app to be managed through CEM.<br><br> MDX File Upload 1<br><br> MDX File Upload 2<br>

If you are using split tunnel mode REVERSE then you can define Reverse Split Tunnel Exclusion List under MDX Policies. Also, you can override the default log settings under MDX Policies.

Step-10:

Install latest version of Secure Hub from Google Play Store.

Step-11:

Launch Secure Hub. Enroll to the CEM environment.

Step-12:

Install the sdk app (e.g. MvpnTestFormsApp) from Secure Hub Store page. It will launch Play Store to install it. If the latest app is not published yet on Play Store, then you can also side load the apk file using adb tool (This is normally helpful for dev testing).

adb install mvpntestformsapp.apk

Using Citrix Xamarin Forms MAM SDK:

Note: If your App is using Xamarin Forms, then follow the below steps. Currently Citrix Xamarin Forms MAM SDK supports only Android platform. iOS platform support is not added yet.

Citrix.Xamarin.Forms.MAMSDK exposes APIs that can be used for MicroVPN tunneling for a Xamarin Forms app. These APIs are provided through a Dependency Service (i.e. MicroVPNService) This class has platform specific implementation to invoke native platform functionality from shared code.<br>

Sample code reference for XAML Binding class to call MicroVPNService.cs Dependency service.

public partial class MainPage : ContentPage, IStartTunnelCallback
{
    public MainPage()
    {
        InitializeComponent();
        urlEntry.Text = "http://mycompanyinternalwebsite.com";
        IMicroVPNService service = DependencyService.Get<IMicroVPNService>();
        service.Init();
    }
    void OnStartTunnel(object sender, EventArgs args)
    {
        activityIndicator.IsRunning = true;
        IMicroVPNService service = DependencyService.Get<IMicroVPNService>();
        service.StartTunnel(this);
    }
    public void OnSuccess()
    {
        activityIndicator.IsRunning = false;
    }
    public void OnError(StartTunnelError error)
    {
        activityIndicator.IsRunning = false;
        DisplayAlert("Error", error.ToString(), "OK");
    }
    void OnStopTunnel(object sender, EventArgs args)
    {
        IMicroVPNService service = DependencyService.Get<IMicroVPNService>();
        service.StopTunnel();
    }
    void OnCheckTunnel(object sender, EventArgs args)
    {
        IMicroVPNService service = DependencyService.Get<IMicroVPNService>();
        bool isRunning = service.IsNetworkTunnelRunning();
        DisplayAlert("Info", isRunning ? "Tunnel is started" : "Tunnel is stopped", "OK");
    }
    async void OnWebView(object sender, EventArgs args)
    {
        activityIndicator.IsRunning = false;
        await Navigation.PushAsync(new WebViewPage(urlEntry.Text));
    }
    async void OnHttpClient(object sender, EventArgs args)
    {
       activityIndicator.IsRunning = true;
        try
        {
            IMicroVPNService service = DependencyService.Get<IMicroVPNService>();
            HttpClient httpClient = service.CreateHttpClient();
            var result = await httpClient.GetStringAsync(urlEntry.Text);
            await DisplayAlert("HttpClient", result, "OK");
        }
        catch (Exception ex)
        {
            await DisplayAlert("Error", ex.Message, "OK");
        }
        finally
        {
            activityIndicator.IsRunning = false;
        }
    }
}

Step-1: Init Tunnel:

DependencyService.Init() method initializes the tunnel.

IMicroVPNService service = DependencyService.Get<IMicroVPNService>();
service.Init();

Step-2: Start Tunnel:

DependencyService.StartTunnel() method starts mVPN tunnel asynchronously. Results are returned through a callback IStartTunnelCallback.

IMicroVPNService service = DependencyService.Get<IMicroVPNService>();
service.StartTunnel(new MyCallback());

Callback has two methods OnSuccess() and OnError(). Depending on start tunnel success or failure, it calls respective methods.

public class MyCallback : IStartTunnelCallback
{
    public void OnSuccess()
    {
        //Tunnel is running. You can send network request now.
    }

    public void OnError(StartTunnelError error)
    {
        //Tunnel is failed to start. Check error for an appropriate error code.
    }
}        

Step-3: Stop Tunnel:

DependencyService.StopTunnel() method stops mVPN tunnel.

IMicroVPNService service = DependencyService.Get<IMicroVPNService>();
service.StopTunnel();

Step-4: Check Tunnel Status:

DependencyService.IsNetworkTunnelRunning() method returns mVPN tunnel status. If tunnel is running then returns true otherwise it will return false.

IMicroVPNService service = DependencyService.Get<IMicroVPNService>();
service.IsNetworkTunnelRunning();

Step-5: Create HttpClient:

DependencyService.CreateHttpClient() method returns HttpClient object that is enabled for tunneling. App needs start tunnel before calling this method.

IMicroVPNService service = DependencyService.Get<IMicroVPNService>();
service.CreateHttpClient();

Step-6: Enable WebView for Tunneling:

Create a custom WebView Renderer class inside <XamarinFormsApp>.Android project by inheriting from MvpnWebViewRenderer. This will enable webview tunneling for Xamarin Forms for Android platform. Example, shown below

using Android.Content;
using Android.Webkit;
using Com.Citrix.Mvpn.Api;
using MvpnTestFormsApp.Droid;
using Xamarin.Forms;
using Xamarin.Forms.Platform.Android;

[assembly: ExportRenderer(typeof(Xamarin.Forms.WebView), typeof(XamarinWebViewRenderer))]
namespace MvpnTestFormsApp.Droid
{
    public class XamarinWebViewRenderer : MvpnWebViewRenderer
    {
        public XamarinWebViewRenderer(Context context) : base(context)
        {
        }

        public override WebViewClient CreateWebViewClient()
        {
            return new FormsWebViewClient(this);
        }
    }
}

Using Citrix Xamarin Android MAM SDK:

Note: If you are using Xamarin Native Android without Xamarin Forms the follow the below steps:

MicroVPNSDK.cs provides methods to start tunnel, stop tunnel and check tunnel status etc.

App needs to start tunnel before making any other calls to mVPN. MicroVPNSDK.StartTunnel(...) method needs to be called to start tunnel. This method starts Micro VPN network tunnel asynchronously. App should invoke #StartTunnel(activity, messenger) method from an activity (e.g. OnCreate() method of an activity) and pass that activity instance as an argument to this method. Also #StartTunnel(context, messenger) method can be called to start tunnel on application launch but this method requires a valid session to exist before starting tunnel. This method also takes a messenger object that is needed for async communication. #StartTunnel(...) returns the result/status using the messenger object back to the app's handler.

Step-1: Start Tunnel:

MicroVPNSDK.StartTunnel() method initializes the tunnel.

MicroVPNSDK.StartTunnel(this, new Messenger(handler));

Messenger object should have a custom Handler that will override Handler#handleMessage() method. When the tunnel starts successfully or fails to start, it will return success or failure messages using the input messenger object. Also, when Netscaler cookie expires, a cookie expiry message will be sent using this messenger. If the value of msg.What is "0" (zero) then tunnel established successfully. Supported Codes (msg.What) are described below.

Sample code for reference for Handler:

public class XamarinTunnelHandler : MvpnDefaultHandler
{
    private readonly static string TAG = "MVPN-TunnelHandler";
    public override void HandleMessage(Message msg)
    {
        ResponseStatusCode responseStatusCode = ResponseStatusCode.FromId(msg.What);
        if (responseStatusCode == ResponseStatusCode.StartTunnelSuccess)
        {
            Log.Info(TAG, "Tunnel started successfully!!!");
            Toast.MakeText(Application.Context, Resource.String.MvpnTunnelStarted, ToastLength.Short).Show();
        }
        else if (responseStatusCode == ResponseStatusCode.TunnelAlreadyRunning)
        {
            Log.Warn(TAG, "Tunnel is already running.");
            Toast.MakeText(Application.Context, Resource.String.MvpnTunnelAlreadyRunning, ToastLength.Short).Show();
        }
        else if (responseStatusCode == ResponseStatusCode.StartTunnelFailed)
        {
            Log.Error(TAG, "Failed to start tunnel!!!");
            Toast.MakeText(Application.Context, Resource.String.MvpnTunnelFailed, ToastLength.Long).Show();
        }
        else if (responseStatusCode == ResponseStatusCode.SessionExpired)
        {
            Log.Info(TAG, "Session Expired!!!");
            Toast.MakeText(Application.Context, Resource.String.MvpnSessionExpired, ToastLength.Short).Show();
        }
        else if (responseStatusCode == ResponseStatusCode.FoundLegacyMode)
        {
            Log.Error(TAG, "Cannot start tunnel for Legacy ManagementMode!!!");
        }
        else if (responseStatusCode == ResponseStatusCode.FoundNonManagedApp)
        {
            Log.Error(TAG, "Could not retrieve policies!!! \n This could be because of the following reasons: \n\t 1. SecureHub is not installed.\n\t 2. SecureHub enrollment is not completed.\n\t 3. App is not managed through CEM.");
            Toast.MakeText(Application.Context, Resource.String.MvpnNonManagedApp, ToastLength.Long).Show();
        }
        else if (responseStatusCode == ResponseStatusCode.FoundNonWebssoMode)
        {
            Log.Error(TAG, "Cannot start tunnel for NetworkAccess mode other than Tunneled - Web SSO!!!");
            Toast.MakeText(Application.Context, Resource.String.MvpnNonWebSsoMode, ToastLength.Long).Show();
        }
        else if (responseStatusCode == ResponseStatusCode.NoNetworkConnection)
        {
            Log.Error(TAG, "Failed to start tunnel. No Network!!!");
            Toast.MakeText(Application.Context, Resource.String.MvpnNoNetworkConnection, ToastLength.Long).Show();
        }
        else if (responseStatusCode == ResponseStatusCode.InvalidAppConfigurationData)
        {
            Log.Error(TAG, "Failed to start tunnel. Invalid application configuration data!!!");
            Toast.MakeText(Application.Context, Resource.String.InvalidAppConfigurationData, ToastLength.Long).Show();
        }
        else if (responseStatusCode == ResponseStatusCode.InvalidOauthToken)
        {
            Log.Error(TAG, "Failed to login to gateway with OAuth token!!!");
            Toast.MakeText(Application.Context, Resource.String.InvalidOauthToken, ToastLength.Long).Show();
        }
        else if (responseStatusCode == ResponseStatusCode.AppLocked)
        {
            Log.Error(TAG, "Failed to start tunnel. App is in locked state!!!");
            Toast.MakeText(Application.Context, Resource.String.AppLocked, ToastLength.Long).Show();
        }
    }
} 

Error Codes (msg.What) for handleMessage: <br> 0 = Tunnel started successfully.<br> 1 = Tunnel failed to start.<br> 2 = Tunnel is already running. <br> 3 = Session is expired.Start Tunnel is required. <br> 4 = App is wrapped and legacy mdx mode. <br> 5 = Network Access mode is not "Tunneled - Web SSO". Tunnel can be started only in "Tunneled - Web SSO" mode for explicit SDK app. <br> 6 = App is not managed. Unable to retrieve policies. <br> 7 = No network connection.<br> 8 = Invalid application configuration data.<br> 9 = Failed to login to gateway with OAuth token.<br> 10 = App is in locked state.<br>

Step-2: Enable WebView for Tunneling:

MicroVPNSDK.EnableWebViewObjectForNetworkTunnel(context, webView, webViewClient) method enables a WebView to use MicroVPN tunnel for sending traffic. This method can be called once tunnel is started successfully.

MicroVPNSDK.EnableWebViewObjectForNetworkTunnel(this, webView, webViewClient);

Step-3: Enable HttpClient for Tunneling :

To tunnel HTTP/S requests using HttpClient pass AndroidMvpnClientHandler instance while creating HttpClient object.

HttpClient httpClient = new HttpClient(new AndroidMvpnClientHandler());

Step-4: Stop Tunnel:

MicroVPNSDK.StopTunnel() method can be used to stop tunnel.

MicroVPNSDK.StopTunnel(context) 

Step-5: Check Tunnel Status:

MicroVPNSDK.IsNetworkTunnelRunning() method can be used to check tunnel status.

MicroVPNSDK.IsNetworkTunnelRunning(context) 

Common Troubleshooting Tips

Issue-1:

I am getting below error while building my project with MAM SDKs. How do I fix this?

“COMPILETODALVIK : Uncaught translation error : com.android.dx.cf.code.SimException: ERROR in com.citrix.mvpn.helper.c.<clinit>:()V: invalid opcode ba - invokedynamic requires --min-sdk-version >= 26 (currently 13) [/Users/rajunandy/Raju/Workspace/MDX/xamarin-mamsdk/Samples/MvpnTestAndroidApp/MvpnTestAndroidApp.csproj]”. 
Solution:

Setting AndroidDexTool to d8 should fix the issue. You will need to add the below property in your .csproj file under the Debug/Release PropertyGroup.

<AndroidDexTool>d8</AndroidDexTool>
<br>

In some cases, you may need to additionally enable desugar by adding AndroidEnableDesugar property with value True in your .csproj file under the Debug/Release PropertyGroup.

<AndroidEnableDesugar>True</AndroidEnableDesugar>

Issue-2:

What is the .NET Standard Version supported for Xamarin MAM SDK?

Solution:

Current Nuget libraries support .NET Standard 2.0 and greater.

Issue-3:

When I call StartTunnel() method, callback is going to OnError() method and it is returning StartTunnelError = NotMAMEnrolled. Also ADB logs shows this error message.

07-22 22:04:40.004 15599 15599 E MVPN-XM-TunnelHandler: NotMAMEnrolled

Solution:

This exception is thrown when App is not managed app. This can be due to several reasons. Things to check.

  1. If SecureHub Enrollment is completed successfully.
  2. Apps APK file has been signed with a keystore and the same keystore is used to generate the MDX file. (Refer #Step-7 under setting up MAM SDK)
  3. MDX file is published in XMS console.
Issue-4:

When I call StartTunnel() method, callback is going to OnError() method and it is returning StartTunnelError = InvalidPolicy. Also ADB logs shows this error message.

07-30 10:46:01.627 16133 16133 E MVPN-XM-TunnelHandler: InvalidPolicy

Solution:

This exception occurs when XMS policies are incorrect for tunnelling. Please check XMS console and make sure Network access policy is set to Tunneled - Web SSO

Issue-5:

I am getting ERR_CLEARTEXT_NOT_PERMITTED error when tunneling HTTP request The webpage at http://… could not be loaded because: net:: ERR_CLEARTEXT_NOT_PERMITTED

Solution:

Add the below line in your AssemblyInfo.cs to allow clear text traffic.

[assembly: Application(UsesCleartextTraffic =true)]

Issue-6:

How do I capture Debug logs for technical support team?

Solution:
  1. Launch Secure Hub and click on the hamburger menu
  2. Navigate to Help → Report Issue and select the app for which you are having an issue.
  3. Click Advanced log settings
  4. Change Log Level to Level 15 Debug10
  5. Change Log destination to select both File and Console
  6. Repro the issue
  7. Enter a description of your issue (optionally you can attach screenshots)
  8. Click Send and choose an email app (e.g. Secure Mail) to email the log bundle.

Installing Xamarin Forms SampleApp Project

Steps:

  1. Unzip MvpnTestFormsApp.zip. This zip file will be located under <Xamarin Mam Sdk Location>/SampleCode folder.
  2. Open this solution project Visaul Studio IDE (e.g. Visual Studio for Mac).
  3. Add nuget sources to your project to point to latest MAM SDK nuget libraries using IDE or command line. Latest Xamarin MAM SDK nuget libraries can be found inside <Enter Xamarin MAM SDK Location Here>/NugetPackage folder. <br> Navigate to <b>Visual Studio → Preferences → NuGet → Sources → Add</b> <br>

Sample App Setup 1 <br><br> Sample App Setup 1b <br><br> Command Line:<br>

nuget sources Add -Name Xamarin.MAMSDK.Android -Source <Enter Xamarin MAM SDK Location Here>/NugetPackage/Android
nuget sources Add -Name Xamarin.MAMSDK.Forms -Source <Enter Xamarin MAM SDK Location Here>/NugetPackage/Forms
  1. Update Xamarin.MAMSDK nuget packages (as highlighted below) to the latest version. <br><br> Sample App Setup 2 <br><br>

  2. Update App package id in <b>AndroidManifest.xml</b> to have a globally unique value. AndroidManifest.xml file will be located under MvpnTestFormsApp.Android/Properties folder.<br><br> Sample App Setup 3<br><br>

  3. Add your keystore details for Android Package Signing in MvpnTestFormsApp.Android project. This can be done either using IDE or by editing MvpnTestFormsApp.Android.csproj file. For IDE, right click on MvpnTestFormsApp.Android project and then navigate to <b>Options → Sources → Android Package Signing</b><br>

Sample App Setup 4<br><br>

<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
    .....
    <AndroidDexTool>d8</AndroidDexTool>
    <AndroidKeyStore>True</AndroidKeyStore>
    <AndroidSigningKeyStore>/Users/****/Downloads/mycompany.keystore</AndroidSigningKeyStore>
    <AndroidSigningStorePass>*****</AndroidSigningStorePass>
    <AndroidSigningKeyAlias>*****</AndroidSigningKeyAlias>
    <AndroidSigningKeyPass>****</AndroidSigningKeyPass>
</PropertyGroup>
  1. Build the MvpnTestFormsApp.Android project using IDE or using command line. For IDE, right click on MvpnTestFormsApp.Android project and click "Build MvpnTestFormsApp.Android" option.<br>

Sample App Setup 5<br><br>

Command Line:<br>

msbuild -p:AndroidSdkDirectory=${ANDROID_HOME} -t:Clean -t:Build -property:Configuration=Release MvpnTestFormsApp.Android/MvpnTestFormsApp.Android.csproj
  1. Archive for Publishing and Sign the APK file using IDE or using command line. <br> For IDE, right click on MvpnTestFormsApp.Android project and click "Archive for Publishing" option.<br>

Sample App Setup 6<br><br>

Command Line:<br>

msbuild -p:Configuration=Release -t:SignAndroidPackage -p:OutputPath=/my/output/path MvpnTestFormsApp.Android/MvpnTestFormsApp.Android.csproj 
  1. Generate MDX file corresponding to Xamarin App APK file using command line tool.<br>
export KEYSTORE_PATH=<Enter Keystore Location Here>
export KEYSTORE_PASSWORD=<Enter Store Password Here>
export KEY_PASSWORD=<Enter Key Password Here>
export KEY_ALIAS=<Enter Keystore Alias Here>
export PACKAGE_NAME=com.citrix.mvpnformstestapp.<uniqueid>
export INPUT_APK_PATH=<Enter APK Location Here>
export OUTPUT_MDX_PATH=<Enter Output MDX Location Here>
export ANDROID_SDK_HOME=<Enter Android SDK Path Here>
export PATH=$ANDROID_SDK_HOME/tools:$ANDROID_SDK_HOME/build-tools/29.0.3:$ANDROID_SDK_HOME/platform-tools:$PATH

java -jar <Enter Xamarin MAM SDK Location Here>/Tools/AndroidTools/managed-app-utility.jar wrap -in $INPUT_APK_PATH -out $OUTPUT_MDX_PATH -appType sdkapp -storeUrl https://play.google.com/store/apps/details?id=$PACKAGE_NAME -keystore $KEYSTORE_PATH -storepass $KEYSTORE_PASSWORD -keyalias $KEY_ALIAS -keypass $KEY_PASSWORD

  1. Publish the signed release APK file using Enterprise App publishing feature in XMS (this feature is available only for cloud). For more details, refer <b>Step-8</b> from "Setting up the library" page.
  2. Once APK is approved in Google playstore, upload the .mdx file to XMS console as an MDX app. For more details, refer <b>Step-9</b> from "Setting up the library" page.
  3. Install latest version of Secure Hub on your android device
  4. Enroll to your CEM environment (Android Enterprise) using Secure Hub.
  5. Once Enrollment completes successfully, install MvpnTestFormsApp from Secure Hub store page or from Managed Google Play
  6. You can also side load the APK file to your device using adb command. Side loading works if your Enterprise has debugging enabled (This is normally helpful for dev testing)
adb install com.citrix.mvpnformstestapp.<uniqueid>.apk
  1. Once MvpnTestFormsApp is installed successfully, launch the app.<br>

Test App 1

  1. Click “START TUNNEL” button to start MicroVPN network tunnel.
  2. Change the URL address to point to a website that is internal to your company network.
  3. Click "WEBVIEW" or "HTTPCLIENT" button to tunnel requests through MicroVPN.

Installing Xamarin Android (Native) SampleApp Project

Steps:

  1. Unzip MvpnTestAndroidApp.zip. This zip file will be located under <Xamarin Mam Sdk Location>/SampleCode folder.
  2. Open the MvpnTestAndroidApp.csproj file Visaul Studio IDE (e.g. Visual Studio for Mac).
  3. Add nuget sources to your project to point to latest MAM SDK nuget libraries using IDE or command line. Latest Xamarin MAM SDK nuget libraries can be found inside <Enter Xamarin MAM SDK Location Here>/NugetPackage folder. <br> Navigate to <b>Visual Studio → Preferences → NuGet → Sources → Add</b> <br>

Sample App Setup 1 <br><br> Command Line:<br>

nuget sources Add -Name Xamarin.MAMSDK.Android -Source <Enter Xamarin MAM SDK Location Here>/NugetPackage/Android
  1. Update Xamarin.MAMSDK nuget packages (as highlighted below) to the latest version. Also add Xamarin.AndroidX.AppCompat library as shown below. <br><br> Sample App Setup 2 <br><br>

  2. Update App package id in <b>AndroidManifest.xml</b> to have a globally unique value. AndroidManifest.xml file will be located under MvpnTestAndroidApp/Properties folder.<br><br> Sample App Setup 3<br><br>

  3. Add your keystore details for Android Package Signing in MvpnTestAndroidApp project. This can be done either using IDE or by editing MvpnTestAndroidApp.csproj file. For IDE, right click on MvpnTestAndroidApp project and then navigate to <b>Options → Sources → Android Package Signing</b><br>

Sample App Setup 4<br><br>

<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
    .....
    <AndroidDexTool>d8</AndroidDexTool>
    <AndroidKeyStore>True</AndroidKeyStore>
    <AndroidSigningKeyStore>/Users/****/Downloads/mycompany.keystore</AndroidSigningKeyStore>
    <AndroidSigningStorePass>*****</AndroidSigningStorePass>
    <AndroidSigningKeyAlias>*****</AndroidSigningKeyAlias>
    <AndroidSigningKeyPass>****</AndroidSigningKeyPass>
</PropertyGroup>
  1. Build the MvpnTestAndroidApp project using IDE or using command line. For IDE, right click on MvpnTestAndroidApp project and click "Build MvpnTestAndroidApp" option.<br>

Sample App Setup 5<br><br>

Command Line:<br>

msbuild -p:AndroidSdkDirectory=${ANDROID_HOME} -t:Clean -t:Build -property:Configuration=Release MvpnTestAndroidApp/MvpnTestAndroidApp.csproj
  1. Archive for Publishing and Sign the APK file using IDE or using command line. <br> For IDE, right click on MvpnTestAndroidApp project and click "Archive for Publishing" option.<br>

Sample App Setup 6<br><br>

Command Line:<br>

msbuild -p:Configuration=Release -t:SignAndroidPackage -p:OutputPath=/my/output/path MvpnTestAndroidApp/MvpnTestAndroidApp.csproj 
  1. Generate MDX file corresponding to Xamarin App APK file using command line tool.<br>
export KEYSTORE_PATH=<Enter Keystore Location Here>
export KEYSTORE_PASSWORD=<Enter Store Password Here>
export KEY_PASSWORD=<Enter Key Password Here>
export KEY_ALIAS=<Enter Keystore Alias Here>
export PACKAGE_NAME=MvpnTestAndroidApp.MvpnTestAndroidApp.<uniqueid>
export INPUT_APK_PATH=<Enter APK Location Here>
export OUTPUT_MDX_PATH=<Enter Output MDX Location Here>
export ANDROID_SDK_HOME=<Enter Android SDK Path Here>
export PATH=$ANDROID_SDK_HOME/tools:$ANDROID_SDK_HOME/build-tools/29.0.3:$ANDROID_SDK_HOME/platform-tools:$PATH

java -jar <Enter Xamarin MAM SDK Location Here>/Tools/AndroidTools/managed-app-utility.jar wrap -in $INPUT_APK_PATH -out $OUTPUT_MDX_PATH -appType sdkapp -storeUrl https://play.google.com/store/apps/details?id=$PACKAGE_NAME -keystore $KEYSTORE_PATH -storepass $KEYSTORE_PASSWORD -keyalias $KEY_ALIAS -keypass $KEY_PASSWORD

  1. Publish the signed release APK file using Enterprise App publishing feature in XMS (this feature is available only for cloud). For more details, refer <b>Step-8</b> from "Setting up the library" page.
  2. Once APK is approved in Google playstore, upload the .mdx file to XMS console as an MDX app. For more details, refer <b>Step-9</b> from "Setting up the library" page.
  3. Install latest version of Secure Hub on your android device
  4. Enroll to your CEM environment (Android Enterprise) using Secure Hub.
  5. Once Enrollment completes successfully, install MvpnTestAndroidApp from Secure Hub store page or from Managed Google Play
  6. You can also side load the APK file to your device using adb command. Side loading works if your Enterprise has debugging enabled (This is normally helpful for dev testing)
adb install MvpnTestAndroidApp.MvpnTestAndroidApp.<uniqueid>.apk
  1. Once MvpnTestAndroidApp is installed successfully, launch the app.<br>

Test App 1

  1. Click “Start Tunnel” button to start MicroVPN network tunnel.
  2. Change the URL address to point to a website that is internal to your company network.
  3. Click "WebView" or "HttpClient" button to tunnel requests through MicroVPN.
APIs & Reference:
For details please refer Xamarin MAM SDK Documentation (Xamarin.MAMSDK-Documentation.zip)
Product Compatible and additional computed target framework versions.
.NET net5.0 was computed.  net5.0-windows was computed.  net6.0 was computed.  net6.0-android was computed.  net6.0-ios was computed.  net6.0-maccatalyst was computed.  net6.0-macos was computed.  net6.0-tvos was computed.  net6.0-windows was computed.  net7.0 was computed.  net7.0-android was computed.  net7.0-ios was computed.  net7.0-maccatalyst was computed.  net7.0-macos was computed.  net7.0-tvos was computed.  net7.0-windows was computed.  net8.0 was computed.  net8.0-android was computed.  net8.0-browser was computed.  net8.0-ios was computed.  net8.0-maccatalyst was computed.  net8.0-macos was computed.  net8.0-tvos was computed.  net8.0-windows was computed. 
.NET Core netcoreapp2.0 was computed.  netcoreapp2.1 was computed.  netcoreapp2.2 was computed.  netcoreapp3.0 was computed.  netcoreapp3.1 was computed. 
.NET Standard netstandard2.0 is compatible.  netstandard2.1 was computed. 
.NET Framework net461 was computed.  net462 was computed.  net463 was computed.  net47 was computed.  net471 was computed.  net472 was computed.  net48 was computed.  net481 was computed. 
MonoAndroid monoandroid was computed.  monoandroid10 is compatible. 
MonoMac monomac was computed. 
MonoTouch monotouch was computed. 
Tizen tizen40 was computed.  tizen60 was computed. 
Xamarin.iOS xamarinios was computed.  xamarinios10 is compatible. 
Xamarin.Mac xamarinmac was computed. 
Xamarin.TVOS xamarintvos was computed. 
Xamarin.WatchOS xamarinwatchos was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

This package has no dependencies.

NuGet packages

This package is not used by any NuGet packages.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last updated
22.11.0.3 342 1/6/2023
21.6.0.4 369 6/29/2021

Release 22.11.0