Giter Site home page Giter Site logo

crm-mobilesdk-library-for-android's Introduction

Microsoft Dynamics CRM Mobile SDK for Android (Java)


This document describes the Java version of the Dynamics CRM Mobile SDK that is being released under an open source license on GitHub.com. This SDK provides service proxy classes and message classes that enable you to develop Android mobile applications that can connect to the CRM organization web service and perform various operations. The supported messages in this SDK, that are defined later in this document, represents a usable subset of what is available in the .NET version of the CRM SDK. In general, it is best to be familiar with the .NET version of the CRM SDK as the programming API in this mobile SDK was based on it. The following documentation describes the key features and API available in this SDK.

OAuth authentication with the Dynamics CRM web service is not managed within this SDK. That functionality is handled in app level code using the Azure Active Directory Authentication Library (ADAL). For an example of using this SDK in a real world Android application, complete with OAuth web service authentication, refer to the sample Android app that is provided as a separate download.

Requirements

This SDK supports and has been tested with the following development environment.

  • Android API level 18 through 23
  • Android Studio version 1.0 and later

At build time, the following open source or 3rd party libraries are downloaded and installed, which require and active internet connection on the development computer.

This SDK is known to work with Dynamics CRM 2013 and 2015, for both on-premises and Online deployments. On-premises identity authentication is provided by Active Directory Federation Services (3.0 or greater) while Online identity authentication is provided by Microsoft Azure Active Directory.

Getting Started

Prior to using the methods provided by this mobile SDK, you must build and run the (.NET) MobileSdkGen command line tool to generate early-bound classes for each entity in the CRM organization that your app needs to access. The tool plus related documentation is provided as a separate download. This tool is similar to the CrmSvcUtil tool provided in the .NET version of the CRM SDK. After running the MobileSdkGen tool, the result is a folder filled with .java class files, one for each entity type (including custom entity types) and option sets that you have specified.

For more information about using early-bound entity types, refer to the related CRM SDK topic Use the early bound entity classes in code. For more information about the CrmSvcUtil tool, see Create early bound entity classes with the code generation tool.

To include this library into your project, you should just take a built *.aar file from the releases section, or from the build folder of this project. You should place that file into your lib folder for you application and include the following into your application's gradle.build file:

compile(name: 'crmsdk2015', ext: 'aar') {
    transitive = true;
}

Also keep in mind that if you are using Proguard you should add this to your proguard-rules.pro file:

-keep class * extends com.microsoft.xrm.sdk.Entity { *; }

Web Service Proxies

There are two web service proxy classes provided in this mobile SDK: OrganizationServiceProxy, and RestOrganizationServiceProxy. It is through the methods of these proxies that you send message requests to the organization web service and receive responses.

public OrganizationServiceProxy(String uri, String sessionToken)
public RestOrganizationServiceProxy(String uri, RequestInterceptor authHeader)

