> ## Documentation Index
> Fetch the complete documentation index at: https://devdocs.xbox.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Android getting started

> NDK 要件、JNI 初期化、およびマニフェスト内のオーディオとマイクの権限を含む、PlayFab Party SDK の Android 固有のセットアップ。

このドキュメントでは、PlayFab Party を Android アプリケーションに統合するために必要な基本的な前提条件と要件を示します。このドキュメントに従ってシステムをセットアップしたら、PlayFab Party のビルディング ブロックのセットアップについて [PlayFab Party のクイックスタート](/services/playfab/multiplayer/networking/quickstart) を参照してください。

## 前提条件

このチュートリアルを開始する前に、以下の前提条件が満たされていることを確認してください。

1. [PlayFab 開発者アカウント](https://developer.playfab.com) を作成した。

2. PlayFab タイトルを作成し、そのタイトルが PlayFab Party の許可リストに登録されている。

3. Android Studio バージョン 3.2 以上がインストールされている。

4. アプリが Android 4.4 (Kitkat) 以上を対象としている。

5. Android NDK 18.1.5063045 以上がインストールされている。

6. [PlayFab Party プラットフォーム リポジトリ](https://github.com/PlayFab/PlayFabParty/releases) にアクセスできる。

7. Android の署名証明書を作成し、その証明書構成を使用してアプリを署名してデプロイした。

## 必要なライブラリとヘッダー ファイルを含める

[PlayFab Party 配布リポジトリ](https://github.com/PlayFab/PlayFabParty) の以下のヘッダー ファイルを含める必要があります。

LIB ファイル

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

<Note>
  SSL ライブラリは [OpenSSL バージョン 1.1.1b-dev](https://github.com/openssl/openssl/tree/OpenSSL_1_1_1-stable) からビルドされています。1.1.1b-dev 以上の openSSL バージョンを使用してください。
</Note>

ヘッダーのインクルード

[Party ヘッダー](https://github.com/PlayFab/PlayFabParty/tree/master/include)

<Note>
  上記の lib ファイルとヘッダーに加えて、PlayFab SDK およびアプリに必要なその他のプラットフォーム固有の依存関係の lib とヘッダーも必要です。詳細については、Android サンプルのプロジェクト ファイル構成を参照してください。
</Note>

## Android で PlayFab Party を動作させる手順

コアの Party ライブラリは C++ で記述されているため、Party ライブラリの機能にアクセスするためのシンプルな JNI ラッパー クラスを作成する必要があります。大まかには、ネットワークを作成し、ネットワークに接続し、ネットワーク間でメッセージを送信する Party API メソッドにアクセスできるクラスが必要です。デモ アプリでは、[NetworkManager Java クラス](https://github.com/PlayFab/PlayFabParty/blob/docs/android/PartySample/demo/src/main/java/com/microsoft/playfab/party/sdk/NetworkManager.java) を介してこれを実現しました。

```java theme={null}

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](https://github.com/PlayFab/PlayFabParty/blob/docs/android/PartySampleNetworkCommon/lib/NetworkManager.cpp) を呼び出す純粋な C++ 実装ファイルによってバックアップされており、次にそれが Party API を呼び出します。

以下は、さまざまなレイヤーを示すサンプル スニペットです。

NetworkManager Java インターフェースは、Party ネットワークに参加するメソッドを公開します。

```java theme={null}
public native boolean joinNetwork(String networkId);
```

`joinNetwork` の実装は、以下に示す [PartyDemo.cpp](https://github.com/PlayFab/PlayFabParty/blob/docs/android/PartySample/demo/src/main/cpp/PartyDemo.cpp) 内の C++ レイヤーにあります。

```cpp theme={null}
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` は `NetworkManager::CreateAndConnectToNetwork()` を呼び出し、次にそれが [Party.h](https://github.com/PlayFab/PlayFabParty/blob/docs/include/Party.h) で公開されている raw な Party API を呼び出します。

```cpp theme={null}
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;
    }
}
```

同様の方法で、NetworkManager JNI インターフェース内の各メソッドが PartyDemo と NetworkManager を介して Party API にマッピングされます。

## 次のステップ

この記事では、Android アプリケーションに Party ライブラリを統合する方法を確認しました。PlayFab Party の残りのビルディング ブロックのセットアップについては、[PlayFab Party のクイックスタート](/services/playfab/multiplayer/networking/quickstart) を参照してください。


## Related topics

- [Linux getting started](/ja-jp/services/playfab/multiplayer/networking/linux-specific-requirements.md)
- [iOS and macOS getting started](/ja-jp/services/playfab/multiplayer/networking/apple-specific-requirements.md)
- [Defold 向け Lua クイックスタート](/ja-jp/services/playfab/sdks/lua/quickstart-defold.md)
- [レガシー C++ PlayFab SDK](/ja-jp/services/playfab/sdks/playfab-cpp/index.md)
- [Native と Phaser 向け JavaScript クイックスタート](/ja-jp/services/playfab/sdks/javascript/quickstart.md)
