Rövid útmutató: Hanghívás hozzáadása az alkalmazáshoz

Ismerkedés az Azure Communication Services szolgáltatással a Hívás SDK használatával hang- és videohívások alkalmazáshoz való hozzáadásához.

Ebben a rövid útmutatóban megtudhatja, hogyan indíthat hívást a WindowsHoz készült Azure Communication Services Calling SDK használatával.

A mintaalkalmazást a GitHubról töltheti le.

Előfeltételek

Az oktatóanyag teljesítéséhez a következő előfeltételekre lesz szüksége:

  • Egy Azure-fiók, aktív előfizetéssel. Fiók ingyenes létrehozása.

  • Telepítse a Visual Studio 2022-t Univerzális Windows-platform fejlesztési számítási feladattal.

  • Üzembe helyezett Communication Services-erőforrás. Hozzon létre egy Communication Services-erőforrást. Ehhez a rövid útmutatóhoz rögzítenie kell a kapcsolati sztring.

  • Felhasználói hozzáférési jogkivonat az Azure Communication Service-hez. Az Azure CLI-t is használhatja, és futtathatja a parancsot a kapcsolati sztring egy felhasználó és egy hozzáférési jogkivonat létrehozásához.

    az communication identity token issue --scope voip --connection-string "yourConnectionString"
    

    További részletekért lásd: Hozzáférési jogkivonatok létrehozása és kezelése az Azure CLI használatával.

Beállítás

A projekt létrehozása

A Visual Studióban hozzon létre egy új projektet az Üres alkalmazás (Univerzális Windows) sablonnal egy egyoldalas Univerzális Windows-platform (UWP) alkalmazás beállításához.

Screenshot showing the New UWP Project window within Visual Studio.

Telepítse a(z) csomagot

Válassza ki a projektet, és nyissa meg az Manage Nuget Packages 1.2.0-beta.1 vagy superior verziótAzure.Communication.Calling.WindowsClient. Győződjön meg arról, hogy az Előzetes belefoglalás jelölőnégyzet be van jelölve.

Hozzáférés kérése

Ugrás és Package.appxmanifest válassza a lehetőséget Capabilities. Ellenőrizze Internet (Client) és Internet (Client & Server) szerezzen bejövő és kimenő hozzáférést az internethez. Ellenőrizze Microphone a mikrofon hangcsatornájának elérését és Webcam a kamera videocsatornájának elérését.

Screenshot showing requesting access to Internet and Microphone in Visual Studio.

Az alkalmazás-keretrendszer beállítása

Egy alapszintű elrendezést kell konfigurálnunk a logikánk csatolásához. Kimenő hívás indításához meg kell TextBox adnia a hívó felhasználóazonosítóját. Egy gombra és egy Start/Join call gombra Hang up is szükségünk van. A Mute minta egy és egy BackgroundBlur jelölőnégyzetet is tartalmaz, amely bemutatja a hangállapotok és a videoeffektusok összesítésének funkcióit.

Nyissa meg a MainPage.xaml projektet, és adja hozzá a Grid csomópontot a következőhöz Page:

<Page
    x:Class="CallingQuickstart.MainPage"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="using:CallingQuickstart"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    mc:Ignorable="d"
    Background="{ThemeResource ApplicationPageBackgroundThemeBrush}" Width="800" Height="600">

    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition Height="16*"/>
            <RowDefinition Height="30*"/>
            <RowDefinition Height="200*"/>
            <RowDefinition Height="60*"/>
            <RowDefinition Height="16*"/>
        </Grid.RowDefinitions>
        <TextBox Grid.Row="1" x:Name="CalleeTextBox" PlaceholderText="Who would you like to call?" TextWrapping="Wrap" VerticalAlignment="Center" Height="30" Margin="10,10,10,10" />

        <Grid x:Name="AppTitleBar" Background="LightSeaGreen">
            <TextBlock x:Name="QuickstartTitle" Text="Calling Quickstart sample title bar" Style="{StaticResource CaptionTextBlockStyle}" Padding="7,7,0,0"/>
        </Grid>

        <Grid Grid.Row="2">
            <Grid.RowDefinitions>
                <RowDefinition/>
            </Grid.RowDefinitions>
            <Grid.ColumnDefinitions>
                <ColumnDefinition Width="*"/>
                <ColumnDefinition Width="*"/>
            </Grid.ColumnDefinitions>
            <MediaPlayerElement x:Name="LocalVideo" HorizontalAlignment="Center" Stretch="UniformToFill" Grid.Column="0" VerticalAlignment="Center" AutoPlay="True" />
            <MediaPlayerElement x:Name="RemoteVideo" HorizontalAlignment="Center" Stretch="UniformToFill" Grid.Column="1" VerticalAlignment="Center" AutoPlay="True" />
        </Grid>
        <StackPanel Grid.Row="3" Orientation="Vertical" Grid.RowSpan="2">
            <StackPanel Orientation="Horizontal">
                <Button x:Name="CallButton" Content="Start/Join call" Click="CallButton_Click" VerticalAlignment="Center" Margin="10,0,0,0" Height="40" Width="123"/>
                <Button x:Name="HangupButton" Content="Hang up" Click="HangupButton_Click" VerticalAlignment="Center" Margin="10,0,0,0" Height="40" Width="123"/>
                <CheckBox x:Name="MuteLocal" Content="Mute" Margin="10,0,0,0" Click="MuteLocal_Click" Width="74"/>
            </StackPanel>
        </StackPanel>
        <TextBox Grid.Row="5" x:Name="Stats" Text="" TextWrapping="Wrap" VerticalAlignment="Center" Height="30" Margin="0,2,0,0" BorderThickness="2" IsReadOnly="True" Foreground="LightSlateGray" />
    </Grid>
</Page>

Nyissa meg a MainPage.xaml.cs tartalmat, és cserélje le a következő implementációra:

using Azure.Communication.Calling.WindowsClient;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Threading.Tasks;
using Windows.ApplicationModel;
using Windows.ApplicationModel.Core;
using Windows.Media.Core;
using Windows.Networking.PushNotifications;
using Windows.UI;
using Windows.UI.ViewManagement;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Media;
using Windows.UI.Xaml.Navigation;

namespace CallingQuickstart
{
    public sealed partial class MainPage : Page
    {
        private const string authToken = "<AUTHENTICATION_TOKEN>";

        private CallClient callClient;
        private CallTokenRefreshOptions callTokenRefreshOptions = new CallTokenRefreshOptions(false);
        private CallAgent callAgent;
        private CommunicationCall call;

        private LocalOutgoingAudioStream micStream;
        private LocalOutgoingVideoStream cameraStream;

        #region Page initialization
        public MainPage()
        {
            this.InitializeComponent();
            // Additional UI customization code goes here
        }

        protected override async void OnNavigatedTo(NavigationEventArgs e)
        {
            base.OnNavigatedTo(e);
        }
        #endregion

        #region UI event handlers
        private async void CallButton_Click(object sender, RoutedEventArgs e)
        {
            // Start a call
        }

        private async void HangupButton_Click(object sender, RoutedEventArgs e)
        {
            // Hang up a call
        }

        private async void MuteLocal_Click(object sender, RoutedEventArgs e)
        {
            // Toggle mute/unmute audio state of a call
        }
        #endregion

        #region API event handlers
        private async void OnIncomingCallAsync(object sender, IncomingCallReceivedEventArgs args)
        {
            // Handle incoming call event
        }

        private async void OnStateChangedAsync(object sender, PropertyChangedEventArgs args)
        {
            // Handle connected and disconnected state change of a call
        }
        #endregion
    }
}

Objektummodell

A következő táblázat az osztályokat és interfészeket sorolja fel, amelyek az Azure Communication Services Calling SDK néhány fő funkcióját kezelik:

Név Leírás
CallClient Ez CallClient a hívó SDK fő belépési pontja.
CallAgent Ez CallAgent a hívások indítására és kezelésére szolgál.
CommunicationCall Ez CommunicationCall egy folyamatban lévő hívás kezelésére szolgál.
CallTokenCredential A CallTokenCredential rendszer a jogkivonat hitelesítő adataiként használja a példányosításhoz.CallAgent
CallIdentifier A CallIdentifier felhasználó identitásának ábrázolására szolgál, amely a következő lehetőségek egyike lehet: UserCallIdentifier, PhoneNumberCallIdentifier stb.

Az ügyfél hitelesítése

Inicializáljon egy példányt CallAgent egy felhasználói hozzáférési jogkivonattal, amely lehetővé teszi a hívások indítását és fogadását, és opcionálisan beszerezhet egy DeviceManager-példányt az ügyféleszköz-konfigurációk lekérdezéséhez.

A kódban cserélje le <AUTHENTICATION_TOKEN> a felhasználói hozzáférési jogkivonatot. Ha még nem rendelkezik jogkivonattal, tekintse meg a felhasználói hozzáférési jogkivonat dokumentációját.

Adjon hozzá InitCallAgentAndDeviceManagerAsync függvényt, amely elindítja az SDK-t. Ez a segéd testre szabható az alkalmazás követelményeinek megfelelően.

        private async Task InitCallAgentAndDeviceManagerAsync()
        {
            this.callClient = new CallClient(new CallClientOptions() {
                Diagnostics = new CallDiagnosticsOptions() { 
                    AppName = "CallingQuickstart",
                    AppVersion="1.0",
                    Tags = new[] { "Calling", "ACS", "Windows" }
                    }
                });

            // Set up local video stream using the first camera enumerated
            var deviceManager = await this.callClient.GetDeviceManagerAsync();
            var camera = deviceManager?.Cameras?.FirstOrDefault();
            var mic = deviceManager?.Microphones?.FirstOrDefault();
            micStream = new LocalOutgoingAudioStream();

            var tokenCredential = new CallTokenCredential(authToken, callTokenRefreshOptions);

            var callAgentOptions = new CallAgentOptions()
            {
                DisplayName = $"{Environment.MachineName}/{Environment.UserName}",
            };

            this.callAgent = await this.callClient.CreateCallAgentAsync(tokenCredential, callAgentOptions);
            this.callAgent.IncomingCallReceived += OnIncomingCallAsync;
        }

A hívás indítása

StartCallOptions Az objektum lekérése CallAgent után az Azure Communication Services-hívás kezdeményezhető:

        private async Task<CommunicationCall> StartAcsCallAsync(string acsCallee)
        {
            var options = new StartCallOptions();
            var call = await this.callAgent.StartCallAsync( new [] { new UserCallIdentifier(acsCallee) }, options);
            return call;
        }

Hívás befejezése

A gomb kattintásával fejezd be az Hang up aktuális hívást. Adja hozzá az implementációt a HangupButton_Click a hívás befejezéséhez, és állítsa le az előnézetet és a videostreameket.

        private async void HangupButton_Click(object sender, RoutedEventArgs e)
        {
            var call = this.callAgent?.Calls?.FirstOrDefault();
            if (call != null)
            {
                await call.HangUpAsync(new HangUpOptions() { ForEveryone = false });
            }
        }

Hang elnémítása/visszahangosításának kikapcsolása

A gombra kattintva elnémíthatja a Mute kimenő hangot. Adja hozzá az implementációt a MuteLocal_Click a hívás elnémításához.

        private async void MuteLocal_Click(object sender, RoutedEventArgs e)
        {
            var muteCheckbox = sender as CheckBox;

            if (muteCheckbox != null)
            {
                var call = this.callAgent?.Calls?.FirstOrDefault();
                if (call != null)
                {
                    if ((bool)muteCheckbox.IsChecked)
                    {
                        await call.MuteOutgoingAudioAsync();
                    }
                    else
                    {
                        await call.UnmuteOutgoingAudioAsync();
                    }
                }

                // Update the UI to reflect the state
            }
        }

Bejövő hívás elfogadása

IncomingCallReceived az event sink be van állítva az SDK bootstrap segédjében InitCallAgentAndDeviceManagerAsync.

    this.callAgent.IncomingCallReceived += OnIncomingCallAsync;

Az alkalmazás konfigurálhatja a bejövő hívás fogadásának módját, például a video- és hangstreamek típusait.

        private async void OnIncomingCallAsync(object sender, IncomingCallReceivedEventArgs args)
        {
            var incomingCall = args.IncomingCall;

            var acceptCallOptions = new AcceptCallOptions() { };

            call = await incomingCall.AcceptAsync(acceptCallOptions);
            call.StateChanged += OnStateChangedAsync;
        }

Állapotváltozási esemény figyelése és válasza

