简体   繁体   English

从服务中运行活动中的调用方法

[英]Call method in a running activity from a service

I am currently working on a Android project. 我目前正在开发一个Android项目。

So far, I have implemented Firebase, in particular the FirebaseInstanceIdService and the FirebaseMessagingService: 到目前为止,我已经实现了Firebase,特别是FirebaseInstanceIdService和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 提前致谢

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 在每个活动onresume方法中写入此代码,并在onpause方法中设置null

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

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

now you can call activity method from service class 现在你可以从服务类调用activity方法了

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

        }

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 (ie GreenRobot's or local broadcast ). 最好的方法是使用事件总线(即GreenRobot本地广播 )。 Your activity registers listener in onResume() (and deregisters in onPause() ) and your service simply broadcasts the message when times comes. 您的活动在onResume()注册侦听器(并在onPause()注销),您的服务只会在时间到来时广播该消息。

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. 您还可以避免最糟糕的解决方案 - 直接调用Activity的方法。

To find out when you are in background or not, it's best to utilis Application's GreenRobot's ActivityLifecycleCallbacks - there's no point of forcing activities to report that as there's completely no benefit from that. 为了了解你是否在后台,最好是利用应用程序的GreenRobot的 ActivityLifecycleCallbacks - 强制活动报告没有任何意义,因为完全没有任何好处。

try with this: 试试这个:

This method check for all running apps, and return true or false whether current app is in background state or in foreground state. 此方法检查所有正在运行的应用程序,并返回true或false,无论当前应用程序是处于后台状态还是处于前台状态。

    public static boolean isAppIsInBackground(Context context) {
        boolean isInBackground = true;
        ActivityManager am = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
        if (Build.VERSION.SDK_INT > Build.VERSION_CODES.KITKAT_WATCH) {
            List<ActivityManager.RunningAppProcessInfo> runningProcesses = am.getRunningAppProcesses();
            for (ActivityManager.RunningAppProcessInfo processInfo : runningProcesses) {
                if (processInfo.importance == ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND) {
                    for (String activeProcess : processInfo.pkgList) {
                        if (activeProcess.equals(context.getPackageName())) {
                            isInBackground = false;
                        }
                    }
                }
            }
        } else {
            List<ActivityManager.RunningTaskInfo> taskInfo = am.getRunningTasks(1);
            ComponentName componentInfo = taskInfo.get(0).topActivity;
            if (componentInfo.getPackageName().equals(context.getPackageName())) {
                isInBackground = false;
            }
        }

        return isInBackground;
    }

Try 尝试

1. Register custom broadcast receiver in your activity 1.在您的活动中注册自定义广播接收器

context.registerReceiver (myBroadcastReceiver, new IntentFilter ("CUSTOM_ACTION"));
private final BroadcastReceiver myBroadcastReceiver = new BroadcastReceiver () {

    @Override
    public void onReceive (Context context, Intent intent) {

        //Do something
    }
};

2. Send broadcast from your service 2.从您的服务发送广播

Intent intent = new Intent ("CUSTOM_ACTION");
context.sendBroadcast (intent)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM