Sinch视频通话在后台不工作

问题描述

我在当前应用中实现了 Sinch 视频通话。当应用程序在前台时,来电一切正常。但是当我关闭应用程序并尝试接听来电时,它没有显示任何来电。如何在应用程序关闭来电时进行视频 Sinch 通话?以下是我的 FCMMessageReceiverService 类。

scripts = soup.find_all('script')
for i in scripts:
    if "salePrice" in str(i):
        required_script = str(i)
        break
temp = required_script.split('"salePrice":{"text":"')[1]
LazPrice = temp.split('",')[0]
print(LazPrice)

这是我的服务代码

public class FCMMessageReceiverService  extends FirebaseMessagingService implements ServiceConnection {

    Context context;
    private SinchService.SinchServiceInterface mSinchServiceInterface;
    HashMap dataHashMap;


    @Override
    public void onMessageReceived(RemoteMessage remoteMessage) {
        context = this;
        if (SinchHelpers.isSinchPushPayload(remoteMessage.getData())) {
            Map data = remoteMessage.getData();
            dataHashMap = (data instanceof HashMap) ? (HashMap) data : new HashMap<>(data);
            if (SinchHelpers.isSinchPushPayload(dataHashMap)) {
                getApplicationContext().bindService(new Intent(getApplicationContext(),SinchService.class),this,Context.BIND_AUTO_CREATE);
            }
        } else {
            Intent intent;
            PendingIntent pendingIntent = null;
            if (remoteMessage.getData().size() > 0) {
                String identifier = remoteMessage.getData().get("identifier");
                if (identifier.equals("0")) {
                    intent = new Intent(this,MainActivity.class);
                    intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
                    pendingIntent = PendingIntent.getActivity(this,intent,PendingIntent.FLAG_ONE_SHOT);
                }
            }
            NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(this);
            notificationBuilder.setWhen(System.currentTimeMillis());
            notificationBuilder.setContentTitle(remoteMessage.getNotification().getTitle());
            notificationBuilder.setContentText(remoteMessage.getNotification().getBody());
            notificationBuilder.setVisibility(NotificationCompat.VISIBILITY_PUBLIC);
            notificationBuilder.setDefaults(Notification.DEFAULT_ALL | Notification.DEFAULT_LIGHTS | Notification.FLAG_SHOW_LIGHTS | Notification.DEFAULT_SOUND);
            notificationBuilder.setAutoCancel(true);
            notificationBuilder.setSmallIcon(R.mipmap.ic_launcher);
            notificationBuilder.setContentIntent(pendingIntent);
            notificationmanager notificationmanager = (notificationmanager) getSystemService(Context.NOTIFICATION_SERVICE);
            notificationmanager.notify(0,notificationBuilder.build());
        }

    }

    public static boolean foregrounded() {
        ActivityManager.RunningAppProcessInfo appProcessInfo = new ActivityManager.RunningAppProcessInfo();
        ActivityManager.getMyMemoryState(appProcessInfo);
        return (appProcessInfo.importance == appProcessInfo.IMPORTANCE_FOREGROUND || appProcessInfo.importance == appProcessInfo.IMPORTANCE_VISIBLE);
    }

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

        // it starts incoming call activity which does not show incoming caller name and picture
        NotificationResult result = mSinchServiceInterface.relayRemotePushNotificationPayload(dataHashMap);
        if (result.isValid() && result.isCall()) {
            CallNotificationResult callResult = result.getCallResult();
            if (callResult.isCallCanceled() || callResult.isTimedOut()) {
                createNotification("Missed Call from : ",callResult.getRemoteUserId());
                return;
            } else {
                if (callResult.isVideoOffered()) {
                    Intent intent = new Intent(this,IncomingCallScreenActivity.class);
                    intent.putExtra(SinchService.CALL_ID,callResult.getRemoteUserId());
                    intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_NO_HISTORY);
                    startActivity(intent);
                }
            }
        } else if (result.isValid() && result.isMessage()) {
            //i want to get message content here
            MessageNotificationResult notificationResult = result.getMessageResult();
            createNotification("Received Message from : ",notificationResult.getSenderId());
        }
    }

    @Override
    public void onServicedisconnected(ComponentName componentName) {
        unbindService(this);
    }

    private void createNotification(String contentTitle,String userId) {
        PendingIntent contentIntent = PendingIntent.getActivity(getApplicationContext(),new Intent(getApplicationContext(),MainActivity.class),0);
        NotificationCompat.Builder mBuilder = new NotificationCompat.Builder(getApplicationContext()).setSmallIcon(R.mipmap.ic_launcher).setContentTitle(contentTitle).setContentText(userId);
        mBuilder.setContentIntent(contentIntent);
        mBuilder.setDefaults(Notification.DEFAULT_SOUND);
        mBuilder.setAutoCancel(true);
        notificationmanager mnotificationmanager = (notificationmanager) getApplicationContext().getSystemService(Context.NOTIFICATION_SERVICE);
        mnotificationmanager.notify(1,mBuilder.build());
    }
}