StateChanged az objektum eseménye CommunicationCall akkor aktiválódik, ha egy folyamatban lévő hívás tranzakcióit egyik állapotból a másikba hívja. Az alkalmazás lehetőséget kínál arra, hogy tükrözze a felhasználói felületen bekövetkező állapotváltozásokat, vagy üzleti logikákat szúrjon be.

        private async void OnStateChangedAsync(object sender, PropertyChangedEventArgs args)
        {
            var call = sender as CommunicationCall;

            if (call != null)
            {
                var state = call.State;

                // Update the UI

                switch (state)
                {
                    case CallState.Connected:
                        {
                            await call.StartAudioAsync(micStream);

                            break;
                        }
                    case CallState.Disconnected:
                        {
                            call.StateChanged -= OnStateChangedAsync;

                            call.Dispose();

                            break;
                        }
                    default: break;
                }
            }
        }

A kód futtatása

A kódot a Visual Studióban hozhatja létre és futtathatja. A megoldásplatformok esetében támogatjuk ARM64a x86. x64

Kimenő hívást úgy kezdeményezhet, hogy megad egy felhasználói azonosítót a szövegmezőben, és rákattint a Start Call/Join gombra. A hívás 8:echo123 egy echo robottal köti össze, ez a funkció kiválóan alkalmas a hangeszközök működésének ellenőrzésére.

Screenshot showing running the UWP quickstart app

Ebben a rövid útmutatóban megtudhatja, hogyan indíthat hívást az Azure Communication Services Call SDK for JavaScript használatával.

Mintakód

A mintaalkalmazást a GitHubról töltheti le.

Feljegyzés

Az Azure Communication Services-felhasználók kimenő hívásai az Azure Communication Services felhasználói felületi kódtárával érhetők el. A felhasználói felületi kódtár lehetővé teszi a fejlesztők számára, hogy csak néhány sornyi kóddal rendelkező, VoIP-kompatibilis hívásügyfélt vegyenek fel az alkalmazásukba.

Előfeltételek

Beállítás

Új Node.js-alkalmazás létrehozása

Nyissa meg a terminált vagy a parancsablakot, és hozzon létre egy új könyvtárat az alkalmazáshoz, és navigáljon hozzá.

mkdir calling-quickstart
cd calling-quickstart

Futtassa npm init -y az alapértelmezett beállításokkal rendelkező package.json fájl létrehozásához.

npm init -y

Telepítse a(z) csomagot

npm install A parancs használatával telepítse az Azure Communication Services Calling SDK for JavaScriptet.

npm install @azure/communication-common --save
npm install @azure/communication-calling --save

A --save beállítás függőségként sorolja fel a tárat a package.json fájlban.

Az alkalmazás-keretrendszer beállítása

Ez a rövid útmutató a Webpack használatával kötegeli az alkalmazásegységeket. Futtassa a következő parancsot az webpacknpm-csomagok webpack-cli telepítéséhez, webpack-dev-server és sorolja fel őket fejlesztési függőségekként a következőben package.json:

npm install copy-webpack-plugin@^11.0.0 webpack@^5.88.2 webpack-cli@^5.1.4 webpack-dev-server@^4.15.1 --save-dev

Íme a html, amelyet hozzá kell adnunk a index.html létrehozott fájlhoz:

<!DOCTYPE html>
<html>
  <head>
    <title>Communication Client - Calling Sample</title>
  </head>
  <body>
    <h4>Azure Communication Services</h4>
    <h1>Calling Quickstart</h1>
    <input 
      id="token-input"
      type="text"
      placeholder="User access token"
      style="margin-bottom:1em; width: 200px;"
    />
    </div>
    <button id="token-submit" type="button">
        Submit
    </button>
    <input 
      id="callee-id-input"
      type="text"
      placeholder="Who would you like to call?"
      style="margin-bottom:1em; width: 200px; display: block;"
    />
    <div>
      <button id="call-button" type="button" disabled="true">
        Start Call
      </button>
      &nbsp;
      <button id="accept-call-button" type="button" disabled="true">
        Accept Call
      </button>
      &nbsp;
      <button id="hang-up-button" type="button" disabled="true">
        Hang Up
      </button>
    </div>
    <script src="./main.js"></script>
  </body>
</html>

Hozzon létre egy fájlt a projekt gyökérkönyvtárában index.js , amely tartalmazza a rövid útmutató alkalmazáslogikát. Adja hozzá a következő kódot a hívó ügyfél importálásához és a DOM-elemekre mutató hivatkozások lekéréséhez, hogy csatolhassuk az üzleti logikát.

import { CallClient } from "@azure/communication-calling";
import { AzureCommunicationTokenCredential } from '@azure/communication-common';

let call;
let incomingCall;
let callAgent;
let deviceManager;
let tokenCredential;
const userToken = document.getElementById("token-input"); 
const calleeInput = document.getElementById("callee-id-input");
const submitToken = document.getElementById("token-submit");
const callButton = document.getElementById("call-button");
const hangUpButton = document.getElementById("hang-up-button");
const acceptCallButton = document.getElementById('accept-call-button');

Objektummodell

A következő osztályok és felületek kezelik az Azure Communication Services Calling SDK néhány fő funkcióját:

Név Leírás
CallClient Ez CallClient a hívó SDK fő belépési pontja.
CallAgent Ez CallAgent a hívások indítására és kezelésére szolgál.
AzureCommunicationTokenCredential Az AzureCommunicationTokenCredential osztály implementálja az CommunicationTokenCredential interfészt, amely a CallAgentpéldányosításra szolgál.

Az ügyfél hitelesítése

Be kell adnia egy érvényes felhasználói hozzáférési jogkivonatot az erőforráshoz a szövegmezőbe, és kattintson a "Küldés" gombra. Ha még nem rendelkezik jogkivonattal, tekintse meg a felhasználói hozzáférési jogkivonat dokumentációját. CallClientA használatával inicializálhat egy példányt CallAgent egy CommunicationTokenCredential olyannal, amely lehetővé teszi a hívások indítását és fogadását.

Szúrja be a következő kódot az app.js fájlba:

submitToken.addEventListener("click", async () => {
  const callClient = new CallClient();
  const userTokenCredential = userToken.value;
    try {
      tokenCredential = new AzureCommunicationTokenCredential(userTokenCredential);
      callAgent = await callClient.createCallAgent(tokenCredential);
      deviceManager = await callClient.getDeviceManager();
      await deviceManager.askDevicePermission({ audio: true });
      callButton.disabled = false;
      submitToken.disabled = true;
      // Listen for an incoming call to accept.
      callAgent.on('incomingCall', async (args) => {
        try {
          incomingCall = args.incomingCall;
          acceptCallButton.disabled = false;
          callButton.disabled = true;
        } catch (error) {
          console.error(error);
        }
      });
    } catch(error) {
      window.alert("Please submit a valid token!");
    }
})

Hívás indítása

Adjon hozzá egy eseménykezelőt a hívás indításához a callButton kattintáskor:

callButton.addEventListener("click", () => {
  // start a call
  const userToCall = calleeInput.value;
  call = callAgent.startCall(
      [{ id: userToCall }],
      {}
  );
  // toggle button states
  hangUpButton.disabled = false;
  callButton.disabled = true;
});

Hívás befejezése

Adjon hozzá egy eseményfigyelőt az aktuális hívás befejezéséhez a hangUpButton kattintáskor:

hangUpButton.addEventListener("click", () => {
  // end the current call
  // The `forEveryone` property ends the call for all call participants.
  call.hangUp({ forEveryone: true });

  // toggle button states
  hangUpButton.disabled = true;
  callButton.disabled = false;
  submitToken.disabled = false;
  acceptCallButton.disabled = true;
});

Bejövő hívás elfogadása

Eseményfigyelő hozzáadása a bejövő hívás fogadásához a acceptCallButton

acceptCallButton.onclick = async () => {
  try {
    call = await incomingCall.accept();
    acceptCallButton.disabled = true;
    hangUpButton.disabled = false;
  } catch (error) {
    console.error(error);
  }
}

A webpack helyi kiszolgálókódjának hozzáadása

Hozzon létre egy fájlt a projekt gyökérkönyvtárában webpack.config.js , amely tartalmazza a helyi kiszolgáló logikáját ebben a rövid útmutatóban. Adja hozzá a következő kódot a webpack.config.js:

const path = require('path');
const CopyPlugin = require("copy-webpack-plugin");

module.exports = {
    mode: 'development',
    entry: './index.js',
    output: {
        filename: 'main.js',
        path: path.resolve(__dirname, 'dist'),
    },
    devServer: {
        static: {
            directory: path.join(__dirname, './')
        },
    },
    plugins: [
        new CopyPlugin({
            patterns: [
                './index.html'
            ]
        }),
    ]
};

A kód futtatása

Az alkalmazás futtatásához használja a parancsot npx webpack serve --config webpack.config.js .

Nyissa meg a böngészőt, és lépjen a http://localhost:8080/. A következő képernyőnek kell megjelennie:

Screenshot of the completed JavaScript Application.

Kimenő VOIP-hívást úgy kezdeményezhet, hogy érvényes felhasználói hozzáférési jogkivonatot és felhasználói azonosítót ad meg a megfelelő szövegmezőkben, és a Hívás indítása gombra kattint.

A hívás 8:echo123 egy echo robottal köti össze, amely kiválóan alkalmas a hangeszközök működésének ellenőrzésére. Az echorobot meghívásához adja át {id: '8:echo123'} a CallAgent.startCall() API-t. Az Azure Communication Services kommunikációs felhasználójának meghívásához adja át {communicationUserId: 'ACS_USER_ID'} az CallAgent.startCall() API-nak.

Ebben a rövid útmutatóban megtudhatja, hogyan indíthat hívást az Androidhoz készült Azure Communication Services Calling SDK használatával.

Mintakód

A mintaalkalmazást a GitHubról töltheti le.

Előfeltételek

  • Egy Azure-fiók, aktív előfizetéssel. Fiók ingyenes létrehozása.

  • Android Studio, androidos alkalmazás létrehozásához.

  • Üzembe helyezett Communication Services-erőforrás. Hozzon létre egy Communication Services-erőforrást. Ehhez a rövid útmutatóhoz rögzítenie kell a kapcsolati sztring.

  • Felhasználói hozzáférési jogkivonat az Azure Communication Service-hez. Az Azure CLI-t is használhatja, és futtathatja a parancsot a kapcsolati sztring egy felhasználó és egy hozzáférési jogkivonat létrehozásához.

    az communication identity token issue --scope voip --connection-string "yourConnectionString"
    

    További részletekért lásd: Hozzáférési jogkivonatok létrehozása és kezelése az Azure CLI használatával.

Beállítás

Android-alkalmazás létrehozása üres tevékenységgel

Az Android Studióban válassza az Új Android Studio-projekt indítása lehetőséget.

Screenshot showing the 'Start a new Android Studio Project' button selected in Android Studio.

Válassza az "Üres tevékenység" projektsablont a "Telefon és táblagép" területen.

Screenshot showing the 'Empty Activity' option selected in the Project Template Screen.

Válassza az "API 26: Android 8.0 (Oreo)" vagy újabb api minimális SDK-ját.

Screenshot showing the 'Empty Activity' option selected in the Project Template Screen 2.

Telepítse a(z) csomagot

Keresse meg a projektszintű build.gradle-t, és vegye fel mavenCentral() az adattárak listájára a következő alatt és alatt buildscript : allprojects

buildscript {
    repositories {
    ...
        mavenCentral()
    ...
    }
}
allprojects {
    repositories {
    ...
        mavenCentral()
    ...
    }
}

Ezután a build.gradle modulszinten adja hozzá a következő sorokat a függőségekhez és az androidos szakaszokhoz

android {
    ...
    packagingOptions {
        pickFirst  'META-INF/*'
    }
    compileOptions {
        sourceCompatibility JavaVersion.VERSION_1_8
        targetCompatibility JavaVersion.VERSION_1_8
    }
}

dependencies {
    ...
    implementation 'com.azure.android:azure-communication-calling:1.0.0-beta.8'
    ...
}

Engedélyek hozzáadása az alkalmazásjegyzékhez

A híváshoz szükséges engedélyek lekéréséhez deklarálni kell őket az alkalmazásjegyzékben (app/src/main/AndroidManifest.xml). Cserélje le a fájl tartalmát a következő kódra:

    <?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.contoso.acsquickstart">

    <uses-permission android:name="android.permission.INTERNET" />
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
    <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
    <uses-permission android:name="android.permission.RECORD_AUDIO" />
    <uses-permission android:name="android.permission.CAMERA" />
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
    <uses-permission android:name="android.permission.READ_PHONE_STATE" />

    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/AppTheme">
        <!--Our Calling SDK depends on the Apache HTTP SDK.
When targeting Android SDK 28+, this library needs to be explicitly referenced.
See https://developer.android.com/about/versions/pie/android-9.0-changes-28#apache-p-->
        <uses-library android:name="org.apache.http.legacy" android:required="false"/>
        <activity android:name=".MainActivity">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>

</manifest>
    

Az alkalmazás elrendezésének beállítása

