Verwalten von Anrufen

Lernen Sie, wie Sie Anrufe mit den Azure Communication Services SDKS verwalten können. Wir erfahren, wie Sie Anrufe tätigen sowie ihre Teilnehmer und Eigenschaften verwalten.

Voraussetzungen

Installieren des SDK

Verwenden Sie den Befehl npm install, um das Azure Communication Services Calling SDK sowie allgemeine SDKs für JavaScript zu installieren.

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

Initialisieren erforderlicher Objekte

Eine CallClient-Instanz ist für die meisten Anrufvorgänge erforderlich. Lassen Sie uns eine neue CallClient-Instanz erstellen. Sie können sie mit benutzerdefinierten Optionen wie eine Protokollierungsinstanz konfigurieren.

Wenn Sie eine CallClient-Instanz verwenden, können Sie eine CallAgent-Instanz erstellen, indem Sie die Methode createCallAgent für die CallClient-Instanz aufrufen. Durch diese Methode wird ein CallAgent-Instanzobjekt asynchron zurückgegeben.

Die Methode createCallAgent verwendet CommunicationTokenCredential als Argument, welches ein Benutzerzugriffstoken akzeptiert.

Sie können die Methode getDeviceManager für die Instanz CallClient verwenden, um auf deviceManager zuzugreifen.

const { CallClient } = require('@azure/communication-calling');
const { AzureCommunicationTokenCredential} = require('@azure/communication-common');
const { AzureLogger, setLogLevel } = require("@azure/logger");

// Set the logger's log level
setLogLevel('verbose');

// Redirect log output to wherever desired. To console, file, buffer, REST API, etc...
AzureLogger.log = (...args) => {
    console.log(...args); // Redirect log output to console
};

const userToken = '<USER_TOKEN>';
callClient = new CallClient(options);
const tokenCredential = new AzureCommunicationTokenCredential(userToken);
const callAgent = await callClient.createCallAgent(tokenCredential, {displayName: 'optional Azure Communication Services user name'});
const deviceManager = await callClient.getDeviceManager()

Tätigen eines Anrufs

Um einen Anruf zu erstellen und zu starten, verwenden Sie eine der APIs für callAgent, und geben Sie einen Benutzer an, den Sie über das Communication Services Identity SDK erstellt haben.

Erstellung und Start des Anrufs erfolgen synchron. Die call-Instanz ermöglicht Ihnen das Abonnieren von Anrufereignissen.

Tätigen eines 1:n-Anrufs an einen Benutzer oder ein Telefonfestnetz

Um einen anderen Communication Services-Benutzer anzurufen, verwenden Sie die Methode startCall für callAgent, und übergeben Sie den CommunicationUserIdentifier, den Sie mit der Communication Services-Verwaltungsbibliothek erstellt haben.

Verwenden Sie für einen 1:1-Anruf bei einem Benutzer den folgenden Code:

const userCallee = { communicationUserId: '<ACS_USER_ID>' }
const oneToOneCall = callAgent.startCall([userCallee]);

Um einen Anruf an ein PSTN (Public Switched Telephone Network) zu tätigen, verwenden Sie die Methode startCall für callAgent, und übergeben Sie den PhoneNumberIdentifier des Empfängers. Die Communication Services-Ressource muss so konfiguriert werden, dass Anrufe über das Telefonfestnetz möglich sind.

Wenn Sie eine Telefonfestnetznummer anrufen, geben Sie Ihre alternative Anrufer-ID an. Eine alternative Anrufer-ID bezieht sich auf eine Telefonnummer (basierend auf dem E.164-Standard), die den Anrufer in einem PSTN-Anruf identifiziert. Dies ist die Telefonnummer, die dem Anrufempfänger bei einem eingehenden Anruf angezeigt wird.

Hinweis

Anrufe über das Telefonfestnetz sind derzeit in der Phase „Private Vorschau“. Um auf diese Funktion zuzugreifen, bewerben Sie sich für das Early Adopter-Programm.

Verwenden Sie für einen 1:1-Anruf einer PSTN-Nummer den folgenden Code:

const pstnCallee = { phoneNumber: '<ACS_USER_ID>' }
const alternateCallerId = {phoneNumber: '<ALTERNATE_CALLER_ID>'};
const oneToOneCall = callAgent.startCall([pstnCallee], {alternateCallerId});

Verwenden Sie für einen 1:N-Aufruf eines Benutzers und einer PSTN-Nummer den folgenden Code:

const userCallee = { communicationUserId: '<ACS_USER_ID>' }
const pstnCallee = { phoneNumber: '<PHONE_NUMBER>'};
const alternateCallerId = {phoneNumber: '<ALTERNATE_CALLER_ID>'};
const groupCall = callAgent.startCall([userCallee, pstnCallee], {alternateCallerId});

Teilnehmen an einem Gruppenanruf

Hinweis

Der groupId-Parameter wird als Systemmetadaten angesehen und kann von Microsoft für Vorgänge verwendet werden, die zum Ausführen des Systems erforderlich sind. Fügen Sie keine personenbezogenen Daten in den groupId-Wert ein. Microsoft behandelt diesen Parameter nicht wie personenbezogene Daten. Seine Inhalte sind möglicherweise für Microsoft-Mitarbeiter sichtbar oder werden langfristig gespeichert.

Der groupId-Parameter erfordert, dass Daten im GUID-Format vorliegen. Es wird empfohlen, zufällig generierte GUIDs zu verwenden, die in Ihren Systemen nicht als personenbezogene Daten betrachtet werden.

Um einen neuen Gruppenanruf zu starten oder an einem aktuellen Gruppenanruf teilzunehmen, müssen Sie die Methode join aufrufen und ein Objekt mit einer groupId-Eigenschaft übergeben. Der groupId-Wert muss eine GUID sein.

const context = { groupId: '<GUID>'};
const call = callAgent.join(context);

Empfangen eines eingehenden Anrufs

Die callAgent-Instanz gibt das Ereignis incomingCall aus, wenn die angemeldete Identität einen eingehenden Anruf empfängt. Um auf dieses Ereignis zu lauschen, abonnieren Sie es mithilfe einer der folgenden Optionen:

const incomingCallHandler = async (args: { incomingCall: IncomingCall }) => {
    const incomingCall = args.incomingCall;	

    // Get incoming call ID
    var incomingCallId = incomingCall.id

    // Get information about this Call. This API is provided as a preview for developers
    // and may change based on feedback that we receive. Do not use this API in a production environment.
    // To use this api please use 'beta' release of Azure Communication Services Calling Web SDK
    var callInfo = incomingCall.info;

    // Get information about caller
    var callerInfo = incomingCall.callerInfo

    // Accept the call
    var call = await incomingCall.accept();

    // Reject the call
    incomingCall.reject();

    // Subscribe to callEnded event and get the call end reason
     incomingCall.on('callEnded', args => {
        console.log(args.callEndReason);
    });

    // callEndReason is also a property of IncomingCall
    var callEndReason = incomingCall.callEndReason;
};
callAgentInstance.on('incomingCall', incomingCallHandler);

Das incomingCall-Ereignis umfasst eine incomingCall-Instanz, die Sie akzeptieren oder ablehnen können.