解决方法

在我们的 SDK 包中,您会在 Samples 文件夹下找到多个示例文件,名为 sinch-rtc-sample-video-push 的文件可以满足您的需求。 您还应该在这里查看我们的文档: https://developers.sinch.com/docs/voice-android-push-notifications

最好的问候

Android Sample Apps

,

将 FCM 添加到您的项目

添加以下代码

public class SinchService  extends Service {
static final String APP_KEY = "************";
static final String APP_SECRET = "***********";
static final String ENVIRONMENT = "clientapi.sinch.com";
public static final int MESSAGE_PERMISSIONS_NEEDED = 1;
public static final String REQUIRED_PERMISSION = "REQUIRED_PESMISSION";
public static final String MESSENGER = "MESSENGER";
private Messenger messenger;

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;
private PersistedSettings mSettings;
private AudioPlayer audioPlayer;
private Handler handler;

@Override
public void onCreate() {
    super.onCreate();
    super.onCreate();
    mSettings = new PersistedSettings(getApplicationContext());
    String userName = mSettings.getUsername();


    if (!userName.isEmpty()) {

       
        start(userName);


    }
    handler = new Handler();

}
private void createClient(String username) {
    mSinchClient = Sinch.getSinchClientBuilder().context(getApplicationContext()).userId(username)
            .applicationKey(APP_KEY)
            .applicationSecret(APP_SECRET)
            .environmentHost(ENVIRONMENT).build();

    mSinchClient.setSupportCalling(true);
    mSinchClient.setSupportManagedPush(true);

    mSinchClient.addSinchClientListener(new MySinchClientListener());
    mSinchClient.getCallClient().addCallClientListener(new SinchCallClientListener());
    mSinchClient.setPushNotificationDisplayName("User " + username);
}


@Override
public void onDestroy() {
    if (mSinchClient != null && mSinchClient.isStarted()) {
        mSinchClient.terminateGracefully();
    }
    super.onDestroy();
}
private boolean hasUsername() {
    if (mSettings.getUsername().isEmpty()) {
        Log.e(TAG,"Can't start a SinchClient as no username is available!");
        return false;
    }
    return true;
}
private void createClientIfNecessary() {
    if (mSinchClient != null)
        return;
    if (!hasUsername()) {
        throw new IllegalStateException("Can't create a SinchClient as no username is available!");
    }
    createClient(mSettings.getUsername());
}

private void start(String userName) {
    boolean permissionsGranted = true;
    if (mSinchClient == null) {
        mSettings.setUsername(userName);
        createClient(userName);
    }
    createClientIfNecessary();
    try {
        //mandatory checks
        mSinchClient.checkManifest();
        if (getApplicationContext().checkCallingOrSelfPermission(Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED) {
            throw new MissingPermissionException(Manifest.permission.CAMERA);
        }
    } catch (MissingPermissionException e) {
        permissionsGranted = false;
        if (messenger != null) {
            Message message = Message.obtain();
            Bundle bundle = new Bundle();
            bundle.putString(REQUIRED_PERMISSION,e.getRequiredPermission());
            message.setData(bundle);
            message.what = MESSAGE_PERMISSIONS_NEEDED;
            try {
                messenger.send(message);
            } catch (RemoteException e1) {
                e1.printStackTrace();
            }
        }
    }
    if (permissionsGranted) {
        Log.d(TAG,"Starting SinchClient");
        try {
            mSinchClient.start();
        } catch (IllegalStateException e) {
            Log.w(TAG,"Can't start SinchClient - " + e.getMessage());
        }
    }
}


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


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

@Override
public IBinder onBind(Intent intent) {
    messenger = intent.getParcelableExtra(MESSENGER);
    return mSinchServiceInterface;
}

public class SinchServiceInterface extends Binder {

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

    public String getUserName() {
        return mSettings.getUsername();
    }
    public void setUsername(String username) {
        mSettings.setUsername(username);
    }
    public void retryStartAfterPermissionGranted() {
        SinchService.this.attemptAutoStart();
    }

    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 VideoController getVideoController() {
        if (!isStarted()) {
            return null;
        }
        return mSinchClient.getVideoController();
    }

    public AudioController getAudioController() {
        if (!isStarted()) {
            return null;
        }
        return mSinchClient.getAudioController();
    }

    public NotificationResult relayRemotePushNotificationPayload(final Map payload) {
        if (!hasUsername()) {
            Log.e(TAG,"Unable to relay the push notification!");
            return null;
        }
        createClientIfNecessary();
        return mSinchClient.relayRemotePushNotificationPayload(payload);
    }

}

private void attemptAutoStart() {
}
public interface StartFailedListener {

    void onStartFailed(SinchError error);

    void onStarted();
}

private class MySinchClientListener 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) {
        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,"onIncomingCall: " + call.getCallId());
        audioPlayer = AudioPlayer.getInstance(getApplicationContext());
        call.addCallListener(new SinchCallListener());
        Intent intent = new Intent(SinchService.this,IncomingCallScreenActivity.class);
        intent.putExtra(EXTRA_ID,MESSAGE_ID);
        intent.putExtra(CALL_ID,call.getCallId());
        boolean inForeground = isAppOnForeground(getApplicationContext());
        intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
        if (inForeground) {
            SinchService.this.startActivity(intent);
        } else {
            if (!audioPlayer.isPlayedRingtone()) {
                audioPlayer.playRingtone();
            }
            ((NotificationManager) Objects.requireNonNull(getSystemService(NOTIFICATION_SERVICE))).notify(MESSAGE_ID,createIncomingCallNotification(call.getRemoteUserId(),intent));
        }
    }
    private boolean isAppOnForeground(Context context) {
        ActivityManager activityManager = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
        List<ActivityManager.RunningAppProcessInfo> appProcesses = null;
        if (activityManager != null) {
            appProcesses = activityManager.getRunningAppProcesses();
        }
        if (appProcesses == null) {
            return false;
        }
        final String packageName = context.getPackageName();
        for (ActivityManager.RunningAppProcessInfo appProcess : appProcesses) {
            if (appProcess.importance == ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND && appProcess.processName.equals(packageName)) {
                return true;
            }
        }
        return false;
    }
    private Bitmap getBitmap(Context context,int resId) {
        int largeIconWidth = (int) context.getResources()
                .getDimension(R.dimen.height);
        int largeIconHeight = (int) context.getResources()
                .getDimension(R.dimen.height);
        Drawable d = context.getResources().getDrawable(resId);
        Bitmap b = Bitmap.createBitmap(largeIconWidth,largeIconHeight,Bitmap.Config.ARGB_8888);
        Canvas c = new Canvas(b);
        d.setBounds(0,largeIconWidth,largeIconHeight);
        d.draw(c);
        return b;
    }
    private PendingIntent getPendingIntent(Intent intent,String action) {
        intent.setAction(action);
        PendingIntent pendingIntent = PendingIntent.getActivity(getApplicationContext(),111,intent,PendingIntent.FLAG_UPDATE_CURRENT);
        return pendingIntent;
    }
    @TargetApi(29)
    private Notification createIncomingCallNotification(String userId,Intent fullScreenIntent) {

        PendingIntent pendingIntent = PendingIntent.getActivity(getApplicationContext(),112,fullScreenIntent,PendingIntent.FLAG_UPDATE_CURRENT);
        NotificationCompat.Builder builder =
                new NotificationCompat.Builder(getApplicationContext(),FcmListenerService.CHANNEL_ID)
                        .setContentTitle("Incoming call")
                        .setContentText(userId)
                        .setLargeIcon(getBitmap(getApplicationContext(),R.drawable.call_normal))
                        .setSmallIcon(R.drawable.call_pressed)
                        .setPriority(NotificationCompat.PRIORITY_MAX)
                        .setContentIntent(pendingIntent)
                        .setFullScreenIntent(pendingIntent,true)
                        .addAction(R.drawable.button_accept,"Answer",getPendingIntent(fullScreenIntent,ACTION_ANSWER))
                        .addAction(R.drawable.button_decline,"Ignore",ACTION_IGNORE))
                        .setOngoing(true);

        return builder.build();
    }
}
private class SinchCallListener implements CallListener {

