किसी गतिविधि से बाहर निकलने के लिए बैक बटन पर दो बार क्लिक करना


330

मैंने हाल ही में बहुत सारे एंड्रॉइड ऐप और गेम्स में इस पैटर्न पर ध्यान दिया है: जब एप्लिकेशन से "बाहर निकलने" के लिए बैक बटन पर क्लिक करते हैं, तो Toast"कृपया क्लिक करें फिर से बाहर निकलने के लिए क्लिक करें" के समान संदेश आता है।

मैं सोच रहा था, जैसा कि मैं इसे अधिक से अधिक बार देख रहा हूं, क्या यह एक अंतर्निहित सुविधा है जिसे आप किसी गतिविधि में किसी भी तरह से एक्सेस कर सकते हैं? मैंने कई वर्गों के स्रोत कोड को देखा है, लेकिन मुझे उसके बारे में कुछ भी पता नहीं लग सकता है।

बेशक, मैं समान कार्यक्षमता को आसानी से प्राप्त करने के कुछ तरीकों के बारे में सोच सकता हूं (सबसे आसान शायद गतिविधि में एक बूलियन रखना है जो इंगित करता है कि उपयोगकर्ता पहले से ही एक बार क्लिक किया है ...) लेकिन मैं सोच रहा था कि क्या यहां पहले से ही कुछ है? ।

संपादित करें : जैसा कि @LAS_VEGAS ने उल्लेख किया है, मुझे वास्तव में पारंपरिक अर्थ में "बाहर निकलने" का मतलब नहीं था। (अर्थात समाप्त) मेरा मतलब था "आवेदन शुरू होने की गतिविधि शुरू होने से पहले जो कुछ भी खुला था उसे वापस जाना", अगर यह समझ में आता है :)


[एंड्रॉइड - टोस्ट के साथ ऐप से बाहर निकलने की पुष्टि करें] [1]: stackoverflow.com/questions/14006461/…
resource8218

1
होलोइवेरी लाइब्रेरी का उपयोग करते समय मुझे भी यही समस्या थी, तो बस आप एंड्रॉइड: लॉन्चमोड = "सिंगलटैस्क" को घोषणा फ़ाइल में गतिविधि परिभाषा में जोड़ सकते हैं।
सोहैब हसून


जवाबों:


947

जावा गतिविधि में:

boolean doubleBackToExitPressedOnce = false;

@Override
public void onBackPressed() {
    if (doubleBackToExitPressedOnce) {
        super.onBackPressed();
        return;
    }

    this.doubleBackToExitPressedOnce = true;
    Toast.makeText(this, "Please click BACK again to exit", Toast.LENGTH_SHORT).show();

    new Handler().postDelayed(new Runnable() {

        @Override
        public void run() {
            doubleBackToExitPressedOnce=false;                       
        }
    }, 2000);
} 

कोटलिन गतिविधि में:

private var doubleBackToExitPressedOnce = false
override fun onBackPressed() {
        if (doubleBackToExitPressedOnce) {
            super.onBackPressed()
            return
        }

        this.doubleBackToExitPressedOnce = true
        Toast.makeText(this, "Please click BACK again to exit", Toast.LENGTH_SHORT).show()

        Handler().postDelayed(Runnable { doubleBackToExitPressedOnce = false }, 2000)
    }

मुझे लगता है कि यह हैंडलर 2 सेकंड के बाद चर को रीसेट करने में मदद करता है।