Creating either of these proxy objects requires you to manage user logon using Active Directory and pass into the constructor either the authentication access token or a pre-built header. RequestInterceptor is a header system that you can create using the Retrofit library. The URI value in these constructors is the SSL (https://) address of your CRM organization's web service (Organization.svc). This address can be found in the CRM web application by navigating to Settings > Customizations > Developer Resources.

The reason for two proxies is that OrganizationServiceProxy supports sending SOAP messages while RestOrganizationServiceProxy supports sending OData messages. Most messages supported by CRM are implemented as SOAP messages. A small subset of messages are supported by the OData v2 endpoint. For more information on the OData v2 endpoint, see Use web service data in web resources (OData and Modern app SOAP endpoint).

RestOrganizationServiceProxy Methods

The following sections describe the available methods of the OData based service proxy.

Each proxy method takes a Callback class instance as a parameter. The Callback class defines two methods named success and failure. One of these methods is called after the web service attempts to perform the intended operation. It is through the success callback that you can obtain the response.

Create

Creates an entity record.

void Create(Entity entity, Callback<UUID> callback)

void Create(Entity relatedTo, Entity entity, String relationshipName, Callback<UUID> callback)

For the Entity instance provided to the method to be serialized correctly, it must be an early-bound subclass of the Entity class provided in the mobile SDK. You can generate these classes using the MobileSdkGen tool. In the example below, the Contact class was generated using this tool. However, if you are using Create to make a related entity it does let you pass in the second entity even if it isn't a subclass of Entity. It will of course throw a network error if you don't use proper schema names for the attributes.

Contact contact = Contact.build()
        .setFirstName("John")
        .setLastName("Doe")
        .setNumberOfChildren(2);

try
{
    restService.Create(contact, new Callback<UUID>() {
        @Override
        public void success(UUID uuid, Response response) {
            // id of the new contact
        }

        @Override
        public void failure(RetrofitError error) {
            // handle network error
        }
    });
}
catch(InvalidClassException ex) {
    // didn't pass in a subclass of entity
}

Update

Updates an existing entity record.

void Update(Entity entity, @Nullable Callback<?> callback)

For the Entity instance provided to the method to be serialized correctly, it must be an early-bound subclass of the Entity class provided in the mobile SDK. You can generate these classes using the MobileSdkGen tool. In the example below, the Contact class was generated using this tool. For an update, the ID of the existing record must be supplied. The callback is nullable so that you can either ignore it or, if you like, create one to handle any network failures coming back.

Contact contact = Contact.build()
        .setContactId(UUID.fromString("ab4db725-0aab-45c9-a23d-d7a865635974"))
        .setNumberOfChildren(3);

try {
    restService.Update(contact, new Callback<Object>() {
        @Override
        public void success(Object object, Response response) {
            // this will never come back
        }

        @Override
        public void failure(RetrofitError error) {
            // handle network error
        }
    });
}
catch(InvalidClassException ex) {
    // didn't pass in a subclass of entity
}

Delete

Deletes an existing entity record.

void Delete(String entitySchemaName, UUID id, @Nullable Callback<?> callback);
restService.Delete("Contact", UUID.fromString("ab4db725-0aab-45c9-a23d-d7a865635974"), null);

Retrieve

Two methods are provided to retrieve records: one to retrieve a single record, and another to retrieve all records of the given type to which the user has read access, or get all related items to a specific entity. Filtering is possible with the OData endpoint using the expand, filter, orderby, select, skip, and top parameters from QueryOptions.

These calls return generic entities and should be cast to early-bound entities using the .toEntity(Class<T>) method.

void RetrieveMultiple(String entitySchemaName, UUID id, String relationshipName, @NonNull QueryOptions queryOptions, final Callback<EntityCollection> callback);

void RetrieveMultiple(String entitySchemaName, QueryOptions query, Callback<EntityCollection> callback);
// Retrieve the top ten activities that have an end date and are related to the contact.
QueryOptions queryOptions = QueryOptions.build()
        .putTop("10")
        .putSelect(Constants.ACTIVITY_SELECT)
        .putFilter("ActualEnd ne null")
        .putOrderBy("ActualEnd desc");

restService.RetrieveMultiple(Contact.class.getSimpleName(), mContact.getId(), "Contact_ActivityPointers",
        queryOptions, new Callback<EntityCollection>() {
            @Override
            public void success(EntityCollection entityCollection, Response response) {
                // handle response
            }

            @Override
            public void failure(RetrofitError error) {
                //handle network error
            }
        });

OrganizationServiceProxy Methods

The following sections describe the available methods of the service proxy that sends SOAP based messages to the organization web service.

Each proxy method takes a Callback class instance as a parameter. The Callback class defines two methods named success and failure. One of these methods is called after the web service attempts to perform the intended operation. It is through the success callback that you can obtain the response.

Execute

The Execute method sends a message request to the organization web service and receives a response back. The message request and response classes, listed later in this document, are derived from OrganizationRequest and OrganizationResponse. There are many more messages available to execute than there are methods on the proxy class. Where there is overlap, for example a Create message and a Create method, you can choose to use either. There is not a significant performance difference between the two techniques.

void Execute(OrganizationRequest request, Callback<OrganizationResponse> callback);

The mobile SDK provides a wide range of message request and response classes for you to use with the Execute proxy method. For example:

SetStateRequest setStateRequest = SetStateRequest.build()
        .setEntityMoniker(new EntityReference("task", activityId))
        .setState(new OptionSetValue(1))
        .setStatus(new OptionSetValue(5));

mOrgService.Execute(setStateRequest, new Callback<OrganizationResponse>() {
    @Override
    public void success(OrganizationResponse organizationResponse, Response response) {
        //handle response
    }

    @Override
    public void failure(RetrofitError error) {
        //handle error
    }
});

Create

Creates an entity record. This is equivalent to using a CreateRequest with the Execute method.

void Create(Entity entity, Callback<UUID> callback);

Update

Updates an existing entity record. This is equivalent to using an UpdateRequest with the Execute method.

void Update(Entity entity, @Nullable Callback<?> callback);

For this method you have the option to use the callback. The success method of the callback class will never get called, however, you will get any network failures back through the callback's failure method.

Delete

Deletes an existing entity record. This is equivalent to using an DeleteRequest with the Execute method.

void Delete(String entityName, UUID id, @Nullable Callback<?> callback);

For this request you have the option to use the callback. The success method of the callback class will never get called, however, you will get any network failures back through the callback's failure method.

Retrieve

Retrieves an existing entity record. This is equivalent to using a RetrieveRequest with the Execute method.

void Retrieve(String entitySchemaName, UUID id, @NonNull ColumnSet columnSet, Callback<Entity> callback);

The column-set defines the attributes that you want returned in the entity record.

RetrieveMultiple

Retrieves multiple entity records. This method is equivalent to using a RetrieveMultipleRequest with the Execute method. One thing that is unique about the SOAP version of RetrieveMultiple compared to the OData version is that both the method and the message request support FetchXML for the query.

void RetrieveMultiple(QueryBase query, Callback<EntityCollection> callback);
FetchExpression fetchExpression = new FetchExpression(String.format(
    "<fetch mapping='logical' count='25'>" +
        "<entity name='contact'>" +
            "<attribute name='contactid'/>" +
            "<attribute name='fullname'/>" +
            "<attribute name='jobtitle'/>" +
            "<link-entity name='account' from='accountid' to='parentcustomerid' link-type='outer'>" +
                "<attribute name='name' alias='accountname' />" +
            "</link-entity>" +
            "<filter type='and'>" +
                "<condition attribute='fullname' operator='like' value='%%%s%%' />" +
            "</filter>" +
        "</entity>" +
    "</fetch>", searchTerm));

mOrgService.RetrieveMultiple(fetchExpression, new Callback<EntityCollection>() {
    @Override
    public void success(EntityCollection entityCollection, Response response) {
        // handle response
    }

    @Override
    public void failure(RetrofitError error) {
        // handle network error
    }
});

For more information about FetchXML see Build queries with FetchXML.

Associate

Creates a link between records that participate in a relationship. This is equivalent to using an AssociateRequest with the Execute method.

void Associate(String entityName, UUID entityId, Relationship relationship, EntityReferenceCollection relatedEntities, @Nullable Callback<?> callback);

Disassociate

Removes the link between records. This is equivalent to using an DisassociateRequest with the Execute method.

void Disassociate(String entityName, UUID entityId, Relationship relationship, EntityReferenceCollection relatedEntities, @Nullable Callback<?> callback);

Supported Organization Web Service (SOAP) Messages

For each of the messages listed below, there exists a request and response class. For example, the Create message includes CreateRequest and CreateResponse classes. These classes can be found in the folder mobilesdk-android\crmsdk2015\src\main\java\com\microsoft\xrm\sdk\Messages.

For more information about each of these messages, see CRM messages in the organization service and xRM messages in the Organization service.

A: AddItemCampaign, AddListMembersList, AddMemberList, AddPrincipalToQueue, AddProductToKit, AddRecurrence, AddToQueue, Assign, AssociateEntities, Associate

B: BackgroundSendEmail, Book

C: CanBeReferenced, CanBeReferencing, CancelContract, CancelSalesOrder, CanManyToMany, CheckIncomingEmail, CheckPromoteEmail CloneContract, CloseIncident, CloseQuote, CopyDynamicListToStatic, CreateEntity, CreateException, CreateInstance, CreateOptionSet, Create

D: DeleteAttribute, DeleteEntity, DeleteOpenInstances, DeleteOptionSet, DeleteOptionValue, DeleteRelationship, Delete, DeliverIncomingEmail, DeliverPromoteEmail, DisassociateEntities, Disassociate

G: GetValidManyToMany, GetValidReferencedEntities, GetValidReferencingEntities

I: InsertOptionValue, InsertStatusValue, IsDataEncryptionActive

L: LockInvoicePricing, LockSalesOrderPricing, LoseOpportunity

M: Merge

O: OrderOption

P: PickFromQueue

Q: QualifyLead

R: Recalculate, ReleaseToQueue, RemoveFromQueue, RemoveItemCampaign, RemoveMemberList, RemovePrivilegeRole, RemoveRelated, ReplacePrivilegesRole, Reschedule, RetrieveAllEntities, RetrieveAllManagedProperties, RetrieveAllOptionSets, RetrieveAttribute, RetrieveDataEncryptionKey, RetrieveEntity, RetrieveManagedProperty, RetrieveMetadataChanges, RetrieveMultiple, RetrieveOptionSet, RetrieveRelationship, Retrieve, RetrieveTimestamp, RetrieveUserQueues, RouteTo

S: SendEmail, SendFax, SetDataEncryptionKey, SetRelated, SetState

U: UpdateAttribute, UpdateOptionSet, UpdateOptionValue, UpdateRelationship, Update, UpdateStateValue

V: ValidateRecurrenceRule

W: WinOpportunity, WinQuote

crm-mobilesdk-library-for-android's People

Contributors

w9jds avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

crm-mobilesdk-library-for-android's Issues

not able to compile android microsoft CRM SDK

not able to compile android Microsoft CRM SDK

hen i compile i am getting following error see attached image

I have set my environment variables as follows

export ANDROID_HOME=/Users/Nihar/Library/Android/sdk
export JAVA_HOME=/Library/Java/JavaVirtualMachines/jdk1.8.0_101.jdk/Contents/Home
export JAVA8_HOME=/Library/Java/JavaVirtualMachines/jdk1.8.0_101.jdk/Contents/Home
export JAVA7_HOME=/Library/Java/JavaVirtualMachines/jdk1.7.0_79.jdk/Contents/Home
export PATH=$PATH:$ANDROID_HOME/bin

screen shot 2016-08-21 at 6 23 39 pm

Problem connect to CRM

Hello,
I'm starting with Microsoft Dynamics and I'm trying to ingregate a mobile application with Microsoft Dynamics CRM 2015 using the new Microsoft Dynamics CRM Mobile SDK for Android and I have problems making some requests: I can't access to the information of my CRM. I authenticate succesfully by means of SOAP (http://jlattimer.blogspot.com.es/2015/02/soap-only-authentication-using-java.html) instead of OAuth, I also generate CRM classes with the MobileSDKGen tool but I don't know how to make a correct request in order to get the information about my CRM. What data should I send in the message's header?
The class builder of OrganizationServiceProxy allows 2 parameters:

  • OrganizationServiceProxy(URI, SessionToken)
  • OrganizationServiceProxy(URI, RequestInterceptor)

On one hand, using SOAP authentication, the server returns a response message that contains not only one but three session tokens: securityToken0, securityToken1 and keyIdentifier.
On the other hand, I don't understand how to create a RequestInterceptor as I have never used before Retrofit library.

Could anyone help me? How can I make a request to CRM server with Mobile SDK, using SOAP authentication?

Thank you very much

Issue with create request

Hi I have been using your library to access and pull data from Microsoft Dynamics successfully, recently I have been trying to create records in the CRM with the library and have been getting an error as a response to the create the error body is

<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/"> <s:Body> <s:Fault> <faultcode xmlns:a="http://schemas.microsoft.com/net/2005/12/windowscommunicationfoundation/dispatcher">a:DeserializationFailed</faultcode> <faultstring xml:lang="en-US"> The formatter threw an exception while trying to deserialize the message: There was an error while trying to deserialize parameter http://schemas.microsoft.com/xrm/2011/Contracts/Services:entity. The InnerException message was 'Error in line 1 position 882. Expecting state 'Element'.. Encountered 'Text' with name '', namespace ''. '. Please see InnerException for more details. </faultstring> </s:Fault> </s:Body> </s:Envelope>

Here is the code used to generate the error.

orgService = new OrganizationServiceProxy(Constant.ENDPOINT, CRMLogin.getRequestInterceptor());


Entity workOrder = new Entity("x_workorder");

final String activityid = service_appointment.getValue(SAptEntry.ACTIVITY_ID);

Log.d("pushUpdatesToCRM>>>","Creating WorkOrder for Activity: "+activityid);

orgService.Create(workOrder, new Callback<UUID>() {

        @Override
        public void success(UUID uuid, Response response) {
            Log.d("pushUpdateToCRM>>>", "WorkOrder created for Activity:" + activityid);
        }

        @Override
        public void failure(RetrofitError error) {
            Log.d("pushUpdateToCRM>>>", "WorkOrder not created for Activity: " + activityid);
            Log.d("pushUpdateToCRM>>>", "WorkOrder create error: " + error.getMessage());
            Log.d("UGG", error.getBody().toString());
        }
    });

Do you have any suggestions on how to proceed? Thanks.

how to create Appoinment from Mobile??

i have try using below code but got error 500 Internal Server Error
@CarlosMendonca @JimDaly @msftgits @saldana

Entity entity = new Entity();
 entity.getAttributes().put("Subject", subject.getText().toString())
try {
            RestOrganizationServiceProxy restService = new RestOrganizationServiceProxy(mOrgService);
            restService.Create(mContact, entity, "Contact_Appointments", new Callback<UUID>() {
                @Override
                public void success(UUID uuid, Response response) {
                    CompleteActivity(uuid);
                }

                @Override
                public void failure(RetrofitError error) {

                    Log.e("error",error.getMessage());
                    displayErrorSnackbar("Unable to create new check in");
                }
            });
        }
        catch(Exception ex) {

        }


if i try to create another entity using same , its create sucessfully

retrive appointment

when retrive appointment its starttime attribute give "Jan" month for all why?

how to create Appoinment from Mobile??

i am creating appointment using below code give "500 Internal Server Error"

Appointment objappointment = Appointment.build()
                .setSubject("Android sub")
                .setDescription("dis from device");


try {
            RestOrganizationServiceProxy restService = new RestOrganizationServiceProxy(mOrgService);
            restService.Create(objappointment,new Callback<UUID>() {
                @Override
                public void success(UUID uuid, Response response) {
                    log("sucess", uuid.toString());

                          }

                @Override
                public void failure(RetrofitError error) {
                    displayError(error.toString());
                    log("error", error.toString());
                }
            });
        }
        catch(Exception ex) {
            displayError(ex.getMessage());
            log("msg",ex.toString());
        }

another entity create successfully using above code just got error in "Appoinment"

Non IFD On premise Installation

Hi

I need to connect the app to a "Non IFD" On-premise installation .

How is it possible?
Any help would be GREATLY appreciated
Best

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.