    @Override
    public void onCallEnded(Call call) {
        cancelNotification();
        if (audioPlayer != null && audioPlayer.isPlayedRingtone()) {
            audioPlayer.stopRingtone();
        }
    }

    @Override
    public void onCallEstablished(Call call) {
        Log.d(TAG,"Call established");
        if (audioPlayer != null && audioPlayer.isPlayedRingtone()) {
            audioPlayer.stopRingtone();
        }
    }

    @Override
    public void onCallProgressing(Call call) {
        Log.d(TAG,"Call progressing");
    }

    @Override
    public void onShouldSendPushNotification(Call call,List<PushPair> pushPairs) {
        // no need to implement for managed push
    }

}
public void cancelNotification() {
    NotificationManager nMgr = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
    if (nMgr != null) {
        nMgr.cancel(MESSAGE_ID);
    }
}
private static class PersistedSettings {
    private SharedPreferences mStore;
    private static final String PREF_KEY = "Sinch";

    public PersistedSettings(Context context) {
        mStore = context.getSharedPreferences(PREF_KEY,MODE_PRIVATE);
    }
    public String getUsername() {
        return mStore.getString("Username","");
    }
    public void setUsername(String username) {
        SharedPreferences.Editor editor = mStore.edit();
        editor.putString("Username",username);
        editor.apply();
    }
}

} 和 crete FcmListenerService 并添加以下代码

