web-dev-qa-db-fra.com

Clic de notification: activité déjà ouverte

J'ai une application avec des notifications qui ouvrent une certaine activité si je clique dessus. Je souhaite que, si je clique sur la notification et que l'activité soit déjà ouverte, il est non redémarré, mais il est simplement présenté au premier plan.

Je pensais pouvoir le faire avec le drapeau FLAG_ACTIVITY_BROUGHT_TO_FRONT ou FLAG_ACTIVITY_REORDER_TO_FRONT _, mais il continue à l'ouvrir à nouveau, donc j'ai l'activité deux fois.

Ceci est mon code:

event_notification = new Notification(R.drawable.icon,
            mContext.getString(R.string.event_notif_message), System.currentTimeMillis()); 
Intent notificationIntent = new Intent(mContext, EventListActivity.class);
notificationIntent.setFlags(Intent.FLAG_ACTIVITY_BROUGHT_TO_FRONT);
sendNotification(event_notification, notificationIntent, mContext.getString(R.string.event_notif_title),
                body, Utils.PA_NOTIFICATIONS_ID);

Puis-je le gérer avec des indicateurs ou dois-je stocker une variable dans SharedPreferences pour vérifier si elle est ouverte ou non?

Merci!

148
PX Developer

Vous devez définir l'attribut launchMode de Activity que vous commencez à singleTop. Cela entraînera la livraison des intentions entrantes à l'instance existante au lieu de démarrer une nouvelle instance lorsque Activity se trouve déjà en haut de la pile de la tâche.

Cela se fait dans le manifeste en ajoutant Android:launchMode="singleTop" À l'élément <activity>. Pour accéder à la dernière intention (si vous êtes intéressé par des données ayant pu être transmises avec celle-ci), remplacez onNewIntent() dans votre Activity.

268
Devunwired

Essayez de régler les drapeaux sur Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOP au lieu.

À partir de la documentation pour FLAG_ACTIVITY_CLEAR_TOP (l'emphase mienne):

Si cette option est définie et que l'activité en cours est déjà en cours d'exécution dans la tâche en cours, alors, au lieu de lancer une nouvelle instance de cette activité, toutes les autres activités s'ajoutant seront fermées, ce qui L’intention sera transmise à l’ancienne activité (désormais la plus importante) en tant que nouvelle intention.

Par exemple, considérons une tâche composée des activités suivantes: A, B, C, D. Si D appelle startActivity () avec une intention qui se résume à la composante de l’activité B, C et D seront terminés et B recevra l’intention donnée. , la pile étant maintenant: A, B.

L'instance actuellement en cours d'activité B dans l'exemple ci-dessus recevra la nouvelle intention que vous commencez ici dans sa méthode onNewIntent () ou sera elle-même terminée et redémarrée avec la nouvelle intention. S'il a déclaré que son mode de lancement était "multiple" (valeur par défaut) et que vous n'avez pas défini FLAG_ACTIVITY_SINGLE_TOP dans la même intention, le processus sera terminé et recréé. pour tous les autres modes de lancement ou si FLAG_ACTIVITY_SINGLE_TOP est défini, cette intention sera transmise à l'instance actuelle onNewIntent ().

34
quietmint

Utilisez onNewIntent() pour gérer les nouvelles données à partir d'une notification, cliquez sur et actualisez l'activité.

Dans onNewIntent, récupérez les nouvelles données de la nouvelle intention (utilisée par la nouvelle notification) et récupérez-les, par exemple:

title = intent.getStringExtra("title")

dans onCreate précédemment :)

Il actualisera l'activité actuelle avec les nouvelles données de notification.

Vous pouvez également suivre ce tutoriel.

