Computer >> कंप्यूटर ट्यूटोरियल >  >> प्रोग्रामिंग >> Android

नोटिफिकेशन इंटेंट को नया बनाने के बजाय कैसे रिज्यूम करें?

यह ट्यूटोरियल बताता है कि नोटिफिकेशन टैप पर एक नई एक्टिविटी इंस्टेंस बनाने के बजाय **मौजूदा एक्टिविटी इंस्टेंस को कैसे पुनर्स्थापित किया जाए**। यह डुप्लिकेट स्क्रीन को रोकता है और ऐप स्थिति को संरक्षित करता है।

मुख्य समाधान: लॉन्च मोड + इंटेंट फ्लैग

दो पूरक दृष्टिकोण एक साथ काम करते हैं:

  1. मैनिफेस्ट में: android:launchMode="singleTop" (या singleTask)
  2. इंटेंट में: FLAG_ACTIVITY_CLEAR_TOP | FLAG_ACTIVITY_SINGLE_TOP

चरण 1: प्रोजेक्ट सेटअप

एंड्रॉइड स्टूडियो में मानक Empty Activity प्रोजेक्ट।

चरण 2: AndroidManifest.xml - महत्वपूर्ण लॉन्च मोड

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="https://schemas.android.com/apk/res/android"
    package="com.example.resumeintent">

    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/Theme.ResumeIntent">

        <activity
            android:name=".MainActivity"
            android:exported="true"
            android:launchMode="singleTop">  <!-- कुंजी: मौजूदा इंस्टेंस का पुन: उपयोग करता है -->
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>
</manifest>

चरण 3: लेआउट (activity_main.xml)

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout
    xmlns:android="https://schemas.android.com/apk/res/android"
    xmlns:app="https://schemas.android.com/apk/res-auto"
    xmlns:tools="https://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:padding="16dp"
    tools:context=".MainActivity">

    <Button
        android:id="@+id/btnCreateNotification"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:text="रिज्यूम-ओनली नोटिफिकेशन बनाएँ"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

    <TextView
        android:id="@+id/tvInstanceInfo"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="24dp"
        android:text="इंस्टेंस आईडी: "
        android:textSize="16sp"
        app:layout_constraintTop_toBottomOf="@id/btnCreateNotification"
        app:layout_constraintStart_toStartOf="parent" />

</androidx.constraintlayout.widget.ConstraintLayout>

चरण 4: MainActivity.java

package com.example.resumeintent;

import android.app.NotificationChannel;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.app.NotificationCompat;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;

public class MainActivity extends AppCompatActivity {

    private static final String CHANNEL_ID = "resume_channel";
    private static final String CHANNEL_NAME = "रिज्यूम नोटिफिकेशन";
    
    // प्रत्येक इंस्टेंस को विशिष्ट रूप से पहचानने के लिए
    private final String instanceId = "Instance-" + System.currentTimeMillis();

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

        TextView tvInstance = findViewById(R.id.tvInstanceInfo);
        tvInstance.setText("इंस्टेंस आईडी: " + instanceId);

        Button btn = findViewById(R.id.btnCreateNotification);
        btn.setOnClickListener(v -> createResumeNotification());
    }

    @Override
    protected void onNewIntent(Intent intent) {
        super.onNewIntent(intent);
        // महत्वपूर्ण: नए इंटेंट डेटा के साथ एक्टिविटी अपडेट करें
        setIntent(intent);
        
        // UI रीफ्रेश करें ताकि यह वही इंस्टेंस दिखाए
        TextView tvInstance = findViewById(R.id.tvInstanceInfo);
        tvInstance.setText("पुनर्स्थापित इंस्टेंस: " + instanceId + " (नया इंटेंट प्राप्त)");
        
        // नए इंटेंट से डेटा निकालें
        if (intent.getBooleanExtra("from_notification", false)) {
            // नोटिफिकेशन-विशिष्ट लॉजिक संभालें
        }
    }

    private void createResumeNotification() {
        createNotificationChannel();

        Intent notificationIntent = new Intent(this, MainActivity.class);
        notificationIntent.putExtra("from_notification", true);
        notificationIntent.putExtra("timestamp", System.currentTimeMillis());
        
        // कुंजी फ्लैग: मौजूदा इंस्टेंस को शीर्ष पर लाता है, नया नहीं बनाता
        notificationIntent.setFlags(
            Intent.FLAG_ACTIVITY_CLEAR_TOP | 
            Intent.FLAG_ACTIVITY_SINGLE_TOP);

        // FLAG_UPDATE_CURRENT सुनिश्चित करता है कि नवीनतम अतिरिक्त डेटा उपयोग किया जाता है
        PendingIntent pendingIntent = PendingIntent.getActivity(
            this, 0, notificationIntent, 
            PendingIntent.FLAG_IMMUTABLE | PendingIntent.FLAG_UPDATE_CURRENT);

        NotificationCompat.Builder builder = new NotificationCompat.Builder(this, CHANNEL_ID)
            .setSmallIcon(R.drawable.ic_launcher_foreground)
            .setContentTitle("रिज्यूम नोटिफिकेशन")
            .setContentText("टैप करें - नई एक्टिविटी नहीं बनाएगा")
            .setPriority(NotificationCompat.PRIORITY_HIGH)
            .setContentIntent(pendingIntent)
            .setAutoCancel(true);

        NotificationManager manager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
        int id = (int) System.currentTimeMillis();
        manager.notify(id, builder.build());
    }

    private void createNotificationChannel() {
        if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.O) {
            NotificationChannel channel = new NotificationChannel(
                CHANNEL_ID, CHANNEL_NAME, NotificationManager.IMPORTANCE_HIGH);
            channel.setDescription("मौजूदा एक्टिविटी इंस्टेंस को पुनर्स्थापित करता है");
            NotificationManager manager = getSystemService(NotificationManager.class);
            manager.createNotificationChannel(channel);
        }
    }
}

