Samouczek: Logowanie użytkowników i wywoływanie interfejsu API Microsoft Graph z aplikacji systemu AndroidTutorial: Sign in users and call the Microsoft Graph API from an Android application

W tym samouczku utworzysz aplikację dla systemu Android, która integruje się z platformą tożsamości firmy Microsoft w celu logowania użytkowników i uzyskiwania tokenu dostępu w celu wywołania interfejsu API Microsoft Graph.In this tutorial, you build an Android app that integrates with the Microsoft identity platform to sign in users and get an access token to call the Microsoft Graph API.

Po ukończeniu tego samouczka aplikacja będzie akceptować logowania do osobistych kont Microsoft (w tym outlook.com, live.com i innych), a także kont służbowych z dowolnej firmy lub organizacji korzystającej z Azure Active Directory.When you've completed this tutorial, your application will accept sign-ins of personal Microsoft accounts (including outlook.com, live.com, and others) as well as work or school accounts from any company or organization that uses Azure Active Directory.

W tym samouczku:In this tutorial:

  • Tworzenie projektu aplikacji systemu Android w Android StudioCreate an Android app project in Android Studio
  • Zarejestruj aplikację w Azure PortalRegister the app in the Azure portal
  • Dodawanie kodu do obsługi logowania i wylogowywania użytkownikówAdd code to support user sign-in and sign-out
  • Dodawanie kodu do wywoływania interfejsu API Microsoft GraphAdd code to call the Microsoft Graph API
  • Testowanie aplikacjiTest the app

Wymagania wstępnePrerequisites

  • Android Studio 3.5 +Android Studio 3.5+

Jak działa ten samouczekHow this tutorial works

Pokazuje sposób działania przykładowej aplikacji wygenerowanej przez ten samouczek

Aplikacja w tym samouczku zaloguje użytkowników i pobierze dane w ich imieniu.The app in this tutorial will sign in users and get data on their behalf. Dostęp do tych danych uzyskuje się za pomocą chronionego interfejsu API (Microsoft Graph API), który wymaga autoryzacji i jest chroniony przez platformę tożsamości firmy Microsoft.This data will be accessed through a protected API (Microsoft Graph API) that requires authorization and is protected by the Microsoft identity platform.

Więcej szczegółów:More specifically:

  • Twoja aplikacja zaloguje użytkownika za pomocą przeglądarki lub Microsoft Authenticator i Intune — Portal firmy.Your app will sign in the user either through a browser or the Microsoft Authenticator and Intune Company Portal.
  • Użytkownik końcowy zaakceptuje uprawnienia wymagane przez aplikację.The end user will accept the permissions your application has requested.
  • Aplikacja zostanie wystawiona token dostępu dla interfejsu API Microsoft Graph.Your app will be issued an access token for the Microsoft Graph API.
  • Token dostępu zostanie uwzględniony w żądaniu HTTP do internetowego interfejsu API.The access token will be included in the HTTP request to the web API.
  • Przetwórz odpowiedź Microsoft Graph.Process the Microsoft Graph response.

Ten przykład używa biblioteki uwierzytelniania firmy Microsoft dla systemu Android (MSAL) w celu zaimplementowania uwierzytelniania: com. Microsoft. Identity. Client.This sample uses the Microsoft Authentication Library for Android (MSAL) to implement Authentication: com.microsoft.identity.client.

Usługa MSAL automatycznie odnawia tokeny, dostarcza Logowanie jednokrotne między innymi aplikacjami na urządzeniu i zarządza kontami.MSAL will automatically renew tokens, deliver single sign-on (SSO) between other apps on the device, and manage the Account(s).

W tym samouczku przedstawiono uproszczone Przykłady pracy z programem MSAL for Android.This tutorial demonstrates simplified examples of working with MSAL for Android. Dla uproszczenia używa tylko trybu jednego konta.For simplicity, it uses Single Account Mode only. Aby zapoznać się z bardziej złożonymi scenariuszami, zobacz ukończony przykładowy kod roboczy w witrynie GitHub.To explore more complex scenarios, see a completed working code sample on GitHub.