43
सबसे बढ़िया उत्तर! आप भी हालत जोड़ सकते हैं अगर (doubleBackToExitPressedOnce || fragmentManager.getBackStackEntryCount ()! = 0) {फ्रैगमेंट-आधारित ऐड के मामले में
एंटोन डेरेविन्कॉन

2
मैं सहमत हूं, यह निश्चित रूप से सबसे अच्छा उत्तर है और स्वीकृत उत्तर होना चाहिए।
ब्रूसहिल

3
आवेदन से बाहर निकलने पर आपको Runnable को हटा देना चाहिए।
वेन

मेरे उत्तर की जाँच करें। मैंने दिए गए उत्तर को संशोधित कर दिया है Sudheesh B Nair ऊपर दिए गए टिप्पणियों को कवर करने के लिए ।
मेहुल जोसर

18
यह एक अच्छा त्वरित समाधान / उत्तर है, लेकिन मैं सहमत नहीं हूं कि यह सबसे अच्छा समाधान है । और जो लोग सोचते हैं कि यह सबसे अच्छा जवाब होगा फिर से मैं सहमत नहीं हो सकता। ये समाधान लीक का कारण बनता है और निपटने के लिए अतिरिक्त प्रयास की आवश्यकता होगी। अधिक जानकारी के लिए नीचे दिए गए ऐशर की जाँच करें ।
सरो तेइसनियन

226

सुदेश बी नायर के सवाल पर एक अच्छा (और स्वीकृत) जवाब है, जो मुझे लगता है कि एक बेहतर विकल्प होना चाहिए जैसे;

TIME_INTERVALअंतिम बैक प्रेस के बाद से पास किए गए समय ( यदि 2000) को पारित किया गया है, तो समय को मापने और जाँचने में क्या गलत है । निम्नलिखित नमूना कोड का उपयोग System.currentTimeMillis();समय को स्टोर करने के onBackPressed()लिए किया जाता है;

private static final int TIME_INTERVAL = 2000; // # milliseconds, desired time passed between two back presses.
private long mBackPressed;

@Override
public void onBackPressed()
{
    if (mBackPressed + TIME_INTERVAL > System.currentTimeMillis()) 
    { 
        super.onBackPressed(); 
        return;
    }
    else { Toast.makeText(getBaseContext(), "Tap back button in order to exit", Toast.LENGTH_SHORT).show(); }

    mBackPressed = System.currentTimeMillis();
}

वापस स्वीकृत उत्तर समालोचना पर ; इसका उपयोग करनाflag करता है, तो यह पिछले में दबाया गया था इंगित करने के लिए TIME_INTERVAL(कहना 2000) मिलीसेकेंड और सेट - रीसेट है के माध्यम से Handlerकी postDelayed()विधि मेरे मन में आने के लिए पहली बात यह थी। लेकिन postDelayed()जब गतिविधि बंद हो रही हो, तो कार्रवाई को रद्द कर दिया जाना चाहिए Runnable

Runnableइसे हटाने के लिए , इसे गुमनाम घोषित नहीं किया जाना चाहिए , और साथ ही सदस्य के रूप में घोषित किया जाना चाहिए Handler। तब की removeCallbacks()विधिHandler उचित रूप से कहा जा सकता है।

निम्नलिखित नमूना प्रदर्शन है;

private boolean doubleBackToExitPressedOnce;
private Handler mHandler = new Handler();

private final Runnable mRunnable = new Runnable() {
    @Override
    public void run() {
        doubleBackToExitPressedOnce = false;                       
    }
};

@Override 
protected void onDestroy() 
{ 
    super.onDestroy();

    if (mHandler != null) { mHandler.removeCallbacks(mRunnable); }
}

@Override
public void onBackPressed() {
    if (doubleBackToExitPressedOnce) {
        super.onBackPressed();
        return;
    }

    this.doubleBackToExitPressedOnce = true;
    Toast.makeText(this, "Please click BACK again to exit", Toast.LENGTH_SHORT).show();

    mHandler.postDelayed(mRunnable, 2000);
}

योगदान के लिए @ धन्यवाद का धन्यवाद; आवेदन बंद होने के बाद भी दिखने वाले टोस्ट संदेश को रोकने के लिए , Toastसदस्य के रूप में घोषित किया जा सकता है - कहते हैं mExitToast- और कॉल mExitToast.cancel();से पहले के माध्यम से रद्द किया जा सकता है super.onBackPressed();


9
जो लोग सोचते हैं कि यह वही है जो सुधेश बी नायर ने कहा था: समान कार्यक्षमता, बेहतर प्रदर्शन। तो +1।
बेदिरिल्मज़

4
मुझे यह जवाब पसंद है और मुझे लगता है कि यह सबसे अच्छा है। मेरा मतलब है कि मुझे नहीं लगता कि यह है, यह सबसे अच्छा जवाब है, ऊपर बताए गए कारणों के लिए। मुझे आशा है कि आप इस के लिए और अधिक उत्थान प्राप्त करेंगे। एक टिप्पणी हालांकि: कोई भी इसे अजीब नहीं मानता है कि ऐप बंद होने के बाद टोस्ट कुछ सेकंड तक बना रहता है? कोई भी टोस्ट को रद्द करने की परवाह नहीं करता है? मुझे पता है कि यह एक छोटा विवरण हो सकता है लेकिन मुझे लगता है कि ऐसा होना चाहिए। आप लोग क्या सोचते हैं?
21

1
@joonty एडिट के लिए धन्यवाद, कि इंट कीवर्ड कुछ समय से गायब है। यह अब संकलित करेगा: (:
सरो तायस्यान

2
@NSouth दूसरा कोड ब्लॉक एक नमूना था जिसका उपयोग mHandlers के लिए किया गया ताकि उसे अधिक प्रयास करने की आवश्यकता हो। मेरा सुझाव है कि आप पहले कोड ब्लॉक का उपयोग करने पर विचार करें, जो हैंडलर का उपयोग नहीं करता है।
सरो तेजियान

1
@acrespo मुझे लगता है कि हमारे पास टोस्ट संदेश के लिए एक ठोस समाधान है, जो अनुप्रयोग बंद होने के बाद अब भी जारी है।
सरो तेइसियन्या

30

बस सोचा था कि मैं इसे साझा करूंगा कि मैंने इसे आखिर में कैसे किया, मैंने सिर्फ अपनी गतिविधि में जोड़ा:

private boolean doubleBackToExitPressedOnce = false;

@Override
protected void onResume() {
    super.onResume();
    // .... other stuff in my onResume ....
    this.doubleBackToExitPressedOnce = false;
}

@Override
public void onBackPressed() {
    if (doubleBackToExitPressedOnce) {
        super.onBackPressed();
        return;
    }
    this.doubleBackToExitPressedOnce = true;
    Toast.makeText(this, R.string.exit_press_back_twice_message, Toast.LENGTH_SHORT).show();
}

और यह ठीक वैसा ही काम करता है जैसा मैं चाहता हूं। जब भी गतिविधि फिर से शुरू की जाती है, तब राज्य के रीसेट को शामिल करना।


15
इस समाधान के साथ दो बैक प्रेस के बीच एक मनमाना राशि हो सकती है। तो आप Backएक बार दबा सकते हैं और Backफिर एक मिनट बाद फिर से दबा सकते हैं और एप्लिकेशन बाहर निकल जाएगा। यह वह व्यवहार नहीं है जिसकी उपयोगकर्ता अपेक्षा करेगा।
ब्रूसहिल

1
मुझे लगता है कि यह स्वाद की बात है। इस मामले में आप उपयोगकर्ता को सिर्फ एक बार सूचित करते हैं, इसलिए उपयोगकर्ता जानता है कि वह मुख्य गतिविधि में है और दूसरा बैक प्रेस ऐप से बाहर निकल जाएगा (संभवतः उपयोगकर्ता द्वारा मुख्य स्क्रीन पर वापस जाने के लिए कुछ समय बाद वापस दबाया गया हो)। अगर, बाद में, उपयोगकर्ता फिर से वापस प्रेस करता है, तो हम मान सकते हैं कि वह ऐप से बाहर निकलना चाहता है (जब तक कि उसने किसी अन्य गतिविधियों में नेविगेट नहीं किया है और संभवतः वह कितना गहरा ट्रैक खो गया है)। उपरोक्त स्वीकृत उत्तर में, आप मानते हैं कि उपयोगकर्ता यह भूल सकता है कि वह पहले से ही मुख्य स्क्रीन में है। आप जो चाहते हैं या विचार करते हैं उसके आधार पर दोनों ठीक हैं।
फेरन मायलिनच

4
@FerranMaylinch - मैं असहमत हूं। यह केवल स्वाद की बात नहीं है। यदि महत्वपूर्ण समय बीत चुका है, तो हमें यह मान लेना चाहिए कि उपयोगकर्ता ने इस बीच अन्य कार्य किए हैं, और अब इस बात पर विचार नहीं करता है कि उसने पहले क्या किया था और आवेदन करने के लिए जारी रखने के लिए नहीं चुना था । वास्तव में, सभी लेकिन सबसे असाधारण उपयोगकर्ता अभी भी उसके दिमाग में नहीं होगा कि उसने पहले ऐसा किया था। समय सीमा के बिना, आपने ऐप को एक अदृश्य मोड में छोड़ दिया है, जिसके बारे में उपयोगकर्ता के पास जानने का कोई तरीका नहीं है। मैं पूरी तरह से विचार करता हूं कि खराब यूजर इंटरफेस डिजाइन होना चाहिए। यूजर्स हैरान रह जाएंगे।
टूलमेकरसेव

IMHO, बेहतर इस पर वेरिएंट यहाँ और यहाँ
टूलमेकरसैट

26

प्रोसेस फ़्लो डायग्राम: बाहर निकलने के लिए फिर से दबाएं।

जावा कोड:

private long lastPressedTime;
private static final int PERIOD = 2000;

@Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
    if (event.getKeyCode() == KeyEvent.KEYCODE_BACK) {
        switch (event.getAction()) {
        case KeyEvent.ACTION_DOWN:
            if (event.getDownTime() - lastPressedTime < PERIOD) {
                finish();
            } else {
                Toast.makeText(getApplicationContext(), "Press again to exit.",
                        Toast.LENGTH_SHORT).show();
                lastPressedTime = event.getEventTime();
            }
            return true;
        }
    }
    return false;
}

1
मैंने सहायक होने के नाते इसे वोट दिया। परेशानी किसी कारण से, यह कुछ हैंडसेट पर काम नहीं करता है। OnBackPressed तरीका सबसे अच्छा काम करता है, लेकिन तब आपके पास टाइमस्टैम्प नहीं होते हैं, इसलिए आपको हैंडलर की आवश्यकता होती है क्योंकि स्वीकृत उत्तर बताता है।
रवमीर

23

इन सभी उत्तरों के बीच बहुत सरल तरीका है।

बस निम्नलिखित कोड onBackPressed()विधि के अंदर लिखें ।

long back_pressed;

@Override
public void onBackPressed() {
    if (back_pressed + 1000 > System.currentTimeMillis()){
        super.onBackPressed();
    }
    else{
        Toast.makeText(getBaseContext(),
                "Press once again to exit!", Toast.LENGTH_SHORT)
                .show();
    }
    back_pressed = System.currentTimeMillis();
}

आपको गतिविधि के back_pressedरूप longमें ऑब्जेक्ट को परिभाषित करने की आवश्यकता है ।


16

स्नैकबार का उपयोग करके मेरा समाधान:

Snackbar mSnackbar;

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

    final LinearLayout layout = findViewById(R.id.layout_main);
    mSnackbar = Snackbar.make(layout, R.string.press_back_again, Snackbar.LENGTH_SHORT);
}

