package org.mercury_im.messenger; import android.annotation.SuppressLint; import android.app.Activity; import android.app.Application; import android.app.NotificationChannel; import android.app.NotificationManager; import android.content.Context; import android.content.Intent; import android.os.Build; import org.mercury_im.messenger.di.component.AppComponent; import org.mercury_im.messenger.di.component.DaggerAppComponent; import org.mercury_im.messenger.di.module.AppModule; import org.mercury_im.messenger.service.MercuryConnectionService; import org.mercury_im.messenger.util.AbstractActivityLifecycleCallbacks; import java.util.concurrent.atomic.AtomicBoolean; import java.util.concurrent.atomic.AtomicInteger; public class MercuryImApplication extends Application { static { // Initialize Smack etc. // new MercuryConfiguration(); } private static MercuryImApplication INSTANCE; AppComponent appComponent; // Keep track of activities in "started" state. // This will come in handy for CSI // see https://medium.com/@iamsadesh/android-how-to-detect-when-app-goes-background-foreground-fd5a4d331f8a private AtomicInteger activityReferences = new AtomicInteger(0); private AtomicBoolean isActivityChangingConfiguration = new AtomicBoolean(false); public static MercuryImApplication getApplication() { return INSTANCE; } @Override public void onCreate() { super.onCreate(); registerActivityLifecycleCallbacks(lifecycleCallbacks); INSTANCE = this; appComponent = createAppComponent(); initializeNotificationChannels(this); Intent serviceIntent = new Intent(getApplicationContext(), MercuryConnectionService.class); serviceIntent.setAction(MercuryConnectionService.ACTION_START); if (Build.VERSION.SDK_INT < 26) { startService(serviceIntent); } else { startForegroundService(serviceIntent); } } /** * Create the Dependency Injection graph. * For testing, overwrite this method with custom modules. */ public AppComponent createAppComponent() { AppComponent appComponent = DaggerAppComponent.builder() .appModule(new AppModule(this)) .build(); appComponent.inject(this); return appComponent; } public void initializeNotificationChannels(Context context) { // Only necessary on Android O and upwards. if (Build.VERSION.SDK_INT < 26) { return; } NotificationManager notificationManager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE); // Foreground notification channel String fName = getResources().getString(R.string.channel_name_foreground); String fDescription = getResources().getString(R.string.channel_description_foreground); @SuppressLint("WrongConstant") NotificationChannel foreground = new NotificationChannel(Notifications.NOTIFICATION_CHANNEL__FOREGROUND_SERVICE, fName, NotificationManager.IMPORTANCE_MIN); foreground.setDescription(fDescription); foreground.setShowBadge(false); notificationManager.createNotificationChannel(foreground); // Incoming Messages notification channel String mName = getResources().getString(R.string.channel_name_message); String mDescription = getResources().getString(R.string.channel_description_message); @SuppressLint("WrongConstant") NotificationChannel messages = new NotificationChannel(Notifications.NOTIFICATION_CHANNEL__NEW_MESSAGE, mName, NotificationManager.IMPORTANCE_DEFAULT); messages.setDescription(mDescription); notificationManager.createNotificationChannel(messages); } public AppComponent getAppComponent() { return appComponent; } private final AbstractActivityLifecycleCallbacks lifecycleCallbacks = new AbstractActivityLifecycleCallbacks() { @Override public void onActivityStarted(Activity activity) { if (activityReferences.incrementAndGet() == 1 && !isActivityChangingConfiguration.get()) { // App enters foreground //connectionCenter.clientStateActive(); } } @Override public void onActivityStopped(Activity activity) { isActivityChangingConfiguration.set(activity.isChangingConfigurations()); if (activityReferences.decrementAndGet() == 0 && !isActivityChangingConfiguration.get()) { // App enters background //connectionCenter.clientStateInactive(); } } }; }