Tworzenie projektuCreate a project

Jeśli nie masz jeszcze aplikacji systemu Android, wykonaj następujące kroki, aby skonfigurować nowy projekt.If you do not already have an Android application, follow these steps to set up a new project.

  1. Otwórz Android Studio i wybierz pozycję Rozpocznij nowy projekt Android Studio.Open Android Studio, and select Start a new Android Studio project.
  2. Wybierz działanie podstawowe i wybierz pozycję dalej.Select Basic Activity and select Next.
  3. Nadaj nazwę aplikacji.Name your application.
  4. Zapisz nazwę pakietu.Save the package name. Wprowadzisz ją później do Azure Portal.You will enter it later into the Azure portal.
  5. Zmień język z Kotlin na Java.Change the language from Kotlin to Java.
  6. Ustaw minimalny poziom interfejsu API na interfejs API 19 lub nowszy, a następnie kliknij przycisk Zakończ.Set the Minimum API level to API 19 or higher, and click Finish.
  7. W widoku Projekt wybierz projekt na liście rozwijanej, aby wyświetlić źródło i nieźródłowe pliki projektu, Otwórz aplikację/Build. Gradle i ustaw targetSdkVersion wartość 28 .In the project view, choose Project in the dropdown to display source and non-source project files, open app/build.gradle and set targetSdkVersion to 28.

Integracja z biblioteką uwierzytelniania firmy MicrosoftIntegrate with the Microsoft Authentication Library

Rejestrowanie aplikacjiRegister your application

  1. Zaloguj się w witrynie Azure Portal.Sign in to the Azure portal.

  2. Jeśli masz dostęp do wielu dzierżawców, Użyj filtru katalogów i subskrypcji w górnym menu, aby wybrać dzierżawcę, w którym chcesz zarejestrować aplikację.

  3. Wyszukaj i wybierz pozycję Azure Active Directory.Search for and select Azure Active Directory.

  4. W obszarze Zarządzaj wybierz pozycję rejestracje aplikacji > Nowa rejestracja.Under Manage, select App registrations > New registration.

  5. Wprowadź nazwę aplikacji.Enter a Name for your application. Użytkownicy Twojej aplikacji mogą zobaczyć tę nazwę i można ją później zmienić.Users of your app might see this name, and you can change it later.

  6. Wybierz pozycję Zarejestruj.Select Register.

  7. W obszarze Zarządzanie wybierz pozycję uwierzytelnianie > Dodaj platformę > Android.Under Manage, select Authentication > Add a platform > Android.

  8. Wprowadź nazwę pakietu projektu.Enter your project's Package Name. Jeśli pobrano kod, ta wartość jest com.azuresamples.msalandroidapp .If you downloaded the code, this value is com.azuresamples.msalandroidapp.

  9. W sekcji skrót podpisu na stronie Konfigurowanie aplikacji systemu Android wybierz pozycję generowanie skrótu sygnatury deweloperskiej.In the Signature hash section of the Configure your Android app page, select Generating a development Signature Hash. i skopiuj polecenie Narzędzia klawiaturowego, które ma być używane dla danej platformy.and copy the KeyTool command to use for your platform.

    KeyTool.exe jest instalowany jako część zestawu Java Development Kit (JDK).KeyTool.exe is installed as part of the Java Development Kit (JDK). Należy również zainstalować narzędzie OpenSSL, aby wykonać polecenie Narzędzia.You must also install the OpenSSL tool to execute the KeyTool command. Aby uzyskać więcej informacji, zapoznaj się z dokumentacją systemu Android dotyczącą generowania klucza .Refer to the Android documentation on generating a key for more information.

  10. Wprowadź skrót podpisu wygenerowany przez narzędzie.Enter the Signature hash generated by KeyTool.

  11. Wybierz pozycję Konfiguruj i Zapisz konfigurację MSAL , która jest wyświetlana na stronie konfiguracji systemu Android , aby można ją było wprowadzić podczas późniejszej konfiguracji aplikacji.Select Configure and save the MSAL Configuration that appears in the Android configuration page so you can enter it when you configure your app later.

  12. Kliknij Gotowe.Select Done.