@Override
public void onBackPressed() {
    if (mSnackbar.isShown()) {
        super.onBackPressed();
    } else {
        mSnackbar.show();
    }
}

सरल और स्टाइलिश।


2
इस समाधान के लिए धन्यवाद। सरल, प्रभावी, कोई जोखिम नहीं।
पिंग ली

2
बॉक्स समाधान से बाहर। (क्लैप)
हितेश धामनिया

13

टिप्पणियों में सही उत्तर और सुझावों के आधार पर, मैंने एक डेमो बनाया है जो बिल्कुल ठीक काम करता है और उपयोग किए जाने के बाद हैंडलर कॉलबैक को हटा देता है।

MainActivity.java

package com.mehuljoisar.d_pressbacktwicetoexit;

import android.os.Bundle;
import android.os.Handler;
import android.app.Activity;
import android.widget.Toast;

public class MainActivity extends Activity {

    private static final long delay = 2000L;
    private boolean mRecentlyBackPressed = false;
    private Handler mExitHandler = new Handler();
    private Runnable mExitRunnable = new Runnable() {

        @Override
        public void run() {
            mRecentlyBackPressed=false;   
        }
    };

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

    @Override
    public void onBackPressed() {

        //You may also add condition if (doubleBackToExitPressedOnce || fragmentManager.getBackStackEntryCount() != 0) // in case of Fragment-based add
        if (mRecentlyBackPressed) {
            mExitHandler.removeCallbacks(mExitRunnable);
            mExitHandler = null;
            super.onBackPressed();
        }
        else
        {
            mRecentlyBackPressed = true;
            Toast.makeText(this, "press again to exit", Toast.LENGTH_SHORT).show();
            mExitHandler.postDelayed(mExitRunnable, delay);
        }
    }

}