Két bemenetre van szükség: a hívásazonosító szöveges bemenetére és a hívás indítására szolgáló gombra. Ezek a bemenetek hozzáadhatók a tervezőn keresztül vagy az elrendezés xml-fájljának szerkesztésével. Gomb létrehozása azonosítóval call_button és szövegbevitellel callee_id. Keresse meg (app/src/main/res/layout/activity_main.xml) és cserélje le a fájl tartalmát a következő kódra:

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">

    <Button
        android:id="@+id/call_button"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginBottom="16dp"
        android:text="Call"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent" />

    <EditText
        android:id="@+id/callee_id"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:ems="10"
        android:hint="Callee Id"
        android:inputType="textPersonName"
        app:layout_constraintBottom_toTopOf="@+id/call_button"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>

A fő tevékenységállványok és kötések létrehozása

A létrehozott elrendezéssel a kötések hozzáadhatók, valamint a tevékenység alapszintű állványzata is. A tevékenység kezeli a futásidejű engedélyek kérését, a hívásügynök létrehozását és a hívás indítását a gomb megnyomásakor. Mindegyikről saját szakasz foglalkozik. A onCreate metódus felül van bírálva a hívási gomb meghívásához getAllPermissions és createAgent kötéseinek hozzáadásához. Ez az esemény csak egyszer fordul elő a tevékenység létrehozásakor. További információt onCreatea tevékenység életciklusának ismertetése című útmutatóban talál.

Lépjen MainActivity.java, és cserélje le a tartalmat a következő kódra:

package com.contoso.acsquickstart;

import androidx.appcompat.app.AppCompatActivity;
import androidx.core.app.ActivityCompat;
import android.media.AudioManager;
import android.Manifest;
import android.content.pm.PackageManager;

import android.os.Bundle;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Toast;

import com.azure.android.communication.common.CommunicationUserIdentifier;
import com.azure.android.communication.common.CommunicationTokenCredential;
import com.azure.android.communication.calling.CallAgent;
import com.azure.android.communication.calling.CallClient;
import com.azure.android.communication.calling.StartCallOptions;


import java.util.ArrayList;

public class MainActivity extends AppCompatActivity {
    
    private CallAgent callAgent;

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

        getAllPermissions();
        createAgent();
        
        // Bind call button to call `startCall`
        Button callButton = findViewById(R.id.call_button);
        callButton.setOnClickListener(l -> startCall());
        
        setVolumeControlStream(AudioManager.STREAM_VOICE_CALL);
    }

    /**
     * Request each required permission if the app doesn't already have it.
     */
    private void getAllPermissions() {
        // See section on requesting permissions
    }

    /**
      * Create the call agent for placing calls
      */
    private void createAgent() {
        // See section on creating the call agent
    }

    /**
     * Place a call to the callee id provided in `callee_id` text input.
     */
    private void startCall() {
        // See section on starting the call
    }
}

Engedélyek kérése futásidőben

Android 6.0 és újabb (API 23- vagy újabb API-szint) esetén targetSdkVersion az engedélyek futásidőben lesznek megadva, nem pedig az alkalmazás telepítésekor. A támogatás érdekében implementálható a getAllPermissions híváshoz ActivityCompat.checkSelfPermission és ActivityCompat.requestPermissions az egyes szükséges engedélyekhez.

/**
 * Request each required permission if the app doesn't already have it.
 */
private void getAllPermissions() {
    String[] requiredPermissions = new String[]{Manifest.permission.RECORD_AUDIO, Manifest.permission.CAMERA, Manifest.permission.WRITE_EXTERNAL_STORAGE, Manifest.permission.READ_PHONE_STATE};
    ArrayList<String> permissionsToAskFor = new ArrayList<>();
    for (String permission : requiredPermissions) {
        if (ActivityCompat.checkSelfPermission(this, permission) != PackageManager.PERMISSION_GRANTED) {
            permissionsToAskFor.add(permission);
        }
    }
    if (!permissionsToAskFor.isEmpty()) {
        ActivityCompat.requestPermissions(this, permissionsToAskFor.toArray(new String[0]), 1);
    }
}

Feljegyzés

Az alkalmazás tervezésekor vegye figyelembe, hogy mikor kell ezeket az engedélyeket igényelni. Az engedélyeket szükség szerint, nem előre kell igényelni. További információ: Android-engedélyek útmutatója.

Objektummodell

A következő osztályok és felületek kezelik az Azure Communication Services Calling SDK néhány fő funkcióját:

Név Leírás
allClient Ez CallClient a hívó SDK fő belépési pontja.
CallAgent Ez CallAgent a hívások indítására és kezelésére szolgál.
CommunicationTokenCredential A CommunicationTokenCredential rendszer a jogkivonat hitelesítő adataiként használja a példányosításhoz.CallAgent
CommunicationIdentifier A CommunicationIdentifier rendszer különböző típusú résztvevőként használja, amelyek egy hívás részét képezhetik.

Ügynök létrehozása a felhasználói hozzáférési jogkivonatból

Egy felhasználói jogkivonattal hitelesített hívásügynök példányosítható. Ez a jogkivonat általában egy olyan szolgáltatásból jön létre, amely az alkalmazásra jellemző hitelesítéssel rendelkezik. A felhasználói hozzáférési jogkivonatokról további információt a Felhasználói hozzáférési jogkivonatok útmutatójában talál.

A rövid útmutatóban cserélje le <User_Access_Token> az Azure Communication Service-erőforráshoz létrehozott felhasználói hozzáférési jogkivonatot.


/**
 * Create the call agent for placing calls
 */
private void createAgent() {
    String userToken = "<User_Access_Token>";

    try {
        CommunicationTokenCredential credential = new CommunicationTokenCredential(userToken);
        callAgent = new CallClient().createCallAgent(getApplicationContext(), credential).get();
    } catch (Exception ex) {
        Toast.makeText(getApplicationContext(), "Failed to create call agent.", Toast.LENGTH_SHORT).show();
    }
}

Hívás indítása a hívásügynök használatával

A hívás elküldése a hívóügynökön keresztül végezhető el, és csak meg kell adnia a hívóazonosítók listáját és a hívási lehetőségeket. A rövid útmutatóban a rendszer az alapértelmezett, videó nélküli hívásbeállításokat és a szöveges bemenetből származó egyetlen hívóazonosítót használja.

/**
 * Place a call to the callee id provided in `callee_id` text input.
 */
private void startCall() {
    EditText calleeIdView = findViewById(R.id.callee_id);
    String calleeId = calleeIdView.getText().toString();
    
    StartCallOptions options = new StartCallOptions();

    callAgent.startCall(
        getApplicationContext(),
        new CommunicationUserIdentifier[] {new CommunicationUserIdentifier(calleeId)},
        options);
}

Indítsa el az alkalmazást, és hívja meg az echo robotot

Az alkalmazás most már elindítható az eszköztár "Alkalmazás futtatása" gombjával (Shift+F10). Ellenőrizze, hogy tud-e hívásokat 8:echo123kezdeményezni. Egy előre rögzített üzenet lejátszása után ismételje meg az üzenetet.

Screenshot showing the completed application.

Ebben a rövid útmutatóban megtudhatja, hogyan indíthat hívást az iOS-hez készült Azure Communication Services Calling SDK használatával.

Mintakód

A mintaalkalmazást a GitHubról töltheti le.

Előfeltételek

Az oktatóanyag teljesítéséhez a következő előfeltételekre lesz szüksége:

  • Egy Azure-fiók, aktív előfizetéssel. Fiók ingyenes létrehozása.

  • Egy Xcode-ot futtató Mac gép, valamint egy érvényes fejlesztői tanúsítvány, amely telepítve van a kulcskarikába.

  • Üzembe helyezett Communication Services-erőforrás. Hozzon létre egy Communication Services-erőforrást. Ehhez a rövid útmutatóhoz rögzítenie kell a kapcsolati sztring.

  • Felhasználói hozzáférési jogkivonat az Azure Communication Service-hez. Az Azure CLI-t is használhatja, és futtathatja a parancsot a kapcsolati sztring egy felhasználó és egy hozzáférési jogkivonat létrehozásához.

    az communication identity token issue --scope voip --connection-string "yourConnectionString"
    

    További részletekért lásd: Hozzáférési jogkivonatok létrehozása és kezelése az Azure CLI használatával.

Beállítás

Az Xcode-projekt létrehozása

Az Xcode-ban hozzon létre egy új iOS-projektet, és válassza ki az alkalmazássablont. Ez az oktatóanyag a SwiftUI keretrendszert használja, ezért a nyelvet Swiftre, a felhasználói felületet pedig SwiftUI-ra kell állítani. Ebben a rövid útmutatóban nem fog teszteket létrehozni. Nyugodtan törölje a jelölést a Belefoglalási tesztek jelölőnégyzetből.

Screenshot showing the New Project window within Xcode.

A csomag és a függőségek telepítése a CocoaPods használatával

  1. Podfile létrehozásához nyissa meg a terminált, és keresse meg a projektmappát, és futtassa a következőt:

    pod init

  2. Adja hozzá a következő kódot a Podfile-hoz, és mentse (győződjön meg arról, hogy a "cél" megegyezik a projekt nevével):

    platform :ios, '13.0'
    use_frameworks!
    
    target 'AzureCommunicationCallingSample' do
      pod 'AzureCommunicationCalling', '~> 1.0.0'
    end
    
  3. Futtassa az pod install parancsot.

  4. Nyissa meg az .xcworkspace Xcode-ot.

Hozzáférés kérése a mikrofonhoz

Az eszköz mikrofonjának eléréséhez frissítenie kell az alkalmazás információs tulajdonságlistáját egy NSMicrophoneUsageDescription. A társított értéket egy olyan értékre string állítja be, amelyet a rendszer a felhasználótól való hozzáférés kéréséhez használ.

Kattintson a jobb gombbal a Info.plist projektfa bejegyzésére, és válassza a Megnyitás forráskódként>lehetőséget. Adja hozzá a következő sorokat a legfelső szintű <dict> szakaszhoz, majd mentse a fájlt.

<key>NSMicrophoneUsageDescription</key>
<string>Need microphone access for VOIP calling.</string>

Az alkalmazás-keretrendszer beállítása

Nyissa meg a projekt ContentView.swift fájlját, és adjon hozzá egy deklarációt import a fájl tetejére a AzureCommunicationCalling libraryfájl importálásához. Emellett az importáláshoz AVFoundationszükség van erre a kódra a hangengedély-kéréshez a kódban.

import AzureCommunicationCalling
import AVFoundation

Cserélje le a ContentView szerkezet implementációját néhány egyszerű felhasználói felületi vezérlőre, amelyek lehetővé teszik a felhasználó számára a hívás kezdeményezését és befejezését. Ebben a rövid útmutatóban üzleti logikát csatolunk ezekhez a vezérlőkhöz.

struct ContentView: View {
    @State var callee: String = ""
    @State var callClient: CallClient?
    @State var callAgent: CallAgent?
    @State var call: Call?

    var body: some View {
        NavigationView {
            Form {
                Section {
                    TextField("Who would you like to call?", text: $callee)
                    Button(action: startCall) {
                        Text("Start Call")
                    }.disabled(callAgent == nil)
                    Button(action: endCall) {
                        Text("End Call")
                    }.disabled(call == nil)
                }
            }
            .navigationBarTitle("Calling Quickstart")
        }.onAppear {
            // Initialize call agent
        }
    }

    func startCall() {
        // Ask permissions
        AVAudioSession.sharedInstance().requestRecordPermission { (granted) in
            if granted {
                // Add start call logic
            }
        }
    }

    func endCall() {
        // Add end call logic
    }
}

Objektummodell

A következő osztályok és felületek kezelik az Azure Communication Services Calling SDK néhány fő funkcióját:

Név Leírás
CallClient Ez CallClient a hívó SDK fő belépési pontja.
CallAgent Ez CallAgent a hívások indítására és kezelésére szolgál.
CommunicationTokenCredential A CommunicationTokenCredential rendszer a jogkivonat hitelesítő adataiként használja a példányosításhoz.CallAgent
CommunicationUserIdentifier A CommunicationUserIdentifier felhasználó identitásának ábrázolására szolgál, amely a következő lehetőségek egyike lehet: CommunicationUserIdentifiervagyPhoneNumberIdentifierCallingApplication.

Az ügyfél hitelesítése

Inicializáljon egy példányt CallAgent felhasználói hozzáférési jogkivonattal, amely lehetővé teszi a hívások indítását és fogadását.

Az alábbi kódban egy érvényes felhasználói hozzáférési jogkivonatot kell lecserélnie <USER ACCESS TOKEN> az erőforráshoz. Ha még nem rendelkezik jogkivonattal, tekintse meg a felhasználói hozzáférési jogkivonat dokumentációját.

Adja hozzá a következő kódot a visszahíváshoz a onAppear ContentView.swiftben:

var userCredential: CommunicationTokenCredential?
do {
    userCredential = try CommunicationTokenCredential(token: "<USER ACCESS TOKEN>")
} catch {
    print("ERROR: It was not possible to create user credential.")
    return
}

self.callClient = CallClient()

// Creates the call agent
self.callClient?.createCallAgent(userCredential: userCredential!) { (agent, error) in
    if error != nil {
        print("ERROR: It was not possible to create a call agent.")
        return
    }
    else {
        self.callAgent = agent
        print("Call agent successfully created.")
    }
}

Hívás indítása

A startCall metódus a Hívás indítása gomb leképezésekor végrehajtott műveletként van beállítva. Frissítse a megvalósítást úgy, hogy hívást indítson a ASACallAgentkövetkezővel:

func startCall()
{
    // Ask permissions
    AVAudioSession.sharedInstance().requestRecordPermission { (granted) in
        if granted {
            // start call logic
            let callees:[CommunicationIdentifier] = [CommunicationUserIdentifier(self.callee)]
            self.callAgent?.startCall(participants: callees, options: StartCallOptions()) { (call, error) in
                if (error == nil) {
                    self.call = call
                } else {
                    print("Failed to get call object")
                }
            }
        }
    }
}

A tulajdonságok StartCallOptions használatával megadhatja a hívás kezdeti beállításait is (vagyis lehetővé teszi a hívás indítását a mikrofon elnémított állapotában).

Hívás befejezése

Implementálja a metódust endCall az aktuális hívás befejezéséhez, amikor a Hívás befejezése gomb le van képezve.

func endCall()
{    
    self.call!.hangUp(options: HangUpOptions()) { (error) in
        if (error != nil) {
            print("ERROR: It was not possible to hangup the call.")
        }
    }
}

A kód futtatása

Az alkalmazást iOS-szimulátoron is létrehozhatja és futtathatja a Termékfuttatás> vagy a (⌘-R) billentyűparanccsal.

Final look and feel of the quick start app

Kimenő VOIP-hívást úgy kezdeményezhet, hogy megad egy felhasználói azonosítót a szövegmezőben, majd a Hívás indítása gombra koppint. A hívás 8:echo123 egy echo robottal köti össze, ez a funkció kiválóan alkalmas a hangeszközök működésének ellenőrzésére.

Feljegyzés

Az első híváskor a rendszer kérni fogja a mikrofonhoz való hozzáférést. Éles alkalmazásokban az AVAudioSession API-val ellenőrizze az engedély állapotát , és zökkenőmentesen frissítse az alkalmazás viselkedését, ha nincs megadva engedély.

Ebben a rövid útmutatóban megtudhatja, hogyan indíthat hívást az Azure Communication Services Call SDK for Unity használatával.

A mintaalkalmazást a GitHubról töltheti le.

Előfeltételek

Az oktatóanyag teljesítéséhez a következő előfeltételekre lesz szüksége:

Beállítás

A projekt létrehozása

A Unity Hubban hozzon létre egy új projektet a 2D Core sablonnal a Unity-projekt beállításához.

Screenshot showing the New Unity Project window within Unity Editor.

Telepítse a(z) csomagot

Az Azure Communication Calling SDK for Unity kétféleképpen telepíthető.

  1. Töltse le az SDK-t a nyilvános npm-hírcsatornából, és importálja a Unity Editor csomagkezelőjében, amely a Windows lap alatt található.

  2. Töltse le a Mixed Reality szolgáltatáseszközt a Microsofttól, és telepítse a vegyes valóság eszközkezelőjével.

Az alkalmazás-keretrendszer beállítása

Egy alapszintű elrendezést kell konfigurálnunk a logikánk csatolásához. Kimenő hívás indításához meg kell TextBox adnia a hívó felhasználóazonosítóját. Egy gombra és egy Start/Join call gombra Hang up is szükségünk van.

Hozzon létre egy új jelenetet a Main projektben.

Nyissa meg a Main.unity fájlt, és cserélje le a tartalmat a következő implementációra:

Main.Unity Code

Main.unity

%YAML 1.1
%TAG !u! tag:unity3d.com,2011:
--- !u!29 &1
OcclusionCullingSettings:
m_ObjectHideFlags: 0
serializedVersion: 2
m_OcclusionBakeSettings:
  smallestOccluder: 5
  smallestHole: 0.25
  backfaceThreshold: 100
m_SceneGUID: 00000000000000000000000000000000
m_OcclusionCullingData: {fileID: 0}
--- !u!104 &2
RenderSettings:
m_ObjectHideFlags: 0
serializedVersion: 9
m_Fog: 0
m_FogColor: {r: 0.5, g: 0.5, b: 0.5, a: 1}
m_FogMode: 3
m_FogDensity: 0.01
m_LinearFogStart: 0
m_LinearFogEnd: 300
m_AmbientSkyColor: {r: 0.212, g: 0.227, b: 0.259, a: 1}
m_AmbientEquatorColor: {r: 0.114, g: 0.125, b: 0.133, a: 1}
m_AmbientGroundColor: {r: 0.047, g: 0.043, b: 0.035, a: 1}
m_AmbientIntensity: 1
m_AmbientMode: 3
m_SubtractiveShadowColor: {r: 0.42, g: 0.478, b: 0.627, a: 1}
m_SkyboxMaterial: {fileID: 0}
m_HaloStrength: 0.5
m_FlareStrength: 1
m_FlareFadeSpeed: 3
m_HaloTexture: {fileID: 0}
m_SpotCookie: {fileID: 10001, guid: 0000000000000000e000000000000000, type: 0}
m_DefaultReflectionMode: 0
m_DefaultReflectionResolution: 128
m_ReflectionBounces: 1
m_ReflectionIntensity: 1
m_CustomReflection: {fileID: 0}
m_Sun: {fileID: 0}
m_IndirectSpecularColor: {r: 0, g: 0, b: 0, a: 1}
m_UseRadianceAmbientProbe: 0
--- !u!157 &3
LightmapSettings:
m_ObjectHideFlags: 0
serializedVersion: 12
m_GIWorkflowMode: 1
m_GISettings:
  serializedVersion: 2
  m_BounceScale: 1
  m_IndirectOutputScale: 1
  m_AlbedoBoost: 1
  m_EnvironmentLightingMode: 0
  m_EnableBakedLightmaps: 0
  m_EnableRealtimeLightmaps: 0
m_LightmapEditorSettings:
  serializedVersion: 12
  m_Resolution: 2
  m_BakeResolution: 40
  m_AtlasSize: 1024
  m_AO: 0
  m_AOMaxDistance: 1
  m_CompAOExponent: 1
  m_CompAOExponentDirect: 0
  m_ExtractAmbientOcclusion: 0
  m_Padding: 2
  m_LightmapParameters: {fileID: 0}
  m_LightmapsBakeMode: 1
  m_TextureCompression: 1
  m_FinalGather: 0
  m_FinalGatherFiltering: 1
  m_FinalGatherRayCount: 256
  m_ReflectionCompression: 2
  m_MixedBakeMode: 2
  m_BakeBackend: 0
  m_PVRSampling: 1
  m_PVRDirectSampleCount: 32
  m_PVRSampleCount: 500
  m_PVRBounces: 2
  m_PVREnvironmentSampleCount: 500
  m_PVREnvironmentReferencePointCount: 2048
  m_PVRFilteringMode: 2
  m_PVRDenoiserTypeDirect: 0
  m_PVRDenoiserTypeIndirect: 0
  m_PVRDenoiserTypeAO: 0
  m_PVRFilterTypeDirect: 0
  m_PVRFilterTypeIndirect: 0
  m_PVRFilterTypeAO: 0
  m_PVREnvironmentMIS: 0
  m_PVRCulling: 1
  m_PVRFilteringGaussRadiusDirect: 1
  m_PVRFilteringGaussRadiusIndirect: 5
  m_PVRFilteringGaussRadiusAO: 2
  m_PVRFilteringAtrousPositionSigmaDirect: 0.5
  m_PVRFilteringAtrousPositionSigmaIndirect: 2
  m_PVRFilteringAtrousPositionSigmaAO: 1
  m_ExportTrainingData: 0
  m_TrainingDataDestination: TrainingData
  m_LightProbeSampleCountMultiplier: 4
m_LightingDataAsset: {fileID: 0}
m_LightingSettings: {fileID: 0}
--- !u!196 &4
NavMeshSettings:
serializedVersion: 2
m_ObjectHideFlags: 0
m_BuildSettings:
  serializedVersion: 3
  agentTypeID: 0
  agentRadius: 0.5
  agentHeight: 2
  agentSlope: 45
  agentClimb: 0.4
  ledgeDropHeight: 0
  maxJumpAcrossDistance: 0
  minRegionArea: 2
  manualCellSize: 0
  cellSize: 0.16666667
  manualTileSize: 0
  tileSize: 256
  buildHeightMesh: 0
  maxJobWorkers: 0
  preserveTilesOutsideBounds: 0
  debug:
    m_Flags: 0
m_NavMeshData: {fileID: 0}
--- !u!1 &247756367
GameObject:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
serializedVersion: 6
m_Component:
- component: {fileID: 247756370}
- component: {fileID: 247756369}
- component: {fileID: 247756368}
m_Layer: 0
m_Name: EventSystem
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!114 &247756368
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 247756367}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: 4f231c4fb786f3946a6b90b886c48677, type: 3}
m_Name: 
m_EditorClassIdentifier: 
m_SendPointerHoverToParent: 1
m_HorizontalAxis: Horizontal
m_VerticalAxis: Vertical
m_SubmitButton: Submit
m_CancelButton: Cancel
m_InputActionsPerSecond: 10
m_RepeatDelay: 0.5
m_ForceModuleActive: 0
--- !u!114 &247756369
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 247756367}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: 76c392e42b5098c458856cdf6ecaaaa1, type: 3}
m_Name: 
m_EditorClassIdentifier: 
m_FirstSelected: {fileID: 0}
m_sendNavigationEvents: 1
m_DragThreshold: 10
--- !u!4 &247756370
Transform:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 247756367}
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
m_LocalPosition: {x: 0, y: 0, z: 0}
m_LocalScale: {x: 1, y: 1, z: 1}
m_ConstrainProportionsScale: 0
m_Children: []
m_Father: {fileID: 0}
m_RootOrder: 2
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
--- !u!1 &293984669
GameObject:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
serializedVersion: 6
m_Component:
- component: {fileID: 293984671}
- component: {fileID: 293984670}
m_Layer: 0
m_Name: AppManager
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!114 &293984670
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 293984669}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: a3a77da2e7bbf604c8b001e299ec9185, type: 3}
m_Name: 
m_EditorClassIdentifier: 
callStatus: {fileID: 1529611528}
--- !u!4 &293984671
Transform:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 293984669}
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
m_LocalPosition: {x: 0, y: 0, z: 0}
m_LocalScale: {x: 1, y: 1, z: 1}
m_ConstrainProportionsScale: 0
m_Children: []
m_Father: {fileID: 0}
m_RootOrder: 1
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
--- !u!1 &438770860
GameObject:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
serializedVersion: 6
m_Component:
- component: {fileID: 438770861}
- component: {fileID: 438770863}
- component: {fileID: 438770862}
m_Layer: 5
m_Name: Text (TMP)
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!224 &438770861
RectTransform:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 438770860}
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
m_LocalPosition: {x: 0, y: 0, z: 0}
m_LocalScale: {x: 1, y: 1, z: 1}
m_ConstrainProportionsScale: 0
m_Children: []
m_Father: {fileID: 1732033234}
m_RootOrder: 0
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_AnchorMin: {x: 0, y: 0}
m_AnchorMax: {x: 1, y: 1}
m_AnchoredPosition: {x: 0, y: 0}
m_SizeDelta: {x: 0, y: 0}
m_Pivot: {x: 0.5, y: 0.5}
--- !u!114 &438770862
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 438770860}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: f4688fdb7df04437aeb418b961361dc5, type: 3}
m_Name: 
m_EditorClassIdentifier: 
m_Material: {fileID: 0}
m_Color: {r: 1, g: 1, b: 1, a: 1}
m_RaycastTarget: 1
m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0}
m_Maskable: 1
m_OnCullStateChanged:
  m_PersistentCalls:
    m_Calls: []
m_text: Start Call
m_isRightToLeft: 0
m_fontAsset: {fileID: 11400000, guid: 8f586378b4e144a9851e7b34d9b748ee, type: 2}
m_sharedMaterial: {fileID: 2180264, guid: 8f586378b4e144a9851e7b34d9b748ee, type: 2}
m_fontSharedMaterials: []
m_fontMaterial: {fileID: 0}
m_fontMaterials: []
m_fontColor32:
  serializedVersion: 2
  rgba: 4281479730