Konfigurowanie aplikacjiConfigure your application

  1. W okienku projektu Android Studio przejdź do app\src\main\res.In Android Studio's project pane, navigate to app\src\main\res.

  2. Kliknij prawym przyciskiem myszy pozycję res i wybierz pozycję Nowy > katalog.Right-click res and choose New > Directory. Wprowadź raw nazwę nowego katalogu, a następnie kliknij przycisk OK.Enter raw as the new directory name and click OK.

  3. W oknie App > src > Main > res > RAW Utwórz nowy plik JSON o nazwie auth_config_single_account.json i wklej wcześniej zapisaną konfigurację MSAL.In app > src > main > res > raw, create a new JSON file called auth_config_single_account.json and paste the MSAL Configuration that you saved earlier.

    Poniżej identyfikatora URI przekierowania wklej:Below the redirect URI, paste:

      "account_mode" : "SINGLE",
    

    Plik konfiguracji powinien wyglądać podobnie do poniższego przykładu:Your config file should resemble this example:

    {
      "client_id" : "0984a7b6-bc13-4141-8b0d-8f767e136bb7",
      "authorization_user_agent" : "DEFAULT",
      "redirect_uri" : "msauth://com.azuresamples.msalandroidapp/1wIqXSqBj7w%2Bh11ZifsnqwgyKrY%3D",
      "broker_redirect_uri_registered" : true,
      "account_mode" : "SINGLE",
      "authorities" : [
        {
          "type": "AAD",
          "audience": {
            "type": "AzureADandPersonalMicrosoftAccount",
            "tenant_id": "common"
          }
        }
      ]
    }
    

    W tym samouczku przedstawiono tylko sposób konfigurowania aplikacji w trybie jednego konta.This tutorial only demonstrates how to configure an app in Single Account mode. Zapoznaj się z dokumentacją, aby uzyskać więcej informacji na temat trybu pojedynczego i wielu kont oraz konfigurowania aplikacjiView the documentation for more information on single vs. multiple account mode and configuring your app

  4. W oknie > src > > AndroidManifest.xml aplikacji głównej Dodaj BrowserTabActivity poniższe działanie do treści aplikacji.In app > src > main > AndroidManifest.xml, add the BrowserTabActivity activity below to the application body. Ten wpis umożliwia firmie Microsoft wywoływanie z powrotem do aplikacji po zakończeniu uwierzytelniania:This entry allows Microsoft to call back to your application after it completes the authentication:

    <!--Intent filter to capture System Browser or Authenticator calling back to our app after sign-in-->
    <activity
        android:name="com.microsoft.identity.client.BrowserTabActivity">
        <intent-filter>
            <action android:name="android.intent.action.VIEW" />
            <category android:name="android.intent.category.DEFAULT" />
            <category android:name="android.intent.category.BROWSABLE" />
            <data android:scheme="msauth"
                android:host="Enter_the_Package_Name"
                android:path="/Enter_the_Signature_Hash" />
        </intent-filter>
    </activity>
    

    Zastąp nazwę pakietu zarejestrowanego w Azure Portal dla tej android:host= wartości.Substitute the package name you registered in the Azure portal for the android:host= value. Zastąp skrót klucza zarejestrowany w Azure Portal android:path= wartości.Substitute the key hash you registered in the Azure portal for the android:path= value. Wartość skrótu podpisu nie powinna być zakodowana w adresie URL.The Signature Hash should not be URL encoded. Upewnij się, że / na początku skrótu podpisu występuje wiodąca wartość.Ensure that there is a leading / at the beginning of your Signature Hash.

    "Nazwa pakietu" zostanie zastąpiona wartością, która android:host powinna wyglądać podobnie do: "com. azuresamples. msalandroidapp".The "Package Name" you will replace the android:host value with should look similar to: "com.azuresamples.msalandroidapp". "Skrót podpisu" spowoduje zamienienie wartości w taki sposób, android:path aby wyglądał wyglądać podobnie do: "/1wIqXSqBj7w + h11ZifsnqwgyKrY =".The "Signature Hash" you will replace your android:path value with should look similar to: "/1wIqXSqBj7w+h11ZifsnqwgyKrY=".

    Można będzie również znaleźć te wartości w bloku uwierzytelnianie rejestracji aplikacji.You will also be able to find these values in the Authentication blade of your app registration. Zwróć uwagę, że identyfikator URI przekierowania będzie wyglądać podobnie do: "msauth://com.azuresamples.msalandroidapp/1wIqXSqBj7w%2Bh11ZifsnqwgyKrY%3D".Note that your redirect URI will look similar to: "msauth://com.azuresamples.msalandroidapp/1wIqXSqBj7w%2Bh11ZifsnqwgyKrY%3D". Gdy skrót sygnatury jest zakodowany na końcu tej wartości, wartość skrótu podpisu nie powinna być zakodowana w adresie URL android:path .While the Signature Hash is URL encoded at the end of this value, the Signature Hash should not be URL encoded in your android:path value.

