{"id":3111,"date":"2023-03-16T13:04:20","date_gmt":"2023-03-16T20:04:20","guid":{"rendered":"https:\/\/devblogs.microsoft.com\/surface-duo\/?p=3111"},"modified":"2023-03-16T13:04:20","modified_gmt":"2023-03-16T20:04:20","slug":"microsoft-graph-android-2","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/surface-duo\/microsoft-graph-android-2\/","title":{"rendered":"Use Microsoft Graph in an Android app"},"content":{"rendered":"<p>\n  Hello Android developers,\n<\/p>\n<p>\n  This week, we\u2019ll be continuing our blog series on using the Microsoft Authentication Library (MSAL) and the Microsoft Graph to connect to M365 services in your own Android apps.\n<\/p>\n<p>\n  Previously, we covered <a href=\"https:\/\/devblogs.microsoft.com\/surface-duo\/android-msal\/\">the basics of MSAL<\/a> and <a href=\"https:\/\/devblogs.microsoft.com\/surface-duo\/microsoft-graph-android\/\">an introduction to MS Graph for Android<\/a>, so be sure to check out those posts first!\n<\/p>\n<p>\n  In this post, we\u2019ll connect all these ideas together by showing you how to call the MS Graph API in Android apps. More specifically, we\u2019ll cover:\n<\/p>\n<ul>\n<li>\n    Review of MSAL authentication\n  <\/li>\n<li>\n    Calling the MS Graph API<\/p>\n<ul>\n<li>\n        With HTTP libraries\n      <\/li>\n<li>\n        With MS Graph SDKs\n      <\/li>\n<\/ul>\n<\/li>\n<\/ul>\n<h2>Review of acquiring tokens with MSAL<\/h2>\n<p>\n  Before we jump into code snippets for calling the MS Graph API, let\u2019s review how to acquire a valid access token from MSAL.\n<\/p>\n<p>\n  As a reminder, after following along with previous blog posts, you should have already:\n<\/p>\n<ul>\n<li>\n    Registered your app in Azure Portal with permissions for MSAL and MS Graph\n  <\/li>\n<li>\n    Configured your Android project to use MSAL\n  <\/li>\n<\/ul>\n<p>\n  Once these prerequisites have been satisfied, you can use MSAL to sign in users and acquire access tokens. If you recall, we finished off the <a href=\"https:\/\/devblogs.microsoft.com\/surface-duo\/android-msal\/#authenticating-users-in-your-app\">MSAL authentication blog post<\/a> by creating a <code>PublicClientApplication<\/code> instance and using it to prompt users for their credentials. Once they were authenticated successfully, we then gained access to an <code><a href=\"https:\/\/javadoc.io\/static\/com.microsoft.identity.client\/msal\/2.2.3\/com\/microsoft\/identity\/client\/IAuthenticationResult.html\">IAuthenticationResult<\/a><\/code> object, which contains the <code>accessToken<\/code> field that we need today!\n<\/p>\n<p>\n   For each MS Graph API request, you will have to pass in this <code>accessToken<\/code> value. You can either store this value after a successful user sign in, or call <code><a href=\"https:\/\/javadoc.io\/static\/com.microsoft.identity.client\/msal\/2.2.3\/com\/microsoft\/identity\/client\/IPublicClientApplication.html#acquireTokenSilent-com.microsoft.identity.client.AcquireTokenSilentParameters-\">acquireTokenSilent<\/a><\/code> to make sure the token hasn\u2019t expired. \n<\/p>\n<p>\n  For readability, our examples in this post will follow the latter approach, but we\u2019d like to note that it\u2019s not required to re-request a token every time you access the API. \n<\/p>\n<p>\n  So, assuming a user has already been authenticated, our request flow will be:\n<\/p>\n<ul>\n<li>\n    Request token silently\n  <\/li>\n<li>\n    On success<\/p>\n<ul>\n<li>\n        Get access token from authentication result\n      <\/li>\n<li>\n        Perform request\n      <\/li>\n<\/ul>\n<\/li>\n<\/ul>\n<p>\n  To request a token, you will first need to know the <code>scopes<\/code> and <code>authority<\/code> for the token. The <a href=\"https:\/\/learn.microsoft.com\/azure\/active-directory\/develop\/scopes-oidc\">scopes<\/a> are the same as the MS Graph permissions you previously added in Graph Explorer or in your app registration, while the <a href=\"https:\/\/learn.microsoft.com\/azure\/active-directory\/develop\/msal-client-application-configuration#authority\">authority<\/a> is the value you entered in your <code>auth_config_x_account.json<\/code> files during MSAL config. You\u2019ll also need a reference to the <code>PublicClientApplication<\/code> object you created when setting up MSAL.\n<\/p>\n<p>\n  Putting all these pieces together, you get the following code snippet:\n<\/p>\n<pre>  \/\/ Set up scopes and authority\r\n  val scopes = arrayOf(\"user.read\")\r\n  val authority = \"https:\/\/login.microsoftonline.com\/common\"\r\n\r\n  \/\/ Create callback to run after token is requested\r\n  val authCallback = object : AuthenticationCallback {\r\n      override fun onSuccess(authenticationResult: IAuthenticationResult) {\r\n          val token = authenticationResult.accessToken\r\n\r\n          \/\/ TODO: perform request using token\r\n      }\r\n\r\n      override fun onError(exception: MsalException) {\r\n          Log.d(\"Example\", \"Error: $exception\")\r\n      }\r\n\r\n      override fun onCancel() {\r\n          Log.d(\"Example\", \"User cancelled login\")\r\n      }\r\n  }\r\n\r\n  \/\/ mSingleAccountApp is our PublicClientApplication instance\r\n  mSingleAccountApp.acquireTokenSilentAsync(scopes, authority, authCallback)\r\n<\/pre>\n<p>\n  Now all that\u2019s left to do is fill in that <code>\/\/TODO<\/code> comment with our actual request code!\n<\/p>\n<h2>Calling the MS Graph API<\/h2>\n<p>\n  To start writing request code, you\u2019ll need to know the endpoint you\u2019re targeting and any headers\/request body details. This is when the Graph Explorer becomes really useful, because you can use it to figure out proper request formatting and response parsing!\n<\/p>\n<p>\n  Today, our example request will be trying to retrieve the <code>displayName<\/code> <a href=\"https:\/\/learn.microsoft.com\/graph\/api\/resources\/user?view=graph-rest-1.0#properties\">user property<\/a> from the <a href=\"https:\/\/learn.microsoft.com\/graph\/api\/user-get?view=graph-rest-1.0&amp;tabs=http\">\/me endpoint<\/a>. From using Graph Explorer, we know that our target resource URL is <code>https:\/\/graph.microsoft.com\/v1.0\/me<\/code> and that we can parse the <code>displayName<\/code> directly from the response JSON.\n<\/p>\n<p>\n  <img decoding=\"async\" width=\"1859\" height=\"1097\" src=\"https:\/\/devblogs.microsoft.com\/surface-duo\/wp-content\/uploads\/sites\/53\/2023\/03\/graphical-user-interface-text-application-email-5.png\" class=\"wp-image-3112\" alt=\"\" srcset=\"https:\/\/devblogs.microsoft.com\/surface-duo\/wp-content\/uploads\/sites\/53\/2023\/03\/graphical-user-interface-text-application-email-5.png 1859w, https:\/\/devblogs.microsoft.com\/surface-duo\/wp-content\/uploads\/sites\/53\/2023\/03\/graphical-user-interface-text-application-email-5-300x177.png 300w, https:\/\/devblogs.microsoft.com\/surface-duo\/wp-content\/uploads\/sites\/53\/2023\/03\/graphical-user-interface-text-application-email-5-1024x604.png 1024w, https:\/\/devblogs.microsoft.com\/surface-duo\/wp-content\/uploads\/sites\/53\/2023\/03\/graphical-user-interface-text-application-email-5-768x453.png 768w, https:\/\/devblogs.microsoft.com\/surface-duo\/wp-content\/uploads\/sites\/53\/2023\/03\/graphical-user-interface-text-application-email-5-1536x906.png 1536w\" sizes=\"(max-width: 1859px) 100vw, 1859px\" \/><br \/><em>Figure 1. After testing our desired request in Graph Explorer, we know what URL to request and what the response will look like.<\/em>\n<\/p>\n<p>\n  Now let\u2019s take a look at two distinct ways that the Graph API can be called using Kotlin and Android libraries. Based on the structure of your app, one approach may be easier to implement than the other.\n<\/p>\n<h3>With an HTTP library<\/h3>\n<p>\n  First, we\u2019ll try to accomplish this example request with an HTTP library. You can call the MS Graph API in an Android app like you would any other REST API. There\u2019s a wide range of libraries available to help you set up, perform, and parse HTTP requests, but for the purposes of this post, we\u2019ll be using <a href=\"https:\/\/google.github.io\/volley\/\">Volley<\/a> to match the <a href=\"https:\/\/learn.microsoft.com\/azure\/active-directory\/develop\/mobile-app-quickstart?pivots=devlang-android\">MS Graph quickstart sample<\/a>.\n<\/p>\n<p>\n  Using the token request skeleton from above, we can just fill in the the <code>\/\/TODO<\/code> comment with our Volley code:\n<\/p>\n<pre>  \/\/ Build HTTP request to \/me endpoint with Volley\r\n  val queue = Volley.newRequestQueue(context)\r\n  val graphResourceUrl = \"https:\/\/graph.microsoft.com\/v1.0\/me\"\r\n\r\n  val stringRequest = object : JsonObjectRequest(\r\n      Request.Method.GET,\r\n      graphResourceUrl,\r\n      null,\r\n      Response.Listener { response -&gt;\r\n          \/\/ Parse display name from response\r\n          val displayName = response[\"displayName\"]\r\n          Log.d(\"Example\", \"Response from Volley: $displayName\")\r\n      },\r\n      Response.ErrorListener { error -&gt;\r\n          Log.d(\"Example\", \"Error from Volley: $error\")\r\n      }\r\n  ) {\r\n      \/\/ Add access token to request headers\r\n      override fun getHeaders(): MutableMap&lt;String, String&gt; {\r\n          val headers = HashMap&lt;String, String&gt;()\r\n          headers[\"Authorization\"] = \"Bearer $token\"\r\n          return headers\r\n      }\r\n  }\r\n\r\n  queue.add(stringRequest)<\/pre>\n<p>\n  In the code snippet, you can see how to build a <code>JSONObjectRequest<\/code> with three important steps:\n<\/p>\n<ul>\n<li>\n    Fill in the proper request details<\/p>\n<ul>\n<li>\n        We pass in the <\/code>\/me<\/code> resource URL and set the request method to <code>GET<\/code>\n      <\/li>\n<\/ul>\n<\/li>\n<li>\n    Add response listeners for success\/error<\/p>\n<ul>\n<li>\n        On success, we parse out the <code>displayName<\/code> field directly from the JSON response\n      <\/li>\n<\/ul>\n<\/li>\n<li>\n    Add MSAL access token to request headers<\/p>\n<ul>\n<li>\n        We add the <code>token<\/code> field from our successful authentication result to the <code>Authorization<\/code> header\n      <\/li>\n<\/ul>\n<\/li>\n<\/ul>\n<p>\n  To learn more about how to use Volley to call the MS Graph API in Android apps, check out the <a href=\"https:\/\/github.com\/Azure-Samples\/ms-identity-android-kotlin\/blob\/master\/app\/src\/main\/java\/com\/azuresamples\/msalandroidkotlinapp\/MSGraphRequestWrapper.kt\">quickstart sample<\/a>.\n<\/p>\n<h3>With an MS Graph SDK<\/h3>\n<p>\n  Next, let\u2019s try making this same request with one of the <a href=\"https:\/\/learn.microsoft.com\/graph\/sdks\/sdks-overview\">Microsoft Graph SDKs<\/a>. The MS Graph team offers SDKs for C#, PowerShell, TypeScript\/JavaScript, Java, Go, PHP, and Python \u2013 today, we\u2019ll be focusing on the <a href=\"https:\/\/github.com\/microsoftgraph\/msgraph-sdk-java\">MS Graph Java SDK<\/a>.\n<\/p>\n<p>\n  To use an MS Graph SDK, there are four main steps:\n<\/p>\n<ol>\n<li>\n  Install the SDK <\/p>\n<p>\n  For our example, we\u2019ll want to import all of the dependencies mentioned in the <a href=\"https:\/\/learn.microsoft.com\/graph\/sdks\/sdk-installation#install-the-microsoft-graph-java-sdk\">MS Graph Java SDK installation instructions<\/a>.\n<\/p>\n<\/li>\n<li>\n  Set up authentication provider<\/p>\n<p>\n  Depending on your use case, you can <a href=\"https:\/\/learn.microsoft.com\/graph\/sdks\/choose-authentication-providers?tabs=Java\">choose different authentication providers<\/a> for the Microsoft Graph. For our example, we\u2019ll just create a simple authentication provider that returns the access token granted by MSAL.\n<\/p>\n<\/li>\n<li>\n  Build graph client<\/p>\n<p>\n  Using the authentication provider, we can then follow the <a href=\"https:\/\/learn.microsoft.com\/graph\/sdks\/create-client?tabs=Android\">instructions to create a Microsoft Graph client<\/a>.\n<\/p>\n<\/li>\n<li>\n  Build request<\/p>\n<p>\n  Finally, using the graph client we just built, we can then build requests and access responses!\n<\/p>\n<\/li>\n<\/ol>\n<p>\n  Putting it all together, this is how we would create the same display name request with the MS Graph Java SDK:\n<\/p>\n<pre>\/\/ Build authentication provider and graph client\r\nval authProvider = IAuthenticationProvider {\r\n   CompletableFuture.supplyAsync { token }\r\n}\r\nval graphClient = GraphServiceClient.builder().authenticationProvider(authProvider).buildClient()\r\n\r\n\/\/ Build display name request\r\ncoroutineScope.launch(Dispatchers.IO) {\r\n    val displayName = graphClient.me().buildRequest().get()?.displayName\r\n    Log.d(\"Example\", \"Response from MS Graph Java SDK: $displayName\")\r\n}<\/pre>\n<p>\n  In the code snippet, you can see how the MS Graph Java SDK makes building the request much simpler and more readable. In fact, if we were following the approach of storing the access token after sign in, instead of re-requesting the token for every API call, then we would only require the last three lines of the code to make the request!\n<\/p>\n<p>\n  However, it\u2019s also important to note that SDK requests cannot be called on the main thread, so it\u2019s on you to make sure these requests are being handled on a background thread.\n<\/p>\n<p>\n  So now, you should know how to set up MSAL for an Android app, then use an MSAL token to make requests to the MS Graph API with HTTP libraries or MS Graph SDKs! We have one blog post remaining in the series, in which we\u2019ll share a new code sample that has more complex examples of building MS Graph API requests in Android apps.\n<\/p>\n<h2>Resources and feedback<\/h2>\n<p>\n  To learn more about using MS Graph in Android apps, check out:\n<\/p>\n<ul>\n<li><a href=\"https:\/\/devblogs.microsoft.com\/microsoft365dev\/category\/microsoft-graph\/\">Microsoft Graph DevBlog<\/a>\n  <\/li>\n<li><a href=\"https:\/\/learn.microsoft.com\/azure\/active-directory\/develop\/tutorial-v2-android\">Tutorial: Sign in users and call the Microsoft Graph from an Android application<\/a>\n  <\/li>\n<li><a href=\"https:\/\/learn.microsoft.com\/azure\/active-directory\/develop\/mobile-app-quickstart?pivots=devlang-android\">Quickstart: Sign in users and call the Microsoft Graph API from a mobile application<\/a>\n<ul>\n<li><a href=\"https:\/\/github.com\/Azure-Samples\/ms-identity-android-java\/\">Quickstart sample repo<\/a> \n      <\/li>\n<\/ul>\n<\/li>\n<li><a href=\"https:\/\/github.com\/microsoftgraph\/msgraph-sdk-java\">Microsoft Graph Java SDK<\/a>\n  <\/li>\n<\/ul>\n<p>\n  If you have any questions, or would like to tell us about your apps, use the <a href=\"http:\/\/aka.ms\/SurfaceDuoSDK-Feedback\">feedback forum<\/a> or message us on <a href=\"https:\/\/twitter.com\/surfaceduodev\">Twitter @surfaceduodev<\/a>.\n<\/p>\n<p>\n  Finally, there won\u2019t be a livestream this week, but check out the <a href=\"https:\/\/youtube.com\/c\/surfaceduodev\">archives on YouTube<\/a>. We\u2019ll see you online again soon!<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Hello Android developers, This week, we\u2019ll be continuing our blog series on using the Microsoft Authentication Library (MSAL) and the Microsoft Graph to connect to M365 services in your own Android apps. Previously, we covered the basics of MSAL and an introduction to MS Graph for Android, so be sure to check out those posts [&hellip;]<\/p>\n","protected":false},"author":90683,"featured_media":3100,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[1],"tags":[730,732,731],"class_list":["post-3111","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-surface-duo-sdk","tag-authentication","tag-graph","tag-msal"],"acf":[],"blog_post_summary":"<p>Hello Android developers, This week, we\u2019ll be continuing our blog series on using the Microsoft Authentication Library (MSAL) and the Microsoft Graph to connect to M365 services in your own Android apps. Previously, we covered the basics of MSAL and an introduction to MS Graph for Android, so be sure to check out those posts [&hellip;]<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/surface-duo\/wp-json\/wp\/v2\/posts\/3111","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/devblogs.microsoft.com\/surface-duo\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/devblogs.microsoft.com\/surface-duo\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/surface-duo\/wp-json\/wp\/v2\/users\/90683"}],"replies":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/surface-duo\/wp-json\/wp\/v2\/comments?post=3111"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/surface-duo\/wp-json\/wp\/v2\/posts\/3111\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/surface-duo\/wp-json\/wp\/v2\/media\/3100"}],"wp:attachment":[{"href":"https:\/\/devblogs.microsoft.com\/surface-duo\/wp-json\/wp\/v2\/media?parent=3111"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/surface-duo\/wp-json\/wp\/v2\/categories?post=3111"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/surface-duo\/wp-json\/wp\/v2\/tags?post=3111"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}