Wenn das angegebene Videokameragerät von einem anderen Prozess verwendet wird oder im System deaktiviert ist, wird der Anruf mit deaktiviertem Video gestartet und eine Anrufdiagnose „cameraStartFailed: true“ ausgelöst, wenn ein Anruf mit aktiviertem Video gestartet/beigetreten/angenommen wird.

Stummschalten und Aufheben der Stummschaltung

Zum Stummschalten oder Aufheben der Stummschaltung des lokalen Endpunkts können Sie die asynchronen APIs mute und unmute verwenden:

//mute local device (microphone / sent audio)
await call.mute();

//unmute local device (microphone / sent audio)
await call.unmute();

Stummschalten und Aufheben der Stummschaltung eingehender Audiodaten

Das Stummschalten eingehender Audio legt die Anruflautstärke auf 0 fest. Zum Stummschalten oder Aufheben der Stummschaltung des eingehenden Tons können Sie die muteIncomingAudio und unmuteIncomingAudio asynchronen APIs verwenden:

//mute local device (speaker)
await call.muteIncomingAudio();

//unmute local device (speaker)
await call.unmuteIncomingAudio();

Wenn eingehende Audio stummgeschaltet wird, empfängt der Teilnehmer weiterhin den Anrufaudio (Audio des Remoteteilnehmers). Die Anrufaudio wird nicht in den Lautsprechern angezeigt, und der Teilnehmer kann erst hören, wenn "call.unmuteIncomingAudio()" aufgerufen wird. Wir können jedoch Filter auf Anrufaudio anwenden und das gefilterte Audio wiedergeben.

Verwalten von Remoteteilnehmern

Alle Remoteteilnehmer werden durch den Typ RemoteParticipant dargestellt und sind über die remoteParticipants-Sammlung für eine Anrufinstanz verfügbar.

Auflisten der Teilnehmer an einem Anruf

Die remoteParticipants-Sammlung gibt eine Liste der Remoteteilnehmer eines Anrufs zurück:

call.remoteParticipants; // [remoteParticipant, remoteParticipant....]

Hinzufügen eines Teilnehmers zu einem Anruf

Wenn Sie einem Anruf einen Teilnehmer (einen Benutzer oder eine Telefonnummer) hinzufügen möchten, können Sie addParticipant verwenden. Geben Sie einen der Identifier-Typen an. Dadurch wird die Instanz remoteParticipant synchron zurückgegeben. Das Ereignis remoteParticipantsUpdated des Anrufs wird ausgelöst, wenn ein Teilnehmer erfolgreich dem Aufruf hinzugefügt wurde.

const userIdentifier = { communicationUserId: '<ACS_USER_ID>' };
const pstnIdentifier = { phoneNumber: '<PHONE_NUMBER>' }
const remoteParticipant = call.addParticipant(userIdentifier);
const remoteParticipant = call.addParticipant(pstnIdentifier, {alternateCallerId: '<ALTERNATE_CALLER_ID>'});

Entfernen eines Teilnehmers aus einem Anruf

Um einen Teilnehmer (einen Benutzer oder eine Telefonnummer) aus einem Anruf zu entfernen, können Sie removeParticipant aufrufen. Sie müssen einen der Identifier-Typen übergeben. Diese Methode wird asynchron aufgelöst, nachdem der Teilnehmer aus dem Anruf entfernt wurde. Der Teilnehmer wird auch aus der remoteParticipants-Sammlung entfernt.

const userIdentifier = { communicationUserId: '<ACS_USER_ID>' };
const pstnIdentifier = { phoneNumber: '<PHONE_NUMBER>' }
await call.removeParticipant(userIdentifier);
await call.removeParticipant(pstnIdentifier);

Zugreifen auf Eigenschaften von Remoteteilnehmern

Remoteteilnehmern ist ein Satz von Eigenschaften und Sammlungen zugeordnet:

  • CommunicationIdentifier: Ruft den Bezeichner eines Remoteteilnehmers ab. „Identity“ ist einer der CommunicationIdentifier-Typen:

    const identifier = remoteParticipant.identifier;
    

Mögliche CommunicationIdentifier-Typen:

  • { communicationUserId: '<ACS_USER_ID'> }: Objekt, das den Azure Communication Services-Benutzer darstellt.

  • { phoneNumber: '<E.164>' }: Objekt, das die Telefonnummer im E.164-Format darstellt.

  • { microsoftTeamsUserId: '<TEAMS_USER_ID>', isAnonymous?: boolean; cloud?: "public" | "dod" | "gcch" }: Objekt, das den Teams-Benutzer darstellt.

  • { id: string }: Objekt, das den Bezeichner darstellt, der keinem der anderen Bezeichnertypen entspricht.

  • state: Ruft den Zustand eines Remoteteilnehmers ab.

    const state = remoteParticipant.state;
    

Mögliche Zustände:

  • Idle: Anfangszustand.

  • Connecting: Übergangszustand, während sich der Teilnehmer mit dem Anruf verbindet.

  • Ringing: Für den Teilnehmeranruf ertönt ein Klingeln.

  • Connected: Der Teilnehmer ist mit dem Anruf verbunden.

  • Hold: Der Teilnehmer wird gehalten.

  • EarlyMedia: Ansage, die vor dem Verbinden eines Teilnehmers mit dem Anruf wiedergegeben wird.

  • InLobby: Gibt an, dass sich der Remoteteilnehmer im Wartebereich befindet.

  • Disconnected: Abschließender Zustand. Der Teilnehmer wird vom Anruf getrennt. Wenn der Remoteteilnehmer seine Netzwerkkonnektivität verliert, ändert sich der Zustand nach zwei Minuten in Disconnected.

  • callEndReason: Um zu erfahren, warum ein Teilnehmer den Anruf verlassen hat, prüfen Sie die Eigenschaft callEndReason:

    const callEndReason = remoteParticipant.callEndReason;
    const callEndReasonCode = callEndReason.code // (number) code associated with the reason
    const callEndReasonSubCode = callEndReason.subCode // (number) subCode associated with the reason
    

    Anmerkung:

    • Diese Eigenschaft wird nur festgelegt, wenn sie einen Remoteteilnehmer über die Call.addParticipant()-API hinzufügen und der Remoteteilnehmer beispielsweise abgelehnt wird.
    • Wenn beispielsweise UserC von UserB gekickt wird, sieht UserA nicht, dass dieser Flag für UserC gesetzt wird. UserA bekommt von Festlegen der callEndReason-Eigenschaft von UserC also überhaupt nicht mit.
  • isMuted-Status: Um herauszufinden, ob ein Remoteteilnehmer stummgeschaltet wurde, überprüfen Sie die Eigenschaft isMuted. Er gibt Boolean zurück.

    const isMuted = remoteParticipant.isMuted;
    
  • isSpeaking-Status: Um herauszufinden, ob ein Remoteteilnehmer gerade spricht, überprüfen Sie die Eigenschaft isSpeaking. Er gibt Boolean zurück.

    const isSpeaking = remoteParticipant.isSpeaking;
    
  • videoStreams: Um alle Videostreams zu prüfen, die ein bestimmter Teilnehmer im Rahmen dieses Anrufs sendet, sehen Sie sich die videoStreams-Sammlung an. Sie enthält RemoteVideoStream-Objekte.

    const videoStreams = remoteParticipant.videoStreams; // [RemoteVideoStream, ...]
    
  • displayName: Um den Anzeigenamen für diesen Remoteteilnehmer zu erhalten, überprüfen Sie die zurückgegebene Zeichenfolge der Eigenschaft displayName.

    const displayName = remoteParticipant.displayName;
    

