Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Call method in a running activity from a service

I am currently working on a Android project.

So far, I have implemented Firebase, in particular the FirebaseInstanceIdService and the FirebaseMessagingService:

public class FirebaseIDService extends FirebaseInstanceIdService {
private static final String TAG = "FirebaseIDService";

private Context context;

@Override
public void onTokenRefresh() {
    context = getApplicationContext();
    // Get updated InstanceID token.
    String refreshedToken = FirebaseInstanceId.getInstance().getToken();
    Log.e(TAG, "Refreshed token: " + refreshedToken);

    SharedPreferences sharedPreferences = context.getSharedPreferences("token", context.MODE_PRIVATE);
    SharedPreferences.Editor editor = sharedPreferences.edit();
    editor.putString("token", refreshedToken);
    editor.commit();

    sendRegistrationToServer(refreshedToken);
}

/**
 * Persist token to backend.
 * @param token The new token.
 */
private void sendRegistrationToServer(String token) {
    SendRegistrationKey task = new SendRegistrationKey(context);
    task.execute(token);
}

}

public class MessagingService extends FirebaseMessagingService {

private static final String TAG = "MsgService";

/**
 * Called when message is received.
 *
 * @param remoteMessage Object representing the message received from Firebase Cloud Messaging.
 */
@Override
public void onMessageReceived(RemoteMessage remoteMessage) {
    Log.e(TAG, "From: " + remoteMessage.getFrom());

    // Check if message contains a data payload.
    if (remoteMessage.getData().size() > 0) {
        Log.e(TAG, "Message data payload: " + remoteMessage.getData());
    }

    // Check if message contains a notification payload.
    if (remoteMessage.getNotification() != null) {
        Log.e(TAG, "Message Notification Body: " + remoteMessage.getNotification().getBody());

        sendNotification(remoteMessage);
    }

    // Also if you intend on generating your own notifications as a result of a received FCM
    // message, here is where that should be initiated. See sendNotification method below.
}
// [END receive_message]

private void sendNotification(RemoteMessage remoteMessage) {
    RemoteMessage.Notification notification = remoteMessage.getNotification();
    PushNotificationManager PNManager = PushNotificationManager.getInstance(getApplicationContext());
    PNManager.buildNotification(notification.getTitle(), notification.getBody());
}

What I want to achieve is the following:

When the App is in background, I just want to have a simple notification in the notification center. (This is already working)

BUT, when the app is in foreground and currently running, I want to have a different behaviour: I want to consume the push notification and show an alert instead.

But my question is: how can I interact with the running activity from the service or what is the correct way to achieve the intended behaviour? Ther must be a simple soultion, right?

Thanks in advance

like image 385
kauppfbi Avatar asked Apr 13 '17 12:04

kauppfbi


2 Answers

write this code in application class

 public Context currentactvity = null;
public Context getCurrentactvity() {
    return currentactvity;
}

public void setCurrentactvity(Context currentactvity) {
    this.currentactvity = currentactvity;
}

write this code in each activity onresume method and in onpause method set null

 // in onresume
MyApplication.getInstance().setCurrentactvity(this);

// in onpause
MyApplication.getInstance().setCurrentactvity(null);

now you can call activity method from service class

  if (MyApplication.getInstance().getCurrentactvity() != null && MyApplication.getInstance().getCurrentactvity() instanceof youractivityname) {
            ((youractivityname) MyApplication.getInstance().getCurrentactvity()).youmethodname(parameter);

        }
like image 158
Hitesh Gehlot Avatar answered Nov 14 '22 05:11

Hitesh Gehlot


how can I interact with the running activity from the service or what is the correct way to achieve the intended behaviour?

The best way would be simply to use Event Bus (i.e. GreenRobot's or local broadcast). Your activity registers listener in onResume() (and deregisters in onPause()) and your service simply broadcasts the message when times comes.

The main benefit is that you keep both elements (service and activity) completely separated. You also avoid worst possible solution - calling Activity's methods directly.

To find out when you are in background or not, it's best to utilis Application's GreenRobot'sActivityLifecycleCallbacks - there's no point of forcing activities to report that as there's completely no benefit from that.

like image 2
Marcin Orlowski Avatar answered Nov 14 '22 05:11

Marcin Orlowski