m_fontColor: {r: 0.19607843, g: 0.19607843, b: 0.19607843, a: 1}
m_enableVertexGradient: 0
m_colorMode: 3
m_fontColorGradient:
  topLeft: {r: 1, g: 1, b: 1, a: 1}
  topRight: {r: 1, g: 1, b: 1, a: 1}
  bottomLeft: {r: 1, g: 1, b: 1, a: 1}
  bottomRight: {r: 1, g: 1, b: 1, a: 1}
m_fontColorGradientPreset: {fileID: 0}
m_spriteAsset: {fileID: 0}
m_tintAllSprites: 0
m_StyleSheet: {fileID: 0}
m_TextStyleHashCode: -1183493901
m_overrideHtmlColors: 0
m_faceColor:
  serializedVersion: 2
  rgba: 4294967295
m_fontSize: 24
m_fontSizeBase: 24
m_fontWeight: 400
m_enableAutoSizing: 0
m_fontSizeMin: 18
m_fontSizeMax: 72
m_fontStyle: 0
m_HorizontalAlignment: 2
m_VerticalAlignment: 512
m_textAlignment: 65535
m_characterSpacing: 0
m_wordSpacing: 0
m_lineSpacing: 0
m_lineSpacingMax: 0
m_paragraphSpacing: 0
m_charWidthMaxAdj: 0
m_enableWordWrapping: 1
m_wordWrappingRatios: 0.4
m_overflowMode: 0
m_linkedTextComponent: {fileID: 0}
parentLinkedComponent: {fileID: 0}
m_enableKerning: 1
m_enableExtraPadding: 0
checkPaddingRequired: 0
m_isRichText: 1
m_parseCtrlCharacters: 1
m_isOrthographic: 1
m_isCullingEnabled: 0
m_horizontalMapping: 0
m_verticalMapping: 0
m_uvLineOffset: 0
m_geometrySortingOrder: 0
m_IsTextObjectScaleStatic: 0
m_VertexBufferAutoSizeReduction: 0
m_useMaxVisibleDescender: 1
m_pageToDisplay: 1
m_margin: {x: 0, y: 0, z: 0, w: 0}
m_isUsingLegacyAnimationComponent: 0
m_isVolumetricText: 0
m_hasFontAssetChanged: 0
m_baseMaterial: {fileID: 0}
m_maskOffset: {x: 0, y: 0, z: 0, w: 0}
--- !u!222 &438770863
CanvasRenderer:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 438770860}
m_CullTransparentMesh: 1
--- !u!1 &519420028
GameObject:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
serializedVersion: 6
m_Component:
- component: {fileID: 519420032}
- component: {fileID: 519420031}
- component: {fileID: 519420029}
m_Layer: 0
m_Name: Main Camera
m_TagString: MainCamera
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!81 &519420029
AudioListener:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 519420028}
m_Enabled: 1
--- !u!20 &519420031
Camera:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 519420028}
m_Enabled: 1
serializedVersion: 2
m_ClearFlags: 2
m_BackGroundColor: {r: 0.19215687, g: 0.3019608, b: 0.4745098, a: 0}
m_projectionMatrixMode: 1
m_GateFitMode: 2
m_FOVAxisMode: 0
m_Iso: 200
m_ShutterSpeed: 0.005
m_Aperture: 16
m_FocusDistance: 10
m_FocalLength: 50
m_BladeCount: 5
m_Curvature: {x: 2, y: 11}
m_BarrelClipping: 0.25
m_Anamorphism: 0
m_SensorSize: {x: 36, y: 24}
m_LensShift: {x: 0, y: 0}
m_NormalizedViewPortRect:
  serializedVersion: 2
  x: 0
  y: 0
  width: 1
  height: 1
near clip plane: 0.3
far clip plane: 1000
field of view: 60
orthographic: 1
orthographic size: 5
m_Depth: -1
m_CullingMask:
  serializedVersion: 2
  m_Bits: 4294967295
m_RenderingPath: -1
m_TargetTexture: {fileID: 0}
m_TargetDisplay: 0
m_TargetEye: 0
m_HDR: 1
m_AllowMSAA: 0
m_AllowDynamicResolution: 0
m_ForceIntoRT: 0
m_OcclusionCulling: 0
m_StereoConvergence: 10
m_StereoSeparation: 0.022
--- !u!4 &519420032
Transform:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 519420028}
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
m_LocalPosition: {x: 0, y: 0, z: -10}
m_LocalScale: {x: 1, y: 1, z: 1}
m_ConstrainProportionsScale: 0
m_Children: []
m_Father: {fileID: 0}
m_RootOrder: 0
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
--- !u!1 &857336305
GameObject:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
serializedVersion: 6
m_Component:
- component: {fileID: 857336306}
- component: {fileID: 857336309}
- component: {fileID: 857336308}
- component: {fileID: 857336307}
m_Layer: 5
m_Name: Placeholder
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!224 &857336306
RectTransform:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 857336305}
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
m_LocalPosition: {x: 0, y: 0, z: 0}
m_LocalScale: {x: 1, y: 1, z: 1}
m_ConstrainProportionsScale: 0
m_Children: []
m_Father: {fileID: 1787936407}
m_RootOrder: 0
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_AnchorMin: {x: 0, y: 0}
m_AnchorMax: {x: 1, y: 1}
m_AnchoredPosition: {x: 0, y: 0}
m_SizeDelta: {x: 0, y: 0}
m_Pivot: {x: 0.5, y: 0.5}
--- !u!114 &857336307
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 857336305}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: 306cc8c2b49d7114eaa3623786fc2126, type: 3}
m_Name: 
m_EditorClassIdentifier: 
m_IgnoreLayout: 1
m_MinWidth: -1
m_MinHeight: -1
m_PreferredWidth: -1
m_PreferredHeight: -1
m_FlexibleWidth: -1
m_FlexibleHeight: -1
m_LayoutPriority: 1
--- !u!114 &857336308
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 857336305}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: f4688fdb7df04437aeb418b961361dc5, type: 3}
m_Name: 
m_EditorClassIdentifier: 
m_Material: {fileID: 0}
m_Color: {r: 1, g: 1, b: 1, a: 1}
m_RaycastTarget: 1
m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0}
m_Maskable: 1
m_OnCullStateChanged:
  m_PersistentCalls:
    m_Calls: []
m_text: Who Would you like to call?
m_isRightToLeft: 0
m_fontAsset: {fileID: 11400000, guid: 8f586378b4e144a9851e7b34d9b748ee, type: 2}
m_sharedMaterial: {fileID: 2180264, guid: 8f586378b4e144a9851e7b34d9b748ee, type: 2}
m_fontSharedMaterials: []
m_fontMaterial: {fileID: 0}
m_fontMaterials: []
m_fontColor32:
  serializedVersion: 2
  rgba: 2150773298
m_fontColor: {r: 0.19607843, g: 0.19607843, b: 0.19607843, a: 0.5}
m_enableVertexGradient: 0
m_colorMode: 3
m_fontColorGradient:
  topLeft: {r: 1, g: 1, b: 1, a: 1}
  topRight: {r: 1, g: 1, b: 1, a: 1}
  bottomLeft: {r: 1, g: 1, b: 1, a: 1}
  bottomRight: {r: 1, g: 1, b: 1, a: 1}
m_fontColorGradientPreset: {fileID: 0}
m_spriteAsset: {fileID: 0}
m_tintAllSprites: 0
m_StyleSheet: {fileID: 0}
m_TextStyleHashCode: -1183493901
m_overrideHtmlColors: 0
m_faceColor:
  serializedVersion: 2
  rgba: 4294967295
m_fontSize: 14
m_fontSizeBase: 14
m_fontWeight: 400
m_enableAutoSizing: 0
m_fontSizeMin: 18
m_fontSizeMax: 72
m_fontStyle: 2
m_HorizontalAlignment: 1
m_VerticalAlignment: 256
m_textAlignment: 65535
m_characterSpacing: 0
m_wordSpacing: 0
m_lineSpacing: 0
m_lineSpacingMax: 0
m_paragraphSpacing: 0
m_charWidthMaxAdj: 0
m_enableWordWrapping: 0
m_wordWrappingRatios: 0.4
m_overflowMode: 0
m_linkedTextComponent: {fileID: 0}
parentLinkedComponent: {fileID: 0}
m_enableKerning: 1
m_enableExtraPadding: 1
checkPaddingRequired: 0
m_isRichText: 1
m_parseCtrlCharacters: 1
m_isOrthographic: 1
m_isCullingEnabled: 0
m_horizontalMapping: 0
m_verticalMapping: 0
m_uvLineOffset: 0
m_geometrySortingOrder: 0
m_IsTextObjectScaleStatic: 0
m_VertexBufferAutoSizeReduction: 0
m_useMaxVisibleDescender: 1
m_pageToDisplay: 1
m_margin: {x: 0, y: 0, z: 0, w: 0}
m_isUsingLegacyAnimationComponent: 0
m_isVolumetricText: 0
m_hasFontAssetChanged: 0
m_baseMaterial: {fileID: 0}
m_maskOffset: {x: 0, y: 0, z: 0, w: 0}
--- !u!222 &857336309
CanvasRenderer:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 857336305}
m_CullTransparentMesh: 1
--- !u!1 &963546686
GameObject:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
serializedVersion: 6
m_Component:
- component: {fileID: 963546687}
- component: {fileID: 963546690}
- component: {fileID: 963546689}
- component: {fileID: 963546688}
m_Layer: 5
m_Name: InputField (TMP)
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!224 &963546687
RectTransform:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 963546686}
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
m_LocalPosition: {x: 0, y: 0, z: 0}
m_LocalScale: {x: 1, y: 1, z: 1}
m_ConstrainProportionsScale: 0
m_Children:
- {fileID: 1787936407}
m_Father: {fileID: 1843906927}
m_RootOrder: 0
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_AnchorMin: {x: 0.5, y: 0.5}
m_AnchorMax: {x: 0.5, y: 0.5}
m_AnchoredPosition: {x: 0.00002861, y: 327}
m_SizeDelta: {x: 1337.7578, y: 71.4853}
m_Pivot: {x: 0.5, y: 0.5}
--- !u!114 &963546688
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 963546686}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: 2da0c512f12947e489f739169773d7ca, type: 3}
m_Name: 
m_EditorClassIdentifier: 
m_Navigation:
  m_Mode: 3
  m_WrapAround: 0
  m_SelectOnUp: {fileID: 0}
  m_SelectOnDown: {fileID: 0}
  m_SelectOnLeft: {fileID: 0}
  m_SelectOnRight: {fileID: 0}
m_Transition: 1
m_Colors:
  m_NormalColor: {r: 1, g: 1, b: 1, a: 1}
  m_HighlightedColor: {r: 0.9607843, g: 0.9607843, b: 0.9607843, a: 1}
  m_PressedColor: {r: 0.78431374, g: 0.78431374, b: 0.78431374, a: 1}
  m_SelectedColor: {r: 0.9607843, g: 0.9607843, b: 0.9607843, a: 1}
  m_DisabledColor: {r: 0.78431374, g: 0.78431374, b: 0.78431374, a: 0.5019608}
  m_ColorMultiplier: 1
  m_FadeDuration: 0.1
m_SpriteState:
  m_HighlightedSprite: {fileID: 0}
  m_PressedSprite: {fileID: 0}
  m_SelectedSprite: {fileID: 0}
  m_DisabledSprite: {fileID: 0}
m_AnimationTriggers:
  m_NormalTrigger: Normal
  m_HighlightedTrigger: Highlighted
  m_PressedTrigger: Pressed
  m_SelectedTrigger: Selected
  m_DisabledTrigger: Disabled
m_Interactable: 1
m_TargetGraphic: {fileID: 963546689}
m_TextViewport: {fileID: 1787936407}
m_TextComponent: {fileID: 1676708954}
m_Placeholder: {fileID: 857336308}
m_VerticalScrollbar: {fileID: 0}
m_VerticalScrollbarEventHandler: {fileID: 0}
m_LayoutGroup: {fileID: 0}
m_ScrollSensitivity: 1
m_ContentType: 0
m_InputType: 0
m_AsteriskChar: 42
m_KeyboardType: 0
m_LineType: 0
m_HideMobileInput: 0
m_HideSoftKeyboard: 0
m_CharacterValidation: 0
m_RegexValue: 
m_GlobalPointSize: 14
m_CharacterLimit: 0
m_OnEndEdit:
  m_PersistentCalls:
    m_Calls: []
m_OnSubmit:
  m_PersistentCalls:
    m_Calls: []
m_OnSelect:
  m_PersistentCalls:
    m_Calls: []
m_OnDeselect:
  m_PersistentCalls:
    m_Calls: []
m_OnTextSelection:
  m_PersistentCalls:
    m_Calls: []
m_OnEndTextSelection:
  m_PersistentCalls:
    m_Calls: []
