Erste Schritte mit Android

In diesem Dokument sind die grundlegenden Voraussetzungen und Anforderungen aufgeführt, die zum Integrieren von PlayFab Party in Ihre Android-Anwendungen erforderlich sind. Nachdem Sie Ihr System gemäß diesem Dokument eingerichtet haben, sehen Sie sich bitte den Schnellstart für PlayFab Party an, um sich mit den Bausteinen von PlayFab Party vertraut zu machen.

Voraussetzungen

Bevor Sie mit diesem Lernprogramm beginnen, stellen Sie sicher, dass die folgenden Voraussetzungen erfüllt sind:

  1. Sie haben ein PlayFab-Entwicklerkonto erstellt.

  2. Sie haben einen PlayFab-Titel erstellt und Ihr Titel wurde für PlayFab Party zugelassen.

  3. Sie haben Android Studio Version 3.2 oder höher installiert.

  4. Ihre App ist auf Android 4.4 (Kitkat) oder höher ausgerichtet.

  5. Sie haben Android NDK 18.1.5063045 oder höher installiert.

  6. Sie haben Zugriff auf das PlayFab Party-Plattformen-Repository

  7. Sie haben ein Android-Signaturzertifikat erstellt und Ihre App für die Bereitstellung mithilfe der Zertifikatskonfiguration signiert.

  8. Apps, die auf der Android-Plattform erstellt werden, müssen sicherstellen, dass BLUETOOTH_CONNECT im App-Manifest vorhanden ist, damit die Vertragspartei verfügbare Bluetooth-Geräte überwachen und eine Verbindung mit diesen herstellen kann.

Einschließlich der erforderlichen Bibliotheken und Headerdateien

Sie müssen die folgenden Headerdateien aus dem PlayFab Party-Verteilungsrepository einschließen.

LIB Files

  1. libParty.a
  2. libcrypto.a
  3. libssl.a

Notiz

Die SSL-Bibliotheken basieren auf Open SSL Version 3.5.7. Bitte verwenden Sie eine openSSL-Version 3.5.7 oder höher.

Kopfzeile enthält

Party-Header

Notiz

Zusätzlich zu den oben genannten lib-Dateien und Headern benötigen Sie auch die Bibliotheken und Header für PlayFab SDK und alle anderen plattformspezifischen Abhängigkeiten, die Ihre App benötigt. Weitere Informationen finden Sie in der Projektdatei-organization für das Android-Beispiel.

Schritte, damit PlayFab Party auf Android funktioniert

Da die Kernbibliothek von Party mit C++ geschrieben ist, müssen wir eine einfache JNI-Wrapperklasse erstellen, um auf die Partybibliotheksfunktionalität zuzugreifen. Auf hoher Ebene benötigen Sie eine Klasse, die Zugriff auf Partei-API-Methoden hat, um ein Netzwerk zu erstellen, eine Verbindung mit einem Netzwerk herzustellen und Nachrichten über ein Netzwerk zu senden. Wir haben dies in unserer Demo-App über die NetworkManager-Java-Klasse erreicht.


import android.util.Log;

public class NetworkManager {
    static {
        System.loadLibrary("partysample");
    }

    private MessageManager messageManager;

    private static NetworkManager networkManager;

    private NetworkManager() {
    }

    public static NetworkManager getInstance() {
        if (networkManager == null) {
            networkManager = new NetworkManager();
        }
        return networkManager;
    }

    public native boolean initialize(String name);

    public native boolean createAndConnectToNetwork(String type, String languageCode);

    public native boolean joinNetwork(String networkId);

    public native void leaveNetwork();

    public native void sendTextMessage(String message, boolean isTTS);

    public native void doWork();

    public native void getPlayerState();

    public native void setLanguage(int idx);

    public native void setPlayFabTitleID(String titleID);

    public void onNetworkCreated(String network) {
        Log.d(getClass().getSimpleName(), "onNetworkCreated: " + network);
        getMessageManager().sendNetworkCreatedMessage(network);
        getMessageManager().sendErrorMessage("Connected to network: " + network);
    }

    public void onMessageReceived(String sender, String message) {
        Log.d(getClass().getSimpleName(), "onMessageReceived: " + sender + ": " + message);
        getMessageManager().sendTextMsgReceivedMessage(sender, message, false);
    }

    public void onTranscriptMessageReceived(String sender, String message) {
        Log.d(getClass().getSimpleName(), "onTranscriptMessageReceived: " + sender + ": " + message);
        getMessageManager().sendTextMsgReceivedMessage(sender, message, true);
    }

    public void onPlayerJoined(String playerId, String name) {
        Log.d(getClass().getSimpleName(), "onPlayerJoined: " + playerId + ": " + name);
        getMessageManager().sendPlayerJoinMessage(playerId, name);
    }

    public void onPlayerLeft(String playerId) {
        Log.d(getClass().getSimpleName(), "onPlayerLeft: " + playerId);
        getMessageManager().sendPlayerLeftMessage(playerId);
    }

    public void toastMessage(String message) {
        getMessageManager().toastMessage(message);
    }

    public void resetChat(String error) {
        getMessageManager().sendResetMessage(error);
    }
    public void resetMessage() {
        getMessageManager().sendResetMessage("Left");
    }

    public void addErrorMessage(String message) {
        getMessageManager().sendErrorMessage(message);
    }

   public void updatePlayerState(String playerId, String state) {
        Log.d(getClass().getSimpleName(), "updatePlayerState: " + playerId + ": " + state);
        getMessageManager().sendPlayerStatusMessage(playerId, state);
    }

    public MessageManager getMessageManager() {
        return MessageManager.getInstance();
    }

}

