10 Xamarin Android Applications
If you use the Xamarin platform to develop Android apps, you can use the SDK that Oracle Mobile Cloud Service (MCS) provides for Xamarin Android apps. This SDK simplifies authentication with MCS and provides native wrapper classes for MCS platform APIs.
Getting the SDK for Xamarin Android
To get the MCS client SDK for Xamarin Android, go to the Oracle Technology Network’s MCS download page.
To use this SDK, you should have the following software on your system:
-
Microsoft Visual Studio, with support for Xamarin development.
-
Java Development Kit (JDK) 1.7.0_67 or compatible.
See http://www.oracle.com/technetwork/java/javase/downloads/index.html for JDK downloads.
Adding the SDK to a Xamarin Android Project
-
If you haven’t already done so, extract the contents from the SDK zip.
-
In Visual Studio, create a Visual C# Android app.
-
Make sure you can connect to the internet from Visual Studio connection so that NuGet packages are reachable.
-
Add GCM and Facebook dependencies to your project:
-
If a Packages node appears in the Solution Explorer for your project, do the following:
-
Right-click the Packages node.
-
Type
GCM
in the search field, selectXamarin.GooglePlayServices.Gcm
(notCrosslight.Xamarin.GooglePlayServices.GCM
), and click Add Package. The remaining GCM dependencies will be added automatically. -
Accept the terms to add the packages successfully.
-
Add
Xamarin.Facebook.Android
by searching for it in the NuGet packages and adding it in the same way you added the GCM packages.
-
-
If a Packages node
doesn't
appear in the Solution Explorer for your project, do the following:-
Select Tools > NuGet Package Manager > Manage NuGet Packages for Solution.
-
Select the Browse tab.
-
Type
GCM
in the search field, selectXamarin.GooglePlayServices.Gcm
(notCrosslight.Xamarin.GooglePlayServices.GCM
), select the checkbox for your app, and click Install. The remaining GCM dependencies will be added automatically. -
After previewing the changes, click OK.
-
Add
Xamarin.Facebook.Android
by searching for it in the NuGet packages and adding it in the same way you added the GCM packages.
-
-
-
At the end make sure you have all the below dependencies. If any of them are missing, search for them in the NuGet package manager.
<packages> <package id="Bolts" version="1.4.0.1" targetFramework="monoandroid71" /> <package id="Xamarin.Android.Support.Animated.Vector.Drawable" version="25.4.0.2" targetFramework="monoandroid71" /> <package id="Xamarin.Android.Support.Annotations" version="25.4.0.2" targetFramework="monoandroid71" /> <package id="Xamarin.Android.Support.Compat" version="25.4.0.2" targetFramework="monoandroid71" /> <package id="Xamarin.Android.Support.Core.UI" version="25.4.0.2" targetFramework="monoandroid71" /> <package id="Xamarin.Android.Support.Core.Utils" version="25.4.0.2" targetFramework="monoandroid71" /> <package id="Xamarin.Android.Support.CustomTabs" version="25.4.0.2" targetFramework="monoandroid71" /> <package id="Xamarin.Android.Support.Design" version="25.4.0.2" targetFramework="monoandroid71" /> <package id="Xamarin.Android.Support.Fragment" version="25.4.0.2" targetFramework="monoandroid71" /> <package id="Xamarin.Android.Support.Media.Compat" version="25.4.0.2" targetFramework="monoandroid71" /> <package id="Xamarin.Android.Support.Transition" version="25.4.0.2" targetFramework="monoandroid71" /> <package id="Xamarin.Android.Support.v4" version="25.4.0.2" targetFramework="monoandroid71" /> <package id="Xamarin.Android.Support.v7.AppCompat" version="25.4.0.2" targetFramework="monoandroid71" /> <package id="Xamarin.Android.Support.v7.CardView" version="25.4.0.2" targetFramework="monoandroid71" /> <package id="Xamarin.Android.Support.v7.RecyclerView" version="25.4.0.2" targetFramework="monoandroid71" /> <package id="Xamarin.Android.Support.Vector.Drawable" version="25.4.0.2" targetFramework="monoandroid71" /> <package id="Xamarin.Build.Download" version="0.4.7" targetFramework="monoandroid80" /> <package id="Xamarin.Facebook.Android" version="4.26.0" targetFramework="monoandroid80" /> <package id="Xamarin.Google.ZXing.Core" version="3.3.0" targetFramework="monoandroid80" /> <package id="Xamarin.GooglePlayServices.Base" version="42.1021.1" targetFramework="monoandroid71" /> <package id="Xamarin.GooglePlayServices.Basement" version="42.1021.1" targetFramework="monoandroid71" /> <package id="Xamarin.GooglePlayServices.Gcm" version="42.1021.1" targetFramework="monoandroid71" /> <package id="Xamarin.GooglePlayServices.Iid" version="42.1021.1" targetFramework="monoandroid71" /> <package id="Xamarin.GooglePlayServices.Tasks" version="42.1021.1" targetFramework="monoandroid71" /> </packages>
-
Add the SDK's DLL file to your app by right-clicking the project's References node and selecting Edit References or Add Reference (depending on which menu item is available).
-
If you select Edit References, click the .NET Assembly tab, and then browse to the
Android.dll
file in the extracted SDK zip. -
If you select Add Reference, click the Browse tab, click the Browse button, and then navigate to the
Android.dll
file in the extracted SDK zip.
-
-
Add the configuration file to the app by right-clicking the project's Assets node and selecting either Add > Add Files or Add > Existing File (depending which is available) and then navigating to the SDK's
oracle_mobile_cloud_config.xml
file. -
Select the node for
oracle_mobile_cloud_config.xml
so that it's properties are displayed in the Properties pane. Then make sure that the Build Action property is set toAndroidAsset
. -
Open
oracle_mobile_cloud_config.xml
and fill in the environment details for the mobile backend that the app will be using. See Configuring SDK Properties for Xamarin Android. -
Update the
AndroidManifest.xml
file with the necessary properties as detailed in Configuring Your AndroidManifest.xml File.
Configuring SDK Properties for Xamarin Android
To use the SDK in an Android app, you need to add the oracle_mobile_cloud_config.xml
configuration file to the app and fill it in with environment details for your mobile backend. In turn, the SDK classes use the information provided in this file to access the mobile backend and construct HTTP headers for REST calls made to APIs.
oracle_mobile_cloud_config.xml
file:<mobileBackends>
<mobileBackend>
<mbeName>MBE_NAME</mbeName>
<mbeVersion>MBE_VERSION</mbeVersion>
<default>true</default>
<appKey>APPLICATION_KEY</appKey>
<baseUrl>BASE_URL</baseUrl>
<enableAnalytics>true</enableAnalytics>
<enableLogger>true</enableLogger>
<authorization>
<offlineAuthenticationEnabled>true</offlineAuthenticationEnabled>
<authenticationType>AUTH_TYPE</authenticationType>
<oauth>
<oAuthTokenEndPoint>OAUTH_URL</oAuthTokenEndPoint>
<oAuthClientId>CLIENT_ID</oAuthClientId>
<oAuthClientSecret>CLIENT_SECRET</oAuthClientSecret>
</oauth>
<basic>
<mobileBackendID>MOBILE_BACKEND_ID</mobileBackendID>
<anonymousKey>ANONYMOUS_KEY</anonymousKey>
</basic>
</authorization>
<!-- additional properties go here -->
</mobileBackend>
</mobileBackends>
-
mobileBackends
— The config file’s root element, containing one or moremobileBackend
elements. -
mobileBackend
— The element for a mobile backend. -
mbeName
— The name of the mobile backend associated with your app. -
mbeVersion
— The version number of your app (for example,1.0
). -
default
— Iftrue
, that mobile backend is treated as the default and thus can be easily referenced using thegetDefaultMobileBackend(Context context)
method in the SDK’sMobileBackendManager
class. -
appKey
— The application key, which is a unique string assigned to your app when you register it as a client in MCS. See Registering an App as a Client in MCS. -
baseUrl
— The URL your app uses to connect to its mobile backend. -
enableLogger
— When set totrue
, logging is included in your app. -
enableAnalytics
— When set totrue
, analytics on the app’s use can be collected. -
authorization
— Use the sub-elements of this element to define the authentication the app will be using and specify the required credentials.-
offlineAuthenticationEnabled
— If set totrue
, offline login will be allowed. For this to work, you also need to add the following to the app’sAndroidManifest.xml
file:<receiver android:name="oracle.cloud.mobile.network.NetworkHelper" <intent-filter> <action android:name="android.net.conn.CONNECTIVITY_CHANGE" /> </intent-filter> </receiver>
-
authenticationType
— Define the kind of authentication mechanism being used to connect your app to MCS. Possible values areoauth
(for OAuth Consumer) ,basic
(for HTTP Basic),sso
,tokenAuth
(for SSO token exchange), andfacebook
(for logging in with Facebook credentials). If this element isn’t specified, OAuth Consumer is used. The other contents and sub-elements of theauthorization
element depend on the type of authentication.
-
OAuth Consumer
<authenticationType>
element to oauth
and fill in the OAuth credentials provided by the mobile backend.
-
oAuthTokenEndPoint
— The URL of the OAuth server your app goes to, to get its authentication token. -
oAuthClient
— The unique client identifier assigned to all apps when they’re first created in your mobile backend. -
oAuthClientSecret
— The unique secret string assigned to all apps they’re first created in your mobile backend.
The resulting authorization
element might look something like this:
<authorization>
<offlineAuthenticationEnabled>true</offlineAuthenticationEnabled>
<authenticationType>oauth</authenticationType>
<oauth>
<oAuthTokenEndPoint>http://oam-server.oracle.com/oam/oauth2/tokens</oAuthTokenEndPoint>
<oAuthClient>f2d3ca5c-7e6f-4d1c-aabc-a2f3caf7ec4e</oAuthClient>
<oAuthClientSecret>vZMRkgniIbhNUiPnSRT2</oAuthClientSecret>
</oauth>
</authorization>
Enterprise SSO
For SSO, set the value of the <authenticationType>
element to sso
, fill in the OAuth credentials provided by the mobile backend, and add the ssoTokenEndpoint
.
The resulting authorization
element might look something like this:
<authorization>
<offlineAuthenticationEnabled>true</offlineAuthenticationEnabled>
<authenticationType>sso</authenticationType>
<oauth>
<oAuthTokenEndPoint>host/mobile/platform/sso/token</oAuthTokenEndPoint>
<oAuthClient>f2d3ca5c-7e6f-4d1c-aabc-a2f3caf7ec4e</oAuthClient>
<oAuthClientSecret>vZMRkgniIbhNUiPnSRT2</oAuthClientSecret>
<ssoTokenEndpoint>https://development-mcspmtrial90.mobileenv.oracle.com:443/mobile/platform/sso/token</ssoTokenEndpoint>
</oauth>
</authorization>
SSO with a Third Party Token
For SSO with a third-party token, set the value of the <authenticationType>
element to tokenAuth
and fill in the HTTP Basic auth credentials provided by the mobile backend (described next).
The resulting authorization
element might look something like this:
<authorization>
<offlineAuthenticationEnabled>true</offlineAuthenticationEnabled>
<authenticationType>tokenAuth</authenticationType>
<basic>
<mobileBackendID>6d3744b8-cab2-479c-998b-ebba2c31560f</mobileBackendID>
<anonymousKey>UFJJTUVfREVDRVBUSUNPTl9NT0JJTEVfQU5PTll</anonymousKey>
</basic>
</authorization>
HTTP Basic
<authenticationType>
element to basic
and fill in the HTTP Basic auth credentials provided by the mobile backend.
-
mobileBackendID
— The unique identifier assigned to a specific mobile backend. It gets passed in an HTTP header of every REST call made from your app to MCS, to connect it to the correct mobile backend. When calling platform APIs, the SDK handles the construction of the authentication headers for you. -
anonymousKey
— A unique string that allows your app to access APIs that don’t require login. In this scenario, the anonymous key is passed to MCS instead of an encoded user name and password combination.
The resulting authorization
element might look something like this:
<authorization>
<offlineAuthenticationEnabled>true</offlineAuthenticationEnabled>
<authenticationType>basic</authenticationType>
<basic>
<mobileBackendID>6d3744b8-cab2-479c-998b-ebba2c31560f</mobileBackendID>
<anonymousKey>UFJJTUVfREVDRVBUSUNPTl9NT0JJTEVfQU5PTll</anonymousKey>
</basic>
</authorization>
<authenticationType>
element to facebook
, fill in the HTTP Basic auth credentials provided by the mobile backend, and add the facebook
element, where you specify the Facebook credentials.
-
facebookAppId
— The Facebook application ID. -
scopes
— You can use this element to specify Facebook permissions (optional).
The resulting authorization
element might look something like this:
<authorization>
<offlineAuthenticationEnabled>true</offlineAuthenticationEnabled>
<authenticationType>facebook</authenticationType>
<basic>
<mobileBackendID>6d3744b8-cab2-479c-998b-ebba2c31560f</mobileBackendID>
<anonymousKey>UFJJTUVfREVDRVBUSUNPTl9NT0JJTEVfQU5PTll</anonymousKey>
</basic>
<facebook>
<facebookAppId>123456789012345</facebookAppId>
<scopes>public_profile,user_friends,email,user_location,user_birthday</scopes>
</facebook>
</authorization>
Configuring Your AndroidManifest.xml File
Permissions for operations such as accessing the network and finding the network state are controlled through permission settings in AndroidManifest.xml
. These permissions are required:
-
permission.INTERNET
— Allows your app to access open network sockets. -
permission.ACCESS_NETWORK_STATE
— Allows your app to access information about networks.
Other permissions are optional. For example, the Analytics platform API uses location to provide detailed information about the usage and performance of your app. If you’re using the Analytics library from the SDK, you’ll want to add these permissions as well.
-
permission.ACCESS_COARSE_LOCATION
— Allows your app to access approximate location information, derived from sources such as wi-fi and cell tower positions. -
permission.ACCESS_FINE_LOCATION
— Allows your app to access precise location information, derived from sources such as GPS.
For more information about permissions in your Android application, see Android Manifest Permissions in the Google documentation.
Add the permissions at the top of your AndroidManifest.xml
file, as shown in the following example:
<?xml version="1.0" encoding="UTF-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="oracle.cloud.mobile.photobox" >
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<application>
<receiver android:name="oracle.cloud.mobile.network.NetworkHelper"
<intent-filter>
<action android:name="android.net.conn.CONNECTIVITY_CHANGE" />
</intent-filter>
</receiver>
(.....)
</application>
</manifest>
If you are using the Notifications API in your app, you may also need to add a broadcast receiver element. See Setting Up a Mobile App for Notifications.
Loading a Mobile Backend's Configuration into a Xamarin Android App
For any calls to MCS APIs using the Xamarin Android SDK to successfully complete, you need to have the mobile backend’s configuration loaded from the app’s oracle_mobile_cloud_config.xml
file. You do this using the MobileBackendManager
class:
MobileBackendManager.Manager.GetMobileBackend(context,"GCMBackend");
Authenticating and Logging In Using the SDK for Xamarin Android
Here is some sample code that you can use for authentication through MCS in your Xamarin Android apps.
OAuth Consumer
First you initialize the authorization agent and set the authentication type to OAUTH
.
MobileBackend mobileBackend;
IAuthorizationAgent mAuthorization;
mobileBackend = MobileBackendManager.Manager.GetDefaultMobileBackend(mCtx);
mAuthorization = mobileBackend.GetAuthorization(AuthType.Oauth);
Then you use the authenticate
method to attempt authentication. The call includes parameters for Android context, user name, password, and a callback that completes the authorization process.
TextView username, password;
username = (AutoCompleteTextView)FindViewById(Resource.Id.username);
password = (EditText)FindViewById(Resource.Id.password);
String userName = username.Text;
String passWord = password.Text;
mAuthorization.Authenticate(mCtx, userName, passWord, new AuthorizationCallback());
Here’s the definition for the callback.
Authorization CallBack
private class AuthorizationCallback : Java.Lang.Object, IAuthorizationCallback
{
public void OnCompletion(ServiceProxyException exception)
{
if (exception != null)
{
Logger.Error(TAG, "Exception while receiving the Access Token", exception);
}
else
{
Logger.Error(TAG, "Authorization successful");
}
}
}
Enterprise SSO
mAuthorization.authenticateSSO(mCtx, false, new AuthorizationCallback());
private class AuthorizationCallback : Java.Lang.Object, IAuthorizationCallback
{
public void OnCompletion(ServiceProxyException exception)
{
if (exception != null)
Logger.Debug(TAG, "Exception " + exception.Message;
else
{
Logger.Debug(TAG, "SSO Auth Succeeded");
}
}
}
SSO with a Third-Party Token
First, your app needs to get a token from the third-party token issuer. The way you can obtain the token varies by issuer. For detailed information on obtaining third-party tokens and configuring identity providers in MCS, see Third-Party SAML and JWT Tokens.
Note:
The default expiration time for storing a third-party token in MCS is 6 hours. You can adjust this time by changing theSecurity_TokenExchangeTimeoutSecs
policy.
IAuthorizationAgent mAuthorization;
MobileBackend mobileBackend;
mobileBackend = MobileBackendManager.Manager.GetDefaultMobileBackend(mCtx);
mAuthorization = mobileBackend.GetAuthorization(AuthType.Tokenauth);
// Check whether credential exists in secure store
Boolean isCredentialLoaded = mAuthorization.LoadSSOTokenExchange(mCtx);
if(isCredentialLoaded){
// Credentials found in secure store - redirect to main activity
Logger.Info(TAG, "Credentials got loaded successfully from secure store.");
Intent intent = new Intent(mCtx, typeof(ContentActivity));
StartActivity(intent);
} else {
// Credentials not found - authenticate using token exchange
Logger.Info(TAG, "Credentials could not be found in secure store.");
mAuthorization.AuthenticateUsingTokenExchange(mCtx, token, true, mLoginCallback);
}
Here’s the callback:
private class AuthorizationCallback : Java.Lang.Object, IAuthorizationCallback
{
public void OnCompletion(ServiceProxyException exception)
{
if (exception == null)
{
//log event with Analytics
mAnalyticsAgent.LogEvent("Login with 3rd party token successfully");
mAnalyticsAgent.Flush();
//redirect to another Activity after login
Intent intent = new Intent(mCtx, typeof(ContentActivity));
LoginActivity.activity.StartActivity(intent);
} else {
Logger.Error(TAG, "Exception during token exchange:", exception);
LoginActivity.activity.Finish();
}
}
}
HTTP Basic Authentication
The code for handling login with HTTP Basic is nearly the same as the code for OAuth.
First you initialize the authorization agent and set the authentication type to BASIC_AUTH
.
MobileBackend mobileBackend;
IAuthorizationAgent mAuthorization;
mobileBackend = MobileBackendManager.Manager.GetDefaultMobileBackend(mCtx);
mAuthorization = mobileBackend.GetAuthorization(AuthType.BasicAuth);
Then you use the Authenticate
method to attempt authentication. The call includes parameters for Android context, user name, password, and a callback that completes the authorization process.
TextView username, password;
username = (AutoCompleteTextView)FindViewById(Resource.Id.username);
password = (EditText)FindViewById(Resource.Id.password);
String userName = username.Text;
String passWord = password.Text;
mAuthorization.Authenticate(mCtx, userName, passWord, new AuthorizationCallback());
Here’s the definition for the callback.
private class AuthorizationCallback : Java.Lang.Object, IAuthorizationCallback
{
public void OnCompletion(ServiceProxyException exception)
{
Logger.Debug(TAG, "OnCompletion Auth Callback");
if (exception != null)
{
Logger.Error(TAG, "Exception while receiving the Access Token", exception);
}
else
{
Logger.Error(TAG, "Authorization successful");
}
}
}
First you initialize the authorization agent and set the authentication type to Facebook
.
ISocialAuthorizationAgent mAuthorization;
SocialMobileBackend socialMobileBackend;
socialMobileBackend = SocialMobileBackendManager.Manager.GetDefaultMobileBackend(context);
mAuthorization = socialMobileBackend.GetSocialAuthorization(SocialAuthType.Facebook);
mAuthorization.SetAuthType(AuthType.Facebook);
Using a CallbackManager
object from Facebook’s SDK, initiate authentication.
ICallbackManager callbackManager;
mAuthorization.Setup(context, new FacebookCallback());
callbackManager = mAuthorization.CallBackManager;
mAuthorization.AuthenticateSocial(activity);
Here’s code you can use for the callback
that is passed above.
private class FacebookCallback : Java.Lang.Object, IFacebookCallback
{
public void OnSuccess(Java.Lang.Object loginResult)
{
Logger.Error(TAG, "facebook login successful.");
}
public void OnCancel()
{
}
public void OnError(FacebookException error)
{
}
}
Override the OnActivityResult()
method to use the callback.
protected override void OnActivityResult(int requestCode, Result resultCode, Intent data)
{
Logger.Debug(TAG, "In OnActivity Result onActivityResult");
base.OnActivityResult(requestCode, resultCode, data);
callBackManger.OnActivityResult(requestCode, (int)resultCode, data);
}
Calling Platform APIs Using the SDK for Xamarin Android
Once the mobile backend’s configuration info is loaded into the app and you have made a call to get the mobile backend, you can use SDK classes for various platform APIs.
Here are some code snippets that illustrate how to access these APIs with the SDK.
User Management
Getting a User
IAuthorizationAgent authorizationAgent = authentication.Authorization;
authorizationAgent.FetchCurrentUser(new UserRegistrationCallback());
private class UserRegistrationCallback : Java.Lang.Object, IUserRegistrationCallback
{
public void OnComplete(ServiceProxyException exception, User user)
{
if (exception == null)
{
mUser = user;
setText("User " + mUser.Username + " details have been fetched successfully.");
}
else
{
//Handle Error
}
}
}
Updating a User
//creating map with properties
IDictionary<string, Object> map = new Dictionary<string,Object>();
map.Add("age", 26);
map.Add("address", "india");
authorizationAgent.UpdateUser(new UserRegistrationCallback(), map);
private class UserRegistrationCallback : Java.Lang.Object, IUserRegistrationCallback
{
public void OnComplete(ServiceProxyException exception, User user)
{
if (exception == null)
{
setText("User " + user.Username + " details have been updated successfully.");
}
else
{
/Handle Error
}
}
}
Location
Initialization
Location location = (Location)mobileBackend.GetServiceProxy(Class.FromType(typeof(Location));
Places, Devices, and Assets
static Location location;
static LocationPlace place;
static LocationDevice device;
static LocationAsset asset;
location = (Location)mobileBackend.GetServiceProxy(Class.FromType(typeof(Location)));
LocationPlaceQuery locationPlaceQuery = location.BuildPlaceQuery();
locationPlaceQuery.Name = "West";
locationPlaceQuery.OrderByAttributeType = LocationDeviceContainerQuery.LocationDeviceContainerQueryOrderByAttributeType.LocationDeviceContainerQueryOrderByAttributeTypeName;
locationPlaceQuery.Format = LocationObjectQuery.LocationObjectQueryFormatType.LocationObjectQueryFormatTypeShort;
locationPlaceQuery.Execute(new LocationObjectQueryCallback());
LocationDeviceQuery locationDeviceQuery = location.BuildDeviceQuery();
locationDeviceQuery.Name = "Beacon";
locationDeviceQuery.OrderByAttributeType = LocationDeviceQuery.LocationDeviceQueryOrderByAttributeType.LocationDeviceQueryOrderByAttributeTypeName;
locationDeviceQuery.Format = LocationObjectQuery.LocationObjectQueryFormatType.LocationObjectQueryFormatTypeShort;
locationDeviceQuery.Execute(new LocationObjectQueryCallback());
LocationAssetQuery locationAssetQuery = location.BuildAssetQuery();
locationAssetQuery.Name = "Joe";
locationAssetQuery.OrderByAttributeType = LocationDeviceContainerQuery.LocationDeviceContainerQueryOrderByAttributeType.LocationDeviceContainerQueryOrderByAttributeTypeName;
locationAssetQuery.Format = LocationObjectQuery.LocationObjectQueryFormatType.LocationObjectQueryFormatTypeShort;
locationAssetQuery.Execute(new LocationObjectQueryCallback());
Fetching a Place
private class LocationObjectQueryCallback : Java.Lang.Object, ILocationObjectsQueryCallback
{
public void OnComplete(LocationObjectQueryResult queryResult, ServiceProxyException exception)
{
if (mProgressDialog != null && mProgressDialog.IsShowing)
{
mProgressDialog.Dismiss();
}
if (exception != null)
{
Logger.Debug(TAG, exception.Message);
setText(exception.Message);
}
else
{
foreach (LocationObject locationobject in queryResult.Items)
{
if (locationobject.GetType().Equals(typeof(LocationPlace))) {
place = (LocationPlace)locationobject;
location.FetchPlace(place.Id, new LocationObjectFetchCallback());
lock (obj)
{
Monitor.Wait(obj);
}
Logger.Debug(TAG, place.Name +" " + place.HasChildren);
}
else if(locationobject.GetType().Equals(typeof(LocationDevice)))
{
device = (LocationDevice)locationobject;
location.FetchDevice(device.Id, new LocationObjectFetchCallback());
lock (obj)
{
Monitor.Wait(obj);
}
Logger.Debug(TAG, device.Name + " ");
}
else if (locationobject.GetType().Equals(typeof(LocationAsset)))
{
asset = (LocationAsset)locationobject;
location.FetchAsset(asset.Id, new LocationObjectFetchCallback());
lock (obj)
{
Monitor.Wait(obj);
}
Logger.Debug(TAG, asset.Name + " ");
}
}
}
}
}
private class LocationObjectFetchCallback : Java.Lang.Object, ILocationObjectFetchCallback
{
public void OnComplete(LocationObject locationObject, ServiceProxyException exception)
{
if (mProgressDialog != null && mProgressDialog.IsShowing)
{
mProgressDialog.Dismiss();
}
if (exception != null)
{
Logger.Debug(TAG, exception.Message);
setText(exception.Message);
}
else
{
Logger.Debug(TAG, locationObject.Name );
}
lock (obj)
{
Monitor.PulseAll(obj);
}
}
}
Refreshing
private class LocationObjectQueryCallback : Java.Lang.Object, ILocationObjectsQueryCallback
{
public void OnComplete(LocationObjectQueryResult queryResult, ServiceProxyException exception)
{
if (mProgressDialog != null && mProgressDialog.IsShowing)
{
mProgressDialog.Dismiss();
}
if (exception != null)
{
Logger.Debug(TAG, exception.Message);
setText(exception.Message);
}
else
{
foreach (LocationObject locationobject in queryResult.Items)
{
if (locationobject.GetType().Equals(typeof(LocationPlace))) {
place = (LocationPlace)locationobject;
place.Refresh(new LocationObjectFetchCallback());
lock (obj)
{
Monitor.Wait(obj);
}
Logger.Debug(TAG, place.Name +" " + place.HasChildren);
}
else if(locationobject.GetType().Equals(typeof(LocationDevice)))
{
device = (LocationDevice)locationobject;
device.Refresh(new LocationObjectFetchCallback());
lock (obj)
{
Monitor.Wait(obj);
}
Logger.Debug(TAG, device.Name + " ");
}
else if (locationobject.GetType().Equals(typeof(LocationAsset)))
{
asset = (LocationAsset)locationobject;
asset.Refresh(new LocationObjectFetchCallback());
lock (obj)
{
Monitor.Wait(obj);
}
Logger.Debug(TAG, asset.Name + " ");
}
}
}
}
}
private class LocationObjectFetchCallback : Java.Lang.Object, ILocationObjectFetchCallback
{
public void OnComplete(LocationObject locationObject, ServiceProxyException exception)
{
if (mProgressDialog != null && mProgressDialog.IsShowing)
{
mProgressDialog.Dismiss();
}
if (exception != null)
{
Logger.Debug(TAG, exception.Message);
setText(exception.Message);
}
else if(locationObject != null)
{
Logger.Debug(TAG, locationObject.Name );
}
lock (obj)
{
Monitor.PulseAll(obj);
}
}
}
Storage
Initialization
Storage storage = (Storage)mobileBackend.GetServiceProxy(Class.FromType(typeof(Storage)));
Getting a Collection
StorageCollection storageCollection = storage.GetStorageCollection("FullCoverage_Private");
StorageObject storageObject = storageCollection.Get("ab911696-7e61-4fcd-a244-b26adb6183ba");
string str = Encoding.UTF8.GetString(Decompress(storageObject.GetPayloadBytes()));
Getting an Object
storageObject = storageCollection.Get("d4400472-b912-4f7a-b4f5-e32523e5c1f3");
Logger.Debug(TAG, "Storage Object: " + storageObject.DisplayName);
Getting All Objects
IList<StorageObject> list = storageCollection.Get(0, 100, true);
IEnumerator<StorageObject> iEnumerator = list.GetEnumerator();
while(iEnumerator.MoveNext()){
storageObject = iEnumerator.Current;
Logger.Debug(TAG, "Storage Object: " + storageObject.DisplayName);
}
Uploading a Text File
Java.Lang.String str = new Java.Lang.String("This is sample txt file");
storageObject = new StorageObject("textfile.txt");
storageObject.SetPayload(str.GetBytes(), "text/plain");
storageCollection.Put(storageObject);
Uploading an Image
System.IO.Stream imageBytes = getFileFromAssets("mcs_oracle.png");
storageObject = new StorageObject("mcs_oracle.png", imageBytes, "image/jpeg");
var imagePosted = storageCollection.Post(storageObject);
Decompressing
static byte[] Decompress(byte[] data)
{
using (var compressedStream = new MemoryStream(data))
using (var zipStream = new GZipStream(compressedStream, CompressionMode.Decompress))
using (var resultStream = new MemoryStream())
{
zipStream.CopyTo(resultStream);
return resultStream.ToArray();
}
}
Notifications
Initialization
LocalBroadcastManager.GetInstance(context)
.RegisterReceiver(new MBroadcastReceiver(),
new IntentFilter(NotificationsConfig.RegistrationComplete));
Notifications notifications = (Notifications)mobileBackend.GetServiceProxy(Java.Lang.Class.FromType(typeof(Notifications)));
Registering for Notifications
bool result = notifications.Initialize(context, "Sender ID");
Broadcast Receiver
private class MBroadcastReceiver : BroadcastReceiver
{
public override void OnReceive(Context context, Intent intent)
{
if (mProgressDialog != null && mProgressDialog.IsShowing)
{
mProgressDialog.Dismiss();
}
ISharedPreferences prefs = PreferenceManager.GetDefaultSharedPreferences(context);
bool sentToken = prefs.GetBoolean(NotificationsConfig.SentTokenToServer, false);
if (sentToken)
{
Logger.Debug(TAG, "Token retrieved and sent to server! App can use GCM");
}
else
{
Logger.Debug(TAG, "An error occurred while either fetching the InstanceID");
}
}
}
Analytics
Initialization
static Analytics analyticsAgent =
(Analytics)mobileBackend
.GetServiceProxy(Class.FromType(typeof(Analytics)));
analyticsAgent.SetContext(activity);
Logging an Event
if (analyticsAgent != null)
analyticsAgent.LogEvent("This is Event No. : " + i);
Setting Context Location
analyticsAgent.SetContextLocation("India", "Telangana", "Hyderabad", "500081");
Flushing an Event
analyticsAgent.Flush();
App Policies
Loading the App Config and Getting Policies
if (mobileBackend != null)
{
mobileBackend.LoadAppConfig(new AAppConfigCallBack());
mProgressDialog = ProgressDialog.Show(activity, "Please Wait", "App Config is being loaded.");
lock(obj){
Monitor.Wait(obj);
}
AppConfig oMCAppConfig = mobileBackend.AppConfig;
//Getting String:
string str = oMCAppConfig.GetString("Test_String", "No value configured");
setText("AppConfig: String: " + str);
//Getting Number
Number number = oMCAppConfig.GetNumber ("Test_number", new Java.Lang.Double(1.0));
setText("AppConfig: Number: " + number);
//Getting boolean
bool boolean = oMCAppConfig.GetBoolean("Test_Boolean", false);
setText("AppConfig: Boolean: " + boolean);
}
private class AAppConfigCallBack : AppConfigCallback
{
public override void OnResult(Oracle.Cloud.Mobile.Utils.McsError error, AppConfig config)
{
if (mProgressDialog != null && mProgressDialog.IsShowing)
{
mProgressDialog.Dismiss();
}
lock(obj){
Monitor.PulseAll(obj);
}
}
}
Calling Custom APIs Using the SDK for Xamarin Android
The SDK provides the CustomHttpResponse
class, the GenericCustomCodeClientCallBack
interface, and the InvokeCustomCodeJSONRequest
method in the authorization classes to simplify the calling of custom APIs in MCS. You can call a REST method (GET, PUT, POST, or DELETE) on an endpoint where the request payload is JSON or empty and the response payload is JSON or empty.
You use GenericCustomCodeClientCallBack
to create a handler for the response (which is returned in the form of a CustomHttpResponse
object.)
Then, to call the custom API, you call InvokeCustomCodeJSONRequest(GenericCustomCodeClientCallBack restClientCallback, JSONObject data, String functionName, RestClient.HttpMethod httpMethod)
on your Authorization
object.
To make a call to a custom API endpoint, you could use something like this:
IAuthorizationAgent mAuthorization = MobileBackendManager.Manager.GetDefaultMobileBackend(context).Authorization;
mAuthorization.Authenticate(mActivity, "user1", "pass1", new AuthorizationCallback());
........
// after the user successfully authenticates, make a call to the custom API endpoint
mAuthorization.InvokeCustomCodeJSONRequest(new GenericCustomCodeClientCallBack(), null, "TaskApi/tasks", RestClient.HttpMethod.Get);
private class GenericCustomCodeClientCallBack : Java.Lang.Object, IGenericCustomCodeClientCallBack
{
public void RequestCompleted(CustomHttpResponse response, JSONObject data, Java.Lang.Exception exception)
{
Logger.Debug(TAG, response.HttpStatus + "");
}
}