m_OnValueChanged:
  m_PersistentCalls:
    m_Calls:
    - m_Target: {fileID: 293984670}
      m_TargetAssemblyTypeName: CallClientHost, Assembly-CSharp
      m_MethodName: set_CalleeIdentity
      m_Mode: 0
      m_Arguments:
        m_ObjectArgument: {fileID: 0}
        m_ObjectArgumentAssemblyTypeName: UnityEngine.Object, UnityEngine
        m_IntArgument: 0
        m_FloatArgument: 0
        m_StringArgument: 
        m_BoolArgument: 0
      m_CallState: 2
m_OnTouchScreenKeyboardStatusChanged:
  m_PersistentCalls:
    m_Calls: []
m_CaretColor: {r: 0.19607843, g: 0.19607843, b: 0.19607843, a: 1}
m_CustomCaretColor: 0
m_SelectionColor: {r: 0.65882355, g: 0.80784315, b: 1, a: 0.7529412}
m_Text: 
m_CaretBlinkRate: 0.85
m_CaretWidth: 1
m_ReadOnly: 0
m_RichText: 1
m_GlobalFontAsset: {fileID: 11400000, guid: 8f586378b4e144a9851e7b34d9b748ee, type: 2}
m_OnFocusSelectAll: 1
m_ResetOnDeActivation: 1
m_RestoreOriginalTextOnEscape: 1
m_isRichTextEditingAllowed: 0
m_LineLimit: 0
m_InputValidator: {fileID: 0}
--- !u!114 &963546689
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 963546686}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3}
m_Name: 
m_EditorClassIdentifier: 
m_Material: {fileID: 0}
m_Color: {r: 1, g: 1, b: 1, a: 1}
m_RaycastTarget: 1
m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0}
m_Maskable: 1
m_OnCullStateChanged:
  m_PersistentCalls:
    m_Calls: []
m_Sprite: {fileID: 10911, guid: 0000000000000000f000000000000000, type: 0}
m_Type: 1
m_PreserveAspect: 0
m_FillCenter: 1
m_FillMethod: 4
m_FillAmount: 1
m_FillClockwise: 1
m_FillOrigin: 0
m_UseSpriteMesh: 0
m_PixelsPerUnitMultiplier: 1
--- !u!222 &963546690
CanvasRenderer:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 963546686}
m_CullTransparentMesh: 1
--- !u!1 &1184525248
GameObject:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
serializedVersion: 6
m_Component:
- component: {fileID: 1184525249}
- component: {fileID: 1184525251}
- component: {fileID: 1184525250}
m_Layer: 5
m_Name: Status Header
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!224 &1184525249
RectTransform:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 1184525248}
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
m_LocalPosition: {x: 0, y: 0, z: 0}
m_LocalScale: {x: 1, y: 1, z: 1}
m_ConstrainProportionsScale: 0
m_Children: []
m_Father: {fileID: 1843906927}
m_RootOrder: 5
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_AnchorMin: {x: 0.5, y: 0.5}
m_AnchorMax: {x: 0.5, y: 0.5}
m_AnchoredPosition: {x: -23, y: -303}
m_SizeDelta: {x: 159.05, y: 33.5037}
m_Pivot: {x: 0.5, y: 0.5}
--- !u!114 &1184525250
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 1184525248}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: f4688fdb7df04437aeb418b961361dc5, type: 3}
m_Name: 
m_EditorClassIdentifier: 
m_Material: {fileID: 0}
m_Color: {r: 1, g: 1, b: 1, a: 1}
m_RaycastTarget: 1
m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0}
m_Maskable: 1
m_OnCullStateChanged:
  m_PersistentCalls:
    m_Calls: []
m_text: Status
m_isRightToLeft: 0
m_fontAsset: {fileID: 11400000, guid: 8f586378b4e144a9851e7b34d9b748ee, type: 2}
m_sharedMaterial: {fileID: 2180264, guid: 8f586378b4e144a9851e7b34d9b748ee, type: 2}
m_fontSharedMaterials: []
m_fontMaterial: {fileID: 0}
m_fontMaterials: []
m_fontColor32:
  serializedVersion: 2
  rgba: 4294967295
m_fontColor: {r: 1, g: 1, b: 1, a: 1}
m_enableVertexGradient: 0
m_colorMode: 3
m_fontColorGradient:
  topLeft: {r: 1, g: 1, b: 1, a: 1}
  topRight: {r: 1, g: 1, b: 1, a: 1}
  bottomLeft: {r: 1, g: 1, b: 1, a: 1}
  bottomRight: {r: 1, g: 1, b: 1, a: 1}
m_fontColorGradientPreset: {fileID: 0}
m_spriteAsset: {fileID: 0}
m_tintAllSprites: 0
m_StyleSheet: {fileID: 0}
m_TextStyleHashCode: -1183493901
m_overrideHtmlColors: 0
m_faceColor:
  serializedVersion: 2
  rgba: 4294967295
m_fontSize: 24
m_fontSizeBase: 24
m_fontWeight: 400
m_enableAutoSizing: 0
m_fontSizeMin: 18
m_fontSizeMax: 72
m_fontStyle: 0
m_HorizontalAlignment: 1
m_VerticalAlignment: 256
m_textAlignment: 65535
m_characterSpacing: 0
m_wordSpacing: 0
m_lineSpacing: 0
m_lineSpacingMax: 0
m_paragraphSpacing: 0
m_charWidthMaxAdj: 0
m_enableWordWrapping: 1
m_wordWrappingRatios: 0.4
m_overflowMode: 0
m_linkedTextComponent: {fileID: 0}
parentLinkedComponent: {fileID: 0}
m_enableKerning: 1
m_enableExtraPadding: 0
checkPaddingRequired: 0
m_isRichText: 1
m_parseCtrlCharacters: 1
m_isOrthographic: 1
m_isCullingEnabled: 0
m_horizontalMapping: 0
m_verticalMapping: 0
m_uvLineOffset: 0
m_geometrySortingOrder: 0
m_IsTextObjectScaleStatic: 0
m_VertexBufferAutoSizeReduction: 0
m_useMaxVisibleDescender: 1
m_pageToDisplay: 1
m_margin: {x: 0, y: 2.5243988, z: 10.097656, w: -2.5243645}
m_isUsingLegacyAnimationComponent: 0
m_isVolumetricText: 0
m_hasFontAssetChanged: 0
m_baseMaterial: {fileID: 0}
m_maskOffset: {x: 0, y: 0, z: 0, w: 0}
--- !u!222 &1184525251
CanvasRenderer:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 1184525248}
m_CullTransparentMesh: 1
--- !u!1 &1332239153
GameObject:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
serializedVersion: 6
m_Component:
- component: {fileID: 1332239154}
- component: {fileID: 1332239157}
- component: {fileID: 1332239156}
- component: {fileID: 1332239155}
m_Layer: 5
m_Name: Hang Up Button
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!224 &1332239154
RectTransform:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 1332239153}
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
m_LocalPosition: {x: 0, y: 0, z: 0}
m_LocalScale: {x: 1, y: 1, z: 1}
m_ConstrainProportionsScale: 0
m_Children:
- {fileID: 1917486034}
m_Father: {fileID: 1843906927}
m_RootOrder: 3
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_AnchorMin: {x: 0.5, y: 0.5}
m_AnchorMax: {x: 0.5, y: 0.5}
m_AnchoredPosition: {x: -277, y: -329}
m_SizeDelta: {x: 212.1357, y: 53.698}
m_Pivot: {x: 0.5, y: 0.5}
--- !u!114 &1332239155
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 1332239153}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: 4e29b1a8efbd4b44bb3f3716e73f07ff, type: 3}
m_Name: 
m_EditorClassIdentifier: 
m_Navigation:
  m_Mode: 3
  m_WrapAround: 0
  m_SelectOnUp: {fileID: 0}
  m_SelectOnDown: {fileID: 0}
  m_SelectOnLeft: {fileID: 0}
  m_SelectOnRight: {fileID: 0}
m_Transition: 1
m_Colors:
  m_NormalColor: {r: 1, g: 1, b: 1, a: 1}
  m_HighlightedColor: {r: 0.9607843, g: 0.9607843, b: 0.9607843, a: 1}
  m_PressedColor: {r: 0.78431374, g: 0.78431374, b: 0.78431374, a: 1}
  m_SelectedColor: {r: 0.9607843, g: 0.9607843, b: 0.9607843, a: 1}
  m_DisabledColor: {r: 0.78431374, g: 0.78431374, b: 0.78431374, a: 0.5019608}
  m_ColorMultiplier: 1
  m_FadeDuration: 0.1
m_SpriteState:
  m_HighlightedSprite: {fileID: 0}
  m_PressedSprite: {fileID: 0}
  m_SelectedSprite: {fileID: 0}
  m_DisabledSprite: {fileID: 0}
m_AnimationTriggers:
  m_NormalTrigger: Normal
  m_HighlightedTrigger: Highlighted
  m_PressedTrigger: Pressed
  m_SelectedTrigger: Selected
  m_DisabledTrigger: Disabled
m_Interactable: 1
m_TargetGraphic: {fileID: 1332239156}
m_OnClick:
  m_PersistentCalls:
    m_Calls:
    - m_Target: {fileID: 293984670}
      m_TargetAssemblyTypeName: AppManager, Assembly-CSharp
      m_MethodName: HangupButton_Click
      m_Mode: 1
      m_Arguments:
        m_ObjectArgument: {fileID: 0}
        m_ObjectArgumentAssemblyTypeName: UnityEngine.Object, UnityEngine
        m_IntArgument: 0
        m_FloatArgument: 0
        m_StringArgument: 
        m_BoolArgument: 0
      m_CallState: 2
--- !u!114 &1332239156
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 1332239153}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3}
m_Name: 
m_EditorClassIdentifier: 
m_Material: {fileID: 0}
m_Color: {r: 1, g: 1, b: 1, a: 1}
m_RaycastTarget: 1
m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0}
m_Maskable: 1
m_OnCullStateChanged:
  m_PersistentCalls:
    m_Calls: []
m_Sprite: {fileID: 10905, guid: 0000000000000000f000000000000000, type: 0}
m_Type: 1
m_PreserveAspect: 0
m_FillCenter: 1
m_FillMethod: 4
m_FillAmount: 1
m_FillClockwise: 1
m_FillOrigin: 0
m_UseSpriteMesh: 0
m_PixelsPerUnitMultiplier: 1
--- !u!222 &1332239157
CanvasRenderer:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 1332239153}
m_CullTransparentMesh: 1
--- !u!1 &1529611526
GameObject:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
serializedVersion: 6
m_Component:
- component: {fileID: 1529611527}
- component: {fileID: 1529611529}
- component: {fileID: 1529611528}
m_Layer: 5
m_Name: Status
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!224 &1529611527
RectTransform:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 1529611526}
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
m_LocalPosition: {x: 0, y: 0, z: 0}
m_LocalScale: {x: 1, y: 1, z: 1}
m_ConstrainProportionsScale: 0
m_Children: []
m_Father: {fileID: 1843906927}
m_RootOrder: 6
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_AnchorMin: {x: 0.5, y: 0.5}
m_AnchorMax: {x: 0.5, y: 0.5}
m_AnchoredPosition: {x: -2.525, y: -344.75}
m_SizeDelta: {x: 200, y: 50}
m_Pivot: {x: 0.5, y: 0.5}
--- !u!114 &1529611528
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 1529611526}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: f4688fdb7df04437aeb418b961361dc5, type: 3}
m_Name: 
m_EditorClassIdentifier: 
m_Material: {fileID: 0}
m_Color: {r: 1, g: 1, b: 1, a: 1}
m_RaycastTarget: 1
m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0}
m_Maskable: 1
m_OnCullStateChanged:
  m_PersistentCalls:
    m_Calls: []
m_text: Disconnected
m_isRightToLeft: 0
m_fontAsset: {fileID: 11400000, guid: 8f586378b4e144a9851e7b34d9b748ee, type: 2}
m_sharedMaterial: {fileID: 2180264, guid: 8f586378b4e144a9851e7b34d9b748ee, type: 2}
m_fontSharedMaterials: []
m_fontMaterial: {fileID: 0}
m_fontMaterials: []
m_fontColor32:
  serializedVersion: 2
  rgba: 4294967295
m_fontColor: {r: 1, g: 1, b: 1, a: 1}
m_enableVertexGradient: 0
m_colorMode: 3
m_fontColorGradient:
  topLeft: {r: 1, g: 1, b: 1, a: 1}
  topRight: {r: 1, g: 1, b: 1, a: 1}
  bottomLeft: {r: 1, g: 1, b: 1, a: 1}
  bottomRight: {r: 1, g: 1, b: 1, a: 1}
m_fontColorGradientPreset: {fileID: 0}
m_spriteAsset: {fileID: 0}
m_tintAllSprites: 0
m_StyleSheet: {fileID: 0}
m_TextStyleHashCode: -1183493901
m_overrideHtmlColors: 0
m_faceColor:
  serializedVersion: 2
  rgba: 4294967295
