Sinch Not Running in background no way (Android)

*爱你&永不变心* 提交于 2019-12-23 04:51:12

问题


Good day.I am using sinch for audio calling.I dont know what to do and there are no clear docs of sinch (which is very frastruating) which would give me any idea on how to keep the sinch client running in background to listen for incoming calls in the background while the app is killed.Meanwhile i reckon that i forced sinch client not to be terminated but every time the app is openning,the client is being started anyway.So if anyone encounter such thing,could you please help me and tell me how can i listen for incoming calls in the background with Sinch?Posting the codes i have already up and running.

The base activity which being inherited by all of my activities.

import android.content.ComponentName;
import android.content.Intent;
import android.content.ServiceConnection;
import android.os.Bundle;
import android.os.IBinder;
import android.support.v7.app.AppCompatActivity;
import android.widget.Toast;

import ink.service.SinchService;

/**
 * Created by USER on 2016-07-24.
 */
public abstract class BaseActivity extends AppCompatActivity implements ServiceConnection {
    private SinchService.SinchServiceInterface mSinchServiceInterface;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        getApplicationContext().bindService(new Intent(this, SinchService.class), this,
                BIND_AUTO_CREATE);
    }

    @Override
    public void onServiceConnected(ComponentName componentName, IBinder iBinder) {
        if (SinchService.class.getName().equals(componentName.getClassName())) {
            mSinchServiceInterface = (SinchService.SinchServiceInterface) iBinder;
            onServiceConnected();
        }
    }

    @Override
    public void onServiceDisconnected(ComponentName componentName) {
        Toast.makeText(BaseActivity.this, "Service disconnected", Toast.LENGTH_SHORT).show();
        if (SinchService.class.getName().equals(componentName.getClassName())) {
            mSinchServiceInterface = null;
            onServiceDisconnected();
        }
    }

    protected void onServiceConnected() {
        // for subclasses
    }

    protected void onServiceDisconnected() {
        // for subclasses
    }

    protected SinchService.SinchServiceInterface getSinchServiceInterface() {
        return mSinchServiceInterface;
    }

}

The sinch service

 * Created by USER on 2016-07-24.
 */
public class SinchService extends Service {

    private static final String APP_KEY = "HIDDEN";
    private static final String APP_SECRET = "HIDDEN";
    private static final String ENVIRONMENT = "HIDDEN";

    public static final String LOCATION = "LOCATION";
    public static final String CALL_ID = "CALL_ID";
    static final String TAG = SinchService.class.getSimpleName();

    private SinchServiceInterface mSinchServiceInterface = new SinchServiceInterface();
    private SinchClient mSinchClient;
    private String mUserId;

    private StartFailedListener mListener;

    @Override
    public void onCreate() {
        super.onCreate();
        Toast.makeText(SinchService.this, "Service created", Toast.LENGTH_SHORT).show();
    }

    @Override
    public void onDestroy() {
//        if (mSinchClient != null && mSinchClient.isStarted()) {
//            mSinchClient.terminate();
//        }
        Toast.makeText(SinchService.this, "Service destroyed", Toast.LENGTH_SHORT).show();
        super.onDestroy();
    }

    private void start(String userName) {
        if (mSinchClient == null) {
            mUserId = userName;
            mSinchClient = Sinch.getSinchClientBuilder().context(getApplicationContext()).userId(userName)
                    .applicationKey(APP_KEY)
                    .applicationSecret(APP_SECRET)
                    .environmentHost(ENVIRONMENT).build();

            mSinchClient.setSupportCalling(true);
            mSinchClient.startListeningOnActiveConnection();
            mSinchClient.setSupportActiveConnectionInBackground(true);

            mSinchClient.addSinchClientListener(new ClientListener());
            mSinchClient.getCallClient().addCallClientListener(new SinchCallClientListener());
            mSinchClient.start();
        }
    }

    private void stop() {
        if (mSinchClient != null) {
            mSinchClient.terminate();
            mSinchClient = null;
        }
    }

    private boolean isStarted() {
        return (mSinchClient != null && mSinchClient.isStarted());
    }

    @Override
    public IBinder onBind(Intent intent) {
        return mSinchServiceInterface;
    }

    public class SinchServiceInterface extends Binder {

        public Call callPhoneNumber(String phoneNumber) {
            return mSinchClient.getCallClient().callPhoneNumber(phoneNumber);
        }