मुझे आशा है कि यह मददगार होगा !!


क्या आप स्मृति रिसाव के मुद्दे को onBackPressed()ठीक करने के लिए हैंडलर को हटा रहे हैं ?
सरो तेइसियन

@ ज़ेफ़नस: जहां तक ​​मुझे पता है यह ठीक हो जाएगा। अगर मैं ग़लत हूं तो मेरी गलती सुझाएं। आपने उपरोक्त कोड के साथ मेमोरी समस्या का पता कैसे लगाया?
मेहुल जोसर

11
 public void onBackPressed() {
    if (doubleBackToExitPressedOnce) {
        super.onBackPressed();
        return;
    }

    this.doubleBackToExitPressedOnce = true;
    Toast.makeText(this, "Please click BACK again to exit", Toast.LENGTH_SHORT).show();

    new Handler().postDelayed(new Runnable() {

        @Override
        public void run() {
            doubleBackToExitPressedOnce=false;
        }
    }, 2000);

परिवर्तनशील घोषित करेंprivate boolean doubleBackToExitPressedOnce = false;

इसे अपनी मुख्य गतिविधि में पेस्ट करें और इससे आपकी समस्या हल हो जाएगी


10

एप्लिकेशन से बाहर निकलते समय Runnable का उपयोग करना एक अच्छा विचार नहीं है, मैंने हाल ही में दो BACK बटन क्लिकों के बीच की अवधि को रिकॉर्ड करने और तुलना करने के लिए बहुत सरल तरीका पता लगाया है। निम्नलिखित के रूप में नमूना कोड:

private static long back_pressed_time;
private static long PERIOD = 2000;

@Override
public void onBackPressed()
{
        if (back_pressed_time + PERIOD > System.currentTimeMillis()) super.onBackPressed();
        else Toast.makeText(getBaseContext(), "Press once again to exit!", Toast.LENGTH_SHORT).show();
        back_pressed_time = System.currentTimeMillis();
}

यह एक निश्चित देरी अवधि के भीतर डबल BACK बटन क्लिक द्वारा एप्लिकेशन से बाहर निकलने की चाल को करेगा जो कि नमूना में 2000 मिलीसेकंड है।


8

स्वीकृत उत्तर सर्वश्रेष्ठ है, लेकिन यदि आप उपयोग कर रहे हैं Android Design Support Libraryतो आप SnackBarबेहतर दृश्यों के लिए उपयोग कर सकते हैं ।

   boolean doubleBackToExitPressedOnce = false;

    @Override
    public void onBackPressed() {
        if (doubleBackToExitPressedOnce) {
            super.onBackPressed();
            return;
        }

        this.doubleBackToExitPressedOnce = true;

        Snackbar.make(findViewById(R.id.photo_album_parent_view), "Please click BACK again to exit", Snackbar.LENGTH_SHORT).show();

        new Handler().postDelayed(new Runnable() {

            @Override
            public void run() {
                doubleBackToExitPressedOnce=false;
            }
        }, 2000);
    }

7

यह कार्यक्षमता में निर्मित नहीं है। मुझे लगता है कि यह अनुशंसित व्यवहार भी नहीं है। Android ऐप्स बाहर निकलने के लिए नहीं हैं:

एंड्रॉइड एप्लिकेशन को "एक्जिट" विकल्प क्यों नहीं प्रदान करते हैं?


मुद्दा लेना। बाहर निकलने से मेरा मतलब था "होम स्क्रीन पर वापस जाना"
गुइलूम

3
अभी भी यह कार्यक्षमता में निर्मित नहीं है। हालांकि मैं इसके खिलाफ किसी भी दिशानिर्देश से अनजान हूं। एक Android उपयोगकर्ता के रूप में, मुझे ऐसी कार्यक्षमता पसंद है।
कनेर

6
  1. MainActivity Class के लिए एक वैश्विक टोस्ट चर घोषित करें। उदाहरण: टोस्ट बाहर निकलना;
  2. इसे ऑनक्रिएट व्यू मेथड में शुरू करें। उदाहरण: exitToast = Toast.makeText (getApplicationContext) (, "बाहर निकलने के लिए फिर से दबाएं", Toast.LENGTH_SHORT);
  3. अंत में इस प्रकार के रूप में एक onBackPressedMethod बनाएँ:

    @Override
    public void onBackPressed() {
    
        if (exitToast.getView().isShown()) {
            exitToast.cancel();
            finish();
        } else {
            exitToast.show();
        }
    }

यह सही ढंग से काम करता है, मैंने परीक्षण किया है। और मुझे लगता है कि यह बहुत सरल है।


5

Zefnus का उत्तर System.currentTimeMillis () का उपयोग करना सबसे अच्छा है (+1)। जिस तरह से मैंने किया वह नहीं है है, लेकिन फिर भी इसे पोस्ट करने के लिए उपरोक्त विचारों को जोड़ना होगा।

यदि बैक बटन दबाए जाने पर टोस्ट दिखाई नहीं देता है, तो टोस्ट प्रदर्शित होता है, जबकि, यदि यह दिखाई देता है (पिछली बार के भीतर एक बार पहले ही दबाया गया है Toast.LENGTH_SHORT), तो यह बाहर निकलता है।

exitToast = Toast.makeText(this, "Press again to exit", Toast.LENGTH_SHORT);
.
.
@Override
public void onBackPressed() {
   if (exitToast.getView().getWindowToken() == null) //if toast is currently not visible
      exitToast.show();  //then show toast saying 'press againt to exit'
   else {                                            //if toast is visible then
      finish();                                      //or super.onBackPressed();
      exitToast.cancel();
   }
}

1
ऐसा करने का एक अच्छा तरीका है, लेकिन अगर आपके पास अधिक टोस्ट संदेश नहीं है।
बोल्डिजर पॉल

@BoldijarPaul नहीं, यह कोड केवल उस विशिष्ट टोस्ट की स्थिति की जाँच करता है। तो किसी भी अन्य टोस्ट व्यवहार को प्रभावित नहीं करेगा।
अत्यावश्यक

5

हाल ही में, मुझे एक ऐप में इस बैक बटन सुविधा को लागू करने की आवश्यकता थी। मूल प्रश्न पर उत्तर उपयोगी थे, लेकिन मुझे दो और बिंदुओं को ध्यान में रखना था:

  1. समय के कुछ बिंदुओं पर, बैक बटन अक्षम है
  2. मुख्य गतिविधि एक बैक स्टैक के साथ संयोजन में टुकड़ों का उपयोग कर रही है

उत्तर और टिप्पणियों के आधार पर, मैंने निम्नलिखित कोड बनाया:

private static final long BACK_PRESS_DELAY = 1000;

private boolean mBackPressCancelled = false;
private long mBackPressTimestamp;
private Toast mBackPressToast;

@Override
public void onBackPressed() {
    // Do nothing if the back button is disabled.
    if (!mBackPressCancelled) {
        // Pop fragment if the back stack is not empty.
        if (getSupportFragmentManager().getBackStackEntryCount() > 0) {
            super.onBackPressed();
        } else {
            if (mBackPressToast != null) {
                mBackPressToast.cancel();
            }

            long currentTimestamp = System.currentTimeMillis();

            if (currentTimestamp < mBackPressTimestamp + BACK_PRESS_DELAY) {
                super.onBackPressed();
            } else {
                mBackPressTimestamp = currentTimestamp;

                mBackPressToast = Toast.makeText(this, getString(R.string.warning_exit), Toast.LENGTH_SHORT);
                mBackPressToast.show();
            }
        }
    }
}

उपरोक्त कोड मानता है कि समर्थन पुस्तकालय का उपयोग किया जाता है। आप टुकड़े नहीं बल्कि समर्थन पुस्तकालय का उपयोग करते हैं, आप बदलना चाहते getSupportFragmentManager()द्वाराgetFragmentManager()

पहले निकालें if, अगर बैक बटन कभी रद्द नहीं हुआ। दूसरा निकालेंif , यदि आप टुकड़े या एक टुकड़ा वापस ढेर का उपयोग नहीं करते हैं

इसके अलावा, यह जानना महत्वपूर्ण है कि onBackPressedएंड्रॉइड 2.0 के बाद से यह विधि समर्थित है। विस्तृत विवरण के लिए इस पृष्ठ की जाँच करें । पुराने वर्जन पर बैक प्रेस फीचर का काम करने के लिए, अपनी गतिविधि में निम्न विधि जोड़ें:

@Override
public boolean onKeyDown(int keyCode, KeyEvent event)  {
    if (android.os.Build.VERSION.SDK_INT < android.os.Build.VERSION_CODES.ECLAIR
            && keyCode == KeyEvent.KEYCODE_BACK
            && event.getRepeatCount() == 0) {
        // Take care of calling this method on earlier versions of
        // the platform where it doesn't exist.
        onBackPressed();
    }

    return super.onKeyDown(keyCode, event);
}

5

जावा में

private Boolean exit = false; 

if (exit) {
onBackPressed(); 
}

 @Override
public void onBackPressed() {
    if (exit) {
        finish(); // finish activity
    } else {
        Toast.makeText(this, "Press Back again to Exit.",
                Toast.LENGTH_SHORT).show();
        exit = true;
        new Handler().postDelayed(new Runnable() {
            @Override
            public void run() {
                exit = false;
            }
        }, 3 * 1000);

    }
}

कोटलिन में

 private var exit = false

 if (exit) {
        onBackPressed()
         }

 override fun onBackPressed(){
           if (exit){
               finish() // finish activity
           }else{
            Toast.makeText(this, "Press Back again to Exit.",
                    Toast.LENGTH_SHORT).show()
            exit = true
            Handler().postDelayed({ exit = false }, 3 * 1000)

        }
    }

4

मुझे पता है कि यह एक बहुत पुराना प्रश्न है, लेकिन यह सबसे आसान तरीका है कि आप क्या चाहते हैं।

@Override
public void onBackPressed() {
   ++k; //initialise k when you first start your activity.
   if(k==1){
      //do whatever you want to do on first click for example:
      Toast.makeText(this, "Press back one more time to exit", Toast.LENGTH_LONG).show();
   }else{
      //do whatever you want to do on the click after the first for example:
      finish(); 
   }
}

मुझे पता है कि यह सबसे अच्छा तरीका नहीं है, लेकिन यह ठीक काम करता है!


3
यह "बाहर निकलने के लिए दो बार बटन क्लिक करने" का सामान्य व्यवहार नहीं है। जैसे ब्रूसहिल की स्वीकृत उत्तर पर टिप्पणी, आपका उत्तर समय के मुद्दे को भी नहीं
सुलझाता

लेकिन इसके साथ आप वापस क्लिक कर सकते हैं, यह संदेश दिखाएगा, और फिर आप थोड़ी देर प्रतीक्षा कर सकते हैं, फिर से वापस जा सकते हैं और यह ऐप को बंद कर देगा, और यह डबल बैक टाइमिंग के व्यवहार को संभाल नहीं
पाएगा

3

इस कार्य के लिए मैंने निम्नलिखित कार्य को कार्यान्वित किया है:

private long onRecentBackPressedTime;
@Override
public void onBackPressed() {
    if (System.currentTimeMillis() - onRecentBackPressedTime > 2000) {
       onRecentBackPressedTime = System.currentTimeMillis();
       Toast.makeText(this, "Please press BACK again to exit", Toast.LENGTH_SHORT).show();
       return;
     }
   super.onBackPressed();
}

3

यह तब भी मदद करता है जब आपके पास स्टैक में संग्रहीत पिछली स्टैक गतिविधि होती है।

मैंने सुधेश के जवाब को संशोधित किया है

boolean doubleBackToExitPressedOnce = false;

@Override
public void onBackPressed() {
    if (doubleBackToExitPressedOnce) {
        //super.onBackPressed();

  Intent intent = new Intent(Intent.ACTION_MAIN);
                    intent.addCategory(Intent.CATEGORY_HOME);
                    intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);//***Change Here***
                    startActivity(intent);
                    finish();
                    System.exit(0);
        return;
    }

    this.doubleBackToExitPressedOnce = true;
    Toast.makeText(this, "Please click BACK again to exit", Toast.LENGTH_SHORT).show();

    new Handler().postDelayed(new Runnable() {

        @Override
        public void run() {
            doubleBackToExitPressedOnce=false;                       
        }
    }, 2000);
} 

