Trying to integrate the Sinch API for Voip getting exception

249 views Asked by At

I am trying to integrate the Sinch API in android .

My VOIPClient. Java is like this

public class VOIPClient {
private static final String TAG = "VOIPClient";

private SinchClient mSinch;
private TTSHelper mTTS;
private Call mCurrentCall;
private BootService mContext;
private SinchClientBuilder mBuilder;
private NsdController mNsdController;

private final CallListener mCallListener = new CallListener() {
    @Override
    public void onCallProgressing(Call call) {
        Log.d(TAG, "Call established at " + " Thusee");
    }

    @Override
    public void onCallEstablished(Call call) {
        Log.d(TAG, "Call established at " + call.getDetails().getEstablishedTime());
        mTTS.speak("Call started", TTSHelper.UTTERANCE_VOIP_START);

        JsonObject payload = new JsonObject();
        payload.addProperty("Status", 0);
        payload.addProperty("Call_status", 1);

        if (mNsdController != null) {
            mNsdController.sendCommand(20, payload);
        }

    }

    @Override
    public void onCallEnded(Call call) {
        Log.d(TAG, "Call ended at " + call.getDetails().getEndedTime() + "caused by " + call.getDetails().getEndCause().toString());
        mTTS.speak("Call ended", TTSHelper.UTTERANCE_VOIP_END);
        mCurrentCall.hangup();

        JsonObject payload = new JsonObject();
        payload.addProperty("Status", 0);
        payload.addProperty("Call_status", 1);

        if (mNsdController != null) {
            mNsdController.sendCommand(21, payload);
        }
    }

    @Override
    public void onShouldSendPushNotification(Call call, List<PushPair> list) {

    }
};

public VOIPClient(BootService context) {
    mContext = context;
    mTTS = TTSHelper.getInstance(context);
    mBuilder = Sinch.getSinchClientBuilder().context(mContext.getApplicationContext())
            .applicationKey(CloudConfig.SINCH_APP_KEY)
            .applicationSecret(CloudConfig.SINCH_APP_SECRET)
            .environmentHost(CloudConfig.SINCH_ENVIRONMENT);

    if (mNsdController != null)
        mNsdController.initialize();
}

public void start() {
    SharedPreferences prefs = mContext.getPreferences();
    int userId = prefs.getInt(MerryClient.PREF_USER_ID, 0);
    String mUserId;

    if (userId > 0) {
        mUserId = String.valueOf(userId);
        mSinch = Sinch.getSinchClientBuilder().context(mContext.getApplicationContext()).userId(mUserId)
                .applicationKey(CloudConfig.SINCH_APP_KEY)
                .applicationSecret(CloudConfig.SINCH_APP_SECRET)
                .environmentHost(CloudConfig.SINCH_ENVIRONMENT).build();

        mSinch.setSupportCalling(true);
        mSinch.setSupportManagedPush(false);

        SinchClientListener sinchClientListener = new SinchClientListener() {
            @Override
            public void onClientStarted(SinchClient sinchClient) {
                Log.d(TAG, "Sinch Client starts: " + sinchClient.getLocalUserId());
                mTTS.speak("Call ready", TTSHelper.UTTERANCE_VOIP_READY);
            }

            @Override
            public void onClientStopped(SinchClient sinchClient) {
                Log.d(TAG, "Sinch Client stops");

            }

            @Override
            public void onClientFailed(SinchClient sinchClient, SinchError sinchError) {
                Log.e(TAG, String.format("Sinch Client error %d: %s", sinchError.getCode(), sinchError.getMessage()));
                mSinch.terminate();
                mTTS.speak("Voice Over IP failed", TTSHelper.UTTERANCE_VOIP_FAIL);
            }

            @Override
            public void onRegistrationCredentialsRequired(SinchClient sinchClient, ClientRegistration clientRegistration) {
                Log.d(TAG, "Sinch Client requires registration");
            }

            @Override
            public void onLogMessage(int i, String s, String s1) {
                Log.d(TAG, s1);
            }
        };

        mSinch.addSinchClientListener(sinchClientListener);

        mSinch.getCallClient().setRespectNativeCalls(false);
        mSinch.getCallClient().addCallClientListener(new SinchCallClientListener());

        mCurrentCall = null;

        mSinch.startListeningOnActiveConnection();
        mSinch.start();
    }
}

public void tearDown() {
    if (mSinch != null) {
        mSinch.stopListeningOnActiveConnection();
        mSinch.terminate();
        mSinch = null;
    }
}

public void restart() {
    tearDown();
    start();
}

public void initiateCall(final String targetUserName) {
    new Thread(new Runnable() {
        public void run() {
            Looper.prepare();
            if (targetUserName != null) {
                try {

                    Call call = callUser(targetUserName);
                    call.addCallListener(mCallListener);
                    mCurrentCall = call;

                } catch (Exception e) {
                    Log.e(TAG, "Initiate VOIP call failed", e);

                }
            }
            Looper.loop();
        }
    }).start();

}

public void answerCall() {
    if (mCurrentCall != null) {

        mCurrentCall.answer();
    }
}

public void hangUpCall() {
    if (mCurrentCall != null) {
        mCurrentCall.hangup();
    }
}

private class SinchCallClientListener implements CallClientListener {
    @Override
    public void onIncomingCall(CallClient callClient, Call call) {

        Log.d(TAG, "Incoming call");
        mTTS.speak("Incoming call from " + call.getRemoteUserId(), TTSHelper.UTTERANCE_VOIP_INCOMING);
        call.addCallListener(mCallListener);
        mCurrentCall = call;

        // For testing only
        answerCall();
    }
}

public Call callUser(String userId) {
    if (mSinch != null && mSinch.isStarted()) {
        start();
    }

    if (mSinch == null) {
        return null;
    }
    return mSinch.getCallClient().callUser(userId);
}

class CallerThread implements Runnable {
    public String mtargetUserName;

