Android, display alertDialog instead of notification when the application is open

I followed this developer's advice and had Geofencing working in my application, as expected.

A notification is sent when a Geofence Transition transition occurs from an IntentService :

 @Override protected void onHandleIntent(Intent intent) { GeofencingEvent geofencingEvent = GeofencingEvent.fromIntent(intent); ... sendNotification(geofenceTransitionDetails); } private void sendNotification(String notificationDetails) { // Create an explicit content Intent that starts the main Activity. Intent notificationIntent = new Intent(getApplicationContext(), MainActivity.class); // Construct a task stack. TaskStackBuilder stackBuilder = TaskStackBuilder.create(this); // Add the main Activity to the task stack as the parent. stackBuilder.addParentStack(MainActivity.class); // Push the content Intent onto the stack. stackBuilder.addNextIntent(notificationIntent); // Get a PendingIntent containing the entire back stack. PendingIntent notificationPendingIntent = stackBuilder.getPendingIntent(0, PendingIntent.FLAG_UPDATE_CURRENT); // Get a notification builder that compatible with platform versions >= 4 NotificationCompat.Builder builder = new NotificationCompat.Builder(this); // Define the notification settings. builder.setSmallIcon(R.mipmap.ic_launcher) // In a real app, you may want to use a library like Volley // to decode the Bitmap. .setLargeIcon(BitmapFactory.decodeResource(getResources(), R.mipmap.ic_launcher)) .setColor(Color.RED) .setContentTitle(notificationDetails) .setContentText("Return to app") .setContentIntent(notificationPendingIntent); // Dismiss notification once the user touches it. builder.setAutoCancel(true); // Get an instance of the Notification manager NotificationManager mNotificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE); // Issue the notification mNotificationManager.notify(0, builder.build()); } 

This is a cookie cutter from a textbook. The institution is set up in its core business:

 private PendingIntent getGeofencePendingIntent() { // Reuse the PendingIntent if we already have it. if (mGeofencePendingIntent != null) { return mGeofencePendingIntent; } Intent intent = new Intent(this, GeofenceTransitionsIntentService.class); // We use FLAG_UPDATE_CURRENT so that we get the same pending intent back when calling // addGeofences() and removeGeofences(). return PendingIntent.getService(this, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT); } 

How to add functionality that suppresses notifications if the application is open and displays an AlertDialog for the user instead? Ideally, I would like to perform various tasks, depending on what kind of user is currently located when the Geofence Transition transition occurs. Can I control / intercept the transition from within each view or somehow globally?

Thanks in advance.

+5
source share
3 answers

Some of the answers were incomplete, so here is a complete solution of what I was looking for.

First of all, set up the MyApplication class, which implements ActivityLifecycleCallbacks :

 public class MyApplication extends Application implements Application.ActivityLifecycleCallbacks { private static boolean isActive; @Override public void onCreate() { super.onCreate(); registerActivityLifecycleCallbacks(this); } public static boolean isActivityVisible(){ return isActive; } @Override public void onActivityResumed(Activity activity) { isActive = true; } @Override public void onActivityPaused(Activity activity) { isActive = false; } ... no other methods need to be used, but there are more that ... must be included for the ActivityLifecycleCallbacks } 

Be sure to indicate this in your manifest (only a line with a name is added, by default - by default):

 <application android:name=".MyApplication" android:allowBackup="true" android:icon="@mipmap/ic_launcher" android:label="@string/app_name" android:theme="@style/AppTheme" android:hardwareAccelerated="true"> 

What was done above is used to track the life cycle of your application. You can use this to check if your application is currently in the foreground or not.

Next, configure BroadcastReceiver , wherever you want to run the code (in the case of opening the application when a trigger occurs). In this case, it is in my MainActivity :

 protected BroadcastReceiver mNotificationReceiver = new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { ... Do whatever you want here Toast.makeText(...).show(); } }; 

Register the receiver in your onCreate the same action:

 protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); ... LocalBroadcastManager.getInstance(this).registerReceiver(mNotificationReceiver, new IntentFilter("some_custom_id")); } 

And do not forget to unregister:

 @Override protected void onDestroy() { LocalBroadcastManager.getInstance(this).unregisterReceiver(mNotificationReceiver); super.onDestroy(); } 

Upon receipt of the broadcast, code is executed inside the receiver.

Now, to check if the application is in the foreground and send a broadcast, if so. Inside the IntentService :

 @Override protected void onHandleIntent(Intent intent) { GeofencingEvent geofencingEvent = GeofencingEvent.fromIntent(intent); if (geofencingEvent.hasError()) { String errorMessage = getErrorString(this, geofencingEvent.getErrorCode()); return; } int geofenceTransition = geofencingEvent.getGeofenceTransition(); // Test that the reported transition was of interest. if (geofenceTransition == Geofence.GEOFENCE_TRANSITION_ENTER || geofenceTransition == Geofence.GEOFENCE_TRANSITION_EXIT) { ... if(MyApplication.isActivityVisible()){ Intent intnt = new Intent("some_custom_id"); intnt.putExtra("message", geofenceTransitionDetails); LocalBroadcastManager.getInstance(this).sendBroadcast(intnt); }else{ sendNotification(geofenceTransitionDetails); } } else { // Log the error. } } 

An important bit is the last nested if statement:

 if(MyApplication.isActivityVisible()){ Intent intnt = new Intent("some_custom_id"); intnt.putExtra("message", geofenceTransitionDetails); LocalBroadcastManager.getInstance(this).sendBroadcast(intnt); }else{ sendNotification(geofenceTransitionDetails); } 

Check to see if the application is in the foreground using MyApplication.isActivityVisible() as above, and then either sends a notification or sends a broadcast. Just make sure your intent code (ie "some_custom_id" ) matches your sender and recipient.

And about that. If the application is in the foreground (in particular, MainActivity), I am executing some code. If the application is not in the foreground, I send a notification.

+5
source

The easiest way is to use the LocalBroadcastManager or some event bus .

So, when the transition occurs, you should send a local translation from the IntentService and intercept it using component X between the IntentService and any of your Activity . component X should keep track of whether any of your Activity in the foreground and

  • if so, transfer another local broadcast (to the forefront of Activity ),
  • if not - show notification.

Please note that in Android you cannot easily track if your application is in the foreground or not (and if you have more than 1 Activity, you cannot do it correctly, in my opinion), but you can try .

+1
source

a) You can notify your service of activity life cycle events.

b) You can save the current state of your user interface in a static field in action and check it from the service before displaying a notification.

0
source

All Articles