Użyj MSALUse MSAL

Dodawanie MSAL do projektuAdd MSAL to your project

  1. W oknie projekt Android Studio przejdź do aplikacji > src > Build. Gradle i Dodaj następujące elementy:In the Android Studio project window, navigate to app > src > build.gradle and add the following:

    repositories{
        jcenter()
    }
    dependencies{
        implementation 'com.microsoft.identity.client:msal:2.+'
        implementation 'com.microsoft.graph:microsoft-graph:1.5.+'
    }
    packagingOptions{
        exclude("META-INF/jersey-module-version")
    }
    

    Więcej informacji na Microsoft Graph zestawie SDKMore on the Microsoft Graph SDK

Wymagane importyRequired Imports

Dodaj następujący kod na początku aplikacji głównej > > > > modelu Java com. przykład (yourapp) > Main. JavaAdd the following to the top of app > src > main> java > com.example(yourapp) > MainActivity.java

import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
import android.widget.Toast;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;
import com.google.gson.JsonObject;
import com.microsoft.graph.authentication.IAuthenticationProvider; //Imports the Graph sdk Auth interface
import com.microsoft.graph.concurrency.ICallback;
import com.microsoft.graph.core.ClientException;
import com.microsoft.graph.http.IHttpRequest;
import com.microsoft.graph.models.extensions.*;
import com.microsoft.graph.requests.extensions.GraphServiceClient;
import com.microsoft.identity.client.AuthenticationCallback; // Imports MSAL auth methods
import com.microsoft.identity.client.*;
import com.microsoft.identity.client.exception.*;

Tworzenie wystąpienia PublicClientApplicationInstantiate PublicClientApplication

Inicjuj zmienneInitialize Variables

private final static String[] SCOPES = {"Files.Read"};
/* Azure AD v2 Configs */
final static String AUTHORITY = "https://login.microsoftonline.com/common";
private ISingleAccountPublicClientApplication mSingleAccountApp;

private static final String TAG = MainActivity.class.getSimpleName();

/* UI & Debugging Variables */
Button signInButton;
Button signOutButton;
Button callGraphApiInteractiveButton;
Button callGraphApiSilentButton;
TextView logTextView;
TextView currentUserTextView;

onCreateonCreate

Wewnątrz MainActivity klasy zapoznaj się z następującą metodą OnCreate (), aby utworzyć wystąpienie MSAL przy użyciu SingleAccountPublicClientApplication .Inside the MainActivity class, refer to the following onCreate() method to instantiate MSAL using the SingleAccountPublicClientApplication.

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    initializeUI();

    PublicClientApplication.createSingleAccountPublicClientApplication(getApplicationContext(),
            R.raw.auth_config_single_account, new IPublicClientApplication.ISingleAccountApplicationCreatedListener() {
                @Override
                public void onCreated(ISingleAccountPublicClientApplication application) {
                    mSingleAccountApp = application;
                    loadAccount();
                }
                @Override
                public void onError(MsalException exception) {
                    displayError(exception);
                }
            });
}