        public Call callUser(String userId) {
            return mSinchClient.getCallClient().callUser(userId);
        }

        public Call callUser(String userId, Map<String, String> headers) {
            return mSinchClient.getCallClient().callUser(userId, headers);
        }

        public String getUserName() {
            return mUserId;
        }

        public boolean isStarted() {
            return SinchService.this.isStarted();
        }

        public void startClient(String userName) {
            start(userName);
        }

        public void stopClient() {
            stop();
        }

        public void setStartListener(StartFailedListener listener) {
            mListener = listener;
        }

        public Call getCall(String callId) {
            return mSinchClient.getCallClient().getCall(callId);
        }
    }

    public interface StartFailedListener {
        void onStartFailed(SinchError error);

        void onStarted();
    }

    private class ClientListener implements SinchClientListener {

        @Override
        public void onClientFailed(SinchClient client, SinchError error) {
            if (mListener != null) {
                mListener.onStartFailed(error);
            }
            mSinchClient.terminate();
            mSinchClient = null;
        }

        @Override
        public void onClientStarted(SinchClient client) {
            Log.d(TAG, "SinchClient started");
            if (mListener != null) {
                mListener.onStarted();
            }
        }

        @Override
        public void onClientStopped(SinchClient client) {
            Toast.makeText(SinchService.this, "Sinch client stopped", Toast.LENGTH_SHORT).show();
            Log.d(TAG, "SinchClient stopped");
        }

        @Override
        public void onLogMessage(int level, String area, String message) {
            switch (level) {
                case Log.DEBUG:
                    Log.d(area, message);
                    break;
                case Log.ERROR:
                    Log.e(area, message);
                    break;
                case Log.INFO:
                    Log.i(area, message);
                    break;
                case Log.VERBOSE:
                    Log.v(area, message);
                    break;
                case Log.WARN:
                    Log.w(area, message);
                    break;
            }
        }

        @Override
        public void onRegistrationCredentialsRequired(SinchClient client,
                                                      ClientRegistration clientRegistration) {
        }
    }

    private class SinchCallClientListener implements CallClientListener {

        @Override
        public void onIncomingCall(CallClient callClient, Call call) {
            Log.d(TAG, "Incoming call");
            Intent intent = new Intent(SinchService.this, IncomingCallScreenActivity.class);
            intent.putExtra(CALL_ID, call.getCallId());
            intent.putExtra(LOCATION, call.getHeaders().get("callerName"));
            intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
            SinchService.this.startActivity(intent);
        }
    }

}

And here is how i start the sinch service inside my launcher activity.

   @Override
    protected void onServiceConnected() {
        if (!getSinchServiceInterface().isStarted()) {
            getSinchServiceInterface().startClient(mSharedHelper.getUserId());
        }
        getSinchServiceInterface().setStartListener(this);
    }

回答1:


1) add to your sinchClient mSinchClient.setSupportManagedPush(true); to receive push notification message when you receive call

2) Set Up a Firebase Cloud Messaging on your app

3) onMessageReceived transfer data to your IncomingTransparentCallActivity

    public class FirebaseMsgService extends FirebaseMessagingService {
            @Override
            public void onMessageReceived(RemoteMessage remoteMessage) {
                super.onMessageReceived(remoteMessage);

        Map<String, String> map = remoteMessage.getData();
                    HashMap dataHashMap =
                            (map instanceof HashMap)
                                    ? (HashMap) map
                                    : new HashMap<>(map);
                    if (SinchHelpers.isSinchPushPayload(map)) {
        ///Check if the application is in foreground if in foreground the SinchService already run //// 
          if (foregrounded()){
                        return;
                    }
                        Intent intent = new Intent(this, IncomingCallActivity.class);
                        NotificationCallVo callVo = new  NotificationCallVo();
                        callVo.setData(dataHashMap);
                        intent.putExtra(Constants.PARCELABLE, callVo);
                        startActivity(intent);

                    }

  ///To check if the app is in foreground ///
    public static boolean foregrounded() {
        ActivityManager.RunningAppProcessInfo appProcessInfo =
                new ActivityManager.RunningAppProcessInfo();
        ActivityManager.getMyMemoryState(appProcessInfo);
        return (appProcessInfo.importance == IMPORTANCE_FOREGROUND
                || appProcessInfo.importance == IMPORTANCE_VISIBLE);
    }

        }

NotificationCallVo

  public class NotificationCallVo implements Parcelable {

        private HashMap data;

        public NotificationCallVo() {
        }

        private NotificationCallVo(Parcel in) {
            data = (HashMap) in.readValue(HashMap.class.getClassLoader());
        }

        @Override
        public int describeContents() {
            return 0;
        }

        @Override
        public void writeToParcel(Parcel dest, int flags) {
            dest.writeValue(data);
        }

        @SuppressWarnings("unused")
        public static final Parcelable.Creator<NotificationCallVo> CREATOR = new Parcelable.Creator<NotificationCallVo>() {
            @Override
            public NotificationCallVo createFromParcel(Parcel in) {
                return new NotificationCallVo(in);
            }

            @Override
            public NotificationCallVo[] newArray(int size) {
                return new NotificationCallVo[size];
            }
        };

        public HashMap getData() {
            return data;
        }

        public void setData(HashMap<String, String> data) {
            this.data = data;
        }
    }

4) On your SinchServiceInterface add the method