Überprüfen von Anrufeigenschaften

Abrufen der eindeutigen ID (Zeichenfolge) für einen Anruf:

const callId: string = call.id;

Abrufen von Informationen zum Anruf:

Hinweis

Diese API wird als Vorschau für Entwickler bereitgestellt. Je nachdem, welches Feedback wir dazu erhalten, werden möglicherweise Änderungen vorgenommen. Verwenden Sie diese API nicht in einer Produktionsumgebung. Verwenden Sie zum Verwenden dieser API die Betaversion des Azure Communication Services Calling Web SDK.

const callInfo = call.info;

Erhalten Sie Informationen zu anderen Anrufteilnehmern, indem Sie sich die remoteParticipants-Sammlung für die call-Instanz ansehen:

const remoteParticipants = call.remoteParticipants;

Identifizieren des Anrufers eines eingehenden Anrufs:

const callerIdentity = call.callerInfo.identifier;

identifier ist einer der CommunicationIdentifier-Typen.

Abrufen des Anrufzustands:

const callState = call.state;

Gibt eine Zeichenfolge zurück, die den aktuellen Zustand eines Anrufs darstellt:

  • None: anfänglicher Anrufzustand.
  • Connecting: anfänglicher Übergangszustand, wenn ein Anruf getätigt oder angenommen wird.
  • Ringing: Weist bei einem ausgehenden Anruf darauf hin, dass für den Anruf Remoteteilnehmer ein Klingeln ertönt. Auf deren Seite lautet der Status Incoming.
  • EarlyMedia: Gibt einen Zustand an, in dem vor dem Verbinden des Anrufs eine Ansage wiedergegeben wird.
  • Connected: Gibt an, dass der Anruf verbunden wurde.
  • LocalHold: Gibt an, dass der Anruf von einem lokalen Teilnehmer gehalten wird. Zwischen dem lokalen Endpunkt und den Remoteteilnehmern werden keine Medien übertragen.
  • RemoteHold: Gibt an, dass der Anruf von einem Remoteteilnehmer gehalten wird. Zwischen dem lokalen Endpunkt und den Remoteteilnehmern werden keine Medien übertragen.
  • InLobby: Gibt an, dass sich der Benutzer im Wartebereich befindet.
  • Disconnecting: Übergangszustand, bevor der Anruf in einen Disconnected-Zustand wechselt.
  • Disconnected: Abschließender Anrufzustand. Wenn die Netzwerkverbindung unterbrochen wird, ändert sich der Zustand nach zwei Minuten in Disconnected.

Ermitteln Sie, warum der Anruf beendet wurde, indem Sie die Eigenschaft callEndReason überprüfen:

const callEndReason = call.callEndReason;
const callEndReasonCode = callEndReason.code // (number) code associated with the reason
const callEndReasonSubCode = callEndReason.subCode // (number) subCode associated with the reason

Erfahren Sie, ob der aktuelle Anruf ein- oder ausgeht, indem Sie die Eigenschaft direction überprüfen. Er gibt CallDirection zurück.

const isIncoming = call.direction == 'Incoming';
const isOutgoing = call.direction == 'Outgoing';

Stellen Sie fest, ob das aktuelle Mikrofon stummgeschaltet ist. Er gibt Boolean zurück.

const muted = call.isMuted;

Überprüfen Sie, ob das aktuelle eingehende Audio (Lautsprecher) stummgeschaltet ist. Er gibt Boolean zurück.

const incomingAudioMuted = call._isIncomingAudioMuted;

Ermitteln Sie, ob der Bildschirmübertragungsstream von einem bestimmten Endpunkt aus gesendet wird, indem Sie die Eigenschaft isScreenSharingOn überprüfen. Er gibt Boolean zurück.

const isScreenSharingOn = call.isScreenSharingOn;

Untersuchen Sie aktive Videostreams, indem Sie sich die localVideoStreams-Sammlung ansehen. Sie gibt LocalVideoStream-Objekte zurück.

const localVideoStreams = call.localVideoStreams;

Installieren des SDKs

Wählen Sie Ihre Datei „build.gradle“ auf Projektebene aus, und stellen Sie sicher, dass Sie mavenCentral() zur Liste der Repositorys unter buildscript und allprojects hinzufügen.

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

Fügen Sie dann in der Datei „build.gradle“ auf Modulebene die folgenden Zeilen zum Abschnitt „dependencies“ hinzu.

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

Initialisieren der erforderlichen Objekte

Zum Erstellen einer CallAgent-Instanz müssen Sie die createCallAgent-Methode für eine CallClient-Instanz aufzurufen. Dadurch wird ein CallAgent-Instanzobjekt asynchron zurückgegeben. Die createCallAgent-Methode verwendet CommunicationUserCredential als Argument, womit ein createCallAgent gekapselt wird. Für den Zugriff auf DeviceManager muss zuerst eine CallAgent-Instanz erstellt werden. Anschließend können Sie mit der CallClient.getDeviceManager-Methode DeviceManager abrufen.

String userToken = '<user token>';
CallClient callClient = new CallClient();
CommunicationTokenCredential tokenCredential = new CommunicationTokenCredential(userToken);
android.content.Context appContext = this.getApplicationContext(); // From within an Activity for instance
CallAgent callAgent = callClient.createCallAgent(appContext, tokenCredential).get();
DeviceManager deviceManager = callClient.getDeviceManager(appContext).get();

Zum Festlegen eines Anzeigenamens für den Anrufer verwenden Sie diese alternative Methode:

String userToken = '<user token>';
CallClient callClient = new CallClient();
CommunicationTokenCredential tokenCredential = new CommunicationTokenCredential(userToken);
android.content.Context appContext = this.getApplicationContext(); // From within an Activity for instance
CallAgentOptions callAgentOptions = new CallAgentOptions();
callAgentOptions.setDisplayName("Alice Bob");
DeviceManager deviceManager = callClient.getDeviceManager(appContext).get();
CallAgent callAgent = callClient.createCallAgent(appContext, tokenCredential, callAgentOptions).get();

Tätigen eines Anrufs

Um einen Anruf zu erstellen und zu starten, müssen Sie die CallAgent.startCall()-Methode aufrufen und den Identifier des/der Angerufenen angeben. Um an einem Gruppenanruf teilzunehmen, müssen Sie die CallAgent.join()-Methode aufrufen und die groupId angeben. Gruppen-IDs müssen das GUID- oder UUID-Format haben.

Erstellung und Start des Anrufs erfolgen synchron. Die Anrufinstanz ermöglicht Ihnen das Abonnieren aller Ereignisse im Rahmen des Anrufs.

Tätigen eines 1:1-Anrufs eines Benutzers

Um einen Anruf eines anderen Communication Services-Benutzers zu tätigen, rufen Sie die call-Methode für callAgent auf und übergeben ein Objekt mit communicationUserId-Schlüssel.

