import android.accounts.Account import android.accounts.AccountManager import android.content.Context import android.os.AsyncTask import com.microsoft.aad.adal.AuthenticationContext import com.microsoft.aad.adal.AuthenticationResult import com.microsoft.aad.adal.PromptBehavior import com.microsoft.graph.authentication.IAuthenticationProvider import com.microsoft.graph.concurrency.ICallback import com.microsoft.graph.core.ClientException import com.microsoft.graph.http.IHttpRequest import com.microsoft.graph.models.extensions.GraphServiceClient import com.microsoft.graph.models.extensions.User import com.microsoft.graph.requests.extensions.IUserCollectionPage import com.microsoft.graph.requests.extensions.GraphServiceClientBuilder class AzureAddressBookRetriever(private val context: Context) { private val authority = "https://login.microsoftonline.com/{tenant-id}" private val clientId = "{client-id}" private val graphScopes = arrayOf("https://graph.microsoft.com/Contacts.Read") fun retrieveAddressBook(callback: AddressBookCallback) { // Authenticate user val authenticationTask = AuthenticationTask(callback) authenticationTask.execute() } private inner class AuthenticationTask(private val callback: AddressBookCallback) : AsyncTask() { override fun doInBackground(vararg params: Void?): AuthenticationResult? { try { val accountManager = AccountManager.get(context) val accounts = accountManager.getAccountsByType("com.microsoft") val account = accounts.firstOrNull() ?: return null val context = AuthenticationContext(context, authority, false) val future = context.acquireTokenSilentAsync(graphScopes, clientId, account, null) return future.get() } catch (e: Exception) { e.printStackTrace() } return null } override fun onPostExecute(result: AuthenticationResult?) { if (result != null) { val token = result.accessToken val authenticationProvider = object : IAuthenticationProvider { override fun authenticateRequest(request: IHttpRequest?) { request?.addHeader("Authorization", "Bearer $token") } } val graphClient = GraphServiceClient.builder() .authenticationProvider(authenticationProvider) .buildClient() fetchAddressBook(graphClient, callback) } else { callback.onFailure("Authentication failed.") } } } private fun fetchAddressBook(graphClient: GraphServiceClient<*>?, callback: AddressBookCallback) { graphClient?.me()?.contacts()?.buildRequest()?.get(object : ICallback { override fun success(result: IUserCollectionPage?) { val users = result?.currentPage?.mapNotNull { it as? User } callback.onSuccess(users) } override fun failure(ex: ClientException?) { callback.onFailure(ex?.localizedMessage ?: "Failed to fetch address book.") } }) } interface AddressBookCallback { fun onSuccess(users: List?) fun onFailure(error: String) } }