2
@Override public void onBackPressed() {
   Log.d("CDA", "onBackPressed Called");
   Intent intent = new Intent();
   intent.setAction(Intent.ACTION_MAIN);
   intent.addCategory(Intent.CATEGORY_HOME);

   startActivity(intent);
}

1
यह डबल प्रेस परिदृश्य को भी कैसे संभालता है? जैसे ही मैं वापस मारा, यह एक गतिविधि शुरू करता है।
किलोकाहन

2

ज़ेफ़नस से थोड़ा बेहतर तरीका मुझे लगता है। System.currentTimeMillis () को केवल एक बार कॉल करें और छोड़ें return;:

long previousTime;

@Override
public void onBackPressed()
{
    if (2000 + previousTime > (previousTime = System.currentTimeMillis())) 
    { 
        super.onBackPressed();
    } else {
        Toast.makeText(getBaseContext(), "Tap back button in order to exit", Toast.LENGTH_SHORT).show();
    }
}

2

यहां पूर्ण कार्य कोड दिया गया है। और कॉलबैक को हटाना भी न भूलें ताकि यह ऐप में मेमोरी लीक का कारण न बने। :)

private boolean backPressedOnce = false;
private Handler statusUpdateHandler;
private Runnable statusUpdateRunnable;

public void onBackPressed() {
        if (backPressedOnce) {
            finish();
        }

        backPressedOnce = true;
        final Toast toast = Toast.makeText(this, "Press again to exit", Toast.LENGTH_SHORT);
        toast.show();

        statusUpdateRunnable = new Runnable() {
            @Override
            public void run() {
                backPressedOnce = false;
                toast.cancel();  //Removes the toast after the exit.
            }
        };

        statusUpdateHandler.postDelayed(statusUpdateRunnable, 2000);
}