StartCallOptions startCallOptions = new StartCallOptions();
Context appContext = this.getApplicationContext();
CommunicationUserIdentifier acsUserId = new CommunicationUserIdentifier(<USER_ID>);
CommunicationUserIdentifier participants[] = new CommunicationUserIdentifier[]{ acsUserId };
call oneToOneCall = callAgent.startCall(appContext, participants, startCallOptions);

1:n-Anruf mit Benutzern und Festnetznummern

Warnung

Zurzeit sind Anrufe über das Telefonfestnetz nicht möglich.

Für einen 1:n-Anruf eines Benutzers und einer Festnetznummer müssen Sie die Telefonnummer des Angerufenen angeben. Die Communication Services-Ressource muss so konfiguriert sein, dass Anrufe über das Telefonfestnetz möglich sind:

CommunicationUserIdentifier acsUser1 = new CommunicationUserIdentifier(<USER_ID>);
PhoneNumberIdentifier acsUser2 = new PhoneNumberIdentifier("<PHONE_NUMBER>");
CommunicationIdentifier participants[] = new CommunicationIdentifier[]{ acsUser1, acsUser2 };
StartCallOptions startCallOptions = new StartCallOptions();
Context appContext = this.getApplicationContext();
Call groupCall = callAgent.startCall(participants, startCallOptions);

Annehmen eines Anrufs

Zum Annehmen eines Anrufs rufen Sie die Methode „accept“ für ein Anrufobjekt auf.

Context appContext = this.getApplicationContext();
IncomingCall incomingCall = retrieveIncomingCall();
Call call = incomingCall.accept(context).get();

Annehmen eines Anrufs mit eingeschalteter Videokamera:

Context appContext = this.getApplicationContext();
IncomingCall incomingCall = retrieveIncomingCall();
AcceptCallOptions acceptCallOptions = new AcceptCallOptions();
VideoDeviceInfo desiredCamera = callClient.getDeviceManager().get().getCameraList().get(0);
acceptCallOptions.setVideoOptions(new VideoOptions(new LocalVideoStream(desiredCamera, appContext)));
Call call = incomingCall.accept(context, acceptCallOptions).get();

Der eingehende Anruf kann durch Abonnieren des onIncomingCall-Ereignisses auf dem callAgent-Objekt abgerufen werden:

// Assuming "callAgent" is an instance property obtained by calling the 'createCallAgent' method on CallClient instance 
public Call retrieveIncomingCall() {
    IncomingCall incomingCall;
    callAgent.addOnIncomingCallListener(new IncomingCallListener() {
        void onIncomingCall(IncomingCall inboundCall) {
            // Look for incoming call
            incomingCall = inboundCall;
        }
    });
    return incomingCall;
}

Teilnehmen an einem Gruppenanruf

Um einen neuen Gruppenanruf zu starten oder an einem laufenden Gruppenanruf teilzunehmen, müssen Sie die „join“-Methode aufrufen und ein Objekt mit einer groupId-Eigenschaft übergeben. Der Wert muss eine GUID sein.

Context appContext = this.getApplicationContext();
GroupCallLocator groupCallLocator = new GroupCallLocator("<GUID>");
JoinCallOptions joinCallOptions = new JoinCallOptions();

call = callAgent.join(context, groupCallLocator, joinCallOptions);

Anrufeigenschaften

Ruft die eindeutige ID für diesen Anruf ab:

String callId = call.getId();

Um mehr über andere Anrufteilnehmer zu erfahren, sehen Sie sich die remoteParticipant-Sammlung für die call-Instanz an:

List<RemoteParticipant> remoteParticipants = call.getRemoteParticipants();

Die Identität des Anrufers bei einem eingehenden Anruf:

CommunicationIdentifier callerId = call.getCallerInfo().getIdentifier();

Ruft den Zustand des Anrufs ab:

CallState callState = call.getState();

Gibt eine Zeichenfolge zurück, die den aktuellen Zustand eines Anrufs darstellt:

  • „NONE“: ursprünglicher Anrufzustand
  • „EARLY_MEDIA“: gibt einen Zustand an, bei dem eine Ansage wiedergegeben wird, bevor der Anruf verbunden wird
  • „CONNECTING“: anfänglicher Übergangszustand, sobald ein Anruf getätigt oder angenommen wird
  • „RINGING“: für einen ausgehenden Anruf; gibt an, dass für den Anruf bei Remoteteilnehmern ein Klingeln ertönt
  • „CONNECTED“: der Anruf wurde verbunden
  • „LOCAL_HOLD“: Der Anruf wird vom lokalen Teilnehmer gehalten; es werden keine Medien zwischen lokalem Endpunkt und Remoteteilnehmern übertragen.
  • „REMOTE_HOLD“: Der Anruf wird von einem Remoteteilnehmer gehalten; es werden keine Medien zwischen lokalem Endpunkt und Remoteteilnehmern übertragen.
  • „DISCONNECTING“: Übergangsstatus, ehe der Anruf in den Zustand „Disconnected“ wechselt
  • „DISCONNECTED“: der Endzustand des Anrufs
  • „IN_LOBBY“: im Gespräch für eine Teams-Besprechungsinteroperabilität

Um zu erfahren, warum ein Anruf beendet wurde, überprüfen Sie die callEndReason-Eigenschaft. Sie enthält Code/Subcode:

CallEndReason callEndReason = call.getCallEndReason();
int code = callEndReason.getCode();
int subCode = callEndReason.getSubCode();

Um festzustellen, ob der aktuelle Anruf ein- oder ausgehend ist, untersuchen Sie die callDirection-Eigenschaft:

CallDirection callDirection = call.getCallDirection(); 
// callDirection == CallDirection.INCOMING for incoming call
// callDirection == CallDirection.OUTGOING for outgoing call

Um festzustellen, ob das aktuelle Mikrofon stummgeschaltet ist, prüfen Sie die muted-Eigenschaft:

boolean muted = call.isMuted();

Um aktive Videostreams zu prüfen, sehen Sie sich die localVideoStreams-Sammlung an:

List<LocalVideoStream> localVideoStreams = call.getLocalVideoStreams();

Stummschalten und Aufheben der Stummschaltung

Zum Stummschalten oder Aufheben der Stummschaltung des lokalen Endpunkts können Sie die asynchronen APIs mute und unmute verwenden:

Context appContext = this.getApplicationContext();
call.mute(appContext).get();
call.unmute(appContext).get();

Ändern der Lautstärke des Anrufs

Während eines Anrufs sollten die Lautstärketasten des Telefons dem Benutzer die Möglichkeit geben, die Anruflautstärke zu ändern. Dies geschieht mithilfe der Methode setVolumeControlStream mit dem Streamtyp AudioManager.STREAM_VOICE_CALL für die Aktivität, bei der der Aufruf getätigt wird. Damit können Sie mit den Hardwarelautstärketasten die Lautstärke des Anrufs ändern (gekennzeichnet durch ein Telefonsymbol oder etwas Ähnliches auf dem Lautstärkeregler) und verhindern, dass Sie die Lautstärke für andere Klangprofile wie Alarme, Medien oder die systemweite Lautstärke ändern. Weitere Informationen finden Sie unter Behandeln von Änderungen an der Audioausgabe | Android-Entwickler.