m_fontSize: 30
m_fontSizeBase: 30
m_fontWeight: 400
m_enableAutoSizing: 0
m_fontSizeMin: 18
m_fontSizeMax: 72
m_fontStyle: 0
m_HorizontalAlignment: 1
m_VerticalAlignment: 256
m_textAlignment: 65535
m_characterSpacing: 0
m_wordSpacing: 0
m_lineSpacing: 0
m_lineSpacingMax: 0
m_paragraphSpacing: 0
m_charWidthMaxAdj: 0
m_enableWordWrapping: 1
m_wordWrappingRatios: 0.4
m_overflowMode: 0
m_linkedTextComponent: {fileID: 0}
parentLinkedComponent: {fileID: 0}
m_enableKerning: 1
m_enableExtraPadding: 0
checkPaddingRequired: 0
m_isRichText: 1
m_parseCtrlCharacters: 1
m_isOrthographic: 1
m_isCullingEnabled: 0
m_horizontalMapping: 0
m_verticalMapping: 0
m_uvLineOffset: 0
m_geometrySortingOrder: 0
m_IsTextObjectScaleStatic: 0
m_VertexBufferAutoSizeReduction: 0
m_useMaxVisibleDescender: 1
m_pageToDisplay: 1
m_margin: {x: 0, y: 0, z: -25.861023, w: 0}
m_isUsingLegacyAnimationComponent: 0
m_isVolumetricText: 0
m_hasFontAssetChanged: 0
m_baseMaterial: {fileID: 0}
m_maskOffset: {x: 0, y: 0, z: 0, w: 0}
--- !u!222 &1529611529
CanvasRenderer:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 1529611526}
m_CullTransparentMesh: 1
--- !u!1 &1676708952
GameObject:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
serializedVersion: 6
m_Component:
- component: {fileID: 1676708953}
- component: {fileID: 1676708955}
- component: {fileID: 1676708954}
m_Layer: 5
m_Name: Text
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!224 &1676708953
RectTransform:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 1676708952}
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
m_LocalPosition: {x: 0, y: 0, z: 0}
m_LocalScale: {x: 1, y: 1, z: 1}
m_ConstrainProportionsScale: 0
m_Children: []
m_Father: {fileID: 1787936407}
m_RootOrder: 1
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_AnchorMin: {x: 0, y: 0}
m_AnchorMax: {x: 1, y: 1}
m_AnchoredPosition: {x: 0, y: 0}
m_SizeDelta: {x: 0, y: 0}
m_Pivot: {x: 0.5, y: 0.5}
--- !u!114 &1676708954
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 1676708952}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: f4688fdb7df04437aeb418b961361dc5, type: 3}
m_Name: 
m_EditorClassIdentifier: 
m_Material: {fileID: 0}
m_Color: {r: 1, g: 1, b: 1, a: 1}
m_RaycastTarget: 1
m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0}
m_Maskable: 1
m_OnCullStateChanged:
  m_PersistentCalls:
    m_Calls: []
m_text: "\u200B"
m_isRightToLeft: 0
m_fontAsset: {fileID: 11400000, guid: 8f586378b4e144a9851e7b34d9b748ee, type: 2}
m_sharedMaterial: {fileID: 2180264, guid: 8f586378b4e144a9851e7b34d9b748ee, type: 2}
m_fontSharedMaterials: []
m_fontMaterial: {fileID: 0}
m_fontMaterials: []
m_fontColor32:
  serializedVersion: 2
  rgba: 4281479730
m_fontColor: {r: 0.19607843, g: 0.19607843, b: 0.19607843, a: 1}
m_enableVertexGradient: 0
m_colorMode: 3
m_fontColorGradient:
  topLeft: {r: 1, g: 1, b: 1, a: 1}
  topRight: {r: 1, g: 1, b: 1, a: 1}
  bottomLeft: {r: 1, g: 1, b: 1, a: 1}
  bottomRight: {r: 1, g: 1, b: 1, a: 1}
m_fontColorGradientPreset: {fileID: 0}
m_spriteAsset: {fileID: 0}
m_tintAllSprites: 0
m_StyleSheet: {fileID: 0}
m_TextStyleHashCode: -1183493901
m_overrideHtmlColors: 0
m_faceColor:
  serializedVersion: 2
  rgba: 4294967295
m_fontSize: 14
m_fontSizeBase: 14
m_fontWeight: 400
m_enableAutoSizing: 0
m_fontSizeMin: 18
m_fontSizeMax: 72
m_fontStyle: 0
m_HorizontalAlignment: 1
m_VerticalAlignment: 256
m_textAlignment: 65535
m_characterSpacing: 0
m_wordSpacing: 0
m_lineSpacing: 0
m_lineSpacingMax: 0
m_paragraphSpacing: 0
m_charWidthMaxAdj: 0
m_enableWordWrapping: 0
m_wordWrappingRatios: 0.4
m_overflowMode: 0
m_linkedTextComponent: {fileID: 0}
parentLinkedComponent: {fileID: 0}
m_enableKerning: 1
m_enableExtraPadding: 1
checkPaddingRequired: 0
m_isRichText: 1
m_parseCtrlCharacters: 1
m_isOrthographic: 1
m_isCullingEnabled: 0
m_horizontalMapping: 0
m_verticalMapping: 0
m_uvLineOffset: 0
m_geometrySortingOrder: 0
m_IsTextObjectScaleStatic: 0
m_VertexBufferAutoSizeReduction: 0
m_useMaxVisibleDescender: 1
m_pageToDisplay: 1
m_margin: {x: 0, y: 0, z: 0, w: 0}
m_isUsingLegacyAnimationComponent: 0
m_isVolumetricText: 0
m_hasFontAssetChanged: 0
m_baseMaterial: {fileID: 0}
m_maskOffset: {x: 0, y: 0, z: 0, w: 0}
--- !u!222 &1676708955
CanvasRenderer:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 1676708952}
m_CullTransparentMesh: 1
--- !u!1 &1732033233
GameObject:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
serializedVersion: 6
m_Component:
- component: {fileID: 1732033234}
- component: {fileID: 1732033237}
- component: {fileID: 1732033236}
- component: {fileID: 1732033235}
m_Layer: 5
m_Name: Start Call Button
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!224 &1732033234
RectTransform:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 1732033233}
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
m_LocalPosition: {x: 0, y: 0, z: 0}
m_LocalScale: {x: 1, y: 1, z: 1}
m_ConstrainProportionsScale: 0
m_Children:
- {fileID: 438770861}
m_Father: {fileID: 1843906927}
m_RootOrder: 2
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_AnchorMin: {x: 0.5, y: 0.5}
m_AnchorMax: {x: 0.5, y: 0.5}
m_AnchoredPosition: {x: -525.52, y: -329}
m_SizeDelta: {x: 212.1357, y: 53.698}
m_Pivot: {x: 0.5, y: 0.5}
--- !u!114 &1732033235
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 1732033233}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: 4e29b1a8efbd4b44bb3f3716e73f07ff, type: 3}
m_Name: 
m_EditorClassIdentifier: 
m_Navigation:
  m_Mode: 3
  m_WrapAround: 0
  m_SelectOnUp: {fileID: 0}
  m_SelectOnDown: {fileID: 0}
  m_SelectOnLeft: {fileID: 0}
  m_SelectOnRight: {fileID: 0}
m_Transition: 1
m_Colors:
  m_NormalColor: {r: 1, g: 1, b: 1, a: 1}
  m_HighlightedColor: {r: 0.9607843, g: 0.9607843, b: 0.9607843, a: 1}
  m_PressedColor: {r: 0.78431374, g: 0.78431374, b: 0.78431374, a: 1}
  m_SelectedColor: {r: 0.9607843, g: 0.9607843, b: 0.9607843, a: 1}
  m_DisabledColor: {r: 0.78431374, g: 0.78431374, b: 0.78431374, a: 0.5019608}
  m_ColorMultiplier: 1
  m_FadeDuration: 0.1
m_SpriteState:
  m_HighlightedSprite: {fileID: 0}
  m_PressedSprite: {fileID: 0}
  m_SelectedSprite: {fileID: 0}
  m_DisabledSprite: {fileID: 0}
m_AnimationTriggers:
  m_NormalTrigger: Normal
  m_HighlightedTrigger: Highlighted
  m_PressedTrigger: Pressed
  m_SelectedTrigger: Selected
  m_DisabledTrigger: Disabled
m_Interactable: 1
m_TargetGraphic: {fileID: 1732033236}
m_OnClick:
  m_PersistentCalls:
    m_Calls:
    - m_Target: {fileID: 293984670}
      m_TargetAssemblyTypeName: CallClientHost, Assembly-CSharp
      m_MethodName: CallButton_Click
      m_Mode: 1
      m_Arguments:
        m_ObjectArgument: {fileID: 0}
        m_ObjectArgumentAssemblyTypeName: UnityEngine.Object, UnityEngine
        m_IntArgument: 0
        m_FloatArgument: 0
        m_StringArgument: 
        m_BoolArgument: 0
      m_CallState: 2
--- !u!114 &1732033236
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 1732033233}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3}
m_Name: 
m_EditorClassIdentifier: 
m_Material: {fileID: 0}
m_Color: {r: 1, g: 1, b: 1, a: 1}
m_RaycastTarget: 1
m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0}
m_Maskable: 1
m_OnCullStateChanged:
  m_PersistentCalls:
    m_Calls: []
m_Sprite: {fileID: 10905, guid: 0000000000000000f000000000000000, type: 0}
m_Type: 1
m_PreserveAspect: 0
m_FillCenter: 1
m_FillMethod: 4
m_FillAmount: 1
m_FillClockwise: 1
m_FillOrigin: 0
m_UseSpriteMesh: 0
m_PixelsPerUnitMultiplier: 1
--- !u!222 &1732033237
CanvasRenderer:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 1732033233}
m_CullTransparentMesh: 1
--- !u!1 &1787936406
GameObject:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
serializedVersion: 6
m_Component:
- component: {fileID: 1787936407}
- component: {fileID: 1787936408}
m_Layer: 5
m_Name: Text Area
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!224 &1787936407
RectTransform:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 1787936406}
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
m_LocalPosition: {x: 0, y: 0, z: 0}
m_LocalScale: {x: 1, y: 1, z: 1}
m_ConstrainProportionsScale: 0
m_Children:
- {fileID: 857336306}
- {fileID: 1676708953}
m_Father: {fileID: 963546687}
m_RootOrder: 0
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_AnchorMin: {x: 0, y: 0}
m_AnchorMax: {x: 1, y: 1}
m_AnchoredPosition: {x: 0, y: -0.4999962}
m_SizeDelta: {x: -20, y: -13}
m_Pivot: {x: 0.5, y: 0.5}
--- !u!114 &1787936408
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 1787936406}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: 3312d7739989d2b4e91e6319e9a96d76, type: 3}
m_Name: 
m_EditorClassIdentifier: 
m_Padding: {x: -8, y: -5, z: -8, w: -5}
m_Softness: {x: 0, y: 0}
--- !u!1 &1843906923
GameObject:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
serializedVersion: 6
m_Component:
- component: {fileID: 1843906927}
- component: {fileID: 1843906926}
- component: {fileID: 1843906925}
- component: {fileID: 1843906924}
m_Layer: 5
m_Name: Canvas
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!114 &1843906924
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 1843906923}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: dc42784cf147c0c48a680349fa168899, type: 3}
m_Name: 
m_EditorClassIdentifier: 
m_IgnoreReversedGraphics: 1
m_BlockingObjects: 0
m_BlockingMask:
  serializedVersion: 2
  m_Bits: 4294967295