Die obige JNI-Brücke wird von einer reinen C++-Implementierungsdatei unterstützt, die die NetworkManager.cpp aufruft, die wiederum die Party-APIs aufruft.

Hier ist ein Beispielausschnitt, der die verschiedenen Ebenen zeigt:

Die Java-Schnittstelle von NetworkManager stellt eine Methode zum Beitreten zu einem Parteinetzwerk zur Verfügung.

public native boolean joinNetwork(String networkId);

Die Implementierung des joinNetwork befindet sich in der C++-Schicht in PartyDemo.cpp unten dargestellt.

JNIEXPORT jboolean JNICALL
    Java_com_microsoft_playfab_party_sdk_NetworkManager_joinNetwork(
        JNIEnv* env,
        jobject thiz,
        jstring networkId
        )
    {
        if (g_isRunning && g_initializeCompleted)
        {
            Managers::Get<NetworkManager>()->Initialize(g_playfabTitleId.c_str());
            const char* networkNameCStr = env->GetStringUTFChars(networkId, NULL);
            g_networkName = networkNameCStr;
            env->ReleaseStringUTFChars(networkId, networkNameCStr);
            g_isSpinDone = false;
            Managers::Get<PlayFabManager>()->GetDescriptor(
                    g_networkName,
                    [](std::string networkDescriptor)
                    {
                        SendSysLogToUI("OnGetDescriptorForConnectTo : %s", networkDescriptor.c_str());
                        g_networkDescriptor = networkDescriptor;
                        ReleaseSpin();
                    }
            );

            HoldSpin();
            // When network connection is not stable, waiting for ConnectToNetwork callback will cost longer time.
            // To avoid App UI busy waiting, return to UI after ConnectToNetwork returns.
            Managers::Get<NetworkManager>()->ConnectToNetwork(
                g_networkName.c_str(),
                g_networkDescriptor.c_str(),
                []()
                {
                    OnNetworkConnected(g_networkName);
                    SendSysLogToUI("OnConnectToNetwork succeeded");
                },
                [](PartyError error)
                {
                    SendSysLogToUI("OnConnectToNetworkFailed %s", GetErrorMessage(error));
                    ResetChat(GetErrorMessage(error));
                });

            return true;
        }
        else
        {
            SendSysLogToUI("Please waiting for initialization done.");
            return false;
        }
    }

Im obigen Codeausschnitt werden die joinNetwork Aufrufe NetworkManager::CreateAndConnectToNetwork() , in die wiederum die unformatierte Party-API in Party.h

void 
NetworkManager::CreateAndConnectToNetwork(
    const char *networkId, 
    std::function<void(std::string)> callback, 
    std::function<void(PartyError)> errorCallback
    )
{
    DEBUGLOG("NetworkManager::CreateAndConnectToNetwork()\n");

    // Set the maximum number of devices allowed in a network to 16 devices
    constexpr uint8_t c_maxSampleNetworkDeviceCount = 16;
    static_assert(c_maxSampleNetworkDeviceCount <= c_maxNetworkConfigurationMaxDeviceCount, "Must be less than or equal to c_maxNetworkConfigurationMaxDeviceCount.");

    // Initialize network configuration for Party Network.
    PartyNetworkConfiguration cfg = {};
    cfg.maxDeviceCount = c_maxSampleNetworkDeviceCount;
    cfg.maxDevicesPerUserCount = 1;
    cfg.maxEndpointsPerDeviceCount = 1;
    cfg.maxUserCount = c_maxSampleNetworkDeviceCount;
    cfg.maxUsersPerDeviceCount = 1;

    //Get the uid from the local chat control
    PartyString uid = nullptr;
    PartyError err = m_localUser->GetEntityId(&uid);

    if (PARTY_FAILED(err))
    {
        DEBUGLOG("GetUserIdentifier failed: %s\n", GetErrorMessage(err));
        errorCallback(err);
        return;
    }

    // Setup the network invitation configuration to use the network id as an invitation id and allow anyone to join.
    PartyInvitationConfiguration invitationConfiguration{
        networkId,                                  // invitation identifier
        PartyInvitationRevocability::Anyone,        // revokability
        0,                                          // authorized user count
        nullptr                                     // authorized user list
    };

    // Initialize an empty network descriptor to hold the result of the following call.
    PartyNetworkDescriptor networkDescriptor = {};

    // Create a new network descriptor
    err = PartyManager::GetSingleton().CreateNewNetwork(
        m_localUser,                                // Local User
        &cfg,                                       // Network Config
        0,                                          // Region List Count
        nullptr,                                    // Region List
        &invitationConfiguration,                   // Invitation configuration
        nullptr,                                    // Async Identifier
        &networkDescriptor,                         // OUT network descriptor
        nullptr                                     // applied initialinvitationidentifier.
    );

    if (PARTY_FAILED(err))
    {
        DEBUGLOG("CreateNewNetwork failed: %s\n", GetErrorMessage(err));
        errorCallback(err);
        return;
    }

    // Connect to the new network
    if (InternalConnectToNetwork(networkDescriptor, networkId, errorCallback))
    {
        m_state = NetworkManagerState::WaitingForNetwork;
        m_onnetworkcreated = callback;
        m_onnetworkcreatederror = errorCallback;
        m_onnetworkconnectedError = errorCallback;
    }
}

In ähnlicher Weise wird jede Methode in der NetworkManager JNI-Schnittstelle über PartyDemo und NetworkManager auf die Party-API abgebildet.

Nächste Schritte

In diesem Artikel haben wir gesehen, wie Sie mit der Integration der Party-Bibliothek in Ihre Android-Anwendung beginnen können. Weitere Informationen zum Einrichten der restlichen Bausteine von PlayFab Party finden Sie unter Schnellstart für PlayFab Party .