[英]Android unable to receive notification when app is killed using FCM
[英]Incoming call Notification using sinch in Android ,I am Using FireBase Messaging service but not getting calls when app is killed in background
我正在开发VoIP应用程序,以便将应用程序调用到应用程序。 我正在使用Sinch API,FCM来接收后台传入的消息。 它工作正常,但是当应用程序在后台被杀死时,我没有接到来电。 我的代码如下
FCM-
public class FireBaseMsgService extends FirebaseMessagingService {
public static SinchClient sinchClient=null;
public static CallClient callClient=null;
String username;
@Override
public void onCreate() {
username=Common.getSavedUserData(this,"user_name");
super.onCreate();
if(username!=null){
initsinch();
}
}
@Override
public void onMessageReceived(RemoteMessage remoteMessage) {
super.onMessageReceived(remoteMessage);
//initsinch();
if(foregrounded()){
return;
}
if(SinchHelpers.isSinchPushPayload(remoteMessage.getData())){
initsinch();
NotificationResult result = sinchClient.relayRemotePushNotificationPayload(remoteMessage.getData()); // relay the background incomming call
}
}
///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);
}
private void initsinch(){
if (sinchClient==null){
android.content.Context context = this.getApplicationContext();
sinchClient = Sinch.getSinchClientBuilder().context(context)
.applicationKey(APP_KEY)
.applicationSecret(APP_SECRET)
.environmentHost(ENVIORNMENT)
.userId(username).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) {
}
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) {
}
});
callClient=sinchClient.getCallClient();
callClient.setRespectNativeCalls(true);
callClient.addCallClientListener(new CallClientListener() {
@Override
public void onIncomingCall(CallClient callClient, Call INCOMMINGCALL) {
Intent it=new Intent(getApplicationContext(),IncomingCallScreenActivity.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();
}
}
}
用户名是在Sinch用户中初始化的登录用户名。 我在ImcomingCallActivity.call中创建了mCall对象,并在Onservice Connected()中接收了调用对象,并按如下方式调用sinchCall侦听器,
public class IncomingCallScreenActivity extends BaseActivity {
static final String TAG=IncomingCallScreenActivity.class.getSimpleName();
private String mCallId;
private String mCallLocation;
private AudioPlayer mAudioPlayer;
TextView highlight;
// private NotificationCallvo mCallVo;
Call fmcall;
ImageView img;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.incoming);
highlight=(TextView)findViewById(R.id.highlight);
Animation a = AnimationUtils.loadAnimation(this, R.anim.blink);
a.reset();
highlight.startAnimation(a);
img=(ImageView)findViewById(R.id.image);
// Animation shake = AnimationUtils.loadAnimation(this, R.anim.milkshake);
// img.startAnimation(shake);
ImageButton answer=(ImageButton)findViewById(R.id.answerButton);
Animation shake = AnimationUtils.loadAnimation(this, R.anim.milkshake);
answer.startAnimation(shake);
answer.setOnClickListener(mClickListener);
ImageButton decline=(ImageButton) findViewById(R.id.declineButton);
decline.startAnimation(shake);
decline.setOnClickListener(mClickListener);
mAudioPlayer=new AudioPlayer(this);
mAudioPlayer.playRingTone();
mCallId=getIntent().getStringExtra(SinchService.CALL_ID);
System.out.println("cllerid++"+mCallId);
mCallLocation=getIntent().getStringExtra(SinchService.LOCATION);
}
@Override
protected void onServiceConnected()
{
if(getIntent().getExtras().get("mCall")!=null){
fmcall=FireBaseMsgService.callClient.getCall((String) getIntent().getExtras().get("mCall"));
((Call) fmcall).addCallListener(new SinchCallListener());
TextView remoteUser = (TextView) findViewById(R.id.remoteUser);
remoteUser.setText(((Call) fmcall).getRemoteUserId());
// TextView remoteUserLocation = (TextView) findViewById(R.id.remoteUserLocation);
// remoteUserLocation.setText("Calling from " + mCallLocation);
}else {
Call call = getSinchServiceInterface().getCall(mCallId);
if (call != null) {
call.addCallListener(new SinchCallListener());
TextView remoteUser = (TextView) findViewById(R.id.remoteUser);
remoteUser.setText(call.getRemoteUserId());
TextView remoteUserLocation = (TextView) findViewById(R.id.remoteUserLocation);
remoteUserLocation.setText("Calling from " + mCallLocation);
} else {
Log.e(TAG, "Started with invalid callId, aborting");
finish();
}
}
}
private void answerClicked() {
mAudioPlayer.stopRingtone();
if (getIntent().getExtras().get("mCall") != null) {
fmcall = FireBaseMsgService.callClient.getCall((String) getIntent().getExtras().get("mCall"));
fmcall.answer();
Intent intent = new Intent(this, CallScreenActivity.class);
intent.putExtra("fcallId", (String) getIntent().getExtras().get("mCall"));
startActivity(intent);
} else {
Call call = getSinchServiceInterface().getCall(mCallId);
if (call != null) {
call.answer();
Intent intent = new Intent(this, CallScreenActivity.class);
intent.putExtra(SinchService.CALL_ID, mCallId);
startActivity(intent);
} else {
finish();
}
}
}
private void declineClicked(){
mAudioPlayer.stopRingtone();
if(getIntent().getExtras().get("mCall")!=null){
fmcall.hangup();
}else {
Call call=getSinchServiceInterface().getCall(mCallId);
if(call!=null)
{
call.hangup();
}
finish();
}
}
private class SinchCallListener implements CallListener {
@Override
public void onCallProgressing(Call call) {
Log.d(TAG,"Call progressing");
}
@Override
public void onCallEstablished(Call call) {
Log.d(TAG,"Call Established");
}
@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 onShouldSendPushNotification(Call call, List<PushPair> list) {
}
}
private View.OnClickListener mClickListener=new View.OnClickListener() {
@Override
public void onClick(View view) {
switch (view.getId())
{
case R.id.answerButton:
answerClicked();
break;
case R.id.declineButton:
declineClicked();
break;
}
}
};
}
当我在后台杀死该应用并使用另一台设备拨打该用户名时,我没有收到呼叫通知。 请帮忙
为此,您需要准备一项服务。 以下是服务代码。
public class SinchService extends Service {
private static final String APP_KEY = "REPLACE_WITH_YOUR_APP_KEY";
private static final String APP_SECRET = "REPLACE_WITH_APP_SECRET";
private static final String ENVIRONMENT = "sandbox.sinch.com";
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();
}
@Override
public void onDestroy() {
if (mSinchClient != null && mSinchClient.isStarted()) {
mSinchClient.terminate();
}
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.addSinchClientListener(new MySinchClientListener());
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 NotificationResult relayRemotePushNotificationPayload(final Map payload) {
if (mSinchClient == null && !mUserId.isEmpty()) {
start(mUserId);
} else if (mSinchClient == null && mUserId.isEmpty()) {
Log.e(TAG, "Can't start a SinchClient as no username is available, unable to relay push.");
return null;
}
return mSinchClient.relayRemotePushNotificationPayload(payload);
}
}
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, "Incoming call");
Intent intent = new Intent(SinchService.this, IncomingCallScreenActivity.class);
intent.putExtra(CALL_ID, call.getCallId());
intent.putExtra(LOCATION, call.getHeaders().get("location"));
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
SinchService.this.startActivity(intent);
}
}
}
之后,在用户允许了插入权限之后,在您的主要活动中使用以下代码启动此服务
FirebaseApp.initializeApp(this);
getApplicationContext().bindService(new Intent(this, SinchService.class), this,
BIND_AUTO_CREATE);
并用以下代码替换您的FireBaseMsgService
public class FireBaseMsgService extends FirebaseMessagingService {
@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) {
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
}
}
payload = null;
}
@Override
public void onServiceDisconnected(ComponentName name) {}
public void relayMessageData(Map<String, String> data) {
payload = data;
getApplicationContext().bindService(new Intent(getApplicationContext(), SinchService.class), this, BIND_AUTO_CREATE);
}
}.relayMessageData(data);
}
}
}
创建临时前台服务
public class TempService extends Service {
@Nullable
@Override
public IBinder onBind(Intent intent) {
return null;
}
@Override
public void onCreate() {
super.onCreate();
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O)
startMyOwnForeground();
else
startForeground(1, new Notification());
return START_STICKY;
}
@RequiresApi(api = Build.VERSION_CODES.O)
private void startMyOwnForeground(){
String NOTIFICATION_CHANNEL_ID = "com.example.simpleapp";
String channelName = "My Background Service";
NotificationChannel chan = new NotificationChannel(NOTIFICATION_CHANNEL_ID, channelName, NotificationManager.IMPORTANCE_NONE);
chan.setLightColor(Color.BLUE);
chan.setLockscreenVisibility(Notification.VISIBILITY_PRIVATE);
NotificationManager manager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
assert manager != null;
manager.createNotificationChannel(chan);
NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(this, NOTIFICATION_CHANNEL_ID);
Notification notification = notificationBuilder.setOngoing(true)
.setSmallIcon(R.drawable.ic_launcher_background)
.setContentTitle("App is running in background")
.setPriority(NotificationManager.IMPORTANCE_MIN)
.setCategory(Notification.CATEGORY_SERVICE)
.build();
startForeground(2, notification);
}
}
并在主要活动中启动该服务
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
startForegroundService(new Intent(this,TempService.class));
} else
startService(new Intent(this,TempService.class));
清单声明部分
<service
android:name=".TempService"
android:exported="true"/>
在您的代码中检查一次您是否没有下面的代码,然后在代码中添加注释
getSinchServiceInterface().stopClient();
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.