Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,27 +1,33 @@
package org.commcare.fragments.connectMessaging;

import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;

import androidx.annotation.NonNull;
import androidx.fragment.app.Fragment;
import androidx.localbroadcastmanager.content.LocalBroadcastManager;
import androidx.navigation.NavDirections;
import androidx.navigation.Navigation;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.swiperefreshlayout.widget.SwipeRefreshLayout;

import org.commcare.adapters.ChannelAdapter;
import org.commcare.android.database.connect.models.ConnectMessagingChannelRecord;
import org.commcare.connect.ConnectDatabaseHelper;
import org.commcare.connect.MessageManager;
import org.commcare.dalvik.databinding.FragmentChannelListBinding;
import org.commcare.services.CommCareFirebaseMessagingService;

import java.util.List;

public class ConnectMessageChannelListFragment extends Fragment {

public static boolean isActive;
private FragmentChannelListBinding binding;
private ChannelAdapter channelAdapter;

Expand Down Expand Up @@ -64,11 +70,30 @@ public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container,
@Override
public void onResume() {
super.onResume();
isActive = true;

LocalBroadcastManager.getInstance(requireContext()).registerReceiver(updateReceiver,
new IntentFilter(CommCareFirebaseMessagingService.MESSAGING_UPDATE_BROADCAST));

MessageManager.retrieveMessages(requireActivity(), success -> {
refreshUi();
});
}

@Override
public void onPause() {
super.onPause();
isActive = false;
LocalBroadcastManager.getInstance(requireContext()).unregisterReceiver(updateReceiver);
}

private final BroadcastReceiver updateReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
refreshUi();
}
};

private void selectChannel(ConnectMessagingChannelRecord channel) {
NavDirections directions;
if(channel.getConsented()) {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,17 +1,20 @@
package org.commcare.fragments.connectMessaging;

import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.Bundle;
import android.os.Handler;
import android.text.Editable;
import android.text.TextWatcher;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.view.inputmethod.InputMethodManager;

import androidx.annotation.NonNull;
import androidx.fragment.app.Fragment;
import androidx.localbroadcastmanager.content.LocalBroadcastManager;
import androidx.recyclerview.widget.RecyclerView;

import org.commcare.adapters.ConnectMessageAdapter;
Expand All @@ -20,14 +23,15 @@
import org.commcare.connect.ConnectDatabaseHelper;
import org.commcare.connect.MessageManager;
import org.commcare.dalvik.databinding.FragmentConnectMessageBinding;
import org.commcare.services.CommCareFirebaseMessagingService;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.UUID;

public class ConnectMessageFragment extends Fragment {

public static String activeChannel;
private String channelId;
private FragmentConnectMessageBinding binding;
private ConnectMessageAdapter adapter;
Expand Down Expand Up @@ -63,17 +67,33 @@ public void run() {
@Override
public void onResume() {
super.onResume();
activeChannel = channelId;

LocalBroadcastManager.getInstance(requireContext()).registerReceiver(updateReceiver,
new IntentFilter(CommCareFirebaseMessagingService.MESSAGING_UPDATE_BROADCAST));

// Start periodic API calls
handler.post(apiCallRunnable);
}

@Override
public void onPause() {
super.onPause();
activeChannel = null;

LocalBroadcastManager.getInstance(requireContext()).unregisterReceiver(updateReceiver);

// Stop the periodic API calls when the screen is not active
handler.removeCallbacks(apiCallRunnable);
}

private final BroadcastReceiver updateReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
refreshUi();
}
};

private void makeApiCall() {
MessageManager.retrieveMessages(requireActivity(), success -> {
refreshUi();
Expand Down
132 changes: 78 additions & 54 deletions app/src/org/commcare/services/CommCareFirebaseMessagingService.java
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
import android.os.Build;

import androidx.core.app.NotificationCompat;
import androidx.localbroadcastmanager.content.LocalBroadcastManager;

import com.google.firebase.messaging.FirebaseMessagingService;
import com.google.firebase.messaging.RemoteMessage;
Expand All @@ -21,6 +22,8 @@
import org.commcare.connect.ConnectDatabaseHelper;
import org.commcare.connect.MessageManager;
import org.commcare.dalvik.R;
import org.commcare.fragments.connectMessaging.ConnectMessageChannelListFragment;
import org.commcare.fragments.connectMessaging.ConnectMessageFragment;
import org.commcare.google.services.analytics.FirebaseAnalyticsUtil;
import org.commcare.sync.FirebaseMessagingDataSyncer;
import org.commcare.util.LogTypes;
Expand All @@ -37,6 +40,7 @@
public class CommCareFirebaseMessagingService extends FirebaseMessagingService {

private final static int FCM_NOTIFICATION = R.string.fcm_notification;
public static final String MESSAGING_UPDATE_BROADCAST = "com.dimagi.messaging.update";
public static final String OPPORTUNITY_ID = "opportunity_id";
public static final String PAYMENT_ID = "payment_id";
public static final String PAYMENT_STATUS = "payment_status";
Expand All @@ -62,7 +66,8 @@ enum ActionTypes {
*/
@Override
public void onMessageReceived(RemoteMessage remoteMessage) {
Logger.log(LogTypes.TYPE_FCM, "CommCareFirebaseMessagingService Message received: " + remoteMessage.getData());
Logger.log(LogTypes.TYPE_FCM, "CommCareFirebaseMessagingService Message received: " +
remoteMessage.getData());
Map<String, String> payloadData = remoteMessage.getData();

// Check if the message contains a data object, there is no further action if not
Expand Down Expand Up @@ -96,9 +101,8 @@ public void onNewToken(String token) {
private void showNotification(Map<String, String> payloadData) {
String notificationTitle = payloadData.get("title");
String notificationText = payloadData.get("body");
NotificationManager mNM = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);

Intent intent;
Intent intent = null;
String action = payloadData.get("action");

if (hasCccAction(action)) {
Expand All @@ -112,14 +116,12 @@ private void showNotification(Map<String, String> payloadData) {
//On channels page (just update the page)
//On message page for the active channel

intent = new Intent(getApplicationContext(), ConnectMessagingActivity.class);
intent.putExtra("action", action);

int notificationTitleId;
String notificationMessage;
String channelId;
if(isMessage) {
ConnectMessagingMessageRecord message = MessageManager.handleReceivedMessage(this, payloadData);
ConnectMessagingMessageRecord message = MessageManager.handleReceivedMessage(this,
payloadData);

if(message == null) {
Logger.log(LogTypes.TYPE_FCM, "Ignoring message without known consented channel: " +
Expand All @@ -128,26 +130,40 @@ private void showNotification(Map<String, String> payloadData) {
return;
}

ConnectMessagingChannelRecord channel = ConnectDatabaseHelper.getMessagingChannel(this, message.getChannelId());
ConnectMessagingChannelRecord channel = ConnectDatabaseHelper.getMessagingChannel(this,
message.getChannelId());

notificationTitleId = R.string.connect_messaging_message_notification_title;
notificationMessage = getString(R.string.connect_messaging_message_notification_message, channel.getChannelName());
notificationMessage = getString(R.string.connect_messaging_message_notification_message,
channel.getChannelName());

channelId = message.getChannelId();
} else {
//Channel
ConnectMessagingChannelRecord channel = MessageManager.handleReceivedChannel(this, payloadData);
ConnectMessagingChannelRecord channel = MessageManager.handleReceivedChannel(this,
payloadData);

notificationTitleId = R.string.connect_messaging_channel_notification_title;
notificationMessage = getString(R.string.connect_messaging_channel_notification_message, channel.getChannelName());
notificationMessage = getString(R.string.connect_messaging_channel_notification_message,
channel.getChannelName());

channelId = channel.getChannelId();
}

notificationTitle = getString(notificationTitleId);
notificationText = notificationMessage;
if(ConnectMessageChannelListFragment.isActive ||
channelId.equals(ConnectMessageFragment.activeChannel)) {
//Notify active page to update instead of showing notification
Intent broadcastIntent = new Intent(MESSAGING_UPDATE_BROADCAST);
LocalBroadcastManager.getInstance(this).sendBroadcast(broadcastIntent);
} else {
//Show push notification
notificationTitle = getString(notificationTitleId);
notificationText = notificationMessage;

intent.putExtra(ConnectMessagingMessageRecord.META_MESSAGE_CHANNEL_ID, channelId);
intent = new Intent(getApplicationContext(), ConnectMessagingActivity.class);
intent.putExtra("action", action);
intent.putExtra(ConnectMessagingMessageRecord.META_MESSAGE_CHANNEL_ID, channelId);
}
} else {
//Intent for ConnectActivity
intent = new Intent(getApplicationContext(), ConnectActivity.class);
Expand All @@ -158,54 +174,62 @@ private void showNotification(Map<String, String> payloadData) {
intent.setAction(Intent.ACTION_MAIN);
intent.addCategory(Intent.CATEGORY_LAUNCHER);
}
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOP | Intent.FLAG_ACTIVITY_NEW_TASK);

int flags = Build.VERSION.SDK_INT >= Build.VERSION_CODES.S
? PendingIntent.FLAG_UPDATE_CURRENT | PendingIntent.FLAG_IMMUTABLE
: PendingIntent.FLAG_UPDATE_CURRENT;

PendingIntent contentIntent = PendingIntent.getActivity(this, 0, intent, flags);

NotificationCompat.Builder fcmNotification = new NotificationCompat.Builder(this,
CommCareNoficationManager.NOTIFICATION_CHANNEL_PUSH_NOTIFICATIONS_ID)
.setContentTitle(notificationTitle)
.setContentText(notificationText)
.setContentIntent(contentIntent)
.setAutoCancel(true)
.setSmallIcon(R.drawable.commcare_actionbar_logo)
.setPriority(NotificationCompat.PRIORITY_HIGH)
.setWhen(System.currentTimeMillis());

// Check if the payload action is CCC_PAYMENTS
if (action.equals(ConnectConstants.CCC_DEST_PAYMENTS)) {
// Yes button intent with payment_id from payload
Intent yesIntent = new Intent(this, PaymentAcknowledgeReceiver.class);
yesIntent.putExtra(OPPORTUNITY_ID,payloadData.get(OPPORTUNITY_ID));
yesIntent.putExtra(PAYMENT_ID,payloadData.get(PAYMENT_ID));
yesIntent.putExtra(PAYMENT_STATUS,true);
PendingIntent yesPendingIntent = PendingIntent.getBroadcast(this, 1, yesIntent, flags);

// No button intent with payment_id from payload
Intent noIntent = new Intent(this, PaymentAcknowledgeReceiver.class);
noIntent.putExtra(OPPORTUNITY_ID,payloadData.get(OPPORTUNITY_ID));
noIntent.putExtra(PAYMENT_ID,payloadData.get(PAYMENT_ID));
noIntent.putExtra(PAYMENT_STATUS,false);
PendingIntent noPendingIntent = PendingIntent.getBroadcast(this, 2, noIntent, flags);

// Add Yes & No action button to the notification
fcmNotification.addAction(0, getString(R.string.connect_payment_acknowledge_notification_yes), yesPendingIntent);
fcmNotification.addAction(0, getString(R.string.connect_payment_acknowledge_notification_no), noPendingIntent);
}

mNM.notify(FCM_NOTIFICATION, fcmNotification.build());
if(intent != null) {
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOP |
Intent.FLAG_ACTIVITY_NEW_TASK);

int flags = Build.VERSION.SDK_INT >= Build.VERSION_CODES.S
? PendingIntent.FLAG_UPDATE_CURRENT | PendingIntent.FLAG_IMMUTABLE
: PendingIntent.FLAG_UPDATE_CURRENT;

PendingIntent contentIntent = PendingIntent.getActivity(this, 0, intent, flags);

NotificationCompat.Builder fcmNotification = new NotificationCompat.Builder(this,
CommCareNoficationManager.NOTIFICATION_CHANNEL_PUSH_NOTIFICATIONS_ID)
.setContentTitle(notificationTitle)
.setContentText(notificationText)
.setContentIntent(contentIntent)
.setAutoCancel(true)
.setSmallIcon(R.drawable.commcare_actionbar_logo)
.setPriority(NotificationCompat.PRIORITY_HIGH)
.setWhen(System.currentTimeMillis());

// Check if the payload action is CCC_PAYMENTS
if (action.equals(ConnectConstants.CCC_DEST_PAYMENTS)) {
// Yes button intent with payment_id from payload
Intent yesIntent = new Intent(this, PaymentAcknowledgeReceiver.class);
yesIntent.putExtra(OPPORTUNITY_ID, payloadData.get(OPPORTUNITY_ID));
yesIntent.putExtra(PAYMENT_ID, payloadData.get(PAYMENT_ID));
yesIntent.putExtra(PAYMENT_STATUS, true);
PendingIntent yesPendingIntent = PendingIntent.getBroadcast(this, 1,
yesIntent, flags);

// No button intent with payment_id from payload
Intent noIntent = new Intent(this, PaymentAcknowledgeReceiver.class);
noIntent.putExtra(OPPORTUNITY_ID, payloadData.get(OPPORTUNITY_ID));
noIntent.putExtra(PAYMENT_ID, payloadData.get(PAYMENT_ID));
noIntent.putExtra(PAYMENT_STATUS, false);
PendingIntent noPendingIntent = PendingIntent.getBroadcast(this, 2,
noIntent, flags);

// Add Yes & No action button to the notification
fcmNotification.addAction(0, getString(R.string.connect_payment_acknowledge_notification_yes), yesPendingIntent);
fcmNotification.addAction(0, getString(R.string.connect_payment_acknowledge_notification_no), noPendingIntent);
}

NotificationManager mNM = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
mNM.notify(FCM_NOTIFICATION, fcmNotification.build());
}
}

private boolean hasCccAction(String action) {
return action != null && action.contains("ccc_");
}

public static void clearNotification(Context context){
NotificationManager notificationManager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
NotificationManager notificationManager = (NotificationManager) context.getSystemService(
Context.NOTIFICATION_SERVICE);
if (notificationManager != null) {
notificationManager.cancel(R.string.fcm_notification);
}
Expand Down