--- !u!114 &1843906925
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 1843906923}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: 0cd44c1031e13a943bb63640046fad76, type: 3}
m_Name: 
m_EditorClassIdentifier: 
m_UiScaleMode: 0
m_ReferencePixelsPerUnit: 100
m_ScaleFactor: 1
m_ReferenceResolution: {x: 800, y: 600}
m_ScreenMatchMode: 0
m_MatchWidthOrHeight: 0
m_PhysicalUnit: 3
m_FallbackScreenDPI: 96
m_DefaultSpriteDPI: 96
m_DynamicPixelsPerUnit: 1
m_PresetInfoIsWorld: 0
--- !u!223 &1843906926
Canvas:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 1843906923}
m_Enabled: 1
serializedVersion: 3
m_RenderMode: 0
m_Camera: {fileID: 0}
m_PlaneDistance: 100
m_PixelPerfect: 0
m_ReceivesEvents: 1
m_OverrideSorting: 0
m_OverridePixelPerfect: 0
m_SortingBucketNormalizedSize: 0
m_VertexColorAlwaysGammaSpace: 0
m_AdditionalShaderChannelsFlag: 25
m_UpdateRectTransformForStandalone: 0
m_SortingLayerID: 0
m_SortingOrder: 0
m_TargetDisplay: 0
--- !u!224 &1843906927
RectTransform:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 1843906923}
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
m_LocalPosition: {x: 0, y: 0, z: 0}
m_LocalScale: {x: 0, y: 0, z: 0}
m_ConstrainProportionsScale: 0
m_Children:
- {fileID: 963546687}
- {fileID: 1732033234}
- {fileID: 1332239154}
- {fileID: 1184525249}
- {fileID: 1529611527}
m_Father: {fileID: 0}
m_RootOrder: 3
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_AnchorMin: {x: 0, y: 0}
m_AnchorMax: {x: 0, y: 0}
m_AnchoredPosition: {x: 0, y: 0}
m_SizeDelta: {x: 0, y: 0}
m_Pivot: {x: 0, y: 0}
--- !u!1 &1917486033
GameObject:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
serializedVersion: 6
m_Component:
- component: {fileID: 1917486034}
- component: {fileID: 1917486036}
- component: {fileID: 1917486035}
m_Layer: 5
m_Name: Text (TMP)
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!224 &1917486034
RectTransform:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 1917486033}
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
m_LocalPosition: {x: 0, y: 0, z: 0}
m_LocalScale: {x: 1, y: 1, z: 1}
m_ConstrainProportionsScale: 0
m_Children: []
m_Father: {fileID: 1332239154}
m_RootOrder: 0
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_AnchorMin: {x: 0, y: 0}
m_AnchorMax: {x: 1, y: 1}
m_AnchoredPosition: {x: 0, y: 0}
m_SizeDelta: {x: 0, y: 0}
m_Pivot: {x: 0.5, y: 0.5}
--- !u!114 &1917486035
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 1917486033}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: f4688fdb7df04437aeb418b961361dc5, type: 3}
m_Name: 
m_EditorClassIdentifier: 
m_Material: {fileID: 0}
m_Color: {r: 1, g: 1, b: 1, a: 1}
m_RaycastTarget: 1
m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0}
m_Maskable: 1
m_OnCullStateChanged:
  m_PersistentCalls:
    m_Calls: []
m_text: Hang Up
m_isRightToLeft: 0
m_fontAsset: {fileID: 11400000, guid: 8f586378b4e144a9851e7b34d9b748ee, type: 2}
m_sharedMaterial: {fileID: 2180264, guid: 8f586378b4e144a9851e7b34d9b748ee, type: 2}
m_fontSharedMaterials: []
m_fontMaterial: {fileID: 0}
m_fontMaterials: []
m_fontColor32:
  serializedVersion: 2
  rgba: 4281479730
m_fontColor: {r: 0.19607843, g: 0.19607843, b: 0.19607843, a: 1}
m_enableVertexGradient: 0
m_colorMode: 3
m_fontColorGradient:
  topLeft: {r: 1, g: 1, b: 1, a: 1}
  topRight: {r: 1, g: 1, b: 1, a: 1}
  bottomLeft: {r: 1, g: 1, b: 1, a: 1}
  bottomRight: {r: 1, g: 1, b: 1, a: 1}
m_fontColorGradientPreset: {fileID: 0}
m_spriteAsset: {fileID: 0}
m_tintAllSprites: 0
m_StyleSheet: {fileID: 0}
m_TextStyleHashCode: -1183493901
m_overrideHtmlColors: 0
m_faceColor:
  serializedVersion: 2
  rgba: 4294967295
m_fontSize: 24
m_fontSizeBase: 24
m_fontWeight: 400
m_enableAutoSizing: 0
m_fontSizeMin: 18
m_fontSizeMax: 72
m_fontStyle: 0
m_HorizontalAlignment: 2
m_VerticalAlignment: 512
m_textAlignment: 65535
m_characterSpacing: 0
m_wordSpacing: 0
m_lineSpacing: 0
m_lineSpacingMax: 0
m_paragraphSpacing: 0
m_charWidthMaxAdj: 0
m_enableWordWrapping: 1
m_wordWrappingRatios: 0.4
m_overflowMode: 0
m_linkedTextComponent: {fileID: 0}
parentLinkedComponent: {fileID: 0}
m_enableKerning: 1
m_enableExtraPadding: 0
checkPaddingRequired: 0
m_isRichText: 1
m_parseCtrlCharacters: 1
m_isOrthographic: 1
m_isCullingEnabled: 0
m_horizontalMapping: 0
m_verticalMapping: 0
m_uvLineOffset: 0
m_geometrySortingOrder: 0
m_IsTextObjectScaleStatic: 0
m_VertexBufferAutoSizeReduction: 0
m_useMaxVisibleDescender: 1
m_pageToDisplay: 1
m_margin: {x: 0, y: 0, z: 0, w: 0}
m_isUsingLegacyAnimationComponent: 0
m_isVolumetricText: 0
m_hasFontAssetChanged: 0
m_baseMaterial: {fileID: 0}
m_maskOffset: {x: 0, y: 0, z: 0, w: 0}
--- !u!222 &1917486036
CanvasRenderer:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 1917486033}
m_CullTransparentMesh: 1


Hozzon létre egy AppManager.cs nevű szkriptet, és csatolja az AppManager objektumhoz a Unity Editorban. Cserélje le a tartalmat a következő megvalósításra:

using Azure.Communication.Calling.UnityClient;
using System.Runtime.InteropServices.ComTypes;
using System;
using UnityEngine;
using System.Linq;
using UnityEngine.UI;
using UnityEngine.Video;
using TMPro;

/// <summary>
/// A singleton which hosts an Azure Communication calling client. This calling client 
/// is then shared across the application.
/// </summary>

public class AppManager : MonoBehaviour
{
    private CallClient callClient;
    private CallAgent callAgent;
    private DeviceManager deviceManager;
    private Call call;
    private LocalOutgoingAudioStream micStream;

    public string CalleeIdentity { get; set; }

    public TMP_Text callStatus;

    public static AppManager Instance;

    private void Awake()
    {
        // start of new code
        if (Instance != null)
        {
            Destroy(gameObject);
            return;
        }
        // end of new code

        callClient = new CallClient();

        Instance = this;
        DontDestroyOnLoad(gameObject);

        InitCallAgentAndDeviceManagerAsync();
    }

    public async void CallButton_Click()
    {
        // Start a call
    }

    public async void HangupButton_Click()
    {
        // Hang up a call
    }

    private async void OnIncomingCallAsync(object sender, IncomingCallReceivedEventArgs args)
    {
        // Handle incoming call event
    }

    private void OnStateChangedAsync(object sender, PropertyChangedEventArgs args)
    {
        // Handle connected and disconnected state change of a call
    }

    //Used For Updating the UI
    private void Update()
    {
        if (call != null)
        {
            switch (call.State)
            {
                case CallState.Connected:
                    if (callStatus.text != "Connected")
                        callStatus.text = "Connected";
                    break;
                case CallState.Disconnected:
                    if (callStatus.text != "Disconnected")
                        callStatus.text = "Disconnected";
                    break;
            }
        }
    }
}

Az AppManager nevű GameObjectben húzza az újonnan létrehozott szkriptet a szkript összetevőjébe. Húzza az Állapot szöveg objektumot a Hívás állapota szövegmezőbe a hívásállapot felhasználói felületi frissítéseinek engedélyezéséhez.

Objektummodell

A következő táblázat az osztályokat és interfészeket sorolja fel, amelyek az Azure Communication Services Calling SDK néhány fő funkcióját kezelik:

Név Leírás
CallClient Ez CallClient a hívó SDK fő belépési pontja.
CallAgent Ez CallAgent a hívások indítására és kezelésére szolgál.
Call Ez CommunicationCall egy folyamatban lévő hívás kezelésére szolgál.
CallTokenCredential A CallTokenCredential rendszer a jogkivonat hitelesítő adataiként használja a példányosításhoz.CallAgent
CallIdentifier A CallIdentifier felhasználó identitásának ábrázolására szolgál, amely a következő lehetőségek egyike lehet: UserCallIdentifier, PhoneNumberCallIdentifier stb.

Az ügyfél hitelesítése

Inicializáljon egy példányt CallAgent egy felhasználói hozzáférési jogkivonattal, amely lehetővé teszi a hívások indítását és fogadását, és opcionálisan beszerezhet egy DeviceManager-példányt az ügyféleszköz-konfigurációk lekérdezéséhez.

A kódban cserélje le <AUTHENTICATION_TOKEN> a felhasználói hozzáférési jogkivonatot. Ha még nem rendelkezik jogkivonattal, tekintse meg a felhasználói hozzáférési jogkivonat dokumentációját.

Adjon hozzá InitCallAgentAndDeviceManagerAsync függvényt, amely elindítja az SDK-t. Ez a segéd testre szabható az alkalmazás követelményeinek megfelelően.

private async void InitCallAgentAndDeviceManagerAsync()
{

    deviceManager = await callClient.GetDeviceManager();

    var tokenCredential = new CallTokenCredential(<AUTHENTICATION_TOKEN>);

    var callAgentOptions = new CallAgentOptions()
    {
        DisplayName = $"{Environment.MachineName}/{Environment.UserName}",
    };

    callAgent = await callClient.CreateCallAgent(tokenCredential, callAgentOptions);
    callAgent.IncomingCallReceived += OnIncomingCallAsync;
}

A hívás indítása

StartCallOptions Az objektum lekérése CallAgent után az Azure Communication Services-hívás kezdeményezhető:

public async void CallButton_Click()
{
    var startCallOptions = new StartCallOptions();
    startCallOptions = new StartCallOptions();

    var callee = new UserCallIdentifier(CalleeIdentity);

    call = await callAgent.StartCallAsync(new CallIdentifier[] { callee }, startCallOptions);
    // Set up handler for call StateChanged event
    call.StateChanged += OnStateChangedAsync;
}

Hívás befejezése

A gomb kattintásával fejezd be az Hang up aktuális hívást. Adja hozzá az implementációt a HangupButton_Click a hívás befejezéséhez, és állítsa le az előnézetet és a videostreameket.

public async void HangupButton_Click()
{
    if (call != null)
    {
        try
        {
            await call.HangUpAsync(new HangUpOptions() { ForEveryone = false });
        }
        catch (Exception ex)
        {
        }
    }
}

Bejövő hívás elfogadása

IncomingCallReceived az event sink be van állítva az SDK bootstrap segédjében InitCallAgentAndDeviceManagerAsync.

callAgent.IncomingCallReceived += OnIncomingCallAsync;

Az alkalmazás konfigurálhatja a bejövő hívás fogadásának módját, például a video- és hangstreamek típusait.

private async void OnIncomingCallAsync(object sender, IncomingCallReceivedEventArgs args)
{
    var incomingCall = args.IncomingCall;

    var acceptCallOptions = new AcceptCallOptions()
    {
        IncomingVideoOptions = new IncomingVideoOptions()
        {
            StreamKind = VideoStreamKind.RemoteIncoming
        }
    };

    call = await incomingCall.AcceptAsync(acceptCallOptions);
    // Set up handler for incoming call StateChanged event
    call.StateChanged += OnStateChangedAsync;
}

Állapotváltozási esemény figyelése és válasza

StateChanged az objektum eseménye Call akkor aktiválódik, ha egy folyamatban lévő hívás tranzakcióit egyik állapotból a másikba hívja. Az alkalmazás lehetőséget kínál arra, hogy tükrözze a felhasználói felületen bekövetkező állapotváltozásokat, vagy üzleti logikákat szúrjon be.

private async void OnStateChangedAsync(object sender, PropertyChangedEventArgs args)
{
    var call = sender as Call;

    if (call != null)
    {
        var state = call.State;
        switch (state)
        {
            case CallState.Connected:
                {
                    await call.StartAudioAsync(micStream);

                    break;
                }
            case CallState.Disconnected:
                {
                    call.StateChanged -= OnStateChangedAsync;

                    call.Dispose();

                    break;
                }
            default: break;
        }
    }
}

A kód futtatása

A kódot létrehozhatja és futtathatja a Unity-szerkesztőben vagy a Unityt használó eszközökön.

Kimenő hívást úgy kezdeményezhet, hogy megad egy felhasználói azonosítót a szövegmezőben, és rákattint a Start Call/Join gombra. A hívás 8:echo123 egy echo robottal köti össze, ez a funkció kiválóan alkalmas a hangeszközök működésének ellenőrzésére.

Screenshot showing running the Unity quickstart app.

Az erőforrások eltávolítása

Ha törölni és eltávolítani szeretne egy Communication Services-előfizetést, törölheti az erőforrást vagy az erőforráscsoportot. Az erőforráscsoport törlése a hozzá társított egyéb erőforrásokat is törli. További információ az erőforrások tisztításáról.

Következő lépések

További információért tekintse át az alábbi cikkeket:

  • Tekintse meg a hívó főhős mintáját
  • A felhasználói felületi kódtár használatának első lépései
  • Tudnivalók az SDK-képességek hívásáról
  • További információ a hívás működéséről