    CallerThread(String targetUserName) {
        this.mtargetUserName = targetUserName;
    }

    @Override
    public void run() {
        Looper.prepare();
        if (mtargetUserName != null) {
            try {

                Call call = callUser(mtargetUserName);
                call.addCallListener(mCallListener);
                mCurrentCall = call;

            } catch (Exception e) {
                Log.e(TAG, "Initiate VOIP call failed", e);
                mContext.getAlexa().start();
            }
        }
        Looper.loop();
    }
}

}

When I try to call to other device then I am getting these kind of exceptions

Initiate VOIP call failed
java.lang.IllegalStateException: SinchClient not started
at com.sinch.android.rtc.internal.client.calling.DefaultCallClient.throwUnlessStarted(Unknown Source)
at com.sinch.android.rtc.internal.client.calling.DefaultCallClient.call(Unknown Source)
at com.sinch.android.rtc.internal.client.calling.DefaultCallClient.callUser(Unknown Source)
at com.sinch.android.rtc.internal.client.calling.DefaultCallClient.callUser(Unknown Source)
at tw.com.test.cloud.VOIPClient.callUser(VOIPClient.java:272)
at tw.com.test.cloud.VOIPClient$CallerThread.run(VOIPClient.java:293)
at java.lang.Thread.run(Thread.java:818)

Also some times I am getting this exception

FATAL EXCEPTION: Thread-75
    Process: tw.com.test.wear, PID: 1123
    java.lang.IllegalThreadStateException: A Looper must be associated with this thread.
    at com.sinch.android.rtc.internal.AndroidLooperCallbackHandler.<init>(Unknown Source)
    at com.sinch.android.rtc.internal.client.InternalSinchClientFactory.createSinchClient(Unknown Source)
    at com.sinch.android.rtc.DefaultSinchClientBuilder.build(Unknown Source)
    at tw.com.test.cloud.VOIPClient.start(VOIPClient.java:109)
    at tw.com.test.cloud.VOIPClient$2.onClientStopped(VOIPClient.java:124)
    at com.sinch.android.rtc.internal.client.DefaultSinchClient.shutdown(Unknown Source)
    at com.sinch.android.rtc.internal.client.DefaultSinchClient.terminate(Unknown Source)
    at tw.com.test.cloud.VOIPClient.tearDown(VOIPClient.java:160)
    at tw.com.test.nsd.NsdController.messageReceived(NsdController.java:570)
    at tw.com.test.nsd.NsdConnection.run(NsdConnection.java:115)
    at java.lang.Thread.run(Thread.java:818)

2 Days I tried my self, I can't able to solve this yet, I am always getting these exception. Sometimes it will work for one time then I need to restart the app.

1

There are 1 answers

0
Kneelon On

You have to start SinchClient sinchClient.start(); and take NOTE during production mode do not place in a plain text form your SINCH_APP_SECRET, because its a secret key, hackers will easily read or decompile your code.

public VOIPClient(BootService context) {
    mContext = context;
    mTTS = TTSHelper.getInstance(context);
    mBuilder = Sinch.getSinchClientBuilder().context(mContext.getApplicationContext())
            .applicationKey(CloudConfig.SINCH_APP_KEY)
            .applicationSecret(CloudConfig.SINCH_APP_SECRET)
            .environmentHost(CloudConfig.SINCH_ENVIRONMENT);

        sinchClient.setSupportCalling(true);
        sinchClient.start();

    if (mNsdController != null)
        mNsdController.initialize();
}