কোনও ক্রিয়াকলাপ থেকে বেরিয়ে আসার জন্য দু'বার পিছনে বোতামটি ক্লিক করা


330

আমি সম্প্রতি প্রচুর অ্যান্ড্রয়েড অ্যাপস এবং গেমগুলিতে এই প্যাটার্নটি লক্ষ্য করেছি: অ্যাপ্লিকেশনটির "প্রস্থান" করতে পিছনের বোতামটি ক্লিক করার সময়, এ Toast করার জন্য দয়া করে আবার ব্যাকটি ক্লিক করুন" এর অনুরূপ একটি বার্তা আসে।

আমি ভাবছিলাম, যেহেতু আমি এটি আরও বেশিবার দেখছি, এটি কি কোনও অন্তর্নির্মিত বৈশিষ্ট্য যা আপনি কোনও ক্রিয়াকলাপে কোনওভাবে অ্যাক্সেস করতে পারবেন? আমি অনেক ক্লাসের সোর্স কোড দেখেছি কিন্তু আমি এ সম্পর্কে কিছুই খুঁজে পাচ্ছি না।

অবশ্যই, আমি একই কার্যকারিতাটি বেশ সহজেই অর্জন করার কয়েকটি উপায় সম্পর্কে ভাবতে পারি (ব্যবহারকারীদের ইতিমধ্যে একবার ক্লিক করা হয়েছে কিনা তা নির্দেশ করে এমন কার্যকলাপে সম্ভবত একটি বুলিয়ান রাখা সহজ) ... তবে আমি ভাবছিলাম যে এখানে ইতিমধ্যে কিছু আছে কিনা? ।

সম্পাদনা : @ এলএএস_ভিগাস যেমন উল্লেখ করেছেন, আমি সত্যিকার অর্থে exitতিহ্যগত অর্থ "প্রস্থান" বলতে চাই নি। (অর্থাত্ সমাপ্ত) আমার অর্থ "অ্যাপ্লিকেশন শুরুর ক্রিয়াকলাপ শুরুর আগে যা কিছু খোলা ছিল তার দিকে ফিরে যাওয়া", যদি তা বোঝা যায় :)