loadAccountloadAccount

//When app comes to the foreground, load existing account to determine if user is signed in
private void loadAccount() {
    if (mSingleAccountApp == null) {
        return;
    }

    mSingleAccountApp.getCurrentAccountAsync(new ISingleAccountPublicClientApplication.CurrentAccountCallback() {
        @Override
        public void onAccountLoaded(@Nullable IAccount activeAccount) {
            // You can use the account data to update your UI or your app database.
            updateUI(activeAccount);
        }

        @Override
        public void onAccountChanged(@Nullable IAccount priorAccount, @Nullable IAccount currentAccount) {
            if (currentAccount == null) {
                // Perform a cleanup task as the signed-in account changed.
                performOperationOnSignOut();
            }
        }

        @Override
        public void onError(@NonNull MsalException exception) {
            displayError(exception);
        }
    });
}

initializeUIinitializeUI

Posłuchaj przycisków i wywołaj metody lub Rejestruj odpowiednio błędy.Listen to buttons and call methods or log errors accordingly.

private void initializeUI(){
        signInButton = findViewById(R.id.signIn);
        callGraphApiSilentButton = findViewById(R.id.callGraphSilent);
        callGraphApiInteractiveButton = findViewById(R.id.callGraphInteractive);
        signOutButton = findViewById(R.id.clearCache);
        logTextView = findViewById(R.id.txt_log);
        currentUserTextView = findViewById(R.id.current_user);

        //Sign in user
        signInButton.setOnClickListener(new View.OnClickListener(){
            public void onClick(View v) {
                if (mSingleAccountApp == null) {
                    return;
                }
                mSingleAccountApp.signIn(MainActivity.this, null, SCOPES, getAuthInteractiveCallback());
            }
        });

        //Sign out user
        signOutButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                if (mSingleAccountApp == null){
                    return;
                }
                mSingleAccountApp.signOut(new ISingleAccountPublicClientApplication.SignOutCallback() {
                    @Override
                    public void onSignOut() {
                        updateUI(null);
                        performOperationOnSignOut();
                    }
                    @Override
                    public void onError(@NonNull MsalException exception){
                        displayError(exception);
                    }
                });
            }
        });

        //Interactive
        callGraphApiInteractiveButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                if (mSingleAccountApp == null) {
                    return;
                }
                mSingleAccountApp.acquireToken(MainActivity.this, SCOPES, getAuthInteractiveCallback());
            }
        });

        //Silent
        callGraphApiSilentButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                if (mSingleAccountApp == null){
                    return;
                }
                mSingleAccountApp.acquireTokenSilentAsync(SCOPES, AUTHORITY, getAuthSilentCallback());
            }
        });
    }

Ważne

Wylogowanie za pomocą usługi MSAL usuwa wszystkie znane informacje o użytkowniku z aplikacji, ale użytkownik będzie nadal mieć aktywną sesję na swoim urządzeniu.Signing out with MSAL removes all known information about a user from the application, but the user will still have an active session on their device. Jeśli użytkownik spróbuje się zalogować ponownie, może wyświetlić interfejs użytkownika logowania, ale może nie być konieczne ponowne wprowadzenie poświadczeń, ponieważ sesja urządzenia jest nadal aktywna.If the user attempts to sign in again they may see sign-in UI, but may not need to reenter their credentials because the device session is still active.

getAuthInteractiveCallbackgetAuthInteractiveCallback

Wywołanie zwrotne używane dla żądań interaktywnych.Callback used for interactive requests.