public class FcmListenerService extends FirebaseMessagingService {
public static String CHANNEL_ID = "Sinch Push Notification Channel";
private final String PREFERENCE_FILE = "com.sinch.android.rtc.sample.push.shared_preferences";
SharedPreferences sharedPreferences;
@Override
public void onMessageReceived(RemoteMessage remoteMessage){
    Map data = remoteMessage.getData();
    if (SinchHelpers.isSinchPushPayload(data)) {
        new ServiceConnection() {
            private Map payload;
            @Override
            public void onServiceConnected(ComponentName name,IBinder service) {

                Context context = getApplicationContext();
                sharedPreferences = context.getSharedPreferences(PREFERENCE_FILE,Context.MODE_PRIVATE);

                if (payload != null) {
                    SinchService.SinchServiceInterface sinchService = (SinchService.SinchServiceInterface) service;
                    if (sinchService != null) {
                        NotificationResult result = sinchService.relayRemotePushNotificationPayload(payload);
                        // handle result,e.g. show a notification or similar
                        // here is example for notifying user about missed/canceled call:
                        if (result!=null && result.isValid() && result.isCall()) {
                            CallNotificationResult callResult = result.getCallResult();
                            if (callResult != null && result.getDisplayName() != null) {
                                SharedPreferences.Editor editor = sharedPreferences.edit();
                                editor.putString(callResult.getRemoteUserId(),result.getDisplayName());
                                editor.apply();
                            }
                            if (callResult != null && callResult.isCallCanceled()) {
                                String displayName = result.getDisplayName();
                                if (displayName == null) {
                                    displayName = sharedPreferences.getString(callResult.getRemoteUserId(),"n/a");
                                }
                                createMissedCallNotification(!displayName.isEmpty() ? displayName : callResult.getRemoteUserId());
                                if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
                                    context.deleteSharedPreferences(PREFERENCE_FILE);
                                }
                            }
                        }
                    }
                }
                payload = null;
            }

            @Override
            public void onServiceDisconnected(ComponentName name) {}

            public void relayMessageData(Map<String,String> data) {
                payload = data;
                createNotificationChannel(NotificationManager.IMPORTANCE_MAX);
                getApplicationContext().bindService(new Intent(getApplicationContext(),SinchService.class),this,BIND_AUTO_CREATE);
            }
        }.relayMessageData(data);
    }
}

