Как я могу обработать намерение уведомления pu sh с изменением действий после создания? - PullRequest
0 голосов
/ 09 июля 2020

У меня есть приложение с двумя действиями android (оба действия - с одним верхом), и я обрабатываю уведомления pu sh. Каждый сценарий уведомления pu sh обрабатывается идеально для меня, за исключением одного, который связан с тем, как создаются намерения уведомления pu sh.

Сценарий, который не выполняется должным образом, - это когда пользователь в одном действии, когда приходит уведомление pu sh, а затем они переходят к другому действию, после чего они решают выбрать уведомление pu sh в раскрывающемся списке своего телефона. Моя проблема в том, что приложение затем пытается go вернуться к активности, которая была активна при создании уведомления, а это не то, что я хочу. Я хочу, чтобы он по-прежнему делал все то же самое с уведомлением и его данными, но вместо этого делал это с текущим действием и не переключался обратно.

Я знаю, почему это происходит, потому что уведомление Код создания разработан следующим образом:

// create notification
        val builder = NotificationCompat.Builder(context,
                channelId)
// more things are done to set up the builder...


// here is why the problem is happening

        val notificationIntent = if (we_are_in_activity_one)
                Intent(context, ActivityOne::class.java) 
            else
                Intent(context, ActivityTwo::class.java)

        notificationIntent.putExtras(data_from_notification)

        builder.setContentIntent(PendingIntent.getActivity(context,
                notificationId,
                notificationIntent,
                PendingIntent.FLAG_UPDATE_CURRENT))
        //Auto cancel
        builder.setAutoCancel(true)

        builder.priority = NotificationCompat.PRIORITY_HIGH

        //Return the generated notification
        return builder

Что мне интересно, так это то, что можно сделать или изменить, чтобы, когда пользователь выбирает уведомление, он не запускал автоматически действие, которое было изначально связано если обстоятельства изменились. Может быть, мне не хватает очевидного флага, который я могу использовать?

Другая информация, которая может быть полезна, заключается в том, что это проблема только тогда, когда они находятся в действии 2, поскольку действие 1 - это действие средства запуска. Таким образом, если уведомление создается в 2, но они возвращаются к 1, действие 2 больше не будет активным. Когда они нажимают на уведомление, оно перезапускает действие 2, чего я не хочу. Я бы хотел, чтобы уведомление на самом деле go возвращалось к действию 2, если оно все еще активно (то есть пользователь все еще находится в нем).

Заранее спасибо и дайте мне знать, могу ли я предоставить более полезные информация

1 Ответ

0 голосов
/ 09 июля 2020

Если я правильно понял, вы хотите получать уведомление о текущей активности пользователя?

Вы можете сделать это следующим образом.

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

Простой способ добиться этого:

  public static boolean isActivityActive(Activity activity) {
   return !activity.isFinishing() && !activity.isDestroyed();
  }

, а затем

  Intent intent = new Intent(context, !isActivityActive(new ActivityTwo()) ? ActivityOne.class : ActivityTwo.class);

Этот метод вернет истину, если действие открыто. В качестве альтернативы вы можете использовать:

  activity.getWindow().getDecorView().isShown();

in isActivityActive(Activity) Значение, возвращаемое этим выражением, изменяется на onStart() / onStop()

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

Требуется всего несколько строк кода.

Сначала сделайте следующее:

 public class MyPreference {

   private Context c;
   private SharedPreferences.Editor editor;
   private SharedPreferences preferences;
   
   public MyPreference (Context c) {
    this.c = c;
    preferences = c.getSharedPreferences("shared_preferences", Context.MODE_PRIVATE);
   }
   
   public void save (String preference, boolean value) {
    editor = preferences.edit();
    editor.putBoolean(preference, value);
    editor.apply();
   }

   public boolean boo (String preference) {
    return preferences.getBoolean(preference, false);
   }
   
   public String is_second_activity_active = "is_second_activity_active";
   
 }