private AuthenticationCallback getAuthInteractiveCallback() {
    return new AuthenticationCallback() {
        @Override
        public void onSuccess(IAuthenticationResult authenticationResult) {
            /* Successfully got a token, use it to call a protected resource - MSGraph */
            Log.d(TAG, "Successfully authenticated");
            /* Update UI */
            updateUI(authenticationResult.getAccount());
            /* call graph */
            callGraphAPI(authenticationResult);
        }

        @Override
        public void onError(MsalException exception) {
            /* Failed to acquireToken */
            Log.d(TAG, "Authentication failed: " + exception.toString());
            displayError(exception);
        }
        @Override
        public void onCancel() {
            /* User canceled the authentication */
            Log.d(TAG, "User cancelled login.");
        }
    };
}

getAuthSilentCallbackgetAuthSilentCallback

Wywołanie zwrotne używane na potrzeby żądań dyskretnychCallback used for silent requests

private SilentAuthenticationCallback getAuthSilentCallback() {
    return new SilentAuthenticationCallback() {
        @Override
        public void onSuccess(IAuthenticationResult authenticationResult) {
            Log.d(TAG, "Successfully authenticated");
            callGraphAPI(authenticationResult);
        }
        @Override
        public void onError(MsalException exception) {
            Log.d(TAG, "Authentication failed: " + exception.toString());
            displayError(exception);
        }
    };
}

Wywoływanie interfejsu API programu Microsoft GraphCall Microsoft Graph API

Poniższy kod ilustruje sposób wywoływania GraphAPI przy użyciu zestawu Graph SDK.The following code demonstrates how to call the GraphAPI using the Graph SDK.

callGraphAPIcallGraphAPI

private void callGraphAPI(IAuthenticationResult authenticationResult) {

    final String accessToken = authenticationResult.getAccessToken();

    IGraphServiceClient graphClient =
            GraphServiceClient
                    .builder()
                    .authenticationProvider(new IAuthenticationProvider() {
                        @Override
                        public void authenticateRequest(IHttpRequest request) {
                            Log.d(TAG, "Authenticating request," + request.getRequestUrl());
                            request.addHeader("Authorization", "Bearer " + accessToken);
                        }
                    })
                    .buildClient();
    graphClient
            .me()
            .drive()
            .buildRequest()
            .get(new ICallback<Drive>() {
                @Override
                public void success(final Drive drive) {
                    Log.d(TAG, "Found Drive " + drive.id);
                    displayGraphResult(drive.getRawObject());
                }

                @Override
                public void failure(ClientException ex) {
                    displayError(ex);
                }
            });
}

Dodawanie interfejsu użytkownikaAdd UI

DziałanieActivity

Jeśli chcesz zamodelować interfejs użytkownika w tym samouczku, następujące metody zapewniają Przewodnik aktualizowania tekstu i nasłuchiwanie przycisków.If you would like to model your UI off this tutorial, the following methods provide a guide to updating text and listening to buttons.

updateUIupdateUI

Włącz/Wyłącz przyciski na podstawie stanu logowania i Ustaw tekst.Enable/disable buttons based on sign-in state and set text.

private void updateUI(@Nullable final IAccount account) {
    if (account != null) {
        signInButton.setEnabled(false);
        signOutButton.setEnabled(true);
        callGraphApiInteractiveButton.setEnabled(true);
        callGraphApiSilentButton.setEnabled(true);
        currentUserTextView.setText(account.getUsername());
    } else {
        signInButton.setEnabled(true);
        signOutButton.setEnabled(false);
        callGraphApiInteractiveButton.setEnabled(false);
        callGraphApiSilentButton.setEnabled(false);
        currentUserTextView.setText("");
        logTextView.setText("");
    }
}

displayErrordisplayError

private void displayError(@NonNull final Exception exception) {
       logTextView.setText(exception.toString());
   }

displayGraphResultdisplayGraphResult

private void displayGraphResult(@NonNull final JsonObject graphResponse) {
      logTextView.setText(graphResponse.toString());
  }

performOperationOnSignOutperformOperationOnSignOut

Metoda aktualizowania tekstu w interfejsie użytkownika w celu odzwierciedlenia wylogowania.Method to update text in UI to reflect sign out.