5
Afjalur Rahman Rana
Notification.Builder mBuilder =
            new Notification.Builder(this)
            .setSmallIcon(R.drawable.cmplayer)
            .setContentTitle("CoderoMusicPlayer")
            .setContentText("PLayer0!");

    Intent resultIntent = new Intent(this, 

    AndroidBuildingMusicPlayerActivity.class);
        resultIntent.setAction(Intent.ACTION_MAIN);
        resultIntent.addCategory(Intent.CATEGORY_LAUNCHER);

        PendingIntent pendingIntent = PendingIntent.getActivity(this, 0,
                resultIntent, 0);

        mBuilder.setContentIntent(pendingIntent);
        NotificationManager mNotificationManager =
            (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
        mNotificationManager.notify(1, mBuilder.build());

Copiez simplement le code et collez-le dans votre activité principale du programme de lancement.

Voici la réponse originale

2
user4356416
Intent intent = new Intent(this, MainActivity.class);
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
PendingIntent contentIntent = PendingIntent.getActivity(this, new Random().nextInt(), intent, 0);
1
Manjunath

Je pense que vous devriez ajouter un peu de logique pour le faire fonctionner, peut-être que cela peut aider:

Par exemple, j'ai un écran de démarrage (Lanceur et MAIN) de APP:

public class SplashScreen extends AppCompatActivity {
    private final int TIME_OUT = 2000;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_splash_screen);

        // Suscribirse al tema Notificaciones
        FirebaseMessaging.getInstance().subscribeToTopic("NOTA");
        if (getIntent().getExtras() != null) {
            if (getIntent().getExtras().size()>1){
                Intent home_activity = new Intent(getApplicationContext(), Home.class);
                home_activity.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
                if (getIntent().getExtras() != null) {
                    for (String key : getIntent().getExtras().keySet()) {
                        String value = "" + getIntent().getExtras().getString(key);
                        Log.d("TAG", key + "=" + value);
                        switch (key) {
                            case "url":
                                home_activity.putExtra("url", value);
                                break;
                        }
                    }
                }
                startActivity(home_activity);
                finish();

            }else{
                new Handler().postDelayed(new Runnable() {
                    @Override
                    public void run() {
                        try {
                            Intent home_activity = new Intent(getApplicationContext(), Home.class);
                            home_activity.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
                            startActivity(home_activity);
                            finish();
                        } catch (Exception ex) {
                            ex.printStackTrace();
                        }
                    }
                }, TIME_OUT);
            }


        } else {
            new Handler().postDelayed(new Runnable() {
                @Override
                public void run() {
                    try {
                        Intent home_activity = new Intent(getApplicationContext(), Home.class);
                        home_activity.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
                        startActivity(home_activity);
                        finish();
                    } catch (Exception ex) {
                        ex.printStackTrace();
                    }
                }
            }, TIME_OUT);
        }

    }

}

Et dans FirebaseService j'ai fait ce qui suit:

public class FCMessagingService extends FirebaseMessagingService {

    private final String TAG = "Push";
    private String body = "";
    private static String _url = "";
    private static int numMessage = 0;

    @Override
    public void onMessageReceived(RemoteMessage remoteMessage) {
        super.onMessageReceived(remoteMessage);

        String from = remoteMessage.getFrom();
        Log.d(TAG, "Mensaje recibido de: " + from);

        if (remoteMessage.getNotification() != null) {
            Log.d(TAG, "Notificación: " + remoteMessage.getNotification().getBody());

            if (remoteMessage.getData().size() > 0) {
                Log.d(TAG, "Data: " + remoteMessage.getData());
                try {
                    JSONObject data = new JSONObject(remoteMessage.getData());
                    String url = data.getString("url");
                    Log.d(TAG, "onMessageReceived: \n" + "Extra Information: " + url);
                    this._url = url;
                    Log.d("_URL",_url);
                    mostrarNotificacion(remoteMessage.getNotification().getTitle(), remoteMessage.getNotification().getBody());
                    mensaje(url, remoteMessage.getNotification().getTitle(), remoteMessage.getNotification().getBody());
                } catch (JSONException e) {
                    e.printStackTrace();
                }
            }
        }



    }


    private void mensaje(String url, String title, String body){
        boolean acti =  Util.comprobarActivityALaVista(getApplicationContext(), "com.dev.Android.subagan.MainActivity");
        if(acti){

            Intent imain = new Intent(MainActivity.URL);

            imain.putExtra("key_url",url);
            imain.putExtra("key_title",title);
            imain.putExtra("key_body",body);

            LocalBroadcastManager.getInstance(getApplicationContext()).sendBroadcast(imain);

        }else{

            Intent ihome = new Intent(Home.URL);

            ihome.putExtra("key_url",url);
            ihome.putExtra("key_title",title);
            ihome.putExtra("key_body",body);
            LocalBroadcastManager.getInstance(getApplicationContext()).sendBroadcast(ihome);

        }

    }




    private void mostrarNotificacion(String title, String body) {

        final int NOTIFICATION_ID = 3000;

        Intent intent = new Intent(this, MainActivity.class);
        intent.putExtra("url",_url);
        intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);


        PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, intent,PendingIntent.FLAG_UPDATE_CURRENT | PendingIntent.FLAG_ONE_SHOT  );



        Uri soundUri = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);

        NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(this)
                .setSmallIcon(R.mipmap.ic_launcher)
                .setContentTitle(title)
                .setContentText(body)
                .setAutoCancel(true)
                .setSound(soundUri)
                .setTicker(body)
                .setContentIntent(pendingIntent);

        NotificationManager notificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
        notificationManager.notify(0, notificationBuilder.build());

    }

}