private void createNotificationChannel(int importance) {
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
        CharSequence name = "Amar LPG";
        String description = "Incoming call notification";
        NotificationChannel channel = new NotificationChannel(CHANNEL_ID,name,importance);
        channel.setDescription(description);
        NotificationManager notificationManager = getSystemService(NotificationManager.class);
        if (notificationManager != null) {
            notificationManager.createNotificationChannel(channel);
        }
    }
}
private void createMissedCallNotification(String userId) {

    createNotificationChannel(NotificationManager.IMPORTANCE_DEFAULT);

    PendingIntent contentIntent = PendingIntent.getActivity(getApplicationContext(),new Intent(getApplicationContext(),IncomingCallScreenActivity.class),0);
    NotificationCompat.Builder builder =
            new NotificationCompat.Builder(getApplicationContext(),CHANNEL_ID)
                    .setSmallIcon(R.drawable.icon)
                    .setContentTitle("Missed call from ")
                    .setContentText(userId)
                    .setContentIntent(contentIntent)
                    .setDefaults(Notification.DEFAULT_SOUND)
                    .setAutoCancel(true);
    NotificationManager mNotificationManager =
            (NotificationManager) getApplicationContext().getSystemService(Context.NOTIFICATION_SERVICE);
    if (mNotificationManager != null) {
        mNotificationManager.notify(1,builder.build());
    }
}

}

在来电屏幕添加以下代码

公共类 IncomingCallScreenActivity 扩展 BaseActivity {

static final String TAG = IncomingCallScreenActivity.class.getSimpleName();
private String mCallId;
private AudioPlayer mAudioPlayer;
public static final String ACTION_ANSWER = "answer";
public static final String ACTION_IGNORE = "ignore";
public static final String EXTRA_ID = "id";
public static int MESSAGE_ID = 14;
private String mAction;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_incoming_call_screen);

    Button answer = (Button) findViewById(R.id.answerButton);
    answer.setOnClickListener(mClickListener);
    Button decline = (Button) findViewById(R.id.declineButton);
    decline.setOnClickListener(mClickListener);

    mAudioPlayer = new AudioPlayer(this);
    mAudioPlayer.playRingtone();
    mCallId = getIntent().getStringExtra(SinchService.CALL_ID);
    mAction = "";
}
@Override
protected void onResume() {
    super.onResume();
    Intent intent = getIntent();
    if (intent != null) {
        if (intent.getStringExtra(SinchService.CALL_ID) != null) {
            mCallId = getIntent().getStringExtra(SinchService.CALL_ID);
        }
        final int id = intent.getIntExtra(EXTRA_ID,-1);
        if (id > 0) {
            NotificationManager notificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
            notificationManager.cancel(id);
        }
        mAction = intent.getAction();
    }
}

@Override
protected void onServiceConnected() {
    Call call = getSinchServiceInterface().getCall(mCallId);
    if (call != null) {
        call.addCallListener(new SinchCallListener());
        TextView remoteUser = (TextView) findViewById(R.id.remoteUser);
        remoteUser.setText(call.getRemoteUserId());

        if (ACTION_ANSWER.equals(mAction)) {
            mAction = "";
            answerClicked();
        } else if (ACTION_IGNORE.equals(mAction)) {
            mAction = "";
            declineClicked();
        }

    } else {
        Log.e(TAG,"Started with invalid callId,aborting");
        finish();
    }
}

private void answerClicked() {
    if (mAudioPlayer!=null && mAudioPlayer.isPlayedRingtone()){
        mAudioPlayer.stopRingtone();
    }

    Call call = getSinchServiceInterface().getCall(mCallId);
    if (call != null) {
        Log.d(TAG,"Answering call");
        call.answer();
        Intent intent = new Intent(this,CallScreenActivity.class);
        intent.putExtra(SinchService.CALL_ID,mCallId);
        startActivity(intent);
    } else {
        finish();
    }
}

private void declineClicked() {
    if (mAudioPlayer!=null && mAudioPlayer.isPlayedRingtone()){
        mAudioPlayer.stopRingtone();
    }
    Call call = getSinchServiceInterface().getCall(mCallId);
    if (call != null) {
        call.hangup();
    }
    finish();
}

private class SinchCallListener implements VideoCallListener {

    @Override
    public void onCallEnded(Call call) {
        CallEndCause cause = call.getDetails().getEndCause();
        Log.d(TAG,"Call ended,cause: " + cause.toString());
        mAudioPlayer.stopRingtone();
        finish();
    }

    @Override
    public void onCallEstablished(Call call) {
        Log.d(TAG,"Call established");
    }

    @Override
    public void onCallProgressing(Call call) {
        Log.d(TAG,List<PushPair> pushPairs) {
        
    }

    @Override
    public void onVideoTrackAdded(Call call) {
        // Display some kind of icon showing it's a video call
    }

    @Override
    public void onVideoTrackPaused(Call call) {

    }

    @Override
    public void onVideoTrackResumed(Call call) {

    }
}

private View.OnClickListener mClickListener = new View.OnClickListener() {
    @Override
    public void onClick(View v) {
        switch (v.getId()) {
            case R.id.answerButton:
                answerClicked();
                break;
            case R.id.declineButton:
                declineClicked();
                break;
        }
    }
};

}