public NotificationResult relayRemotePushNotificationPayload(final Map payload) {
            if (mSinchClient == null && !mSettings.getUsername().isEmpty()) {
                startClient(mSettings.getUsername());
            } else if (mSinchClient == null && mSettings.getUsername().isEmpty()) {
                Log.e(TAG, "Can't start a SinchClient as no username is available, unable to relay push.");
                return null;
            }
            return mSinchClient.relayRemotePushNotificationPayload(payload);
        } 

5) on IncomingTransparentCallActivity Connect to SinchService and onServiceConnected transfer data to sinchServiceInterface

public class IncomingTransparentCallActivity extends BaseCallActivity {
    private NotificationCallVo mCallVo;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        if (getIntent().getParcelableExtra(Constants.PARCELABLE) != null &&
                getIntent().getParcelableExtra(Constants.PARCELABLE) instanceof NotificationCallVo) {
            mCallVo = getIntent().getParcelableExtra(Constants.PARCELABLE);
        }
    }

    @Override
    protected void onServiceConnected(IBinder iBinder) {
        SinchService.SinchServiceInterface sinchServiceInterface = getSinchServiceInterface();
        if (mCallVo != null) {
            NotificationResult result = sinchServiceInterface.relayRemotePushNotificationPayload(mCallVo.getData());
            setContentView(R.layout.activity_incoming_call);
        }
    }
}

6) BaseCallActivity

public abstract class BaseCallActivity extends AppCompatActivity implements ServiceConnection {
    private SinchService.SinchServiceInterface mSinchServiceInterface;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        bindService(new Intent(this, SinchService.class), this,
                Context.BIND_AUTO_CREATE);
    }

    @Override
    public void onServiceConnected(ComponentName name, IBinder iBinder) {
        if (SinchService.class.getName().equals(name.getClassName())) {
            mSinchServiceInterface = (SinchService.SinchServiceInterface) iBinder;
            onServiceConnected(iBinder);
        }
    }

    @Override
    public void onServiceDisconnected(ComponentName name) {
        if (SinchService.class.getName().equals(name.getClassName())) {
            mSinchServiceInterface = null;
            onServiceDisconnected();
        }
    }

    @Override
    public void onBindingDied(ComponentName name) {

    }

    protected void onServiceConnected(IBinder iBinder) {
        // for subclasses
    }

    protected void onServiceDisconnected() {
        // for subclasses
    }

    protected SinchService.SinchServiceInterface getSinchServiceInterface() {
        return mSinchServiceInterface;
    }

    public void setmSinchServiceInterface(SinchService.SinchServiceInterface mSinchServiceInterface) {
        this.mSinchServiceInterface = mSinchServiceInterface;
    }



    @Override
    protected void onDestroy() {
        unbindService(this);
        super.onDestroy();
    }
}

7) SinchCallClientListener will listen to your incoming call and open your activity

check the below link [https://www.sinch.com/learn/sinch-managed-push-calling-android/][1]




回答2:


It seems like you haven't declared your Service in manifest file. Do it following way:

<service
        android:name=".SinchService"   
        android:exported="false" />

If you have, please share your manifest file with us.



来源:https://stackoverflow.com/questions/38556403/sinch-not-running-in-background-no-way-android

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!