@Override
protected void onCreate(Bundle savedInstanceState) {
    ...
    setVolumeControlStream(AudioManager.STREAM_VOICE_CALL);
}

Verwaltung von Remoteteilnehmern

Alle Remoteteilnehmer werden durch den Typ RemoteParticipant dargestellt und sind über die remoteParticipants-Sammlung für eine Anrufinstanz verfügbar.

Auflisten der Teilnehmer an einem Anruf

Die remoteParticipants-Sammlung gibt eine Liste der Remoteteilnehmer an einem angegebenen Anruf zurück:

List<RemoteParticipant> remoteParticipants = call.getRemoteParticipants(); // [remoteParticipant, remoteParticipant....]

Hinzufügen eines Teilnehmers zu einem Anruf

Um einen Teilnehmer einem Anruf hinzuzufügen (entweder als Benutzer oder Telefonnummer), können Sie addParticipant aufrufen. Dadurch wird die Instanz des Remoteteilnehmers synchron zurückgegeben.

const acsUser = new CommunicationUserIdentifier("<acs user id>");
const acsPhone = new PhoneNumberIdentifier("<phone number>");
RemoteParticipant remoteParticipant1 = call.addParticipant(acsUser);
AddPhoneNumberOptions addPhoneNumberOptions = new AddPhoneNumberOptions(new PhoneNumberIdentifier("<alternate phone number>"));
RemoteParticipant remoteParticipant2 = call.addParticipant(acsPhone, addPhoneNumberOptions);

Entfernen eines Teilnehmers aus einem Anruf

Um einen Teilnehmer aus einem Anruf zu entfernen (entweder als Benutzer oder Telefonnummer), können Sie removeParticipant aufrufen. Dieser Vorgang wird asynchron aufgelöst, sobald der Teilnehmer aus dem Anruf entfernt wurde. Der Teilnehmer wird auch aus der remoteParticipants-Sammlung entfernt.

RemoteParticipant acsUserRemoteParticipant = call.getParticipants().get(0);
RemoteParticipant acsPhoneRemoteParticipant = call.getParticipants().get(1);
call.removeParticipant(acsUserRemoteParticipant).get();
call.removeParticipant(acsPhoneRemoteParticipant).get();

Eigenschaften von Remoteteilnehmern

Einem Remoteteilnehmer sind eine Reihe von Eigenschaften und Sammlungen zugeordnet:

  • Ruft den Bezeichner dieses Remoteteilnehmers ab. „Identity“ ist einer der „Identifier“-Typen

    CommunicationIdentifier participantIdentifier = remoteParticipant.getIdentifier();
    
  • Ruft den Zustand dieses Remoteteilnehmers ab.

    ParticipantState state = remoteParticipant.getState();
    

Folgende Werte sind hierfür möglich:

  • „IDLE“: Anfangszustand

  • „EARLY_MEDIA“: Ansage wird wiedergegeben, bevor der Teilnehmer mit dem Anruf verbunden ist

  • „RINGING“: Der Teilnehmeranruf klingelt.

  • „CONNECTING“: Übergangszustand, während sich der Teilnehmer mit dem Anruf verbindet

  • „CONNECTED“: Teilnehmer ist mit dem Anruf verbunden

  • „HOLD“: Teilnehmer wird gehalten

  • „IN_LOBBY“: Der Teilnehmer wartet im Wartebereich darauf, zugelassen zu werden. Wird derzeit nur in Teams-Interoperabilitätsszenarien verwendet.

  • „DISCONNECTED“: In diesem Endzustand wird der Teilnehmer vom Anruf getrennt.

  • Um zu erfahren, warum ein Teilnehmer den Anruf verlassen hat, prüfen Sie die callEndReason-Eigenschaft:

    CallEndReason callEndReason = remoteParticipant.getCallEndReason();
    
  • Um zu prüfen, ob dieser Remoteteilnehmer stummgeschaltet ist oder nicht, prüfen Sie die isMuted-Eigenschaft:

    boolean isParticipantMuted = remoteParticipant.isMuted();
    
  • Um zu prüfen, ob dieser Remoteteilnehmer spricht oder nicht, prüfen Sie die isSpeaking-Eigenschaft:

    boolean isParticipantSpeaking = remoteParticipant.isSpeaking();
    
  • Um alle Videostreams zu prüfen, die ein bestimmter Teilnehmer im Rahmen dieses Anrufs sendet, sehen Sie sich die videoStreams-Sammlung an:

    List<RemoteVideoStream> videoStreams = remoteParticipant.getVideoStreams(); // [RemoteVideoStream, RemoteVideoStream, ...]
    

Verwenden von Vordergrunddiensten

Wenn Sie einen für Benutzer sichtbaren Task auch dann ausführen möchten, wenn Ihre Anwendung im Hintergrund ausgeführt wird, können Sie Vordergrunddienste verwenden.

Mithilfe von Vordergrunddiensten können Sie z. B. eine für Benutzer sichtbare Benachrichtigung beibehalten, wenn Ihre Anwendung über einen aktiven Anruf verfügt. Auf diese Weise ist der Anruf auch dann aktiv, wenn der Benutzer auf den Startbildschirm wechselt oder die Anwendung vom Bildschirm „Zuletzt verwendet“ entfernt.

Wenn Sie während eines Anrufs keinen Vordergrunddienst verwenden, kann die Navigation zum Startbildschirm den Anruf aktiv halten. Wenn Sie die Anwendung jedoch aus dem Bildschirm „Zuletzt verwendet“ entfernen, kann der Anruf beendet werden, wenn das Android-Betriebssystem den Prozess Ihrer Anwendung beendet.

Sie sollten den Vordergrunddienst starten, wenn Sie einen Anruf starten/ihm beitreten, z. B.:

call = callAgent.startCall(context, participants, options);
startService(yourForegroundServiceIntent);

Beenden Sie den Vordergrunddienst, wenn Sie den Anruf beenden oder der Status des Anrufs „Getrennt“ lautet, z. B.:

call.hangUp(new HangUpOptions()).get();
stopService(yourForegroundServiceIntent);

Hinweise zum Verwenden von Vordergrunddiensten

Beachten Sie, dass Szenarien wie das Beenden eines bereits ausgeführten Vordergrunddiensts, wenn die App aus der „Zuletzt verwendet“-Liste entfernt wird, die für den Benutzer sichtbare Benachrichtigung entfernen, und das Android-Betriebssystem kann Ihren Anwendungsprozess für einen zusätzlichen Zeitraum aktiv halten, was bedeutet, dass der Anruf während dieses Zeitraums weiterhin aktiv sein kann.

Wenn Ihre Anwendung beispielsweise den Vordergrunddienst für die Dienstmethode onTaskRemoved beendet, kann Ihre Anwendung Audio- und Videodaten gemäß Ihrem Aktivitätslebenszyklus starten/beenden, z. B. Audio und Video beenden, wenn Ihre Aktivität mit Außerkraftsetzung durch die onDestroy-Methode zerstört wird.

Einrichten des Systems

Erstellen des Xcode-Projekts

Erstellen Sie in Xcode ein neues iOS-Projekt, und wählen Sie die Vorlage Single View App aus. In dieser Schnellstartanleitung wird das SwiftUI-Framework verwendet. Legen Sie daher Language (Sprache) auf Swift und User Interface (Benutzeroberfläche) auf SwiftUI fest.

Während dieses Schnellstarts werden keine Komponenten- oder Benutzeroberflächentests erstellt. Die Textfelder Include Unit Tests (Komponententests einbeziehen) und Include UI Tests (Benutzeroberflächentests einbeziehen) können daher geleert werden.

Screenshot: Fenster zum Erstellen eines Projekts in Xcode

Installieren des Pakets und der Abhängigkeiten mit CocoaPods

  1. Erstellen Sie wie folgt eine Podfile für die Anwendung:

    platform :ios, '13.0'
    use_frameworks!
    target 'AzureCommunicationCallingSample' do
        pod 'AzureCommunicationCalling', '~> 1.0.0'
    end
    
  2. Führen Sie pod install aus.

  3. Öffnen Sie .xcworkspace mit Xcode.

Anfordern des Zugriffs auf das Mikrofon

Um auf das Mikrofon des Geräts zugreifen zu können, müssen Sie die Liste der Informationseigenschaften Ihrer App mit NSMicrophoneUsageDescription aktualisieren. Legen Sie den zugehörigen Wert auf eine Zeichenfolge (string) fest. Diese wird in das Dialogfeld eingeschlossen, mit dem das System Zugriff vom Benutzer anfordert.

Klicken Sie mit der rechten Maustaste auf den Eintrag Info.plist der Projektstruktur, und wählen Sie anschließend Open As (Öffnen als) >Source Code (Quellcode) aus. Fügen Sie im Abschnitt <dict> der obersten Ebene die folgenden Zeilen hinzu, und speichern Sie dann die Datei.

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

Einrichten des App-Frameworks

Öffnen Sie die Datei ContentView.swift Ihres Projekts, und fügen Sie am Anfang der Datei eine Deklaration vom Typ hinzu, um die Bibliothek AzureCommunicationCalling zu importieren. Importieren Sie außerdem AVFoundation. Dies ist für Audioberechtigungsanforderungen im Code erforderlich.

import AzureCommunicationCalling
import AVFoundation

Initialisieren von „CallAgent“

Um eine CallAgent-Instanz auf der Grundlage von CallClient zu erstellen, müssen Sie eine Methode vom Typ callClient.createCallAgent verwenden, die asynchron ein Objekt vom Typ CallAgent zurückgibt, nachdem es initialisiert wurde.

Für die Erstellung eines Anrufclients muss ein Objekt vom Typ CommunicationTokenCredential übergeben werden.

import AzureCommunication

let tokenString = "token_string"
var userCredential: CommunicationTokenCredential?
do {
    let options = CommunicationTokenRefreshOptions(initialToken: token, refreshProactively: true, tokenRefresher: self.fetchTokenSync)
    userCredential = try CommunicationTokenCredential(withOptions: options)
} catch {
    updates("Couldn't created Credential object", false)
    initializationDispatchGroup!.leave()
    return
}

// tokenProvider needs to be implemented by Contoso, which fetches a new token
public func fetchTokenSync(then onCompletion: TokenRefreshOnCompletion) {
    let newToken = self.tokenProvider!.fetchNewToken()
    onCompletion(newToken, nil)
}

Übergeben Sie das von Ihnen erstellte Objekt vom Typ CommunicationTokenCredential an CallClient, und legen Sie den Anzeigenamen fest.

self.callClient = CallClient()
let callAgentOptions = CallAgentOptions()
options.displayName = " iOS Azure Communication Services User"

self.callClient!.createCallAgent(userCredential: userCredential!,
    options: callAgentOptions) { (callAgent, error) in
        if error == nil {
            print("Create agent succeeded")
            self.callAgent = callAgent
        } else {
            print("Create agent failed")
        }
})

Hinweis

Bei Implementierung von Ereignisdelegaten muss die Anwendung einen eindeutigen Verweis auf die Objekte enthalten, die Ereignisabonnements erfordern. Wenn beispielsweise ein RemoteParticipant-Objekt beim Aufrufen der call.addParticipant-Methode zurückgegeben wird und die Anwendung den Delegaten auf das Lauschen auf RemoteParticipantDelegate festlegt, muss die Anwendung einen eindeutigen Verweis auf das RemoteParticipant-Objekt enthalten. Andernfalls löst der Delegat, wenn dieses Objekt erfasst wird, eine schwerwiegende Ausnahme aus, sobald das Calling SDK versucht, das Objekt aufzurufen.

Tätigen eines ausgehenden Anrufs

Um einen Anruf zu erstellen und zu starten, müssen Sie eine der APIs für CallAgent aufrufen und die Communication Services-Identität eines Benutzers angeben, den Sie unter Verwendung des Verwaltungs-SDK von Communication Services bereitgestellt haben.

Erstellung und Start des Anrufs erfolgen synchron. Sie erhalten eine Anrufinstanz, die es Ihnen ermöglicht, alle Ereignisse im Zusammenhang mit dem Anruf zu abonnieren.

Tätigen eines 1:1-Anrufs eines Benutzers oder eines 1:n-Anrufs mit Benutzern und Festnetznummern

let callees = [CommunicationUser(identifier: 'UserId')]
self.callAgent?.startCall(participants: callees, options: StartCallOptions()) { (call, error) in
     if error == nil {
         print("Successfully started outgoing call")
         self.call = call
     } else {
         print("Failed to start outgoing call")
     }
}

1:n-Anruf mit Benutzern und Festnetznummern

Um den Anruf über das Telefonfestnetz zu tätigen, müssen Sie die Telefonnummer angeben, die Sie mit Communication Services bezogen haben.

let pstnCallee = PhoneNumberIdentifier(phoneNumber: '+1999999999')
let callee = CommunicationUserIdentifier('UserId')
self.callAgent?.startCall(participants: [pstnCallee, callee], options: StartCallOptions()) { (groupCall, error) in
     if error == nil {
         print("Successfully started outgoing call to multiple participants")
         self.call = groupCall
     } else {
         print("Failed to start outgoing call to multiple participants")
     }
}

Teilnehmen an einem Gruppenanruf

Um an einem Anruf teilzunehmen, müssen Sie eine der APIs für CallAgent aufrufen.

let groupCallLocator = GroupCallLocator(groupId: UUID(uuidString: "uuid_string")!)
self.callAgent?.join(with: groupCallLocator, joinCallOptions: JoinCallOptions()) { (call, error) in
    if error == nil {
        print("Successfully joined group call")
        self.call = call
    } else {
        print("Failed to join group call")
    }
}

Abonnieren eines eingehenden Anrufs

Abonnieren Sie ein Ereignis für einen eingehenden Anruf.

final class IncomingCallHandler: NSObject, CallAgentDelegate, IncomingCallDelegate
{
    // Event raised when there is an incoming call
    public func callAgent(_ callAgent: CallAgent, didReceiveIncomingCall incomingcall: IncomingCall) {
        self.incomingCall = incomingcall
        // Subscribe to get OnCallEnded event
        self.incomingCall?.delegate = self
    }

