我正在我的应用程序中使用Sinch进行视频,音频和消息传递。当应用程序在前台运行时,调用和消息传递可以正常工作。当应用程序关闭并从堆栈中删除时,传入消息和调用仍然可以正常工作,因为我实现了推送通知以查找传入调用和消息(我在调试模式下进行了检查)。我的问题是
1)当我从firebaseMessaginService开始传入呼叫活动时,当我通过relayRemotePushNotificationPayload(HashMap)启动它时,它没有显示正在发送标头中的呼叫者姓名和图片; 2)我无法从传入消息中获取消息内容数据并相应地显示通知。
我的代码。
公共类MyFirebaseMessagingService扩展了FirebaseMessagingService实现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, 0, intent, PendingIntent.FLAG_ONE_SHOT);
} else if (identifier.equals("1")) {
intent = new Intent(this, Appointments.class);
pendingIntent = PendingIntent.getActivity(this, 0, intent, PendingIntent.FLAG_ONE_SHOT);
StaticInfo.saveData("HEALTH_TIP", "TIP", this);
}
}
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 == IMPORTANCE_FOREGROUND || appProcessInfo.importance == 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, IncomingVideoCall.class);
intent.putExtra(SinchService.CALL_ID, callResult.getRemoteUserId());
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_NO_HISTORY);
startActivity(intent);
} else {
Intent intent = new Intent(this, IncomingAudioCall.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(), 0, 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());
}
}
Sinch服务是
public class SinchService extends Service {
private static final String APP_KEY = "123abc";
private static final String APP_SECRET = "123abc";
private static final String ENVIRONMENT = "sandbox.sinch.com";
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;
@Override
public void onCreate() {
super.onCreate();
mSettings = new PersistedSettings(getApplicationContext());
String userName = mSettings.getUsername();
if (!userName.isEmpty()) {
start(userName);
}
}
@Override
public void onDestroy() {
if (mSinchClient != null && mSinchClient.isStarted()) {
mSinchClient.terminate();
}
super.onDestroy();
}
private void start(String userName) {
if (mSinchClient == null) {
mSettings.setUsername(userName);
mUserId = userName;
mSinchClient = Sinch.getSinchClientBuilder().context(getApplicationContext()).userId(userName).applicationKey(APP_KEY).applicationSecret(APP_SECRET).environmentHost(ENVIRONMENT).build();
mSinchClient.setSupportCalling(true);
mSinchClient.setSupportMessaging(true);
mSinchClient.setSupportManagedPush(true);
mSinchClient.checkManifest();
mSinchClient.setSupportActiveConnectionInBackground(true);
mSinchClient.startListeningOnActiveConnection();
mSinchClient.addSinchClientListener(new MySinchClientListener());
mSinchClient.getCallClient().setRespectNativeCalls(false);
mSinchClient.getCallClient().addCallClientListener(new SinchCallClientListener());
mSinchClient.getVideoController().setResizeBehaviour(VideoScalingType.ASPECT_FILL);
mSinchClient.start();
}
}
private void stop() {
if (mSinchClient != null) {
mSinchClient.terminate();
mSinchClient = null;
}
mSettings.setUsername("");
}
private boolean isStarted() {
return (mSinchClient != null && mSinchClient.isStarted());
}
@Override
public IBinder onBind(Intent intent) {
return mSinchServiceInterface;
}
public class SinchServiceInterface extends Binder {
public NotificationResult relayRemotePushNotificationPayload(final Map payload) {
if (mSinchClient == null && !mSettings.getUsername().isEmpty()) {
start(mSettings.getUsername());
} else if (mSinchClient == null && mSettings.getUsername().isEmpty()) {
if (!StaticInfo.getSavedData("username", SinchService.this).equals("")) {
start(StaticInfo.getSavedData("username", SinchService.this));
}
return null;
}
return mSinchClient.relayRemotePushNotificationPayload(payload);
}
public void sendMessage(String recipientUserId, String Name, String textBody, String imageUrl) {
SinchService.this.sendMessage(recipientUserId, Name, textBody, imageUrl);
}
public void addMessageClientListener(MessageClientListener listener) {
SinchService.this.addMessageClientListener(listener);
}
public void removeMessageClientListener(MessageClientListener listener) {
SinchService.this.removeMessageClientListener(listener);
}
public Call callUser(String userId, HashMap<String, String> name) {
if (mSinchClient == null) {
return null;
}
return mSinchClient.getCallClient().callUser(userId, name);
}
public Call callUserVideo(String userId, HashMap<String, String> name) {
return mSinchClient.getCallClient().callUserVideo(userId, name);
}
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 VideoController getVideoController() {
if (!isStarted()) {
return null;
}
return mSinchClient.getVideoController();
}
public AudioController getAudioController() {
if (!isStarted()) {
return null;
}
return mSinchClient.getAudioController();
}
public void LogOut() {
if (mSinchClient != null) {
mSinchClient.stopListeningOnActiveConnection();
mSinchClient.unregisterPushNotificationData();
mSinchClient.unregisterManagedPush();
//mSinchClient.terminate();
}
}
}
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) {
if (call.getDetails().isVideoOffered()) {
Intent intent = new Intent(SinchService.this, IncomingVideoCall.class);
intent.putExtra(CALL_ID, call.getCallId());
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_NO_HISTORY);
SinchService.this.startActivity(intent);
} else {
Intent intent = new Intent(SinchService.this, IncomingAudioCall.class);
intent.putExtra(CALL_ID, call.getCallId());
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_NO_HISTORY);
SinchService.this.startActivity(intent);
}
}
}
private 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.commit();
}
}
public void sendMessage(String recipientUserId, String name, String textBody, String imageUrl) {
if (isStarted()) {
WritableMessage message = new WritableMessage();
message.addHeader("imageUrl", imageUrl);
message.addHeader("Name", name);
message.addRecipient(recipientUserId);
message.setTextBody(textBody);
mSinchClient.getMessageClient().send(message);
}
}
public void addMessageClientListener(MessageClientListener listener) {
if (mSinchClient != null) {
mSinchClient.getMessageClient().addMessageClientListener(listener);
}
}
public void removeMessageClientListener(MessageClientListener listener) {
if (mSinchClient != null) {
mSinchClient.getMessageClient().removeMessageClientListener(listener);
}
}
}
我正在发送这样的消息。
private void sendMessage() {
String textBody = mTxtTextBody.getText().toString();
if (textBody.isEmpty()) {
Toast.makeText(this, "No text message", Toast.LENGTH_SHORT).show();
return;
}
getSinchServiceInterface().sendMessage(receiver_username, name, textBody, picture);
mTxtTextBody.setText("");
}
和提取消息头的适配器
public class MessageAdapter extends BaseAdapter {
public static final int DIRECTION_INCOMING = 0;
public static final int DIRECTION_OUTGOING = 1;
private List<Pair<Message, Integer>> mMessages;
private SimpleDateFormat mFormatter;
private LayoutInflater mInflater;
Context context; // modification here
int res = 0;
String photo_url;
public MessageAdapter(Activity activity) {
mInflater = activity.getLayoutInflater();
context = activity;
mMessages = new ArrayList<>();
mFormatter = new SimpleDateFormat("hh:mm aa");
}
public void addMessage(Message message, int direction) {
mMessages.add(new Pair(message, direction));
notifyDataSetChanged();
}
@Override
public int getCount() {
return mMessages.size();
}
@Override
public Object getItem(int i) {
return mMessages.get(i);
}
@Override
public long getItemId(int i) {
return 0;
}
@Override
public int getViewTypeCount() {
return 2;
}
@Override
public int getItemViewType(int i) {
return mMessages.get(i).second;
}
@Override
public View getView(int i, View convertView, ViewGroup viewGroup) {
int direction = getItemViewType(i);
if (convertView == null) {
if (direction == DIRECTION_INCOMING) {
res = R.layout.message_right;
} else if (direction == DIRECTION_OUTGOING) {
res = R.layout.message_left;
}
convertView = mInflater.inflate(res, viewGroup, false);
}
Message message = mMessages.get(i).first;
String name = message.getHeaders().get("Name");
if (direction == DIRECTION_INCOMING) {
photo_url = message.getHeaders().get("imageUrl");
} else if (direction == DIRECTION_OUTGOING) {
photo_url = StaticInfo.getSavedData("photo", context);
}
CircleImageView photo = convertView.findViewById(R.id.pic);
Picasso.with(context).load(photo_url).into(photo);
TextView txtSender = convertView.findViewById(R.id.txtSender);
TextView txtMessage = convertView.findViewById(R.id.txtMessage);
TextView txtDate = convertView.findViewById(R.id.txtDate);
txtSender.setText(name);
txtMessage.setText(message.getTextBody());
txtDate.setText(mFormatter.format(message.getTimestamp()));
return convertView;
}
}