在登录活动中添加以下代码。

公共类 MainActivity 扩展 BaseActivity 实现 SinchService.StartFailedListener、PushTokenRegistrationCallback、UserRegistrationCallback {

private Button mLoginButton;
private EditText mLoginName;
private ProgressDialog mSpinner;
private String mUserId;
private long mSigningSequence = 1;




@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

   
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
        requestPermissions(new String[]{Manifest.permission.RECORD_AUDIO,Manifest.permission.CAMERA,Manifest.permission.ACCESS_NETWORK_STATE,Manifest.permission.READ_PHONE_STATE},100);
    }

   
    mLoginName = (EditText) findViewById(R.id.loginName);
    mLoginButton = (Button) findViewById(R.id.loginButton);
    mLoginButton.setEnabled(false);
    mLoginButton.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            loginClicked();
        }
    });
}
@Override
protected void onResume() {
    super.onResume();
}


@Override
protected void onServiceConnected() {
    mLoginButton.setEnabled(true);
    getSinchServiceInterface().setStartListener(this);
}

@Override
protected void onPause() {
    if (mSpinner != null) {
        mSpinner.dismiss();
    }
    super.onPause();
}

@Override
public void onStartFailed(SinchError error) {
    Toast.makeText(this,error.toString(),Toast.LENGTH_LONG).show();
    if (mSpinner != null) {
        mSpinner.dismiss();
    }
}


@Override
public void onStarted() {
    openPlaceCallActivity();
}


private void loginClicked() {
    String userName = mLoginName.getText().toString();

    if (userName.isEmpty()) {
        Toast.makeText(this,"Please enter a name",Toast.LENGTH_LONG).show();
        return;
    }

    if (!getSinchServiceInterface().isStarted()) {
        getSinchServiceInterface().startClient(userName);
        showSpinner();
    } else {
        openPlaceCallActivity();
    }
    mUserId = userName;
    UserController uc = Sinch.getUserControllerBuilder()
            .context(getApplicationContext())
            .applicationKey(APP_KEY)
            .userId(mUserId)
            .environmentHost(ENVIRONMENT)
            .build();
    uc.registerUser(this,this);
}




private void openPlaceCallActivity() {
    Intent mainActivity = new Intent(this,PlaceCallActivity.class);
    startActivity(mainActivity);
    finish();
}

private void showSpinner() {
    mSpinner = new ProgressDialog(this);
    mSpinner.setTitle("Logging in");
    mSpinner.setMessage("Please wait...");
    mSpinner.show();
}
private void dismissSpinner() {
    if (mSpinner != null) {
        mSpinner.dismiss();
        mSpinner = null;
    }
}

@Override
public void tokenRegistered() {
    dismissSpinner();
    startClientAndOpenPlaceCallActivity();

}

private void startClientAndOpenPlaceCallActivity() {
    // start Sinch Client,it'll result onStarted() callback from where the place call activity will be started
    if (!getSinchServiceInterface().isStarted()) {
        getSinchServiceInterface().startClient("");
        showSpinner();
    }
}

@Override
public void tokenRegistrationFailed(SinchError sinchError) {
    dismissSpinner();
    Toast.makeText(this,"Push token registration failed - incoming calls can't be received!",Toast.LENGTH_LONG).show();
}

@Override
public void onCredentialsRequired(ClientRegistration clientRegistration) {
    String toSign = mUserId + APP_KEY + mSigningSequence + APP_SECRET;
    String signature;
    MessageDigest messageDigest;
    try {
        messageDigest = MessageDigest.getInstance("SHA-1");
        byte[] hash = messageDigest.digest(toSign.getBytes("UTF-8"));
        signature = Base64.encodeToString(hash,Base64.DEFAULT).trim();
    } catch (Exception e) {
        throw new RuntimeException(e.getMessage(),e.getCause());
    }

    clientRegistration.register(signature,mSigningSequence++);

}

@Override
public void onUserRegistered() {

}

@Override
public void onUserRegistrationFailed(SinchError sinchError) {
    dismissSpinner();
    Toast.makeText(this,"Registration failed!",Toast.LENGTH_LONG).show();
}

}