[অ্যান্ড্রয়েড - সঙ্গে টোস্ট নিশ্চিত অ্যাপ্লিকেশন প্রস্থান] [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
সেরা উত্তর! আপনি যদি শর্তও যুক্ত করতে পারেন তবে (ডাবলব্যাকটোজিটপ্রেসডঅনস || ফ্র্যাগমেন্টমেনেজেরেটেজেটব্যাটব্যাকস্ট্যাক্ট্রিএকন্ট্রি ()! = 0)
Fra

2
আমি সম্মত, এটি অবশ্যই সেরা উত্তর এবং এটি গ্রহণযোগ্য উত্তর হওয়া উচিত।
ব্রুসহিল

3
প্রস্থান করার সময় অ্যাপলিকেশনটি আপনাকে রান্নেবল সরিয়ে ফেলতে হবে।
ওয়েইন

আমার উত্তরটি পরীক্ষা করুন above Sudheesh B Nairউপরের প্রস্তাবিত মন্তব্যগুলি কভার করার জন্য আমি প্রদত্ত উত্তরটি সংশোধন করেছি ।
মেহুল জোয়েসার

18
এটা একটা চমৎকার দ্রুত সমাধান / উত্তর কিন্তু আমি না সম্মত হন যে এটা সবচেয়ে ভালো সমাধান । এবং যারা মনে করেন তাদের পক্ষে এটি আবার সেরা উত্তর হবে আমি সম্মত হতে পারি না। এই সমাধানগুলি ফাঁসের কারণ এবং পরিচালনা করার জন্য অতিরিক্ত প্রচেষ্টা প্রয়োজন effort পরীক্ষা করে দেখুন aswers আরও বিস্তারিত জানার জন্য ক্লিক করুন।
সরো তাকান

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
আমি এই উত্তরটি পছন্দ করি এবং আমি মনে করি এটি সেরা। আমি বোঝাতে চাইছি না বলে মনে করি, উপরোক্ত কারণগুলির জন্য এটিই সেরা উত্তর। আমি আশা করি আপনি এটির জন্য আরও উপার্জন পাবেন। যদিও একটি মন্তব্য: কেউই এটিকে অদ্ভুত বলে মনে করে না যে অ্যাপটি বন্ধ হয়ে যাওয়ার পরে টোস্টটি কয়েক সেকেন্ড স্থায়ী হয়? টোস্ট বাতিল করার জন্য কারও পাত্তা নেই? আমি জানি এটি একটি ছোট বিশদ হতে পারে তবে আমি মনে করি এটি হওয়া উচিত। তোমরা কি ভাবো?
একরপো

1
সম্পাদনার জন্য @joonty ধন্যবাদ, যে int- এ শব্দ কিছু সময়ের জন্য অনুপস্থিত হয়েছে। এটি এখন
সংকলিত

2
@ নথ সেকেন্ড কোড ব্লকটি এমহ্যান্ডলারগুলি ব্যবহার করে আরও পরিশ্রমের প্রয়োজন দেখানোর জন্য একটি নমুনা ছিল। আমি আপনাকে প্রথম কোড ব্লকটি ব্যবহার করার কথা বিবেচনা করার পরামর্শ দিচ্ছি, যা হ্যান্ডলার ব্যবহার করে না।
সরো তাকান

1
@ অ্যাক্রেসপো আমি মনে করি অ্যাপ্লিকেশন বন্ধ হওয়ার পরে টস্ট ম্যাসেজের জন্য আমাদের কাছে একটি কঠিন সমাধান রয়েছে ।
সরো তাকিয়ান

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
@ ফেরানমেলঞ্চ - আমি একমত নই এটি নিছক স্বাদের বিষয় নয়। যদি উল্লেখযোগ্য সময় অতিবাহিত হয় তবে আমাদের ধরে নেওয়া উচিত যে ব্যবহারকারী ইতিমধ্যে অন্য ক্রিয়াগুলি করেছেন এবং তিনি এর আগে আর কী করেছিলেন তা বিবেচনা করে না এবং প্রয়োগ করা চালিয়ে যাওয়া বেছে নেওয়া হয় না । প্রকৃতপক্ষে, সবচেয়ে ব্যতিক্রমী ব্যবহারকারী ব্যতীত এখনও তার মনে এখনও তা থাকবে না যে তিনি আগে এটি করেছিলেন। কোনও সময়সীমা ছাড়াই আপনি অ্যাপটিকে একটি অদৃশ্য মোডে রেখে গেছেন যা সম্পর্কে ব্যবহারকারীদের জানার কোনও উপায় নেই। আমি একেবারে বিবেচ্যভাবে ইউজার ইন্টারফেসের দুর্বল নকশাকে। ব্যবহারকারীরা অবাক হবেন।
টুলমেকারস্টেভ

আইএমএইচও, এখানে এবং এখানে এর আরও ভাল রূপগুলি ।
টুলমেকারস্টেভ

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
আমি প্রাথমিকভাবে এটি সহায়ক হিসাবে ভোট দিয়েছি। সমস্যা হ'ল কোনও কারণে, এটি কিছু হ্যান্ডসেটগুলিতে কাজ করে না। অনব্যাকপ্রেসড পদ্ধতিটি সর্বোত্তমভাবে কাজ করে, তবে তারপরে আপনার কাছে টাইমস্ট্যাম্পগুলি নেই, তাই আপনাকে গ্রহণযোগ্য উত্তর হিসাবে হ্যান্ডলারের প্রয়োজন।
রাভেমির

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
বক্স সমাধানের বাইরে of (তালি)
হিতেশ ধামশনিয়া

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

অ্যাপ্লিকেশন থেকে প্রস্থান করার সময় রান্নেবল ব্যবহার করা ভাল ধারণা নয়, আমি সম্প্রতি দুটি পিএইচসি বোতামের ক্লিকের মধ্যে সময়কাল রেকর্ড এবং তুলনা করার জন্য খুব সহজ উপায় বের করেছি। নিম্নলিখিত হিসাবে নমুনা কোড:

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

এটি কার্যকরীভাবে অন্তর্নির্মিত নয়। আমি মনে করি এটি এমনকি প্রস্তাবিত আচরণ নয়। অ্যান্ড্রয়েড অ্যাপ্লিকেশনগুলি প্রস্থান করার অর্থ নয়:

কেন অ্যান্ড্রয়েড অ্যাপ্লিকেশনগুলি "প্রস্থান" বিকল্প সরবরাহ করে না?


পয়েন্ট নেওয়া হয়েছে। প্রস্থান করার অর্থ, আমি "হোম স্ক্রিনে ফিরে যাওয়া" বোঝাতে চাইছি
গিলাইম

3
তবুও এটি কার্যকরীভাবে অন্তর্নির্মিত নয়। তবে আমি এর বিরুদ্ধে কোনও গাইডলাইন সম্পর্কে অসচেতন। অ্যান্ড্রয়েড ব্যবহারকারী হিসাবে, আমি এই জাতীয় কার্যকারিতা পছন্দ করি।
ক্যানার

6
  1. মেইনএকটিভিটি ক্লাসের জন্য একটি গ্লোবাল টোস্ট ভেরিয়েবল ঘোষণা করুন। উদাহরণ: টোস্ট প্রস্থান
  2. এটি অনক্রিট ভিউ পদ্ধতিতে শুরু করুন। উদাহরণস্বরূপ :स्थानত্যাগ = টোস্ট.মেকটেক্সট (getApplicationContext (), "প্রস্থান করতে আবার ফিরে টিপুন", টোস্ট। এলএনজিটিএসএইচআরটি);
  3. অবশেষে একটি অনব্যাকপ্রেসড মেঠোড অনুসরণ করুন:

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

এটি সঠিকভাবে কাজ করে, আমি পরীক্ষা করেছি। এবং আমি মনে করি এটি অনেক সহজ।


5

সিস্টেম.কোর্নটাইমমিলিস () ব্যবহার করে জিফনাসের উত্তরটি সেরা (+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
এটি করার একটি ভাল উপায় তবে আপনার যদি আরও টোস্ট বার্তা থাকে তবে তা হয় না।
বোলদিজার পল

@ বোল্ডিজারপল নং, এই কোডটি কেবলমাত্র সেই নির্দিষ্ট টোস্টের স্থিতি পরীক্ষা করে। সুতরাং অন্য কোনও টোস্ট আচরণের উপর প্রভাব ফেলবে না।
তাত্ক্ষণিকভাবে

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 থেকে সমর্থিত supported বিস্তৃত বর্ণনার জন্য এই পৃষ্ঠাটি দেখুন । পুরানো সংস্করণগুলিতে ব্যাক প্রেস বৈশিষ্ট্যটিও কাজ করতে, আপনার ক্রিয়াকলাপে নিম্নলিখিত পদ্ধতিটি যুক্ত করুন:

@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

আমার মনে হয় জেফনাসের চেয়ে কিছুটা ভাল পদ্ধতি । সিস্টেমে.কমেন্ট টাইমমিলিস () কেবল একবারে কল করুন এবং বাদ দিন 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

এখানে, আমি এন ট্যাপ গণনাগুলির জন্য কোড লিখতে সাধারণীকরণ করেছি। কোডটি একইভাবে অ্যান্ড্রয়েড ডিভাইস ফোনে বিকাশকারী সক্ষম করুন বিকল্পের জন্য লেখা is এমনকি আপনি বিকাশকারীদের অ্যাপটি পরীক্ষা করার সময় বৈশিষ্ট্যগুলি সক্ষম করতে এটি ব্যবহার করতে পারেন।

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

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

 }

ব্যাকপ্রেস বা লগআউট বিকল্পে 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

যখন হোমঅ্যাক্টিভিটিতে নেভিগেশন ড্রয়ার থাকে এবং অ্যাপটি থেকে বেরিয়ে আসার জন্য ডাবল ব্যাকপ্রেসড () মজাদার থাকে। (গ্লোবাল ভেরিয়েবল বুলিয়ান ডাবলব্যাকটোএক্সিটপ্রেসড ওন্সেস (ভুয়া;) শুরু করতে ভুলবেন না

@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

এখানে আরও একটি উপায় রয়েছে ... কাউন্টডাউনটাইমার পদ্ধতিটি ব্যবহার করে

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

    }
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.