다음을 통해 공유


Android 시작하기

이 문서에서는 PlayFab Party를 Android 애플리케이션에 통합하는 데 필요한 기본 필수 구성 요소 및 요구 사항을 나열합니다. 이 문서에 따라 시스템을 설정한 경우 PlayFab Party의 구성 요소를 사용하여 설정하려면 PlayFab Party용 빠른 시작을 살펴보세요.

필수 구성 요소

이 자습서를 시작하기 전에 다음 필수 구성 요소가 충족되었는지 확인하세요.

  1. PlayFab 개발자 계정을 만들었습니다.

  2. PlayFab 타이틀을 만들었으며 타이틀이 PlayFab Party의 허용 목록에 포함되었습니다.

  3. Android Studio 버전 3.2 이상이 설치되어 있습니다.

  4. 앱에서 Android 4.4(Kitkat) 이상을 대상으로 합니다.

  5. Android NDK 18.1.5063045 이상이 설치되어 있습니다.

  6. PlayFab Party 플랫폼 리포지토리에 액세스할 수 있습니다.

  7. Android 서명 인증서를 만들고 인증서 구성을 사용하여 배포를 위해 앱에 서명했습니다.

필수 라이브러리 및 헤더 파일 포함

PlayFab Party 배포 리포지토리에서 다음 헤더 파일을 포함해야 합니다.

LIB 파일

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

참고 항목

SSL 라이브러리는 Open SSL 버전 1.1.1b-dev에서 빌드됩니다. 1.1.1b-dev 이상인 openSSL 버전을 사용하세요.

헤더에 포함된 사항

Party 헤더

참고 항목

위의 lib 파일 및 헤더 외에도 PlayFab SDK 및 앱에 필요한 다른 플랫폼별 종속성에 대한 라이브러리 및 헤더도 필요합니다. 자세한 내용은 Android 샘플에 대한 프로젝트 파일 조직을 살펴보세요.

Android에서 PlayFab Party를 작동하는 단계

핵심 Party 라이브러리는 C++를 사용하여 작성되었으므로 Party lib 기능에 액세스하려면 간단한 JNI 래퍼 클래스를 만들어야 합니다. 상위 수준에서 네트워크를 만들고 네트워크에 연결하며 네트워크를 통해 메시지를 보내기 위해 Party API 메서드에 액세스할 수 있는 클래스가 필요합니다. NetworkManager Java 클래스를 통해 데모 앱에서 이를 달성했습니다.


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();
    }

}

위의 JNI 브리지는 NetworkManager.cpp로 호출하는 순수 C++ 구현 파일에서 지원하며, 이 파일은 Party API를 호출합니다.

다음은 다양한 계층을 보여 주는 예제 조각입니다.

NetworkManager Java 인터페이스는 Party 네트워크에 참여할 수 있는 메서드를 보여 줍니다.

public native boolean joinNetwork(String networkId);

joinNetwork 구현은 C++ 레이어에서 아래에 표시된 PartyDemo.cpp에 있습니다.

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;
        }
    }

위의 코드 조각에서, joinNetwork은(는) Party.h에 노출된 원시 Party API를 차례로 호출하는 NetworkManager::CreateAndConnectToNetwork()(으)로 호출됩니다.

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

    PartyNetworkConfiguration cfg = {};

    // Setup the network to allow the maximum number of single-device players of any device type
    cfg.maxDeviceCount = c_maxNetworkConfigurationMaxDeviceCount;
    cfg.maxDevicesPerUserCount = 1;
    cfg.maxEndpointsPerDeviceCount = 1;
    cfg.maxUserCount = c_maxNetworkConfigurationMaxDeviceCount;
    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;
    }
}

비슷한 방식으로 NetworkManager JNI 인터페이스의 각 메서드는 PartyDemo 및 NetworkManager를 통해 Party API에 매핑됩니다.

다음 단계

이 문서에서는 Party 라이브러리를 Android 애플리케이션에 통합하는 방법을 알아보았습니다. PlayFab Party의 나머지 구성 요소를 사용하여 설정하려면 PlayFab Party용 빠른 시작을 참조하세요.