@Override
protected void onDestroy() {
    super.onDestroy();
    if (statusUpdateHandler != null) {
        statusUpdateHandler.removeCallbacks(statusUpdateRunnable);
    }
}

2

यहाँ, मैंने N टैप काउंट के लिए कोड को सामान्यीकृत किया है। कोड समान रूप से एंड्रॉइड डिवाइस फोन में डेवलपर डेवलपर विकल्प के लिए लिखा गया है। यहां तक ​​कि आप इसका उपयोग कर सकते हैं ताकि एप्लिकेशन का परीक्षण करते समय सुविधाओं को सक्षम किया जा सके।

 private Handler tapHandler;
 private Runnable tapRunnable;
 private int mTapCount = 0;
 private int milSecDealy = 2000;

onCreate(){
 ...
tapHandler = new Handler(Looper.getMainLooper());

 }

Backpress या logout ऑप्शन पर askToExit () को कॉल करें ।

private void askToExit() {
   if (mTapCount >= 2) {
    releaseTapValues();
    /* ========= Exit = TRUE  =========  */
   }

   mTapCount++;
   validateTapCount();
  }


  /* Check with null to avoid create multiple instances of the runnable */
  private void validateTapCount() {
   if (tapRunnable == null) {
    tapRunnable = new Runnable() {
     @Override
     public void run() {
      releaseTapValues();
      /* ========= Exit = FALSE  =========  */
     }
    };
    tapHandler.postDelayed(tapRunnable, milSecDealy);
   }
  }

  private void releaseTapValues() {
   /* Relase the value  */
   if (tapHandler != null) {
    tapHandler.removeCallbacks(tapRunnable);
    tapRunnable = null; /* release the object */
    mTapCount = 0; /* release the value */
   }
  }


  @Override
  protected void onDestroy() {
   super.onDestroy();
   releaseTapValues();
  }