Теперь вы можете сохранить жизненные циклы вашего второго действия, запустив MyPreference следующим образом:

 public class ActivityTwo extends AppCompatActivity {

   MyPreference p;
   
   @Override
   protected void onCreate(Bundle state) {
    super.onCreate(state);
    p = new MyPreference(context);
    // some source...
   }
   
   @Override
   protected void onStart() {
    super.onStart();
    p.save(p.is_second_activity_active, true);
    // your activity is active
   }
   
   @Override
   protected void onStop() {
    super.onStop();
    p.save(p.is_second_activity_active, false);
    // your activity is not active
   }
 }

Вы можете понять жизненный цикл Activity здесь

Наконец, в вашем классе уведомлений извлеките статус вашего второго действия:

  // create notification
  // ...    

  MyPreference p = new MyPreference(context);

  Intent intent = new Intent
   (context, p.boo(p.is_second_activity_active) ? ActivityTwo.class : ActivityOne.class);

  // continue...

Извините, мой английский sh, я не владею свободно. Надеюсь, ты понимаешь. Я не пишу в kotlin, поэтому вы можете преобразовать код.

Сообщите мне, помогло ли это вам. Спасибо. > <</p>

ИЗМЕНИТЬ

Невозможно изменить поведение уведомления после того, как оно было создано одним способом. Вы можете обновить уведомление при изменении обстоятельств.

Вам необходимо определить setOnlyAlertOnce (true) в своем NotificationCompat.Builder, а затем отправить новое уведомление с тем же id, что и в старом уведомлении.

Если id совпадает с setOnlyAlertOnce (true), ваше уведомление будет обновлено без всплывающего окна, звука или предупреждения о вибрации. Вы можете использовать один и тот же Builder для каждого обновления.

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

Внимание: Android применяет ограничение скорости при обновлении уведомления. Если вы публикуете обновления для уведомления слишком часто (многие из них менее чем за одну секунду), система может сбросить некоторые обновления. Документация

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

В качестве альтернативы я рекомендую вам попробовать это.

Вместо того, чтобы открывать действие напрямую с помощью уведомления, откройте его из BroadcastReceiver, а затем решите, какое действие открыть. .

Чтобы транслировать ваше уведомление, ваше намерение должно выглядеть следующим образом

 // create notification
 // ...  
 
 Intent intent = new Intent();
 intent.setAction(MyNotification.ACTION_OPEN);
 intent.putExtra("get", "something");
 
 // use getBroadCast instead of getActivity
 PendingIntent pIntent = PendingIntent.getBroadcast(context, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);

 builder.setContentIntent(pIntent);
 // configure your builder normally

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

 public class MyNotification extends BroadcastReceiver {

    public static String ACTION_OPEN = "com.example.intent.action.NOTIFICATION_OPEN";
 
    @Override
    public void onReceive(Context context, Intent intent) {
      
      MyPreference m = new MyPreference(context);
      boolean open_notification = ACTION_OPEN.equals(intent.getAction());

      if (open_notification ) {
        boolean is_active = m.boo(m.is_second_activity_active);
        String log = is_active ? "Open in ActivityTwo" : "Open in ActivityOne";
        
        Intent new_intent = new Intent(context, is_active ? two.class : one.class);
        new_intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_SINGLE_TOP);
        new_intent.putExtra("get", intent.getExtras());
        context.startActivity(new_intent);
        
        Log.e("log", log);
      }
    }
 }

Если хотите, используйте свой метод, чтобы узнать, участвует ли пользователь во втором действии, или воспользуйтесь примерами, которые я упомянул ранее.

ПРИМЕЧАНИЕ: Методы onStart () и onStop () на самом деле лучше, чем onResume () и onDestroy (), чтобы проверять, находится ли пользователь в действии. onDestroy () никогда не вызывается, когда пользователь закрывает приложение из недавних приложений.

Наконец, объявите свою трансляцию в AndroidManifest.xml

  <receiver android:name=".MyNotification"
        android:exported="false">
        <intent-filter>
            <action android:name="com.example.intent.action.NOTIFICATION_OPEN" />
            <category android:name="android.intent.category.DEFAULT" />
        </intent-filter>
  </receiver>

Не забудьте добавить android:launchMode="singleTop" на ваш ActivityOne и ActivityTwo

Уведомление будет открываться в соответствии с действиями пользователя, независимо от того, где оно было создано.

Таким образом, если действие - единственное, что изменений, нет необходимости обновлять уведомления при изменении обстоятельств.

Теперь он должен работать. хх

...