Bấm thông báo: hoạt động đã mở


164

Tôi có một ứng dụng với các thông báo mở một hoạt động nhất định nếu tôi nhấp vào chúng. Tôi muốn rằng, nếu tôi nhấp vào thông báo và hoạt động đã được mở, nó sẽ không bắt đầu lại mà chỉ được đưa ra phía trước.

Tôi nghĩ rằng tôi có thể làm điều đó với cờ FLAG_ACTIVITY_BROUGHT_TO_FRONThoặc FLAG_ACTIVITY_REORDER_TO_FRONT, nhưng nó cứ mở lại để tôi có hoạt động hai lần.

Đây là mã của tôi:

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

Tôi có thể quản lý nó bằng cờ hay tôi nên lưu trữ một biến trong SharedPreferences để kiểm tra xem nó có mở hay không?

Cảm ơn!


1
Tôi sử dụng aim.setFlags (Intent.FLAG_ACTIVITY_SINGLE_TOP | Intent.FLAG_ACTIVITY_NO_HISTORY);
tro bụi

Câu trả lời:


298

Bạn cần đặt launchModethuộc tính của Activitybạn đang bắt đầu singleTop. Điều này sẽ khiến các Ý định đến được gửi đến phiên bản hiện tại thay vì bắt đầu một phiên bản mới khi đó Activityđã ở trên cùng của ngăn xếp của nhiệm vụ.

Điều này được thực hiện trong tệp kê khai bằng cách thêm android:launchMode="singleTop"vào <activity>phần tử. Để truy cập mới nhất Ý định (nếu bạn đang quan tâm đến bất kỳ dữ liệu nào có thể đã trôi qua với nó), ghi đè lên onNewIntent()trong bạn Activity.


6
Tôi chạy vào nhiều câu trả lời cho biết đặt cờ của ý định cho nhiều thứ khác nhau. Điều này đã không làm việc. Đây có phải là vì ý định, bất kể cờ của nó, sẽ đi đến một hoạt động mới được tạo ra? Tôi hỏi vì Devunwired cho biết thuộc tính launchMode thay đổi trong đó Ý định được phân phối.
lululoo

5
Trang tài liệu có tại developer.android.com/guide/topics/manifest/
mẹo

1
Tôi thấy rằng nếu bạn sử dụng phương pháp này cho hoạt động được khởi chạy từ màn hình chính, thì mỗi lần bạn khởi chạy ứng dụng sẽ bắt đầu với hoạt động gốc, phá hủy mọi hoạt động đã được hiển thị trước đó. Đây chắc chắn không phải là hành vi được mong đợi đối với người dùng đặt ứng dụng ở chế độ nền trong khi ở một hoạt động khác và mở lại.
Đức

38

Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOPThay vào đó hãy thử đặt cờ .

Từ tài liệu cho FLAG_ACTIVITY_CLEAR_TOP (nhấn mạnh của tôi):

Nếu được đặt và hoạt động được khởi chạy đã chạy trong tác vụ hiện tại, thì thay vì khởi chạy một phiên bản mới của hoạt động đó, tất cả các hoạt động khác ở trên cùng sẽ bị đóng và Ý định này sẽ được gửi đến (ngay bây giờ đầu trang) hoạt động cũ như một ý định mới.

Ví dụ, hãy xem xét một nhiệm vụ bao gồm các hoạt động: A, B, C, D. Nếu D gọi startActivity () với một Ý định giải quyết thành phần của hoạt động B, thì C và D sẽ kết thúc và B nhận được Ý định đã cho , dẫn đến ngăn xếp bây giờ là: A, B.

Ví dụ hiện đang chạy của hoạt động B trong ví dụ trên sẽ nhận được ý định mới mà bạn đang bắt đầu ở đây trong phương thức onNewIntent () của nó hoặc tự kết thúc và khởi động lại với mục đích mới. Nếu nó đã tuyên bố chế độ khởi chạy của nó là "nhiều" (mặc định) và bạn chưa đặt FLAG_ACTIVITY_SINGLE_TOP trong cùng một mục đích, thì nó sẽ được hoàn thành và tạo lại; đối với tất cả các chế độ khởi chạy khác hoặc nếu FLAG_ACTIVITY_SINGLE_TOP được đặt thì Ý định này sẽ được gửi đến phiên bản hiện tại onNewIntent ().


1
Đây là những gì tôi cần. Chỉ cần thêm một mô tả mà chúng ta cần thêm cờ này vào ý định : new Intent(this, getClass()).addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOP).
Morteza Rastgoo

6

Sử dụng onNewIntent()để xử lý dữ liệu mới từ nhấp thông báo và làm mới hoạt động.

Trong onNewIntentlấy dữ liệu mới từ mục đích mới (phục vụ bởi các thông báo mới) và bắt họ, ví dụ:

title = intent.getStringExtra("title")

onCreatetrước :)

Nó sẽ làm mới hoạt động hiện tại với dữ liệu thông báo mới.

Bạn cũng có thể làm theo hướng dẫn này.


3
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());

Chỉ cần Sao chép mã và dán nó vào hoạt động launcher chính của bạn.

Đây là câu trả lời gốc


0

Tôi nghĩ bạn nên thêm một số logic để làm cho nó hoạt động, có lẽ điều này có thể giúp:

Ví dụ: tôi có Màn hình Splash (Trình khởi chạy và MAIN) của 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);
        }

    }

}

Và trong FirebaseService của tôi, tôi đã làm như sau:

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

    }

}

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

4
Vui lòng giải thích cách mã của bạn giúp giải quyết vấn đề được đề cập trong câu hỏi. Điều này có thể không rõ ràng đối với các độc giả khác đang đối mặt với các vấn đề tương tự / tương tự.
NOh
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.