Android, отображать alertDialog вместо уведомления, когда приложение открыто

Я следил за этим руководством для разработчиков и, как и ожидалось, работал с Geofencing в моем приложении.

Уведомление отправляется, когда происходит переход IntentService Transition из 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's 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()); } 

Это куки-резак из учебника. Учреждение настроено в Основной деятельности:

 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); } 

Как добавить функциональность, которая подавляет уведомления, если приложение открыто, и вместо этого отображает AlertDialog для пользователя? В идеале, я хотел бы иметь возможность выполнять разные задачи, в зависимости от того, какой вид пользователь в данный момент находится в случае перехода Geofence Transition. Могу ли я контролировать / перехватывать переход изнутри каждого представления или как-то глобально?

Заранее спасибо.

Некоторые из ответов были неполными, поэтому вот полное решение того, что я искал.

Прежде всего, MyApplication класс MyApplication , который реализует 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 } 

Обязательно укажите это в своем манифесте (добавлена ​​только строка с именем, остальное – по умолчанию):

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

То, что было сделано выше, используется для отслеживания жизненного цикла вашего приложения. Вы можете использовать это, чтобы проверить, находится ли ваше приложение в настоящее время на переднем плане или нет.

Далее следует настроить BroadcastReceiver , где бы вы не захотели запускать код (в случае, если приложение открыто при возникновении триггера). В этом случае он находится в моей MainActivity :

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

Зарегистрируйте получателя в своем onCreate того же действия:

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

И не забудьте отменить регистрацию:

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

Когда широковещательная передача принимается, выполняется код внутри получателя.

Теперь, чтобы проверить, находится ли приложение на переднем плане и отправить широковещательную рассылку, если это так. Внутри 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. } } 

Важным битом является последний вложенный оператор if:

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

Проверьте, находится ли приложение на переднем плане с помощью MyApplication.isActivityVisible() , как определено выше, а затем либо отправляет уведомление, либо отправляет широковещательную передачу. Просто убедитесь, что ваш код намерения (т.е. "some_custom_id" ) совпадает с вашим отправителем и получателем.

И это все. Если приложение находится на переднем плане (в частности, MainActivity), я выполняю некоторый код. Если приложение не находится на переднем плане, я отправляю уведомление.

Самый простой способ – использовать LocalBroadcastManager или некоторую шину событий .

Поэтому, когда происходит переход, вы должны отправить локальную трансляцию с IntentService и поймать ее с помощью некоторого component X между IntentService и любым из ваших Activity . Component X должен отслеживать, находится ли какой-либо из ваших Activity на переднем плане и

  • Если да – передать другую локальную широковещательную рассылку (на переднюю Activity ),
  • Если нет – показать уведомление.

Обратите внимание, что в Android вы не можете легко отслеживать, если ваше приложение находится на переднем плане или нет (и если у вас более одного действия, вы не можете сделать это правильно, на мой взгляд), но вы можете попробовать .

А) Вы можете уведомить об услугах событий жизненного цикла деятельности.

B) Вы можете сохранить текущее состояние своего пользовательского интерфейса в статическом поле в действии и проверить его из службы перед показом уведомления.

Intereting Posts
Android – android.view.InflateException: двоичная строка XML-файла # 8: ошибка раздувания фрагмента класса Снизьте Android SDK (api 23 -> api 21) Android – можно использовать in-app для загрузки контента? Android SearchView Filter ListView Android.view.ViewGroup $ LayoutParams нельзя отбрасывать в android.widget.AbsListView $ LayoutParams Отладка устройства Android Wear через USB Как установить фиксированное количество строк в android gridView? Как получить сертификат отпечатка SHA-1 в Android Studio для режима отладки? Изменение цвета текста RadioButton при нажатии на android Обнаружение попыток скриншотов на Android 4.0+ AndroidRuntime Caused by: java.lang.unsatisfiedLinkError: Не удалось загрузить tfp_jni: findLibrary возвратил null Повторение растрового изображения не очень хорошо отражается на состоянии state_pressed Как отобразить вывод console.log () в приложении PhoneGap с использованием Eclipse и HTC Desire HD? Интеграция Unity3D и Android Studio TextInputLayout анимация перекрывает текст, когда текст установлен программно