लॉन्च मोड तुलना

लॉन्च मोडव्यवहारउपयोग का मामला
standard (डिफ़ॉल्ट)प्रत्येक इंटेंट के लिए नया इंस्टेंस बनाता हैअधिकांश एक्टिविटी
singleTopयदि पहले से शीर्ष पर है, तो onNewIntent() के माध्यम से पुन: उपयोग करता हैनोटिफिकेशन लक्ष्य, खोज परिणाम
singleTaskटास्क में सिंगल इंस्टेंस; उसके ऊपर की अन्य एक्टिविटी साफ़ करता हैमुख्य प्रवेश बिंदु, डीप लिंक
singleInstanceअपने टास्क में अकेला; अन्य ऐप्स इसका पुन: उपयोग कर सकते हैंबहुत दुर्लभ; विशेष मामले

फ्लैग संयोजन व्याख्या

// अनुशंसित संयोजन:
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOP);

// FLAG_ACTIVITY_CLEAR_TOP: यदि लक्ष्य एक्टिविटी स्टैक में मौजूद है,
  // उसके ऊपर की सभी एक्टिविटी नष्ट हो जाती हैं, और लक्ष्य शीर्ष पर आ जाता है
// FLAG_ACTIVITY_SINGLE_TOP: यदि लक्ष्य पहले से शीर्ष पर है,
  // नया इंस्टेंस बनाने के बजाय onNewIntent() के माध्यम से नया इंटेंट डिलीवर करता है
// साथ में: "मौजूदा इंस्टेंस ढूंढें, इसके ऊपर साफ़ करें, इसे शीर्ष पर लाएं, पुन: उपयोग करें"

PendingIntent फ्लैग (Android 12+ के लिए महत्वपूर्ण)

फ्लैगउद्देश्य
FLAG_IMMUTABLEAndroid 12+ (API 31) पर आवश्यक; PendingIntent को अपरिवर्तनीय बनाता है
FLAG_UPDATE_CURRENTयदि PendingIntent पहले से मौजूद है, तो इसके अतिरिक्त डेटा को नए इंटेंट से अपडेट करता है
FLAG_CANCEL_CURRENTमौजूदा PendingIntent को नए से पहले कैंसिल करता है

सामान्य नुकसान

  • launchMode भूलना: मैनिफेस्ट में singleTop के बिना, फ्लैग का कोई प्रभाव नहीं होता
  • onNewIntent() लागू नहीं करना: नए डेटा के साथ UI अपडेट नहीं होगा
  • FLAG_UPDATE_CURRENT के बजाय FLAG_CANCEL_CURRENT उपयोग करना: यदि एक ही अनुरोध कोड के साथ कई नोटिफिकेशन भेजे जाते हैं तो डेटा बासी हो सकता है
  • FLAG_IMMUTABLE छोड़ना: Android 12+ पर क्रैश होता है

परीक्षण सत्यापन

  1. ऐप लॉन्च करें → इंस्टेंस आईडी नोट करें
  2. नोटिफिकेशन बनाएँ → होम दबाएँ
  3. नोटिफिकेशन पर टैप करें → ऐप खुलता है, **समान इंस्टेंस आईडी** दिखाता है
  4. दोहराएँ → इंस्टेंस आईडी कभी नहीं बदलती
  1. Android में रिमाइंडर नोटिफिकेशन कैसे बनाएं? Android में रिमाइंडर नोटिफिकेशन कैसे बनाएं?

    Android में रिमाइंडर नोटिफिकेशन बनाना यह उदाहरण दर्शाता है कि Android में रिमाइंडर नोटिफिकेशन कैसे बनाया जाता है। चरण 1 - नया प्रोजेक्ट बनाएं Android Studio में File → New Project पर जाएं और नया प्रोजेक्ट बनाने के लिए सभी आवश्यक विवरण भरें। चरण 2 - res/layout/activity_main.xml में कोड जोड़ें <?

  1. फोन रीबूट के बाद Android स्टेटस बार नोटिफिकेशन को स्थायी कैसे रखें? फोन रीबूट के बाद Android स्टेटस बार नोटिफिकेशन को स्थायी कैसे रखें?

    फोन रीबूट के बाद Android स्टेटस बार नोटिफिकेशन को स्थायी रखना यह उदाहरण दर्शाता है कि फोन रीबूट के बाद Android स्टेटस बार नोटिफिकेशन को स्थायी कैसे रखा जाता है। चरण 1 - नया प्रोजेक्ट बनाएं Android Studio में File → New Project पर जाएं और नया प्रोजेक्ट बनाने के लिए सभी आवश्यक विवरण भरें। चरण 2 - re

  1. Android में Intent का उपयोग करके फोन कॉल कैसे करें? Android में Intent का उपयोग करके फोन कॉल कैसे करें?

    Android में Intent का उपयोग करके फोन कॉल करना यह उदाहरण दर्शाता है कि Android में Intent का उपयोग करके फोन कॉल कैसे किया जाता है। चरण 1 - नया प्रोजेक्ट बनाएं Android Studio में File → New Project पर जाएं और नया प्रोजेक्ट बनाने के लिए सभी आवश्यक विवरण भरें। चरण 2 - res/layout/activity_main.xml में