2

मैं इसका उपयोग करता हूं

import android.app.Activity;
import android.support.annotation.StringRes;
import android.widget.Toast;

public class ExitApp {

    private static long lastClickTime;

    public static void now(Activity ctx, @StringRes int message) {
        now(ctx, ctx.getString(message), 2500);
    }

    public static void now(Activity ctx, @StringRes int message, long time) {
        now(ctx, ctx.getString(message), time);
    }

    public static void now(Activity ctx, String message, long time) {
        if (ctx != null && !message.isEmpty() && time != 0) {
            if (lastClickTime + time > System.currentTimeMillis()) {
                ctx.finish();
            } else {
                Toast.makeText(ctx, message, Toast.LENGTH_SHORT).show();
                lastClickTime = System.currentTimeMillis();
            }
        }
    }

}

घटना में उपयोग करेंonBackPressed

@Override
public void onBackPressed() {
   ExitApp.now(this,"Press again for close");
}

या ExitApp.now(this,R.string.double_back_pressed)

परिवर्तन के सेकंड के लिए नज़दीकी, निर्दिष्ट मिलिसेकंड की आवश्यकता होती है

ExitApp.now(this,R.string.double_back_pressed,5000)


2

जब HomeActivity में नेविगेशन ड्रॉअर और ऐप से बाहर निकलने के लिए डबल बैकड्रेस () फ़ंसीशन होता है। (वैश्विक चर बूलियन doubleBackToExitPressedOnce = false को भूल जाना न भूलें;) 2 सेकंड के बाद नया हैंडलर सेट करें

@Override
public void onBackPressed() {
    DrawerLayout drawer = findViewById(R.id.drawer_layout);
    if (drawer.isDrawerOpen(GravityCompat.END)) {
        drawer.closeDrawer(GravityCompat.END);
    } else {
        if (doubleBackToExitPressedOnce) {
            super.onBackPressed();
            moveTaskToBack(true);
            return;
        } else {
            this.doubleBackToExitPressedOnce = true;
            Toast.makeText(this, "Please click BACK again to exit", Toast.LENGTH_SHORT).show();
            new Handler().postDelayed(new Runnable() {
                @Override
                public void run() {
                    doubleBackToExitPressedOnce = false;
                }
            }, 2000);
        }
    }
}

