1

I've used the Sinch SDK to build a test app that implements basic app-to-app calling, and everything worked perfectly.

I'm now trying to move that work over into a more polished/full featured app but I keep getting an exception when I try to initiate a call:

mSinchClient.getCallClient().callUser(userId);

Here is the stacktrace:

02-23 21:37:57.979 W/System.err(15111): com.sinch.android.rtc.MissingPermissionException: Requires permission: android.permission.RECORD_AUDIO
02-23 21:37:57.979 W/System.err(15111):     at com.sinch.android.rtc.internal.client.calling.DefaultCallClient.throwIfMissingPermission(Unknown Source)
02-23 21:37:57.979 W/System.err(15111):     at com.sinch.android.rtc.internal.client.calling.DefaultCallClient.call(Unknown Source)
02-23 21:37:57.980 W/System.err(15111):     at com.sinch.android.rtc.internal.client.calling.DefaultCallClient.callConference(Unknown Source)
02-23 21:37:57.980 W/System.err(15111):     at com.sinch.android.rtc.internal.client.calling.DefaultCallClient.callConference(Unknown Source)
02-23 21:37:57.980 W/System.err(15111):     at com.brenthiggins.clickapp.vext.VextingManagerSinchImpl.connectContact(VextingManagerSinchImpl.java:122)
02-23 21:37:57.980 W/System.err(15111):     at com.brenthiggins.clickapp.fragments.VextFragment.vextContactIfNecessary(VextFragment.java:97)
02-23 21:37:57.980 W/System.err(15111):     at com.brenthiggins.clickapp.fragments.VextFragment.onSpeakingCompleted(VextFragment.java:81)
02-23 21:37:57.980 W/System.err(15111):     at com.brenthiggins.clickapp.helpers.TextToSpeechManager.isDone(TextToSpeechManager.java:141)
02-23 21:37:57.980 W/System.err(15111):     at com.brenthiggins.clickapp.helpers.TextToSpeechManager.onDone(TextToSpeechManager.java:69)
02-23 21:37:57.980 W/System.err(15111):     at android.speech.tts.TextToSpeech$Connection$1.onSuccess(TextToSpeech.java:2108)
02-23 21:37:57.980 W/System.err(15111):     at android.speech.tts.ITextToSpeechCallback$Stub.onTransact(ITextToSpeechCallback.java:63)
02-23 21:37:57.980 W/System.err(15111):     at android.os.Binder.execTransact(Binder.java:453)

I definitely have the record audio permission:

  • I have it in the manifest
  • I request it from the user
  • It shows up under apps > my app > permissions
  • I even used the MediaRecorder to successfully test recording audio from the mic

I also called tried calling

SinchClient.checkManifest()

in SinchClientListener.onClientStarted() and no exception was thrown. However when I using checkManifest() before calling CallClient.callUser(), it fails (ie throws an exception).

Any help would be greatly appreciated! Thank you!

Mihai
  • 296
  • 2
  • 12

3 Answers3

3

The issue was using different threads.

I was calling SinchClient.start() on the main thread and CallClient.callUser on a background thread.

The error message is absolutely terrible as this has nothing to do with RECORD_AUDIO permissions.

It's either the case that Sinch must be used on the main thread or simply that all calls must be made on one thread.

They seem to elude to this somewhat in one of their docs:

Note: All listener callbacks emitted from the Sinch SDK are invoked on the same thread that the call to SinchClientBuilder.build is made on. If the invoking thread is not the main-thread, it needs to have an associated Looper.

I've messaged them telling them that this should probably be documented more thoroughly and the error message should be more relevant.

Mihai
  • 296
  • 2
  • 12
0

You need to add a runtime permission after Marshmallow like this:

//Declare these params in your activity
private static final String[] INITIAL_PERMS={
        Manifest.permission.RECORD_AUDIO,
};

private static final int INITIAL_REQUEST=1337;



// add these lines in your onCreate method
 if (android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
        if (!canAccessLocation()) {
            requestPermissions(INITIAL_PERMS, INITIAL_REQUEST);
        }
    }


// implemente these methods
private boolean canAccessLocation() {
    return(hasPermission(Manifest.permission.RECORD_AUDIO));
}

private boolean hasPermission(String perm) {
    return(PackageManager.PERMISSION_GRANTED==checkSelfPermission(perm));
}
Marlon
  • 1,839
  • 2
  • 19
  • 42
Dharmbir Singh
  • 17,485
  • 5
  • 50
  • 66
  • as mentioned, I already do request permissions from the user, and have confirmed that works by a. checking my apps permissions in settings and b. successfully recording audio through MediaPlayer. I also use ContextCompat.checkSelfPermission to verify I have all the permissions. – Mihai Feb 24 '17 at 07:02
0

I had the same problem.

Well i just created my "SinchClient (Make it static)" in my previous Activity and make a call in my next activity.

This is happening we start to make a call before Sinch client is started

Code:- Activity A Code

 android.content.Context context = this.getApplicationContext();
        sinchClient = Sinch.getSinchClientBuilder().context(context)
                .applicationKey(SichChatCredentials.app_key)
                .applicationSecret(SichChatCredentials.secreates)
                .environmentHost(SichChatCredentials.enviroment)
                .userId("userID")
                .build();


        sinchClient.setSupportMessaging(true);
        sinchClient.setSupportCalling(true);
//        sinchClient.setSupportManagedPush(true);

        sinchClient.setSupportActiveConnectionInBackground(true);
        sinchClient.startListeningOnActiveConnection();



        sinchClient.addSinchClientListener(new SinchClientListener() {
            public void onClientStarted(SinchClient client) { }
            public void onClientStopped(SinchClient client) { }
            public void onClientFailed(SinchClient client, SinchError error) { }
            public void onRegistrationCredentialsRequired(SinchClient client, ClientRegistration registrationCallback) { }
            public void onLogMessage(int level, String area, String message) { }
        });
        sinchClient.start();

Activity B Code:-

  CallClient callClient = sinchClient.getCallClient();
        Call call = callClient.callUser(doctorEmail);
        call.addCallListener(this);
TahirRaza
  • 81
  • 8