美好的一天。我正在使用sinch进行音频通话。我不知道该怎么做,并且没有明确的sinch文件(这是非常令人费解的),这会让我知道如何让sinch客户端在后台运行在应用程序被杀时,在后台监听来电。同时我认为我强迫sinch客户端不被终止,但每次应用程序打开时,客户端都会被启动。所以,如果有人遇到这样的事情,你能不能请帮帮我,告诉我怎样才能在Sinch的后台听取来电?发布我已经启动并运行的代码。
我所有活动都继承的基本活动。
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;
}
}
sinch服务
* 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);
}
}
}
以下是我在启动器活动中启动sinch服务的方法。
@Override
protected void onServiceConnected() {
if (!getSinchServiceInterface().isStarted()) {
getSinchServiceInterface().startClient(mSharedHelper.getUserId());
}
getSinchServiceInterface().setStartListener(this);
}
答案 0 :(得分:4)
1)添加到您的sinchClient mSinchClient.setSupportManagedPush(true);
以在接到电话时收到推送通知消息
2)在您的应用上设置Firebase云消息传递
3)onMessageReceived将数据传输到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)在SinchServiceInterface上添加方法
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)关于IncomingTransparentCallActivity连接到SinchService和onServiceConnected传输数据到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将收听您的来电并打开您的活动
检查以下链接 [https://www.sinch.com/learn/sinch-managed-push-calling-android/][1]
答案 1 :(得分:1)
好像您还没有在清单文件中声明您的服务。按照以下方式进行:
<service
android:name=".SinchService"
android:exported="false" />
如果有,请与我们分享您的清单文件。
答案 2 :(得分:0)
我的回答可能有点晚了,但我希望它会有用。不久前,我遇到了同样的问题,并使用sinch的文档(link here)解决了该问题,如果您在应用中使用FCM进行推送通知,请按照以下步骤操作:
1。使用这些变量在您的应用中创建FCM服务,并在打开应用以初始化前台调用时调用startservice:
public static SinchClient sinchClient=null;
public static CallClient callClient=null;
@Override
public void onCreate() {
initsinch();
Log.d(MY_TAG,"onCreate FCM");
super.onCreate();
}
2。根据sinch的文档:
在以下情况下,应用程序被视为离线:
- 应用程序未运行时
- 已为Sinch客户端禁用后台模式,并且应用程序不在前台。
对于这两种情况,推送通知必须在 能够接收来电和即时消息的应用程序。 以下各节介绍如何支持接听电话和 通过推送通知发送消息。
所以您需要在onMessageReceived()中做什么:
if (SinchHelpers.isSinchPushPayload(remoteMessage.getData())) { //it sinch payload
initsinch(); // init sinch and callclient for background call
NotificationResult result = sinchClient.relayRemotePushNotificationPayload(remoteMessage.getData()); // relay the background incomming call
}else { //push your own notifications }
3。在imcommingcall活动中,您应该使用在FCM服务类中创建的sinchclient创建mCall对象。(这就是sinchclient变量需要公开的原因):
if (getIntent().getExtras().get("mCall")!=null)
{
mCall =MyFirebaseMessaging.callClient.getCall(getIntent().getExtras().get("mCall").toString());
mCall.addCallListener(callListener);
}
这就是您需要做的。我没有将sinch用作绑定服务。只是将其用作公共变量。让我知道它是否有效
这是我的initsinch()方法:
private void initsinch() {
if (sinchClient==null){
Log.d(MY_TAG,"Init sinch FCM");
android.content.Context context = this.getApplicationContext();
sinchClient = Sinch.getSinchClientBuilder().context(context)
.applicationKey("your own applicationKey")
.applicationSecret("your own applicationSecret")
.environmentHost("sandbox.sinch.com")
.userId("your own user id").build();
sinchClient.setSupportCalling(true);
sinchClient.setSupportActiveConnectionInBackground(true);
sinchClient.startListeningOnActiveConnection();
sinchClient.setSupportManagedPush(true);
sinchClient.setPushNotificationDisplayName("my display name");
sinchClient.addSinchClientListener(new SinchClientListener() {
public void onClientStarted(SinchClient client) {
Log.d(MY_TAG,"Sinch started");
}
public void onClientStopped(SinchClient client) {
Log.d(MY_TAG,"Sinch stopped");
}
public void onClientFailed(SinchClient client, SinchError error) {
Log.d(MY_TAG,"Sinch Fail");
}
public void onRegistrationCredentialsRequired(SinchClient client, ClientRegistration registrationCallback) {
}
public void onLogMessage(int level, String area, String message) {
}
});
callClient=sinchClient.getCallClient();
callClient.setRespectNativeCalls(true);
callClient.addCallClientListener(new CallClientListener() {
@Override
public void onIncomingCall(CallClient callClient, Call INCOMMINGCALL) {
if (INCOMMINGCALL.getDetails().isVideoOffered()){
Intent it=new Intent(getApplicationContext(),Video_imcomming_call.class);
it.putExtra("mCall", INCOMMINGCALL.getCallId());
it.putExtra("mCall_caller", INCOMMINGCALL.getRemoteUserId());
it.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(it);
}else {
Intent it=new Intent(getApplicationContext(),Incomming_call.class);
it.putExtra("mCall", INCOMMINGCALL.getCallId());
it.putExtra("mCall_caller", INCOMMINGCALL.getRemoteUserId());
it.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(it);
}
}
});
}
if (sinchClient!=null && !sinchClient.isStarted()){
sinchClient.start();
}
}