1
boolean doubleBackToExitPressedOnce = false;

@Override
public void onBackPressed() {
    if (doubleBackToExitPressedOnce) {
        super.onBackPressed();
        return;
    }

    this.doubleBackToExitPressedOnce = true;

    Snackbar.make(findViewById(R.id.photo_album_parent_view), "Please click BACK again to exit", Snackbar.LENGTH_SHORT).show();

    new Handler().postDelayed(new Runnable() {

        @Override
        public void run() {
            doubleBackToExitPressedOnce=false;
        }
    }, 2000);
}

1

सुदेश बी नायर के जवाब में कुछ सुधार, मैंने देखा है कि यह तुरंत दो बार वापस दबाने पर भी हैंडलर की प्रतीक्षा करेगा, इसलिए नीचे दिखाए अनुसार हैंडलर को रद्द करें। मैंने ऐप से बाहर निकलने के बाद इसे रोकने के लिए टोस्ट टोस्ट भी किया है।

 boolean doubleBackToExitPressedOnce = false;
        Handler myHandler;
        Runnable myRunnable;
        Toast myToast;

    @Override
        public void onBackPressed() {
            if (doubleBackToExitPressedOnce) {
                myHandler.removeCallbacks(myRunnable);
                myToast.cancel();
                super.onBackPressed();
                return;
            }

            this.doubleBackToExitPressedOnce = true;
            myToast = Toast.makeText(this, "Please click BACK again to exit", Toast.LENGTH_SHORT);
            myToast.show();

            myHandler = new Handler();

            myRunnable = new Runnable() {

                @Override
                public void run() {
                    doubleBackToExitPressedOnce = false;
                }
            };
            myHandler.postDelayed(myRunnable, 2000);
        }

1

यह स्वीकृत और सर्वाधिक मत वाली प्रतिक्रिया के समान है लेकिन इस स्नैच ने टोस्ट के बजाय स्नैकबार का उपयोग किया।

boolean doubleBackToExitPressedOnce = false;

    @Override
    public void onBackPressed() {
        if (doubleBackToExitPressedOnce) {
            super.onBackPressed();
            return;
        }

        this.doubleBackToExitPressedOnce = true;
        Snackbar.make(content, "Please click BACK again to exit", Snackbar.LENGTH_SHORT)
                .setAction("Action", null).show();


        new Handler().postDelayed(new Runnable() {

            @Override
            public void run() {
                doubleBackToExitPressedOnce=false;
            }
        }, 2000);
    }

1

मेरे मामले में, मैं Snackbar#isShown()बेहतर के लिए निर्भर हूं UX

private Snackbar exitSnackBar;

@Override
public void onBackPressed() {
    if (isNavDrawerOpen()) {
        closeNavDrawer();
    } else if (getSupportFragmentManager().getBackStackEntryCount() == 0) {
        if (exitSnackBar != null && exitSnackBar.isShown()) {
            super.onBackPressed();
        } else {
            exitSnackBar = Snackbar.make(
                    binding.getRoot(),
                    R.string.navigation_exit,
                    2000
            );
            exitSnackBar.show();
        }
    } else {
        super.onBackPressed();
    }
}

1

नेविगेशन ड्रॉअर वाली गतिविधि के लिए, OnBackPressed () के लिए निम्न कोड का उपयोग करें

boolean doubleBackToExitPressedOnce = false;

@Override
    public void onBackPressed() {
        DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
        if (drawer.isDrawerOpen(GravityCompat.START)) {
            drawer.closeDrawer(GravityCompat.START);
        } else {
            if (doubleBackToExitPressedOnce) {
                if (getFragmentManager().getBackStackEntryCount() ==0) {
                    finishAffinity();
                    System.exit(0);
                } else {
                    getFragmentManager().popBackStackImmediate();
                }
                return;
            }

            if (getFragmentManager().getBackStackEntryCount() ==0) {
                this.doubleBackToExitPressedOnce = true;
                Toast.makeText(this, "Please click BACK again to exit", Toast.LENGTH_SHORT).show();

                new Handler().postDelayed(new Runnable() {

                    @Override
                    public void run() {
                        doubleBackToExitPressedOnce = false;
                    }
                }, 2000);
            } else {
                getFragmentManager().popBackStackImmediate();
            }
        }
    }

1

यहाँ एक और तरीका है ... CountDownTimer विधि का उपयोग करना

private boolean exit = false;
@Override
public void onBackPressed() {
        if (exit) {
            finish();
        } else {
            Toast.makeText(this, "Press back again to exit",
                    Toast.LENGTH_SHORT).show();
            exit = true;
            new CountDownTimer(3000,1000) {

                @Override
                public void onTick(long l) {

                }

                @Override
                public void onFinish() {
                    exit = false;
                }
            }.start();
        }

    }
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.