Использование Sinch с формами Xamarin (кросс-платформенный) - PullRequest
0 голосов
/ 24 ноября 2018

Нам нравится реализовывать голосовые вызовы из приложения в приложение (VoIP) с использованием форм xamarin в visual studio 2017. Здесь я нашел одно решение с использованием приложения sinch, но они дали только xamarin android github.Хотя мы пытаемся создать приложение форм xamarin с помощью Sinch, но я получаю сообщение об ошибке, когда я запускаю проект (исключение нулевого указателя) в приемнике sinchcall, мы совершенно новый голосовой вызов VoIP, мы не знаем, как вызвать (навигацию) страницу входящих вызововс Android, принять вызов, отклонить вызов и аудио-плеер.Мое требование - голосовой вызов из приложения в приложение (VoIP), после чего получите время голосового вызова, время начала и окончания.Дайте мне предложение, чтобы решить эту проблему, мы вставляем код ниже

        Interface
        ISinchService.cs
        public interface ISinchService
            {
                void StartSinchClient(string username);
                void StopSinchClient();
                bool IsSinchClientStarted();
                void CallVoice(string receipientId);
                string GetUserId();
            }

        Interfaceimplementation
        SinchService.cs

        using App1.Interface;
        using System;
        using System.Collections.Generic;
        using System.Text;
        using Xamarin.Forms;

        namespace App1.InterfaceImplemets
        {
            public class SinchService : ISinchService
            {

                ISinchService sinchService;// = DependencyService.Get<ISinchService>();

                public SinchService()
                {
                    sinchService = DependencyService.Get<ISinchService>();
                }        
                public void CallVoice(string receipientId)
                {
                    sinchService.CallVoice(receipientId);
                }
                public string GetUserId()
                {
                    return sinchService.GetUserId();
                }
                public bool IsSinchClientStarted()
                {
                    return sinchService.IsSinchClientStarted();
                }
                public void StartSinchClient(string username)
                {
                    sinchService.StartSinchClient(username);
                }
                public void StopSinchClient()
                {
                    sinchService.StopSinchClient();
                }
            }
        }

        MainPage.xaml

        <?xml version="1.0" encoding="utf-8" ?>
        <ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
                     xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
                     xmlns:local="clr-namespace:App1"
                     x:Class="App1.MainPage">
            <StackLayout VerticalOptions="CenterAndExpand"
                         HorizontalOptions="CenterAndExpand">
                <Label x:Name="progress"
                   Text="Welcome to Xamarin Forms!" 
                   VerticalOptions="Center" 
                   HorizontalOptions="Center" />
                <Label Text="Enter user name"
                       TextColor="Purple"
                       FontSize="Medium"/>
                <Entry x:Name="usernameId"
                       Placeholder="enter username here"
                       PlaceholderColor="MediumAquamarine"
                       TextColor="Purple"
                       FontSize="Medium"/>
                <Button x:Name="loginBtn"
                        Text="Login"
                        TextColor="White"
                        BackgroundColor="Purple"
                        Clicked="loginBtn_Clicked"/>
            </StackLayout>
        </ContentPage>

        MainPage.xaml.cs

        using App1.InterfaceImplemets;
        using App1.View;
        using System;
        using System.Collections.Generic;
        using System.Diagnostics;
        using System.Linq;
        using System.Text;
        using System.Threading.Tasks;
        using Xamarin.Forms;
        using Xamarin.Forms.Xaml;

        namespace App1
        {
            [XamlCompilation(XamlCompilationOptions.Compile)]
            public partial class MainPage : ContentPage
            {
                SinchService sinchService;
                public MainPage()
                {
                    InitializeComponent();
                    sinchService = new SinchService();
                }
                private async void loginBtn_Clicked(object sender, EventArgs e)
                {
                    string userId = usernameId.Text;
                    if (userId != null)
                    {
                        sinchService.StartSinchClient(userId);
                        while (!IsSinchStarted())
                        {
                            progress.Text = "Please wait app is starting to sinch service...";
                            await Task.Delay(500);
                        }
                        Debug.WriteLine(sinchService.IsSinchClientStarted().ToString());
                        LaunchReciepientAsync();

                    }

                }

                private void LaunchReciepientAsync()
                {
                    Navigation.PushModalAsync(new RecipientPage(sinchService));
                }
                private bool IsSinchStarted()
                {
                    return sinchService.IsSinchClientStarted();
                }
            }
        }

        RecipientPage.xaml

        <?xml version="1.0" encoding="utf-8" ?>
        <ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
                     xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
                     x:Class="App1.View.RecipientPage">
            <ContentPage.Content>
                <StackLayout>
                    <Label x:Name="userId"
                           Text="Welcome to Xamarin Forms!" />

                    <Label Text="Enter reciepient username"
                       TextColor="Purple"
                       FontSize="Medium"/>
                    <Entry x:Name="reciepientId"
                       Placeholder="enter username here"
                       PlaceholderColor="MediumAquamarine"
                       TextColor="Purple"
                       FontSize="Medium"/>
                    <Button x:Name="voiceCallBtn"
                        Text="Voice"
                        TextColor="White"
                        BackgroundColor="Purple"
                        Clicked="voiceCallBtn_Clicked"/>
                </StackLayout>
            </ContentPage.Content>
        </ContentPage>

        RecipientPage.xaml.cs

        using App1.InterfaceImplemets;
        using System;
        using System.Collections.Generic;
        using System.Linq;
        using System.Text;
        using System.Threading.Tasks;
        using Xamarin.Forms;
        using Xamarin.Forms.Xaml;

        namespace App1.View
        {
            [XamlCompilation(XamlCompilationOptions.Compile)]
            public partial class RecipientPage : ContentPage
            {
                SinchService sinchService;
                public RecipientPage()
                {
                    InitializeComponent();
                }

                public RecipientPage(SinchService sinchService)
                {
                    InitializeComponent();
                    this.sinchService = sinchService;
                    userId.Text = sinchService.GetUserId();
                }

                private void voiceCallBtn_Clicked(object sender, EventArgs e)
                {
                    if (!string.IsNullOrWhiteSpace(reciepientId.Text))
                    {
                        LaunchVoiceAsync();
                    }
                }

                private void LaunchVoiceAsync()
                {
                    sinchService.CallVoice(reciepientId.Text);
                    Navigation.PushModalAsync(new CallPage(sinchService, reciepientId.Text, voiceCallBtn.Text));
                }


            }
        }

        CallPage.xaml

        <?xml version="1.0" encoding="utf-8" ?>
        <ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
                     xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
                     x:Class="App1.View.CallPage">
            <ContentPage.Content>
                <StackLayout>
                    <Label Text="Welcome to Xamarin Forms!" />
                    <Label x:Name="reciepientId"
                        Text=""
                       TextColor="Purple"
                       FontSize="Medium"/>
                    <Label x:Name="callState"
                        Text=""
                       TextColor="Purple"
                       FontSize="Medium"/>
                    <Label x:Name="callDuration"
                        Text="0:00"
                       TextColor="Purple"
                       FontSize="Medium"/>
                    <Button x:Name="stopBtn"
                        Text="STOP"
                        TextColor="White"
                        BackgroundColor="Red"/>



                    <Button x:Name="voiceCallBtn"
                        Text="Voice"
                        TextColor="White"
                        BackgroundColor="Purple"/>
                </StackLayout>
            </ContentPage.Content>
        </ContentPage>

        CallPage.xaml.cs

        using App1.InterfaceImplemets;
        using System;
        using System.Collections.Generic;
        using System.Linq;
        using System.Text;
        using System.Threading.Tasks;

        using Xamarin.Forms;
        using Xamarin.Forms.Xaml;

        namespace App1.View
        {
            [XamlCompilation(XamlCompilationOptions.Compile)]
            public partial class CallPage : ContentPage
            {
                private SinchService sinchService;
                private string text1;
                private string text2;

                public CallPage()
                {
                    InitializeComponent();
                }

                public CallPage(SinchService sinchService, string text1, string text2)
                {
                    this.sinchService = sinchService;
                    this.text1 = text1;
                    this.text2 = text2;
                }
            }
        }

        Android
        InterfaceImplementations

        SinchService.cs

        using System;
        using System.Collections.Generic;
        using System.Linq;
        using System.Text;

        using Android.App;
        using Android.Content;
        using Android.OS;
        using Android.Runtime;
        using Android.Util;
        using Android.Views;
        using Android.Widget;
        using App1.Droid.InterfaceImplementations;
        using App1.Interface;
        using Com.Sinch.Android.Rtc;
        using Com.Sinch.Android.Rtc.Calling;
        using Xamarin.Forms;

        [assembly: Xamarin.Forms.Dependency(typeof(SinchService))]
        namespace App1.Droid.InterfaceImplementations
        {
            [Service]
            public class SinchService : Service, ISinchService
            {
        // go to link and signup(https://portal.sinch.com/#/signup) then you will get sinch app key and app secret key and call id 
                static readonly string APP_KEY = "xxxxxxxxxxxxxxxxxxxxxxxxxxx"; 
                static readonly string APP_SECRET = "xxxxxxxxxxxxxxxxxxxx";
                static readonly string ENVIRONMENT = "clientapi.sinch.com";
                public static readonly string CALL_ID = "xxxxxx";

                static readonly string TAG = nameof(SinchService);
                public SinchServiceInterface mSinchServiceInterface;
                ISinchClient mSinchClient;
                string mUserId;
                IStartFailedListener mListener;

                public SinchService()
                {
                    mSinchServiceInterface = new SinchServiceInterface(this);
                }

                public void CallVoice(string receipientId)
                {
                    mSinchServiceInterface.CallUserVoice(receipientId);
                }
                public override IBinder OnBind(Intent intent)
                {
                    return mSinchServiceInterface;
                }
                public override void OnCreate()
                {
                    base.OnCreate();
                }
                public override void OnDestroy()
                {
                    if (mSinchClient != null && mSinchClient.IsStarted)
                    {
                        mSinchClient.Terminate();
                    }
                    base.OnDestroy();
                }
                public void StartSinchClient(string username)
                {
                    if (mSinchClient == null)
                    {
                        mUserId = username;
                        mSinchClient = Sinch.SinchClientBuilder.Context(Forms.Context).UserId(username)
                                .ApplicationKey(APP_KEY)
                                .ApplicationSecret(APP_SECRET)
                                .EnvironmentHost(ENVIRONMENT).Build();

                        mSinchClient.SetSupportCalling(true);
                        mSinchClient.SetSupportMessaging(true);
                        mSinchClient.SetSupportPushNotifications(true);
                        //mSinchClient.SetSupportManagedPush(true);
                        mSinchClient.SetSupportActiveConnectionInBackground(true);
                        mSinchClient.StartListeningOnActiveConnection();

                        mSinchClient.AddSinchClientListener(new SinchClientListener(this));
                        // Permission READ_PHONE_STATE is needed to respect native calls.
                        mSinchClient.CallClient.SetRespectNativeCalls(false);
                        mSinchClient.CallClient.AddCallClientListener(new SinchCallClientListener(this));
                       // mSinchClient.MessageClient.AddMessageClientListener(new SinchMessageClientListener(this));
                        mSinchClient.Start();
                        Log.Debug(TAG, "Started1!!!!!!!!!!!!!!!!!!!!!11");
                    }
                }

                public void StopSinchClient()
                {
                    if (mSinchClient != null)
                    {
                        mSinchClient.Terminate();
                        mSinchClient = null;
                    }
                }
                public bool IsSinchClientStarted()
                {
                    return (mSinchClient != null && mSinchClient.IsStarted);
                }
                public string GetUserId()
                {
                    return mUserId;
                }
                public interface IStartFailedListener
                {
                    void OnStartFailed(ISinchError error);

                    void OnStarted();
                }
                public class SinchServiceInterface : Binder
                {
                    private SinchService sinchService;

                    public SinchServiceInterface(SinchService sinchService)
                    {
                        this.sinchService = sinchService;
                    }
                    public ICall CallPhoneNumber(String phoneNumber)
                    {
                        return sinchService.mSinchClient.CallClient.CallPhoneNumber(phoneNumber);
                    }
                    public ICall CallUserVoice(String userId)
                    {
                        if (sinchService.mSinchClient == null)
                        {
                            return null;
                        }
                        return sinchService.mSinchClient.CallClient.CallUser(userId);
                    }
                    public string GetUserName()
                    {
                        return sinchService.mUserId;
                    }
                    public bool IsStarted()
                    {
                        return sinchService.IsSinchClientStarted();
                    }
                    public void StartClient(String userName)
                    {
                        sinchService.StartSinchClient(userName);
                    }
                    public void StopClient()
                    {
                        sinchService.StopSinchClient();
                    }
                    public void SetStartListener(IStartFailedListener listener)
                    {
                        sinchService.mListener = listener;
                    }
                    public ICall GetCall(String callId)
                    {
                        return sinchService.mSinchClient.CallClient.GetCall(callId);
                    }
                }

                class SinchCallClientListener : Java.Lang.Object, ICallClientListener
                {
                    readonly SinchService sinchService;
                    public SinchCallClientListener(SinchService sinchService)
                    {
                        this.sinchService = sinchService;
                    }
                    public void OnIncomingCall(ICallClient callClient, ICall call)
                    {
                        Log.Debug(TAG, "Incoming call");
//Here i am getting error null pointer exception while i run the project
                        Intent intent = new Intent(sinchService, typeof(IncomingCallScreenActivity));
                        intent.PutExtra(CALL_ID, call.CallId);
                        intent.AddFlags(ActivityFlags.NewTask);
                        sinchService.StartActivity(intent);
                    }
                }
                class SinchClientListener : Java.Lang.Object, ISinchClientListener
                {
                    private readonly SinchService sinchService;

                    public SinchClientListener(SinchService sinchService)
                    {
                        this.sinchService = sinchService;
                    }

                    public void OnClientFailed(ISinchClient sinchClient, ISinchError sinchError)
                    {
                        if (sinchService.mListener != null)
                        {
                            sinchService.mListener.OnStartFailed(sinchError);
                        }
                        sinchService.mSinchClient.Terminate();
                        sinchService.mSinchClient = null;
                    }

                    public void OnClientStarted(ISinchClient sinchClient)
                    {
                        Log.Debug(TAG, "SinchClient started");
                        if (sinchService.mListener != null)
                        {
                            sinchService.mListener.OnStarted();
                        }
                    }
                    public void OnClientStopped(ISinchClient sinchClient)
                    {
                        Log.Debug(TAG, "SinchClient stopped");
                    }
                    public void OnLogMessage(int level, string area, string message)
                    {
                        switch (level)
                        {
                            case 3://Log.DEBUG:
                                Log.Debug(area, message);
                                break;
                            case 6://Log.ERROR:
                                Log.Error(area, message);
                                break;
                            case 4://Log.INFO:
                                Log.Info(area, message);
                                break;
                            case 2://Log.VERBOSE:
                                Log.Verbose(area, message);
                                break;
                            case 5://Log.WARN:
                                Log.Warn(area, message);
                                break;
                        }
                    }
                    public void OnRegistrationCredentialsRequired(ISinchClient sinchClient, IClientRegistration clientReg)
                    {
                        //throw new NotImplementedException();
                    }
                }                    
            }
        }

    //Here i created a activity class    
        //Activity
        //IncomingCallScreenActivity.cs

        using System;
        using System.Collections.Generic;
        using System.Linq;
        using System.Text;

        using Android.App;
        using Android.Content;
        using Android.OS;
        using Android.Runtime;
        using Android.Views;
        using Android.Widget;

        namespace App1.Droid
        {
            [Activity(Label = "IncomingCallScreenActivity")]
            public class IncomingCallScreenActivity : Activity
            {
                protected override void OnCreate(Bundle savedInstanceState)
                {
                    base.OnCreate(savedInstanceState);
                    // Create your application here
                }
            }
        }


    Note: We use to develop app using this link(https://github.com/Onotseike/CallMessageDemoSinch)
...