คลิกแจ้งเตือน: กิจกรรมเปิดอยู่แล้ว


164

ฉันมีแอปพลิเคชันพร้อมการแจ้งเตือนที่เปิดกิจกรรมบางอย่างถ้าฉันคลิก ฉันต้องการสิ่งนั้นหากฉันคลิกที่การแจ้งเตือนและกิจกรรมได้เปิดขึ้นแล้วมันไม่ได้เริ่มขึ้นอีกเลย

ฉันคิดว่าฉันสามารถทำได้ด้วยการตั้งค่าสถานะFLAG_ACTIVITY_BROUGHT_TO_FRONTหรือFLAG_ACTIVITY_REORDER_TO_FRONTแต่จะเปิดมันอีกครั้งเพื่อให้ฉันมีกิจกรรมสองครั้ง

นี่คือรหัสของฉัน:

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

ฉันสามารถจัดการมันด้วยค่าสถานะหรือฉันควรเก็บตัวแปรใน SharedPreferences เพื่อตรวจสอบว่ามีการเปิดหรือไม่

ขอบคุณ!


1
ฉันใช้ intent.setFlags (Intent.FLAG_ACTIVITY_SINGLE_TOP | Intent.FLAG_ACTIVITY_NO_HISTORY);
รังเกียจ

คำตอบ:


298

คุณจำเป็นต้องตั้งค่าlaunchModeแอตทริบิวต์ของคุณจะเริ่มต้นที่Activity singleTopสิ่งนี้จะทำให้ Intent ที่เข้ามาถูกส่งไปยังอินสแตนซ์ที่มีอยู่แทนที่จะเริ่มอินสแตนซ์ใหม่เมื่อActivityมันอยู่ที่ด้านบนสุดของสแต็กของงาน

นี้จะกระทำในที่ประจักษ์โดยการเพิ่มandroid:launchMode="singleTop"ไปยัง<activity>องค์ประกอบ ในการเข้าถึงล่าสุดแสดงเจตจำนง (ถ้าคุณมีความสนใจในข้อมูลใด ๆ ที่อาจจะมีการส่งผ่านไปในกับมัน) แทนที่ในของคุณonNewIntent()Activity


6
ฉันวิ่งเข้าไปหาคำตอบมากมายที่กล่าวว่าตั้งค่าสถานะของเจตนาต่อสิ่งต่าง ๆ สิ่งนี้ไม่ได้ผล นี่เป็นเพราะความตั้งใจไม่ว่าจะเป็นธงชาติจะเป็นกิจกรรมที่สร้างขึ้นใหม่หรือไม่? ฉันถามเพราะ Devunwired กล่าวว่าการเปลี่ยนแปลงของคุณลักษณะของ launchMode ที่ Intents ได้รับการส่งมอบ
lululoo

5
หน้าเอกสารประกอบอยู่ที่developer.android.com/guide/topics/manifest/…
Mifeng

1
ฉันเห็นว่าถ้าคุณใช้วิธีการนี้กับกิจกรรมที่เปิดตัวจากหน้าจอหลักทุกครั้งที่คุณเรียกใช้แอปพลิเคชันจะเริ่มต้นด้วยกิจกรรมรูททำลายกิจกรรมใด ๆ ที่เคยแสดงอยู่ด้านบน สิ่งนี้ไม่ใช่พฤติกรรมที่คาดไว้สำหรับผู้ใช้ที่วางแอปในพื้นหลังขณะที่อยู่ในกิจกรรมที่แตกต่างกันและเปิดใหม่อีกครั้ง
เยอรมัน

38

ลองตั้งค่าสถานะเป็นIntent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOPแทน

จากเอกสารสำหรับ FLAG_ACTIVITY_CLEAR_TOP (เน้นที่เหมือง):

หากตั้งค่าและกิจกรรมที่กำลังเปิดตัวกำลังทำงานอยู่ในงานปัจจุบันแล้วแทนที่จะเปิดตัวอินสแตนซ์ใหม่ของกิจกรรมนั้นกิจกรรมอื่น ๆ ทั้งหมดที่ด้านบนจะถูกปิดและความตั้งใจนี้จะถูกส่งไปที่ (ตอนนี้ กิจกรรมเก่าเป็นเจตนาใหม่

ตัวอย่างเช่นพิจารณางานที่ประกอบด้วยกิจกรรม: A, B, C, D ถ้า D เรียก startActivity () ด้วย Intent ที่แก้ไขส่วนประกอบของกิจกรรม B แล้ว C และ D จะเสร็จสิ้นและ B ได้รับ Intent ที่กำหนด ส่งผลให้สแต็กตอนนี้เป็น: A, B

อินสแตนซ์ที่ทำงานอยู่ในปัจจุบันของกิจกรรม B ในตัวอย่างด้านบนจะได้รับความตั้งใจใหม่ที่คุณกำลังเริ่มต้นที่นี่ในเมธอด onNewIntent () หรือทำเสร็จแล้วและเริ่มต้นใหม่ด้วยความตั้งใจใหม่ หากได้ประกาศโหมดเรียกใช้เป็น "หลาย" (ค่าเริ่มต้น) และคุณยังไม่ได้ตั้งค่า FLAG_ACTIVITY_SINGLE_TOP ในเจตนาเดียวกันมันจะเสร็จสิ้นและสร้างขึ้นใหม่ สำหรับโหมดการเรียกใช้อื่น ๆ ทั้งหมดหรือหากตั้งค่า FLAG_ACTIVITY_SINGLE_TOP แล้ว Intent นี้จะถูกส่งไปยังอินสแตนซ์ปัจจุบันของ onNewIntent ()


1
นี่คือสิ่งที่ฉันต้องการ new Intent(this, getClass()).addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOP)เพียงแค่เพิ่มรายละเอียดที่เราต้องเพิ่มธงนี้เพื่อเจตนา:
Morteza Rastgoo

6

ใช้onNewIntent()สำหรับจัดการข้อมูลใหม่จากการแจ้งเตือนคลิกและรีเฟรชกิจกรรม

ในการonNewIntentรับข้อมูลใหม่จากความตั้งใจใหม่ (ซึ่งให้บริการโดยการแจ้งเตือนใหม่) และจับพวกเขาตัวอย่างเช่น:

title = intent.getStringExtra("title")

ใน onCreateก่อนหน้านี้ :)

มันจะรีเฟรชกิจกรรมปัจจุบันด้วยข้อมูลการแจ้งเตือนใหม่

คุณสามารถติดตามบทช่วยสอนนี้ได้


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

เพียงแค่คัดลอกรหัสและวางในกิจกรรมหลักของคุณ

นี่คือคำตอบเดิม


0

ฉันคิดว่าคุณควรเพิ่มตรรกะบางอย่างเพื่อให้ทำงานได้บางทีนี่อาจช่วยได้:

ตัวอย่างเช่นฉันมีหน้าจอสแปลช (ตัวเปิดและหลัก):

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

    }

}

และใน FirebaseService ของฉันฉันได้ทำสิ่งต่อไปนี้:

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
โปรดอธิบายว่ารหัสของคุณช่วยแก้ปัญหาที่กล่าวถึงในคำถามได้อย่างไร สิ่งนี้อาจไม่ชัดเจนสำหรับผู้อ่านรายอื่นที่ประสบปัญหาเดียวกันหรือคล้ายกัน
NOhs
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.