private void performOperationOnSignOut() {
    final String signOutText = "Signed Out.";
    currentUserTextView.setText("");
    Toast.makeText(getApplicationContext(), signOutText, Toast.LENGTH_SHORT)
            .show();
}

LayoutLayout

Przykładowy activity_main.xml plik do wyświetlania przycisków i pól tekstowych.Sample activity_main.xml file to display buttons and text boxes.

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/activity_main"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="#FFFFFF"
    android:orientation="vertical"
    tools:context=".MainActivity">

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="horizontal"
        android:paddingTop="5dp"
        android:paddingBottom="5dp"
        android:weightSum="10">

        <Button
            android:id="@+id/signIn"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="5"
            android:gravity="center"
            android:text="Sign In"/>

        <Button
            android:id="@+id/clearCache"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="5"
            android:gravity="center"
            android:text="Sign Out"
            android:enabled="false"/>

    </LinearLayout>
    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:gravity="center"
        android:orientation="horizontal">

        <Button
            android:id="@+id/callGraphInteractive"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="5"
            android:text="Get Graph Data Interactively"
            android:enabled="false"/>

        <Button
            android:id="@+id/callGraphSilent"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="5"
            android:text="Get Graph Data Silently"
            android:enabled="false"/>
    </LinearLayout>

    <TextView
        android:text="Getting Graph Data..."
        android:textColor="#3f3f3f"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginLeft="5dp"
        android:id="@+id/graphData"
        android:visibility="invisible"/>

    <TextView
        android:id="@+id/current_user"
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_marginTop="20dp"
        android:layout_weight="0.8"
        android:text="Account info goes here..." />

    <TextView
        android:id="@+id/txt_log"
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_marginTop="20dp"
        android:layout_weight="0.8"
        android:text="Output goes here..." />
</LinearLayout>

Testowanie aplikacjiTest your app

Uruchamianie lokalnieRun locally

Kompiluj i Wdróż aplikację na urządzeniu testowym lub w emulatorze.Build and deploy the app to a test device or emulator. Powinno być możliwe zalogowanie się i uzyskanie tokenów dla usługi Azure AD lub osobistych kont Microsoft.You should be able to sign in and get tokens for Azure AD or personal Microsoft accounts.

Po zalogowaniu aplikacja będzie wyświetlać dane zwrócone z /me punktu końcowego Microsoft Graph.After you sign in, the app will display the data returned from the Microsoft Graph /me endpoint. PR 4PR 4

Gdy użytkownik po raz pierwszy zaloguje się do aplikacji, otrzyma monit o tożsamość firmy Microsoft, aby wyrazić zgodę na wymagane uprawnienia.The first time any user signs into your app, they will be prompted by Microsoft identity to consent to the permissions requested. Niektórzy dzierżawy usługi Azure AD wyłączyli zgodę użytkownika, która wymaga od administratorów wyrażania zgody w imieniu wszystkich użytkowników.Some Azure AD tenants have disabled user consent which requires admins to consent on behalf of all users. Aby obsługiwać ten scenariusz, trzeba utworzyć własną dzierżawę lub odebrać zgodę administratora.To support this scenario, you will either need to create your own tenant or receive admin consent.

Czyszczenie zasobówClean up resources

Gdy nie jest już potrzebne, Usuń obiekt aplikacji, który został utworzony w kroku zarejestruj aplikację .When no longer needed, delete the app object that you created in the Register your application step.

Pomoc i obsługa technicznaHelp and support

Jeśli potrzebujesz pomocy, Chcę zgłosić problem lub uzyskać więcej informacji na temat opcji pomocy technicznej, zobacz Pomoc i obsługa deweloperów.If you need help, want to report an issue, or want to learn about your support options, see Help and support for developers.

Następne krokiNext steps

Dowiedz się więcej o tworzeniu aplikacji mobilnych, które wywołują chronione interfejsy API sieci Web w naszej wieloczęściowej serii scenariuszy.Learn more about building mobile apps that call protected web APIs in our multi-part scenario series.