    // Event raised when incoming call was not answered
    public func incomingCall(_ incomingCall: IncomingCall, didEnd args: PropertyChangedEventArgs) {
        print("Incoming call was not answered")
        self.incomingCall = nil
    }
}

Annehmen eines eingehenden Anrufs

Rufen Sie zum Annehmen eines Anrufs die Methode accept für ein IncomingCall-Objekt auf.

self.incomingCall!.accept(options: AcceptCallOptions()) { (call, error) in
   if (error == nil) {
       print("Successfully accepted incoming call")
       self.call = call
   } else {
       print("Failed to accept incoming call")
   }
}

let firstCamera: VideoDeviceInfo? = self.deviceManager!.cameras.first
localVideoStreams = [LocalVideoStream]()
localVideoStreams!.append(LocalVideoStream(camera: firstCamera!))
let acceptCallOptions = AcceptCallOptions()
acceptCallOptions.videoOptions = VideoOptions(localVideoStreams: localVideoStreams!)
if let incomingCall = self.incomingCall {
    incomingCall.accept(options: acceptCallOptions) { (call, error) in
        if error == nil {
            print("Incoming call accepted")
        } else {
            print("Failed to accept incoming call")
        }
    }
} else {
  print("No incoming call found to accept")
}

Ausführen von Vorgängen während eines Anrufs

Sie können während eines Anrufs verschiedene Vorgänge ausführen, um Einstellungen für Video und Audio zu verwalten.

Stummschalten und Aufheben der Stummschaltung

Zum Stummschalten oder Aufheben der Stummschaltung des lokalen Endpunkts können Sie die asynchronen APIs mute und unmute verwenden.

call!.mute { (error) in
    if error == nil {
        print("Successfully muted")
    } else {
        print("Failed to mute")
    }
}

Verwenden Sie den folgenden Code, um die Stummschaltung des lokalen Endpunkts asynchron aufzuheben:

call!.unmute { (error) in
    if error == nil {
        print("Successfully un-muted")
    } else {
        print("Failed to unmute")
    }
}

Verwalten von Remoteteilnehmern

Alle Remoteteilnehmer werden durch den Typ RemoteParticipant dargestellt und sind über die Sammlung remoteParticipants für eine Anrufinstanz verfügbar.

Auflisten der Teilnehmer an einem Anruf

call.remoteParticipants

Hinzufügen eines Teilnehmers zu einem Anruf

Wenn Sie einen Teilnehmer einem Anruf hinzufügen möchten (entweder als Benutzer oder Telefonnummer), können Sie addParticipant aufrufen. Durch diesen Befehl wird synchron die Instanz eines Remoteteilnehmers zurückgegeben.

let remoteParticipantAdded: RemoteParticipant = call.add(participant: CommunicationUserIdentifier(identifier: "userId"))

Entfernen eines Teilnehmers aus einem Anruf

Wenn Sie einen Teilnehmer aus einem Anruf entfernen möchten (entweder als Benutzer oder Telefonnummer), können Sie die API removeParticipant aufrufen. Dieser Vorgang wird asynchron aufgelöst.

call!.remove(participant: remoteParticipantAdded) { (error) in
    if (error == nil) {
        print("Successfully removed participant")
    } else {
        print("Failed to remove participant")
    }
}

Abrufen von Eigenschaften von Remoteteilnehmern

// [RemoteParticipantDelegate] delegate - an object you provide to receive events from this RemoteParticipant instance
var remoteParticipantDelegate = remoteParticipant.delegate

// [CommunicationIdentifier] identity - same as the one used to provision a token for another user
var identity = remoteParticipant.identifier

// ParticipantStateIdle = 0, ParticipantStateEarlyMedia = 1, ParticipantStateConnecting = 2, ParticipantStateConnected = 3, ParticipantStateOnHold = 4, ParticipantStateInLobby = 5, ParticipantStateDisconnected = 6
var state = remoteParticipant.state

// [Error] callEndReason - reason why participant left the call, contains code/subcode/message
var callEndReason = remoteParticipant.callEndReason

// [Bool] isMuted - indicating if participant is muted
var isMuted = remoteParticipant.isMuted

// [Bool] isSpeaking - indicating if participant is currently speaking
var isSpeaking = remoteParticipant.isSpeaking

// RemoteVideoStream[] - collection of video streams this participants has
var videoStreams = remoteParticipant.videoStreams // [RemoteVideoStream, RemoteVideoStream, ...]

Einrichten

Erstellen des Visual Studio-Projekts

Erstellen Sie für die UWP-App in Visual Studio 2019 ein neues Blank App (Universal Windows)-Projekt. Nach der Eingabe des Projektnamens können Sie ein beliebiges Windows SDK höher als 10.0.17134 auswählen.

Erstellen Sie für die WinUI 3-App ein neues Projekt mit der Blank App, Packaged (WinUI 3 in Desktop)-Vorlage, um eine WinUI 3-App auf einer einzelnen Seite einzurichten. Windows App SDK Version 1.2 Preview 2 und höher ist erforderlich.

Installieren des Pakets und der Abhängigkeiten mit NuGet-Paket-Manager

Die Calling SDK-APIs und -Bibliotheken sind über ein NuGet-Paket öffentlich verfügbar. In den folgenden Schritten wird veranschaulicht, wie Sie das Calling SDK-NuGet-Paket suchen, herunterladen und installieren.

  1. Öffnen des NuGet-Paket-Managers (Tools ->NuGet Package Manager ->Manage NuGet Packages for Solution)
  2. Klicken Sie auf Browse, und geben Sie dann Azure.Communication.Calling in das Suchfeld ein.
  3. Stellen Sie sicher, dass das Kontrollkästchen Include prerelease aktiviert ist.
  4. Klicken Sie auf das Azure.Communication.Calling-Paket, wählen Sie Azure.Communication.Calling1.0.0-beta.33 oder eine neuere Version aus.
  5. Aktivieren Sie auf der rechten Registerkarte das Kontrollkästchen, das dem CS-Projekt entspricht.
  6. Klicken Sie auf die Schaltfläche Install.

Anfordern des Zugriffs auf das Mikrofon

Die App benötigt Zugriff auf das Mikrofon, um ordnungsgemäß ausgeführt zu werden. In UWP-Apps sollte die Mikrofonfunktion in der App-Manifestdatei deklariert werden. Mit den folgenden Schritten wird veranschaulicht, wie dies erreicht werden kann.

  1. Doppelklicken Sie im Panel Solution Explorer auf die Datei mit der Erweiterung .appxmanifest.
  2. Klicken Sie auf die Registerkarte Capabilities.
  3. Aktivieren Sie in der Liste der Funktionen das Kontrollkästchen Microphone.

Erstellen von Benutzeroberflächenschaltflächen zum Tätigen und Beenden des Anrufs

Diese einfache Beispiel-App enthält zwei Schaltflächen: eine zum Tätigen und eine weitere zum Beenden des Anrufs. In den folgenden Schritten wird veranschaulicht, wie Sie diese Schaltflächen zur App hinzufügen.

  1. Doppelklicken Sie im Bereich Solution Explorer für UWP auf die Datei namens MainPage.xaml bzw. für WinUI 3 auf MainWindows.xaml.
  2. Suchen Sie im zentralen Panel in der Vorschau der Benutzeroberfläche nach dem XAML-Code.
  3. Ersetzen Sie den XAML-Code durch den folgenden Auszug:
<TextBox x:Name="CalleeTextBox" Text="Who would you like to call?" TextWrapping="Wrap" VerticalAlignment="Center" Grid.Row="0" Height="40" Margin="10,10,10,10" />
<StackPanel Orientation="Horizontal">
    <Button x:Name="CallButton" Content="Start Call" Click="CallButton_Click" VerticalAlignment="Center" Margin="10,0,0,0" Height="40" Width="200"/>
    <Button x:Name="HangupButton" Content="Hang Up" Click="HangupButton_Click" VerticalAlignment="Center" Margin="10,0,0,0" Height="40" Width="200"/>
</StackPanel>

Einrichten der App mit Calling SDK-APIs

Die Calling SDK-APIs befinden sich in zwei verschiedenen Namespaces. Mit den folgenden Schritten wird der C#-Compiler über diese Namespaces informiert, damit IntelliSense in Visual Studio die Codeentwicklung unterstützen kann.

  1. Klicken Sie im Bereich Solution Explorer für UWP auf den Pfeil links neben der Datei mit dem Namen MainPage.xaml bzw. für WinUI 3 auf MainWindows.xaml.
  2. Doppelklicken Sie auf die Datei namens MainPage.xaml.cs oder MainWindows.xaml.cs.
  3. Fügen Sie am Ende der aktuellen using-Anweisungen die folgenden Befehle hinzu.
using Azure.Communication;
using Azure.Communication.Calling;

Lassen Sie MainPage.xaml.cs bzw. MainWindows.xaml.cs geöffnet. In den nächsten Schritten wird weiterer Code hinzugefügt.

Zulassen von App-Interaktionen

Die zuvor hinzugefügten Benutzeroberflächenschaltflächen müssen auf einem platzierten Call ausgeführt werden. Das bedeutet, dass ein Call-Datenelement zur Klasse MainPage oder MainWindow hinzugefügt werden muss. Darüber hinaus muss derselben Klasse ein CallAgent-Datenelement hinzugefügt werden, damit der asynchrone Vorgang für die Erstellung von CallAgent erfolgreich ist.

Fügen Sie der Klasse MainPage oder MainWindow die folgenden Datenelemente hinzu:

CallAgent callAgent;
Call call;

Erstellen von Schaltflächenhandlern

Zuvor wurden dem XAML-Code zwei Benutzeroberflächenschaltflächen hinzugefügt. Der folgende Code fügt die Handler hinzu, die ausgeführt werden sollen, wenn ein Benutzer die Schaltfläche auswählt. Der folgende Code sollte nach den Datenelementen aus dem vorherigen Abschnitt hinzugefügt werden.

private async void CallButton_Click(object sender, RoutedEventArgs e)
{
    // Start call
}

private async void HangupButton_Click(object sender, RoutedEventArgs e)
{
    // End the current call
}

Objektmodell

Die folgenden Klassen und Schnittstellen befassen sich mit einigen der wichtigsten Features der Azure Communication Services-Clientbibliothek „Calling“ für UWP.

Name Beschreibung
CallClient CallClient ist der Haupteinstiegspunkt in die Clientbibliothek „Calling“.
CallAgent „CallAgent“ dient zum Starten von und Teilnehmen an Anrufen.
Aufruf „Call“ wird verwendet, um Anrufe zu verwalten, die getätigt oder an denen teilgenommen wurde.
CommunicationTokenCredential „CommunicationTokenCredential“ dient als tokengestützte Anmeldeinformation zum Instanziieren von „CallAgent“.
CallAgentOptions „CallAgentOptions“ enthält Informationen zum Identifizieren des Anrufers.
HangupOptions „HangupOptions“ informiert, ob ein Anruf für alle Teilnehmer beendet werden soll.

Initialisieren von „CallAgent“

Zum Erzeugen einer CallAgent-Instanz anhand von CallClient müssen Sie die CallClient.CreateCallAgent-Methode verwenden, die ein CallAgent-Objekt asynchron zurückgibt, nachdem es initialisiert wurde.

Zum Erstellen von CallAgent müssen Sie ein CommunicationTokenCredential-Objekt und ein CallAgentOptions-Objekt übergeben. Denken Sie daran, dass CommunicationTokenCredential eine Ausnahme auslöst, wenn ein falsch formatiertes Token übergeben wird.

Der folgende Code sollte innerhalb einer Hilfsfunktion hinzugefügt werden, die bei der App-Initialisierung aufgerufen werden soll.

var callClient = new CallClient();
this.deviceManager = await callClient.GetDeviceManager();

var tokenCredential = new CommunicationTokenCredential("<AUTHENTICATION_TOKEN>");
var callAgentOptions = new CallAgentOptions()
{
    DisplayName = "<DISPLAY_NAME>"
};

this.callAgent = await callClient.CreateCallAgent(tokenCredential, callAgentOptions);

<AUTHENTICATION_TOKEN> muss durch ein gültiges Anmeldeinformationstoken für Ihre Ressource ersetzt werden. Wenn ein Anmeldeinformationstoken eingebunden werden muss, lesen Sie die Dokumentation zu Benutzerzugriffstoken.

Erstellen von CallAgent und Tätigen eines Anrufs

Die Objekte, die zum Erstellen eines CallAgent erforderlich sind, sind jetzt bereit. Es ist an der Zeit, CallAgent asynchron zu erstellen und einen Anruf zu tätigen.

Der folgende Code sollte nach der Behandlung der Ausnahme aus dem vorherigen Schritt hinzugefügt werden.

var startCallOptions = new StartCallOptions();

var callees = new ICommunicationIdentifier[1] { new CommunicationUserIdentifier(CalleeTextBox.Text.Trim()) };

this.call = await this.callAgent.StartCallAsync(callees, startCallOptions);
this.call.OnStateChanged += Call_OnStateChangedAsync;

Sie können auch 8:echo123 verwenden, um mit dem Azure Communication Services-Echobot zu sprechen.

Beenden eines Anrufs

Sobald ein Anfruf getätigt wurde, sollte die HangupAsync-Methode des Call-Objekts verwendet werden, um den Anruf zu beenden.

Eine Instanz von HangupOptions sollte auch verwendet werden, um zu informieren, ob der Anruf für alle Teilnehmer beendet werden muss.

Der folgende Code sollte in HangupButton_Click hinzugefügt werden.

this.call.OnStateChanged -= Call_OnStateChangedAsync;
await this.call.HangUpAsync(new HangUpOptions());

Ausführen des Codes

Stellen Sie sicher, dass Visual Studio die App für x64, x86 oder ARM64 erstellt, und klicken Sie dann auf F5, um die Ausführung der App zu starten. Klicken Sie anschließend auf die Schaltfläche Call, um den festgelegten Gesprächspartner anzurufen.

Beachten Sie, dass das System beim ersten Ausführen der App den Benutzer zur Gewährung des Zugriffs auf das Mikrofon auffordert.

Nächste Schritte