एक Android एप्लिकेशन पृष्ठभूमि में चल रहा है या नहीं, यह जांचना


329

पृष्ठभूमि से, मेरा मतलब है कि एप्लिकेशन की कोई भी गतिविधि वर्तमान में उपयोगकर्ता को दिखाई नहीं दे रही है?



7
मैं यहाँ उलझन में हूँ .. क्यों Android इस के लिए आवेदन वर्ग पर एक साधारण ओवरराइड प्रदान नहीं कर सकता? क्या प्लेटफॉर्म स्तर पर यह जानना बहुत मुश्किल है? @Override संरक्षित शून्य onApplicationSentToBackground () {}
चक डी

2
@ChuckD - यह समझ में आता है, जो कि एंड्रॉइड एसडीके कई बार ऐसा करने से बचना पसंद करता है। : /
मार्क


1
iOS में यह हुकुम है, यकीन नहीं होता कि Google इसे इतना कठिन क्यों बनाता है। यह एक ऐसी स्पष्ट आवश्यकता है।
जेरी डेस्ट्रेम्प्स

जवाबों:


388

यह पता लगाने के कुछ तरीके हैं कि आपका एप्लिकेशन पृष्ठभूमि में चल रहा है या नहीं, लेकिन उनमें से केवल एक ही पूरी तरह से विश्वसनीय है:

  1. सही समाधान (क्रेडिट दान , कॉमन्सवेयर और नेइटइन्स्टाईएनएन पर जाते हैं )
    अपने आवेदन की दृश्यता को ट्रैक करके अपने आप का उपयोग करते हुए Activity.onPause, Activity.onResumeतरीकों से। स्टोर "दृश्यता" की स्थिति कुछ अन्य वर्ग में। अच्छे विकल्प आपके स्वयं के कार्यान्वयन हैं Applicationया Service( इस समाधान के कुछ रूपांतर भी हैं यदि आप सेवा से गतिविधि की दृश्यता की जांच करना चाहते हैं)।
     
    उदाहरण
    कस्टम Applicationवर्ग लागू करें ( isActivityVisible()स्थिर विधि पर ध्यान दें ):

    public class MyApplication extends Application {
    
      public static boolean isActivityVisible() {
        return activityVisible;
      }  
    
      public static void activityResumed() {
        activityVisible = true;
      }
    
      public static void activityPaused() {
        activityVisible = false;
      }
    
      private static boolean activityVisible;
    }

    इसमें अपना आवेदन वर्ग पंजीकृत करें AndroidManifest.xml:

    <application
        android:name="your.app.package.MyApplication"
        android:icon="@drawable/icon"
        android:label="@string/app_name" >

    जोड़े onPauseऔर onResumeहर के लिए Activityपरियोजना में (यदि आप करना चाहते हैं तो आप अपने गतिविधियों के लिए एक आम पूर्वज बना सकते हैं, लेकिन अगर अपनी गतिविधि को पहले से ही से बढ़ा दिया गया है MapActivity/ ListActivityआदि आप अभी भी हाथ से निम्नलिखित लिखने की ज़रूरत):

    @Override
    protected void onResume() {
      super.onResume();
      MyApplication.activityResumed();
    }
    
    @Override
    protected void onPause() {
      super.onPause();
      MyApplication.activityPaused();
    }

     
    अद्यतन
    गतिविधिलिफ़साइकलबैक को एपीआई स्तर 14 (एंड्रॉइड 4.0) में जोड़ा गया था। आप उन्हें ट्रैक करने के लिए उपयोग कर सकते हैं कि क्या आपके एप्लिकेशन की गतिविधि वर्तमान में उपयोगकर्ता को दिखाई दे रही है। विवरण के लिए नीचे कॉर्न्स्टल के उत्तर की जाँच करें।

  2. गलत
    मैं निम्नलिखित समाधान का सुझाव देता था:

    आप वर्तमान में अग्रभूमि / पृष्ठभूमि अनुप्रयोग का पता लगा सकते हैं, ActivityManager.getRunningAppProcesses()जिसके साथ RunningAppProcessInfoरिकॉर्ड की एक सूची मिलती है। यह निर्धारित करने के लिए कि आपका आवेदन अग्रभूमि चेक RunningAppProcessInfo.importanceफ़ील्ड पर समानता के लिए है RunningAppProcessInfo.IMPORTANCE_FOREGROUNDजबकि RunningAppProcessInfo.processNameआपके एप्लिकेशन पैकेज नाम के बराबर है।

    यदि आप ActivityManager.getRunningAppProcesses()अपने एप्लिकेशन UI थ्रेड से कॉल करते हैं, तो यह IMPORTANCE_FOREGROUNDआपके कार्य के लिए महत्व देगा चाहे वह वास्तव में अग्रभूमि में हो या नहीं। इसे बैकग्राउंड थ्रेड (उदाहरण के माध्यम से AsyncTask) में कॉल करें और यह सही परिणाम देगा।

    हालांकि यह समाधान काम कर सकता है (और यह वास्तव में ज्यादातर समय काम करता है) मैं दृढ़ता से इसका उपयोग करने से परहेज करने की सलाह देता हूं। और यहाँ क्यों है। जैसा कि डायने हैकॉर्न ने लिखा है :

    ये एपीआई अपने यूआई प्रवाह को आधार बनाने के लिए अनुप्रयोगों के लिए नहीं हैं, लेकिन ऐसा करने के लिए उपयोगकर्ता को चलने वाले एप्लिकेशन या एक कार्य प्रबंधक, या इस तरह की चीजें दिखाते हैं।

    हाँ इन बातों के लिए स्मृति में रखी गई एक सूची है। हालाँकि, यह एक अन्य प्रक्रिया में बंद है, आपके द्वारा अलग से चल रहे थ्रेड्स द्वारा प्रबंधित किया जाता है, और कुछ ऐसा नहीं जिसे आप (ए) सही निर्णय लेने के लिए समय में देख सकते हैं (बी) आपके पास लौटने के समय तक एक सुसंगत तस्वीर है। प्लस "जाने के लिए" अगली "गतिविधि के बारे में निर्णय हमेशा उस बिंदु पर किया जाता है जहां स्विच होना है, और यह उस सटीक बिंदु तक नहीं है (जहां गतिविधि राज्य संक्षेप में स्विच करने के लिए बंद है) कि हम वास्तव में यह सुनिश्चित करने के लिए जानते हैं कि अगली चीज क्या होगी।

    और यहाँ कार्यान्वयन और वैश्विक व्यवहार भविष्य में समान रहने की गारंटी नहीं है।

    काश, मैंने एसओ पर जवाब पोस्ट करने से पहले इसे पढ़ा हो, लेकिन उम्मीद है कि मेरी गलती को स्वीकार करने में देर नहीं हुई होगी।

  3. एक अन्य गलत समाधान
    Droid-Fu पुस्तकालय में वर्णित एक विधि में ActivityManager.getRunningTasksइसका उपयोग किया गया isApplicationBroughtToBackgroundहै। ऊपर डायने की टिप्पणी देखें और उस पद्धति का उपयोग न करें।


4
यह जानने के लिए कि क्या आपने होम बटन दबाया है या किसी अन्य ऐप ने फोकस प्राप्त किया है: 1) अच्छा समाधान लागू करें । 2) के OnStopअनुरोध में isActivityVisible
ब्रिस गैबिन

28
दुर्भाग्य से आपका 'सही' समाधान मेरे लिए काम नहीं करता है। अपने ऐप के भीतर की गतिविधियों पर विचार करें। फिर क्या होता है कि आपका 'इनफोरग्राउंड' झंडा इस तरह से चलता है: यह सच है, गलत (पहली गतिविधि के बीच और दूसरी गतिविधि के चालू होने पर) फिर सही है, आदि। फिर आपको किसी प्रकार के हिस्टैरिसीस की आवश्यकता होगी।
रादु

14
यदि आप सीधे सभी गतिविधियों को नियंत्रित नहीं कर सकते हैं तो यह समाधान काम नहीं करता है। उदाहरण के लिए यदि आपके पास 3rd पार्टी एसडीके से कोई गतिविधि है या यहां तक ​​कि एक ACTION_VIEW इरादे लॉन्च करें।
user123321

66
एंड्रॉइड एक ऐसा भयावह मलबे है। किसी ने नहीं सोचा था कि कोई व्यक्ति ऐप स्तर के डेटा को जारी रखना चाहता है? मुझे एक ब्रेक दे

8
ऐसा लगता है कि इस प्रश्न का वास्तविक उत्तर "आप इसे ठीक से नहीं देख सकते हैं"। तथाकथित 'सही' समाधान सबसे अच्छा एक समाधान है, इसलिए एक्टिविटी लाइफ़ साइकल कॉलबैक का उपयोग कर रहा है। आपको अभी भी उन गतिविधियों के बीच स्विच करने पर विचार करना होगा जो "अग्रभूमि में नहीं" के रूप में पंजीकृत होंगे। यह मेरे दिमाग को उड़ा देता है कि आप इस तरह की एक साधारण चीज की जांच नहीं कर सकते ...
सेरीन

263

इस का उपयोग न करें

user1269737 का उत्तर ऐसा करने के लिए उचित (Google / Android अनुमोदित) तरीका है । उनके उत्तर को पढ़ें और उन्हें +1 दें।

मैं अपने मूल उत्तर को यहाँ पोस्टर्सिटी की खातिर छोड़ दूँगा। यह 2012 में सबसे अच्छा उपलब्ध था, लेकिन अब इसके लिए एंड्रॉइड का उचित समर्थन है।

मूल उत्तर

कुंजी उपयोग कर रही है ActivityLifecycleCallbacks(ध्यान दें कि इसके लिए Android API स्तर 14 (Android 4.0) की आवश्यकता है)। बस जाँच करें कि क्या रुकी गतिविधियों की संख्या शुरू की गई गतिविधियों की संख्या के बराबर है। यदि वे समान हैं, तो आपके आवेदन को पृष्ठभूमि में रखा जा रहा है। यदि अधिक आरंभिक गतिविधियाँ हैं, तो भी आपका आवेदन दिख रहा है। यदि रुकी हुई गतिविधियों की तुलना में अधिक फिर से शुरू किया जाता है, तो आपका आवेदन न केवल दिखाई देता है, बल्कि यह अग्रभूमि में भी है। 3 मुख्य राज्य हैं जो आपकी गतिविधि में हो सकते हैं, फिर: दृश्यमान और अग्रभूमि में, दृश्यमान लेकिन अग्रभूमि में नहीं, और दृश्यमान नहीं और अग्रभूमि में नहीं (अर्थात पृष्ठभूमि में)।

इस विधि के बारे में बहुत अच्छी बात यह है कि यह अतुल्यकालिक मुद्दों नहीं है getRunningTasks()है, लेकिन आप भी हर संशोधित करने की जरूरत नहीं है Activityमें सेट / सेट किए बिना कुछ करने के लिए अपने आवेदन में onResumed()/ onPaused()। यह कोड की कुछ पंक्तियाँ है जो स्वयं निहित है, और यह आपके पूरे आवेदन में काम करती है। इसके अलावा, कोई फंकी परमिशन की भी जरूरत नहीं है।

MyLifecycleHandler.java:

public class MyLifecycleHandler implements ActivityLifecycleCallbacks {
    // I use four separate variables here. You can, of course, just use two and
    // increment/decrement them instead of using four and incrementing them all.
    private int resumed;
    private int paused;
    private int started;
    private int stopped;

    @Override
    public void onActivityCreated(Activity activity, Bundle savedInstanceState) {
    }

    @Override
    public void onActivityDestroyed(Activity activity) {
    }

    @Override
    public void onActivityResumed(Activity activity) {
        ++resumed;
    }

    @Override
    public void onActivityPaused(Activity activity) {
        ++paused;
        android.util.Log.w("test", "application is in foreground: " + (resumed > paused));
    }

    @Override
    public void onActivitySaveInstanceState(Activity activity, Bundle outState) {
    }

    @Override
    public void onActivityStarted(Activity activity) {
        ++started;
    }

    @Override
    public void onActivityStopped(Activity activity) {
        ++stopped;
        android.util.Log.w("test", "application is visible: " + (started > stopped));
    }

    // If you want a static function you can use to check if your application is
    // foreground/background, you can use the following:
    /*
    // Replace the four variables above with these four
    private static int resumed;
    private static int paused;
    private static int started;
    private static int stopped;

    // And these two public static functions
    public static boolean isApplicationVisible() {
        return started > stopped;
    }

    public static boolean isApplicationInForeground() {
        return resumed > paused;
    }
    */
}

MyApplication.java:

// Don't forget to add it to your manifest by doing
// <application android:name="your.package.MyApplication" ...
public class MyApplication extends Application {
    @Override
    public void onCreate() {
        // Simply add the handler, and that's it! No need to add any code
        // to every activity. Everything is contained in MyLifecycleHandler
        // with just a few lines of code. Now *that's* nice.
        registerActivityLifecycleCallbacks(new MyLifecycleHandler());
    }
}

@ मेवेज़र ने इस पद्धति के बारे में कुछ अच्छे प्रश्न पूछे हैं जिनका मैं इस उत्तर में सभी के लिए जवाब देना चाहता हूँ:

onStop()कम स्मृति स्थितियों में नहीं कहा जाता है; कि यहाँ एक समस्या है?

नहीं के लिए डॉक्स onStop() कहने के :

ध्यान दें कि इस विधि को कभी भी नहीं बुलाया जा सकता है, कम स्मृति स्थितियों में जहां सिस्टम में पर्याप्त मेमोरी नहीं होती है कि वह आपकी गतिविधि की प्रक्रिया को चालू रखने के बाद चालू करें () विधि कहलाती है।

यहाँ कुंजी है "अपनी गतिविधि की प्रक्रिया को चालू रखें ..." यदि यह कम स्मृति स्थिति कभी भी पहुंच जाती है, तो आपकी प्रक्रिया वास्तव में मार दी जाती है (न कि केवल आपकी गतिविधि)। इसका मतलब यह है कि बैकग्राउंडेड-नेस के लिए जाँच करने का यह तरीका अभी भी मान्य है क्योंकि a) आप वैसे भी बैकग्राउंडिंग के लिए जाँच नहीं कर सकते हैं यदि आपकी प्रक्रिया मारी गई है, और b) यदि आपकी प्रक्रिया फिर से शुरू होती है (क्योंकि एक नई गतिविधि बनती है), सदस्य चर (स्थिर या नहीं) के लिए MyLifecycleHandlerरीसेट किया जाएगा0

क्या यह विन्यास परिवर्तन के लिए काम करता है?

डिफ़ॉल्ट रूप से, नहीं। आपको स्पष्ट रूप से सेट करना होगा configChanges=orientation|screensize( पहले से ही मेरी सभी परियोजनाओं में क्योंकि यह मेरी पूरी गतिविधि के लिए स्क्रीन रोटेट / रिसाइज पर नष्ट होने के लिए अवांछनीय था, इसलिए मैंने इसे कभी भी समस्याग्रस्त नहीं पाया है। (इसके लिए अपनी स्मृति को ताज़ा करने के लिए dpimka के लिए धन्यवाद)। और मुझे सही कर रहा है!)| अपनी मैनिफ़ेस्ट फ़ाइल में किसी भी चीज़ के साथ) और कॉन्फ़िगरेशन परिवर्तन को संभालना होगा, अन्यथा आपकी गतिविधि नष्ट हो जाएगी और फिर से बनाई जाएगी। यदि आप इसे सेट नहीं करते हैं, तो आपकी गतिविधि के तरीकों को इस क्रम में बुलाया जाएगा onCreate -> onStart -> onResume -> (now rotate) -> onPause -> onStop -> onDestroy -> onCreate -> onStart -> onResume:। जैसा कि आप देख सकते हैं, कोई ओवरलैप नहीं है (आम तौर पर, दो गतिविधियों को बहुत संक्षेप में ओवरलैप करते हैं जब दोनों के बीच स्विच करते हैं, जो कि यह पृष्ठभूमि-पता लगाने की विधि कैसे काम करती है)। इसे प्राप्त करने के लिए, आपको सेट करना होगा configChangesताकि आपकी गतिविधि नष्ट न हो। सौभाग्य से, मुझे सेट करना पड़ाconfigChanges

एक नोट:

जब मैंने इस उत्तर में "पृष्ठभूमि" कहा है, तो मेरा मतलब है "आपका ऐप अब दिखाई नहीं दे रहा है।" एंड्रॉइड गतिविधियां अभी तक अग्रभूमि में नहीं दिखाई दे सकती हैं (उदाहरण के लिए, यदि पारदर्शी अधिसूचना ओवरले है)। इसीलिए मैंने इस उत्तर को प्रतिबिंबित करने के लिए अद्यतन किया है।

यह जानना महत्वपूर्ण है कि एंड्रॉइड में गतिविधियों को स्विच करने के दौरान एक अजीब अंग है, जहां कुछ भी अग्रभूमि में नहीं है । इस कारण से, यदि आप जाँचते हैं कि गतिविधियों के बीच स्विच करने पर आपका एप्लिकेशन अग्रभूमि में है (उसी ऐप में), तो आपको बताया जाएगा कि आप अग्रभूमि में नहीं हैं (भले ही आपका ऐप अभी भी सक्रिय ऐप है और दिखाई दे रहा है )।

आप देख सकते हैं कि आपके ऐप अपने में अग्रभूमि में चल रही Activityहै onPause()विधि के बाद super.onPause() । बस अजीब सी लिमो स्टेट याद है जिसकी मैंने अभी बात की थी।

आप (यानी अगर यह पृष्ठभूमि में नहीं है) की जांच कर सकते कि आपके ऐप में दिखाई दे रहा है अपने में Activityकी onStop()विधि के बाद super.onStop()


1
यह दिलचस्प लग रहा है - लेकिन कम स्मृति स्थितियों में क्या होता है? यह गारंटी नहीं है कि onStop () कहा जाएगा। क्या हम कभी ऐसी स्थिति में आ सकते हैं, जहाँ onStop () को नहीं बुलाया गया हो और रुका हुआ काउंटर बढ़ा हुआ न हो - इसका मतलब यह है कि पृष्ठभूमि वाला चेक अब विश्वसनीय नहीं है? या ऐसा कभी नहीं होगा?
मेवाजर

1
इसके अलावा, क्या यह कॉन्फ़िगरेशन परिवर्तनों को अनदेखा करेगा? या क्या किसी कॉन्फ़िगरेशन परिवर्तन (जैसे ओरिएंटेशन में परिवर्तन) के परिणामस्वरूप किसी गतिविधि को फिर से बनाए जाने पर एप्लिकेशन को पृष्ठभूमि में माना जाएगा? क्षमा करें, प्रश्नों के लिए, लेकिन मुझे लगता है कि आप किसी चीज़ पर हैं और यह जानने में रुचि रखते हैं कि क्या यह इन मामलों में काम करता है।
मेवाड़

1
@ मेवज़र: मैं एक टिप्पणी के रूप में जवाब देने जा रहा था, लेकिन इन उत्तरों को प्राप्त करने के लिए थोड़ा सा टाइपिंग करने जा रहा हूं, इसलिए कुछ मिनटों में वापस जांचें और मैं अपना उत्तर संपादित करूंगा।
कॉर्नस्टॉक

1
@ मेवज़र: अब आपको अपने जवाब ढूंढने चाहिए। मुझे पता है अगर कोई अन्य प्रश्न हैं!
कॉर्नस्टॉक

2
@Mewzer: मैं बस एक ध्यान दें कि आप में रुचि हो सकती जोड़ा विशेष रूप से, में backgrounding लिए जाँच करें। onStop()के बाद super.onStop()। में पृष्ठभूमि के लिए जाँच न करें onPause()
कॉर्नस्टॉक

186

GOOGLE SOLUTION - एक हैक नहीं, पिछले समाधानों की तरह। ProcessLifecycleOwner Kotlin का उपयोग करें

:

class ArchLifecycleApp : Application(), LifecycleObserver {

    override fun onCreate() {
        super.onCreate()
        ProcessLifecycleOwner.get().lifecycle.addObserver(this)
    }

    @OnLifecycleEvent(Lifecycle.Event.ON_STOP)
    fun onAppBackgrounded() {
        //App in background
    }

    @OnLifecycleEvent(Lifecycle.Event.ON_START)
    fun onAppForegrounded() {
        // App in foreground
    }

}


जावा:

public class ArchLifecycleApp extends Application implements LifecycleObserver {

    @Override
    public void onCreate() {
        super.onCreate();
        ProcessLifecycleOwner.get().getLifecycle().addObserver(this);
    }

    @OnLifecycleEvent(Lifecycle.Event.ON_STOP)
    public void onAppBackgrounded() {
        //App in background
    }

    @OnLifecycleEvent(Lifecycle.Event.ON_START)
    public void onAppForegrounded() {
        // App in foreground
    }
}

app.gradle में

dependencies {
    ...
    implementation "android.arch.lifecycle:extensions:1.1.0"

    //New Android X dependency is this - 
    implementation "androidx.lifecycle:lifecycle-extensions:2.0.0"

}

allprojects {
    repositories {
        ...
        google()
        jcenter()
        maven { url 'https://maven.google.com' }
    }
}

आप लाइफसाइकल से संबंधित वास्तुकला घटकों के बारे में अधिक यहाँ पढ़ सकते हैं - https://developer.android.com/topic/lbooks/ RGBecture / lifecycle


10
यह निश्चित रूप से सही उत्तर होना चाहिए! इसने एक आकर्षण की तरह काम किया: D
JaviOverflow

2
यह पूरी तरह से काम करता है, मैंने थोड़ा भी संशोधित किया है ताकि मैं इस वर्ग के बाहर अग्रभूमि / पृष्ठभूमि राज्य तक आसानी से पहुंच सके: companion object { private var foreground = false fun isForeground() : Boolean { return foreground } }फिर आप अग्रभूमि राज्य प्राप्त कर सकते हैंArchLifecycleApp.isForeground()
जोस जेट

2
अरे यार, यह मेरे पुराने जवाब से बहुत बेहतर है। मेरे से +1 है। मैंने लोगों को आपकी ओर इंगित करने के लिए अपना उत्तर अपडेट किया।
कॉर्नस्टालक्स '’

2
हालाँकि यह एक सही उत्तर है कि कॉलबैक को लागू करने की कोई आवश्यकता नहीं है, आप जब चाहे तब ProcessLifecycleOwner को क्वेरी कर सकते हैं। चेक stackoverflow.com/a/52678290/6600000
Keivan Esbati

2
जैसा कि डॉक्टर कहते हैं The LifecycleOwner for the whole application process. Note that if your application has multiple processes, this provider does not know about other processes. , यह multiple processesऐप्स के लिए काम नहीं कर रहा है, क्या कुछ एपि हैं जिन्हें हम शान से हासिल कर सकते हैं?
acntwww

23

समर्थन लाइब्रेरी संस्करण 26 शुरू करना आप ProcessLifecycleOwner का उपयोग कर सकते हैं , बस इसे अपनी निर्भरता में जोड़ें जैसे कि यहाँ वर्णित है , उदाहरण के लिए:

dependencies {
    def lifecycle_version = "1.1.1"

    // ViewModel and LiveData
    implementation "android.arch.lifecycle:extensions:$lifecycle_version"
    // alternatively - Lifecycles only (no ViewModel or LiveData).
    //     Support library depends on this lightweight import
    implementation "android.arch.lifecycle:runtime:$lifecycle_version"
    annotationProcessor "android.arch.lifecycle:compiler:$lifecycle_version" // use kapt for Kotlin
}

और फिर ProcessLifecycleOwnerजब भी आप एप्लिकेशन स्टेट के लिए चाहें तो क्वेरी करें , उदाहरण:

//Check if app is in background
ProcessLifecycleOwner.get().getLifecycle().getCurrentState() == Lifecycle.State.CREATED;

//Check if app is in foreground
ProcessLifecycleOwner.get().getLifecycle().getCurrentState().isAtLeast(Lifecycle.State.STARTED);

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

यदि आवेदन पूरी तरह से बंद हो जाता है तो पहला तरीका क्या होगा?
एवगेनी मिशुस्टीन

@EvgeniyMishustin जो कि एप्लिकेशन की वर्तमान स्थिति पर निर्भर करता है, लेकिन आप आमतौर पर तब DESTROYED बनाकर देखते हैं और उसके बाद, आपको कोई नई ईवेंट नहीं मिलेगी।
कीवन एसबटी

तो आईएफ ऐप को बैकग्राउंड (अग्रभूमि) में देखने के लिए कोई "IF" स्टेटमेंट कहाँ है ???
ekashking

@ekashking ने पूरा बयान इफ़-क्लॉज़ में रखा। उदाहरण के लिए: अगर (ProcessLifecycleOwner.get () getLifecycle () getCurrentState () isAtLeast (Lifecycle.State.STARTED)।।।) => अनुप्रयोग अग्रभूमि में चल रही
Keivan Esbati

20

एंड्रॉइड एपीआई 16 के बाद से यह जांचने का एक सरल तरीका है कि ऐप अग्रभूमि में है या नहीं। यह मूर्खतापूर्ण नहीं हो सकता है, लेकिन एंड्रॉइड पर कोई भी तरीके मूर्ख नहीं हैं। यह विधि उपयोग करने के लिए पर्याप्त है जब आपकी सेवा सर्वर से अपडेट प्राप्त करती है और यह तय करना होता है कि क्या अधिसूचना दिखाना है, या नहीं (क्योंकि यदि यूआई अग्रभूमि है, तो उपयोगकर्ता अधिसूचना के बिना अपडेट को नोटिस करेगा)।

RunningAppProcessInfo myProcess = new RunningAppProcessInfo();
ActivityManager.getMyMemoryState(myProcess);
isInBackground = myProcess.importance != RunningAppProcessInfo.IMPORTANCE_FOREGROUND;

क्या यह कोड सेवा वर्ग या अन्य वर्ग जैसे अनुप्रयोग वर्ग के अंदर होना चाहिए? बहुत बहुत धन्यवाद।
वोप्पी

..जब भी आप इसे अंतिम पंक्ति के रूप में उपयोग करना चाहते हैं, तो बस एक बूलियन है जिसके खिलाफ आप जांच करेंगे।
AO_

पुश सूचनाओं के लिए AWS Android SDK की यही पद्धति है।
स्पॅकमाड

ज्ञात हो कि "सेवा सीमाओं के उद्देश्यों के लिए पृष्ठभूमि की परिभाषा स्मृति प्रबंधन द्वारा उपयोग की जाने वाली परिभाषा से अलग है; एक ऐप पृष्ठभूमि में स्मृति प्रबंधन से संबंधित हो सकता है, लेकिन अग्रभूमि में सेवाओं को लॉन्च करने की क्षमता से संबंधित है।) " developer.android.com/about/versions/oreo/background.html (
ARLabs

धन्यवाद, यह काम किया! मैं इस कोड का उपयोग यह JobServiceपता लगाने में सक्षम था कि सेवा पृष्ठभूमि में चल रही है।
माइकल ओसोफ़्स्की

17

आइडलोन का उत्तर त्रुटि प्रवण है और बहुत अधिक जटिल अलहदा दोहराया गया है यहां देखें कि एंड्रॉइड एप्लिकेशन अग्रभूमि में है या नहीं? और यहाँ एक पृष्ठभूमि कार्य या सेवा से वर्तमान अग्रभूमि अनुप्रयोग का निर्धारण

अधिक सरल दृष्टिकोण है:

सभी कार्यकलापों का विस्तार करने वाले एक बेसएक्टिविटी पर :

protected static boolean isVisible = false;

 @Override
 public void onResume()
 {
     super.onResume();
     setVisible(true);
 }


 @Override
 public void onPause()
 {
     super.onPause();
     setVisible(false);
 }

जब भी आपको यह जांचने की आवश्यकता होती है कि क्या आपकी कोई भी एप्लिकेशन गतिविधियां केवल जांच के लिए अग्रभूमि में हैं isVisible() ;

इस दृष्टिकोण को समझने के लिए, साइड-बाय-साइड गतिविधि जीवनचक्र के इस उत्तर की जाँच करें: गतिविधि साइड-बाय-साइड जीवनचक्र


3
Idolon's answer is error prone- दुर्भाग्य से मुझे आपसे सहमत होना होगा। Google समूह में डायने हैकॉर्न की टिप्पणी के आधार पर मैंने अपना उत्तर अपडेट किया है। विवरण के लिए कृपया इसे जांचें।
मूर्ती

2
यह वह जगह है नहीं एक सरल समाधान या तो। एक परिदृश्य है अगर उपयोगकर्ता अधिसूचना पैनल नीचे खींच लिया, तो न तो onPause, onStopऔर न ही onResumeघटना कहा जाता है। तो अगर आप इन घटनाओं में से कोई भी निकाल दिया जाता है तो आप क्या करते हैं ?!

इसने मुझे इस प्रश्न की ओर ले गया: stackoverflow.com/questions/33657102/…
रुचिर बरोनिया

अफसोस की बात है, लेकिन जब स्क्रीन बंद होती है तो यह गतिविधि गलत हो जाती है। इस मामले में onResume और onPause को isV अदृश्य = गलत बनाना कहा जाता है।
कूलमाइंड

@CoolMind क्या आप बता सकते हैं कि पृष्ठभूमि में रहते हुए आप गतिविधि का उपयोग करने के मामले में क्या प्रयोग करेंगे?
neteinstein

11

मैंने Application.ActivityLifecycleCallbacks और कई अन्य का उपयोग करने वाले अनुशंसित समाधान की कोशिश की , लेकिन वे उम्मीद के मुताबिक काम नहीं कर पाए। सर्ज के लिए धन्यवाद , मैं एक बहुत ही आसान और सरल समाधान के साथ आया जिसका मैं नीचे वर्णन कर रहा हूं।

वे समाधान की कुंजी यह समझने का तथ्य है कि अगर हमारे पास एक्टिवा और एक्टीबीबी है, और हम एक्टिवा से एक्टिविबी कहते हैं (और कॉल नहीं करते हैं ActivityA.finish), तो एक्टिवा से पहले एक्टिविटीबी को onStart()कॉल किया जाएगा ।onStop()

यह भी मुख्य अंतर है onStop()और onPause()मैंने जो लेख पढ़ा, उसमें किसी ने भी इसका उल्लेख नहीं किया।

तो इस गतिविधि के जीवनचक्र के व्यवहार के आधार पर, आप बस यह गिन सकते हैं कि कितनी बार किया onStart()और onPause()अपने कार्यक्रम में बुलाया। ध्यान दें कि प्रत्येक के लिए Activity अपने कार्यक्रम की, आप को ओवरराइड चाहिए onStart()और onStop()आदेश में, वेतन वृद्धि / कमी स्थिर चर गिनती के लिए इस्तेमाल करने के लिए। नीचे इस तर्क को लागू करने वाला कोड है। ध्यान दें कि मैं एक वर्ग का उपयोग कर रहा हूं जो विस्तारित होता है Application, इसलिए Manifest.xmlआवेदन टैग के अंदर घोषित करना न भूलें : android:name=".Utilities"हालांकि, यह एक सरल कस्टम वर्ग का उपयोग करके भी लागू किया जा सकता है।

public class Utilities extends Application
{
    private static int stateCounter;

    public void onCreate()
    {
        super.onCreate();
        stateCounter = 0;
    }

    /**
     * @return true if application is on background
     * */
    public static boolean isApplicationOnBackground()
    {
        return stateCounter == 0;
    }

    //to be called on each Activity onStart()
    public static void activityStarted()
    {
        stateCounter++;
    }

    //to be called on each Activity onStop()
    public static void activityStopped()
    {
        stateCounter--;
    }
}

अब हमारे कार्यक्रम के प्रत्येक गतिविधि पर, हम ओवरराइड करना चाहिए onStart()और onStop()नीचे के रूप में दिखाया गया है और वेतन वृद्धि / कमी:

@Override
public void onStart()
{
    super.onStart();
    Utilities.activityStarted();
}

@Override
public void onStop()
{
    Utilities.activityStopped();
    if(Utilities.isApplicationOnBackground())
    {
        //you should want to check here if your application is on background
    }
    super.onStop();
}

इस तर्क के साथ, 2 संभावित मामले हैं:

  1. stateCounter = 0 : रोकी गई संख्या शुरू की गई गतिविधियों की संख्या के बराबर है, जिसका अर्थ है कि आवेदन पृष्ठभूमि पर चल रहा है।
  2. stateCounter > 0 : प्रारंभ की संख्या रुकी हुई संख्या से बड़ी है, जिसका अर्थ है कि एप्लिकेशन अग्रभूमि पर चल रहा है।

सूचना: stateCounter < 0इसका मतलब होगा कि शुरू होने के बजाय अधिक रुकी हुई गतिविधियाँ हैं, जो असंभव है। यदि आप इस मामले का सामना करते हैं, तो इसका मतलब है कि आप उस काउंटर को नहीं बढ़ा रहे हैं / घटा रहे हैं जैसा आपको चाहिए।

तुम जाने के लिए तैयार हो। यदि आपका एप्लिकेशन बैकग्राउंड में है, तो आपको जांचना चाहिए onStop()


मैं के लिए कदम था if(Utilities.isApplicationOnBackground()) …करने के लिए Utilities। क्योंकि अन्यथा केवल एक विशिष्ट गतिविधि घटना पर प्रतिक्रिया करेगी।
प्रदर्शन नाम

10

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


2
एंड्रॉइड में, हमारे पास "बैकग्राउंड डेटा" नामक एक सेटिंग है। जब एप्लिकेशन बैकग्राउंड में चल रहा हो तो यह किसी भी बैकग्राउंड डेटा कनेक्शन की सेटिंग को बदल देता है। मैं अपने एप्लिकेशन के लिए "पृष्ठभूमि डेटा" टॉगल लागू करना चाहता हूं, इसलिए जब उपयोगकर्ता को मेरी कोई भी गतिविधि दिखाई नहीं दे रही है, तो मैं चाहूंगा कि मेरी सेवा किसी भी डेटा ट्रांसफर को रोक दे, लेकिन जिस क्षण मेरी एक गतिविधि फिर से शुरू होती है, मैं उसे लागू करना चाहूंगा डेटा ट्रांसफर फिर से शुरू करें
cppdev

1
@cppdev: उम्मीद है, "डेटा ट्रांसफर" एक द्वारा संचालित किया जा रहा है Service। यदि ऐसा है, तो अपनी गतिविधियों को सेवा को सूचित करें क्योंकि वे दिखाई देते हैं और गायब हो जाते हैं। यदि यह Serviceनिर्धारित करता है कि कोई गतिविधियाँ दिखाई नहीं दे रही हैं, और यह कुछ समय के लिए इस तरह से बनी हुई है, तो अगले तार्किक रोक बिंदु पर डेटा स्थानांतरण को रोक दें। हां, इसके लिए आपकी प्रत्येक गतिविधि के लिए कोड की आवश्यकता होगी, लेकिन अभी, यह अपरिहार्य AFAIK है।
कॉमन्सवेअर

1
आप अपने सभी गतिविधियों के बीच आम कोड को कॉपी-पेस्ट करने से बचना चाहते हैं, तो आप एक वर्ग बना सकते हैं MyActivityClassसे इनहेरिट Activityऔर जीवन चक्र के तरीकों को लागू करने, और अपने सभी गतिविधियों से विरासत बनाने के MyActivityClass। यह PreferenceActivityया MapActivityइसके लिए कोई काम नहीं करेगा ( इस प्रश्न को देखें )
गिलोय ब्रूनरी

@CommonsWare मैंने OnPause () OnResume () के साथ प्रयास किया था कि यह सक्रिय है या नहीं, लेकिन अगर मेरा ऐप व्यू स्क्रीन में नहीं दिखता है अगर यह बैकग्राउंड में चलता है तो कैसे जांचें कि यह सक्रिय है या नहीं
मनोज

@CommonsWare मैंने OnPause () OnResume () के साथ प्रयास किया था कि यह सक्रिय है या नहीं, लेकिन अगर मेरा ऐप व्यू स्क्रीन में नहीं दिख रहा है अगर यह बैकग्राउंड में चलता है तो यह जांचें कि यह सक्रिय है या नहीं
मनोज

5

ऐप पृष्ठभूमि में है या नहीं, इसका पता लगाने के लिए आप ComponentCallbacks2 का उपयोग कर सकते हैं । BTW यह कॉलबैक केवल एपीआई स्तर 14 (आइसक्रीम सैंडविच) और इसके बाद के संस्करण में उपलब्ध है।

आपको विधि के लिए एक कॉल मिलेगा:

public abstract void onTrimMemory (int level)

यदि स्तर है ComponentCallbacks2.TRIM_MEMORY_UI_HIDDENतो ऐप पृष्ठभूमि में है।

तुम एक करने के लिए इस इंटरफ़ेस को लागू कर सकते हैं activity, serviceआदि

public class MainActivity extends AppCompatActivity implements ComponentCallbacks2 {
   @Override
   public void onConfigurationChanged(final Configuration newConfig) {

   }

   @Override
   public void onLowMemory() {

   }

   @Override
   public void onTrimMemory(final int level) {
     if (level == ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN) {
        // app is in background
     }
   }
}

1
अपना उत्तर देने की कोशिश की है लेकिन उतना विश्वसनीय नहीं है। onTrimMemory कॉलबैक स्क्रीन लॉक होने पर और स्क्रीन लॉक करने के लिए "पावर" बटन दबाने पर ट्रिगर नहीं होगा। यदि आपका ऐप दिखाई दे रहा है और आप किसी अन्य एप्लिकेशन को स्टेटस बार नोटिफिकेशन के माध्यम से खोलते हैं तो यह हमेशा TRIM_MEMORY_UI_HIDDEN नहीं लौटेगा। एकमात्र विश्वसनीय समाधान है एक्टीफाइसेलेकॉलकॉल को लागू करना और इसे उपयोग करने वाले लोगों के मामले में समायोजित करना।
वेलावल

4

@Cornstalks पर निर्माण उपयोगी सुविधाओं के एक जोड़े को शामिल करने के लिए उत्तर देता है।

अतिरिक्त विशेषताएँ:

  • शुरू की गई सिंगलटन पैटर्न को आप कहीं भी आवेदन में कर सकते हैं: AppLifecycleHandler.isApplicationV अदृश्य () और AppLifecycleHandler.isApplicationInForeground ()
  • डुप्लिकेट ईवेंट की अतिरिक्त हैंडलिंग (टिप्पणियों को देखें // दृश्यता के परिवर्तन पर कुछ कार्रवाई करें और // अग्रभूमि में परिवर्तन पर कुछ कार्रवाई करें)

App.java

public class App extends Application {
    @Override
    public void onCreate() {
        super.onCreate();

        registerActivityLifecycleCallbacks(AppLifecycleHandler.getInstance());
    }
}

AppLifecycleHandler.java

public class AppLifecycleHandler implements Application.ActivityLifecycleCallbacks {
    private int resumed;
    private int started;

    private final String DebugName = "AppLifecycleHandler";

    private boolean isVisible = false;
    private boolean isInForeground = false;

    private static AppLifecycleHandler instance;

    public static AppLifecycleHandler getInstance() {
        if (instance == null) {
            instance = new AppLifecycleHandler();
        }

        return instance;
    }

    private AppLifecycleHandler() {
    }

    @Override
    public void onActivityCreated(Activity activity, Bundle savedInstanceState) {
    }

    @Override
    public void onActivityDestroyed(Activity activity) {
    }

    @Override
    public void onActivityResumed(Activity activity) {
        ++resumed;
        android.util.Log.w(DebugName, "onActivityResumed -> application is in foreground: " + (resumed > 0) + " (" + activity.getClass() + ")");
        setForeground((resumed > 0));
    }

    @Override
    public void onActivityPaused(Activity activity) {
        --resumed;
        android.util.Log.w(DebugName, "onActivityPaused -> application is in foreground: " + (resumed > 0) + " (" + activity.getClass() + ")");
        setForeground((resumed > 0));
    }

    @Override
    public void onActivitySaveInstanceState(Activity activity, Bundle outState) {
    }

    @Override
    public void onActivityStarted(Activity activity) {
        ++started;
        android.util.Log.w(DebugName, "onActivityStarted -> application is visible: " + (started > 0) + " (" + activity.getClass() + ")");
        setVisible((started > 0));
    }

    @Override
    public void onActivityStopped(Activity activity) {
        --started;
        android.util.Log.w(DebugName, "onActivityStopped -> application is visible: " + (started > 0) + " (" + activity.getClass() + ")");
        setVisible((started > 0));
    }

    private void setVisible(boolean visible) {
        if (isVisible == visible) {
            // no change
            return;
        }

        // visibility changed
        isVisible = visible;
        android.util.Log.w(DebugName, "App Visiblility Changed -> application is visible: " + isVisible);

        // take some action on change of visibility
    }

    private void setForeground(boolean inForeground) {
        if (isInForeground == inForeground) {
            // no change
            return;
        }

        // in foreground changed
        isInForeground = inForeground;
        android.util.Log.w(DebugName, "App In Foreground Changed -> application is in foreground: " + isInForeground);

        // take some action on change of in foreground

    }

    public static boolean isApplicationVisible() {
        return AppLifecycleHandler.getInstance().started > 0;
    }

    public static boolean isApplicationInForeground() {
        return AppLifecycleHandler.getInstance().resumed > 0;
    }
}

3

सबसे अच्छा समाधान मैं टाइमर्स का उपयोग करता हूं।

आपने ऑनपॉज़ () में एक टाइमर शुरू किया है और ऑनस्क्यूम () में उसी टाइमर को रद्द कर दिया है, टाइमर का 1 उदाहरण है (आमतौर पर एप्लिकेशन वर्ग में परिभाषित किया गया है)। टाइमर स्वयं 2 सेकंड (या जो भी अंतराल आपको उपयुक्त लगता है) के बाद एक रननेबल चलाने के लिए सेट किया गया है, जब टाइमर फायर करता है तो आप पृष्ठभूमि में होने के नाते आवेदन को चिह्नित करते हुए एक ध्वज सेट करते हैं।

टाइमर को रद्द करने से पहले onResume () विधि में, आप किसी भी स्टार्टअप ऑपरेशन (जैसे डाउनलोड शुरू करने या स्थान सेवाओं को सक्षम करने) के लिए पृष्ठभूमि ध्वज को क्वेरी कर सकते हैं।

यह समाधान आपको बैक स्टैक पर कई गतिविधियाँ करने की अनुमति देता है, और इसे लागू करने के लिए किसी भी अनुमति की आवश्यकता नहीं होती है।

यदि आप किसी ईवेंट बस का भी उपयोग करते हैं, तो यह समाधान अच्छी तरह से काम करता है, क्योंकि आपका टाइमर किसी ईवेंट को आग लगा सकता है और आपके ऐप के विभिन्न भागों के अनुसार प्रतिक्रिया दे सकता है।


मुझे लगता है कि यह सबसे अच्छा (हालांकि दुर्भाग्यपूर्ण) समाधान है
dhaag23

हां यह सबसे अच्छा समाधान है जिसे मैंने भी प्रबंधित किया है। जब एप्लिकेशन को अग्रभूमि नहीं किया गया था, तो मुझे ब्लूटूथ स्कैनिंग को रोकने की आवश्यकता थी, लेकिन मैं सिर्फ ऐप को रोकना या नष्ट नहीं कर सकता था या नष्ट नहीं कर सकता था क्योंकि जब उपयोगकर्ता ऐप के आसपास नेविगेट करता था, तो मैं लगातार रोकना और शुरू नहीं करना चाहता था।
कैप्चरस्पेस

3

यदि आप डेवलपर सेटिंग्स को चालू करते हैं, तो "एक्टीविटीज़ न रखें" - केवल बनाए गए एक्टिविटीज़ की गिनती की जाँच करें पर्याप्त नहीं है। आपको यह भी देखना होगा कि SaveInstanceState है । मेरा कस्टम तरीका है ApplicationRunning () चेक है android app चल रहा है:

यहाँ मेरा काम कोड:

public class AppLifecycleService implements Application.ActivityLifecycleCallbacks {
    private int created;
    private boolean isSaveInstanceState;
    private static AppLifecycleService instance;

    private final static String TAG = AppLifecycleService.class.getName();

    public static AppLifecycleService getInstance() {
        if (instance == null) {
            instance = new AppLifecycleService();
        }
        return instance;
    }

    public static boolean isApplicationRunning() {
        boolean isApplicationRunning = true;
        if (getCountCreatedActvities() == 0 && !isSaveInstanceState()) {
            isApplicationRunning = false;
        }
        return isApplicationRunning;
    }

    public static boolean isSaveInstanceState() {
        return AppLifecycleService.getInstance().isSaveInstanceState;
    }

    public static int getCountCreatedActvities() {
        return AppLifecycleService.getInstance().created;
    }

    private AppLifecycleService() {
    }

    @Override
    public void onActivitySaveInstanceState(Activity activity, Bundle outState) {
        this.isSaveInstanceState = true;
    }

    @Override
    public void onActivityCreated(Activity activity, Bundle savedInstanceState) {
        ++created;
    }

    @Override
    public void onActivityDestroyed(Activity activity) {
        --created;
    }

    @Override
    public void onActivityResumed(Activity activity) {   }

    @Override
    public void onActivityPaused(Activity activity) { }


    @Override
    public void onActivityStarted(Activity activity) { }

    @Override
    public void onActivityStopped(Activity activity) { }        

}

3

एकमात्र सही समाधान:

MainActivity.java:

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        MyApp.mainActivity = this;
        super.onCreate(savedInstanceState);
        ...
    }

MyApp.java:

public class MyApp extends Application implements LifecycleObserver {

    public static MainActivity mainActivity = null;

    @Override
    public void onCreate() {
        super.onCreate();
        ProcessLifecycleOwner.get().getLifecycle().addObserver(this);
    }

    @OnLifecycleEvent(Lifecycle.Event.ON_STOP)
    void onAppBackgrounded() {
        // app in background
        if (mainActivity != null) {
            ...
        }
    }

    @OnLifecycleEvent(Lifecycle.Event.ON_START)
    void onAppForegrounded() {
        // app in foreground
        if (mainActivity != null) {
            ...
        }
    }

}

मैं यह नहीं देखता कि यह समाधान संभवतः मुझे मेरी गतिविधि (या टुकड़े) पर एक IF स्टेटमेंट के भीतर एक सरल प्रश्न पर जवाब दे सकता है या नहीं कि मेरा ऐप पृष्ठभूमि या अग्रभूमि पर है या नहीं। "IF" स्टेटमेंट कहाँ है ???
ekashking

2

CommonsWare और Key ने जो कहा है, उस पर गुल्लक करने के लिए, आप शायद अनुप्रयोग वर्ग का विस्तार कर सकते हैं और आपकी सभी गतिविधियाँ कॉल कर सकती हैं जो उनके ऑनपॉन्ज / onResume विधियों पर हैं। यह आपको यह जानने की अनुमति देगा कि कौन सी गतिविधि (ies) दिखाई दे रही है, लेकिन इसे शायद बेहतर तरीके से संभाला जा सकता है।

क्या आप इसके बारे में विस्तार से बता सकते हैं कि आपके मन में क्या है? जब आप कहते हैं कि पृष्ठभूमि में चल रहा है, तो क्या इसका मतलब यह है कि आपका आवेदन अभी भी स्मृति में है, हालांकि यह वर्तमान में स्क्रीन पर नहीं है? क्या आपने सेवाओं का उपयोग अपने ऐप को प्रबंधित करने के लिए एक अधिक स्थायी तरीके के रूप में किया है जब यह ध्यान में नहीं है?


एंड्रॉइड में, हमारे पास "पृष्ठभूमि डेटा" नामक एक सेटिंग है। जब एप्लिकेशन बैकग्राउंड में चल रहा होता है, तो यह किसी भी बैकग्राउंड डेटा कनेक्शन की सेटिंग को बदल देता है। मैं अपने एप्लिकेशन के लिए "पृष्ठभूमि डेटा" टॉगल लागू करना चाहता हूं, इसलिए जब उपयोगकर्ता को मेरी कोई भी गतिविधि दिखाई नहीं दे रही है, तो मैं चाहूंगा कि मेरी सेवा किसी भी डेटा स्थानांतरण को रोक दे, लेकिन जिस क्षण मेरी एक गतिविधि फिर से शुरू होती है, मैं उसे लागू करना चाहूंगा डेटा ट्रांसफर फिर से शुरू करें
cppdev

1
Applicationहै onPause()या नहीं onResume()
कॉमन्सवेयर सेपर

1
@CommonsWare आप सही हैं, मैं प्रत्येक व्यक्ति गतिविधि को उनके ठहराव / फिर से शुरू करने पर आवेदन से संपर्क करने की बात कर रहा था। यह मूल रूप से विचार है जो आपने टिप्पणी पर अपने उत्तर में साझा किया है, हालांकि आपने सेवाओं का उपयोग किया है जो मुझे लगता है कि एक चालाक कदम है।
दान

2

मैंने एक्टिविटी लाइफ़ साइकल कॉलबैक का अपना कार्यान्वयन किया। मैं शर्लकअक्टिविटी का उपयोग कर रहा हूं, लेकिन सामान्य गतिविधि के लिए वर्ग काम कर सकता है।

सबसे पहले, मैं एक इंटरफ़ेस बना रहा हूँ जिसमें गतिविधियों के जीवनचक्र को ट्रैक करने के सभी तरीके हैं:

public interface ActivityLifecycleCallbacks{
    public void onActivityStopped(Activity activity);
    public void onActivityStarted(Activity activity);
    public void onActivitySaveInstanceState(Activity activity, Bundle outState);
    public void onActivityResumed(Activity activity);
    public void onActivityPaused(Activity activity);
    public void onActivityDestroyed(Activity activity);
    public void onActivityCreated(Activity activity, Bundle savedInstanceState);
}

दूसरा, मैंने इस इंटरफ़ेस को अपने एप्लिकेशन की कक्षा में लागू किया:

public class MyApplication extends Application implements my.package.ActivityLifecycleCallbacks{

    @Override
    public void onCreate() {
        super.onCreate();           
    }

    @Override
    public void onActivityStopped(Activity activity) {
        Log.i("Tracking Activity Stopped", activity.getLocalClassName());

    }

    @Override
    public void onActivityStarted(Activity activity) {
        Log.i("Tracking Activity Started", activity.getLocalClassName());

    }

    @Override
    public void onActivitySaveInstanceState(Activity activity, Bundle outState) {
        Log.i("Tracking Activity SaveInstanceState", activity.getLocalClassName());
    }

    @Override
    public void onActivityResumed(Activity activity) {
        Log.i("Tracking Activity Resumed", activity.getLocalClassName());
    }

    @Override
    public void onActivityPaused(Activity activity) {
        Log.i("Tracking Activity Paused", activity.getLocalClassName());
    }

    @Override
    public void onActivityDestroyed(Activity activity) {
        Log.i("Tracking Activity Destroyed", activity.getLocalClassName());
    }

    @Override
    public void onActivityCreated(Activity activity, Bundle savedInstanceState) {
        Log.i("Tracking Activity Created", activity.getLocalClassName());
    }
}

तीसरा, मैं एक वर्ग बना रहा हूँ जो शेरलाक्टिविटी से निकला है:

public class MySherlockActivity extends SherlockActivity {

    protected MyApplication nMyApplication;

    protected void onCreate(Bundle savedInstanceState) {
        // TODO Auto-generated method stub
        super.onCreate(savedInstanceState);
        nMyApplication = (MyApplication) getApplication();
        nMyApplication.onActivityCreated(this, savedInstanceState);
    }

    protected void onResume() {
        // TODO Auto-generated method stub
        nMyApplication.onActivityResumed(this);
        super.onResume();

    }

    @Override
    protected void onPause() {
        // TODO Auto-generated method stub
        nMyApplication.onActivityPaused(this);
        super.onPause();
    }

    @Override
    protected void onDestroy() {
        // TODO Auto-generated method stub
        nMyApplication.onActivityDestroyed(this);
        super.onDestroy();
    }

    @Override
    protected void onStart() {
        nMyApplication.onActivityStarted(this);
        super.onStart();
    }

    @Override
    protected void onStop() {
        nMyApplication.onActivityStopped(this);
        super.onStop();
    }

    @Override
    protected void onSaveInstanceState(Bundle outState) {
        nMyApplication.onActivitySaveInstanceState(this, outState);
        super.onSaveInstanceState(outState);
    }   
}

चौथा, सभी वर्ग जो शेरलाकिटिविटी से विस्तार करते हैं, मैंने माईशर्लोक्टक्टिविटी के लिए प्रतिस्थापित किया:

public class MainActivity extends MySherlockActivity{

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

}

अब, लॉगकैट में आप MyApplication में किए गए इंटरफ़ेस कार्यान्वयन में प्रोग्राम किए गए लॉग देखेंगे।


1

जब एक डायलॉग इसके ऊपर आता है तो गतिविधि रुक ​​जाती है इसलिए सभी अनुशंसित समाधान आधे-समाधान होते हैं। आपको संवादों के लिए भी हुक बनाने की जरूरत है।



1

आधिकारिक डॉक्स:

सिस्टम अग्रभूमि और पृष्ठभूमि एप्लिकेशन के बीच अंतर करता है। (सेवा सीमाओं के प्रयोजनों के लिए पृष्ठभूमि की परिभाषा स्मृति प्रबंधन द्वारा उपयोग की जाने वाली परिभाषा से अलग है; एक ऐप पृष्ठभूमि में स्मृति प्रबंधन से संबंधित हो सकती है , लेकिन अग्रभूमि में सेवाओं को लॉन्च करने की क्षमता से संबंधित है।) एक ऐप। निम्न में से कोई भी सत्य होने पर अग्रभूमि में माना जाता है:

  1. इसमें एक दृश्य गतिविधि है, चाहे गतिविधि शुरू हो या रुकी हो।
  2. इसमें अग्रभूमि सेवा है।
  3. एक अन्य अग्रभूमि ऐप ऐप से जुड़ा हुआ है, या तो अपनी सेवाओं में से किसी एक के लिए बाध्य है या अपने किसी एक सामग्री प्रदाता का उपयोग करके। उदाहरण के लिए, ऐप अग्रभूमि में है यदि कोई अन्य ऐप इसके लिए बाध्य है:
    • IME
    • वॉलपेपर सेवा
    • अधिसूचना श्रोता
    • आवाज या पाठ सेवा

यदि उन स्थितियों में से कोई भी सत्य नहीं है, तो एप्लिकेशन को पृष्ठभूमि में माना जाता है।


0

इस पुरानी पोस्ट का एक और समाधान (उन लोगों के लिए जो इसे मदद कर सकता है):


<application android:name=".BaseApplication" ... >

public class BaseApplication extends Application {

    private class Status {
        public boolean isVisible = true;
        public boolean isFocused = true;
    }

    private Map<Activity, Status> activities;

    @Override
    public void onCreate() {
        activities = new HashMap<Activity, Status>();
        super.onCreate();
    }

    private boolean hasVisibleActivity() {
        for (Status status : activities.values())
            if (status.isVisible)
                return true;
        return false;
    }

    private boolean hasFocusedActivity() {
        for (Status status : activities.values())
            if (status.isFocused)
                return true;
        return false;
    }

    public void onActivityCreate(Activity activity, boolean isStarting) {
        if (isStarting && activities.isEmpty())
            onApplicationStart();
        activities.put(activity, new Status());
    }

    public void onActivityStart(Activity activity) {
        if (!hasVisibleActivity() && !hasFocusedActivity())
            onApplicationForeground();
        activities.get(activity).isVisible = true;
    }

    public void onActivityWindowFocusChanged(Activity activity, boolean hasFocus) {
        activities.get(activity).isFocused = hasFocus;
    }

    public void onActivityStop(Activity activity, boolean isFinishing) {
        activities.get(activity).isVisible = false;
        if (!isFinishing && !hasVisibleActivity() && !hasFocusedActivity())
            onApplicationBackground();
    }

    public void onActivityDestroy(Activity activity, boolean isFinishing) {
        activities.remove(activity);
        if(isFinishing && activities.isEmpty())
            onApplicationStop();
    }

    private void onApplicationStart() {Log.i(null, "Start");}
    private void onApplicationBackground() {Log.i(null, "Background");}
    private void onApplicationForeground() {Log.i(null, "Foreground");}
    private void onApplicationStop() {Log.i(null, "Stop");}

}

public class MyActivity extends BaseActivity {...}

public class BaseActivity extends Activity {

    private BaseApplication application;

    @Override
    protected void onCreate(Bundle state) {
        application = (BaseApplication) getApplication();
        application.onActivityCreate(this, state == null);
        super.onCreate(state);
    }

    @Override
    protected void onStart() {
        application.onActivityStart(this);
        super.onStart();
    }

    @Override
    public void onWindowFocusChanged(boolean hasFocus) {
        application.onActivityWindowFocusChanged(this, hasFocus);
        super.onWindowFocusChanged(hasFocus);
    }

    @Override
    protected void onStop() {
        application.onActivityStop(this, isFinishing());
        super.onStop();
    }

    @Override
    protected void onDestroy() {
        application.onActivityDestroy(this, isFinishing());
        super.onDestroy();
    }

}

0

OnActivityDestroyed फ़ंक्शन में टिप्पणी देखें।

एसडीके लक्ष्य संस्करण 14> के साथ काम करता है:

import android.app.Activity;
import android.app.Application;
import android.os.Bundle;
import android.util.Log;

public class AppLifecycleHandler implements Application.ActivityLifecycleCallbacks {

    public static int active = 0;

    @Override
    public void onActivityStopped(Activity activity) {
        Log.i("Tracking Activity Stopped", activity.getLocalClassName());
        active--;
    }

    @Override
    public void onActivityStarted(Activity activity) {
        Log.i("Tracking Activity Started", activity.getLocalClassName());
        active++;
    }

    @Override
    public void onActivitySaveInstanceState(Activity activity, Bundle outState) {
        Log.i("Tracking Activity SaveInstanceState", activity.getLocalClassName());
    }

    @Override
    public void onActivityResumed(Activity activity) {
        Log.i("Tracking Activity Resumed", activity.getLocalClassName());
        active++;
    }

    @Override
    public void onActivityPaused(Activity activity) {
        Log.i("Tracking Activity Paused", activity.getLocalClassName());
        active--;
    }

    @Override
    public void onActivityDestroyed(Activity activity) {
        Log.i("Tracking Activity Destroyed", activity.getLocalClassName());
        active--;

        // if active var here ever becomes zero, the app is closed or in background
        if(active == 0){
            ...
        }

    }

    @Override
    public void onActivityCreated(Activity activity, Bundle savedInstanceState) {
        Log.i("Tracking Activity Created", activity.getLocalClassName());
        active++;
    }
}

0

आपको अपनी गतिविधियों से सेवा बंधन का उपयोग करके संपत्ति को संग्रहीत करने और उस पर कार्य करने के लिए एक साझा प्राथमिकता का उपयोग करना चाहिए । यदि आप केवल बाइंडिंग का उपयोग करते हैं, (जो कि कभी भी startService का उपयोग नहीं करता है), तो आपकी सेवा केवल तभी चलेगी जब आप इसे बाँधेंगे, (onResume और unbind onPause पर बाँधें) जो इसे केवल अग्रभूमि पर चलाएगा, और यदि आप काम करना चाहते हैं पृष्ठभूमि आप नियमित स्टार्ट स्टॉप सेवा का उपयोग कर सकते हैं।


0

मुझे लगता है कि यह प्रश्न अधिक स्पष्ट होना चाहिए। कब? कहाँ पे? यदि आपका ऐप बैकग्राउंड में है, तो आपकी विशिष्ट स्थिति क्या है?

मैं बस अपने तरीके से अपने समाधान का परिचय देता हूं।
मैं अपने ऐप RunningAppProcessInfoमें हर गतिविधि के onStopतरीके में कक्षा के "महत्व" के क्षेत्र का उपयोग करके इसे प्राप्त करता हूं, जिसे केवल "महत्व" के मूल्य की जांच BaseActivityकरने के लिए onStopविधि को लागू करने के लिए अन्य गतिविधियों के लिए प्रदान करके प्राप्त किया जा सकता है । यहाँ कोड है:

public static boolean isAppRunning(Context context) {
    ActivityManager activityManager = (ActivityManager) context
        .getSystemService(Context.ACTIVITY_SERVICE);
    List<RunningAppProcessInfo> appProcesses = activityManager
        .getRunningAppProcesses();
    for (RunningAppProcessInfo appProcess : appProcesses) {
        if (appProcess.processName.equals(context.getPackageName())) {
            if (appProcess.importance != RunningAppProcessInfo.IMPORTANCE_PERCEPTIBLE) {
                return true;
            } 
        }
    }
    return false;
}

@ आइडलोन के उत्तर में कहा गया यह एक अनुशंसित समाधान नहीं है।
कूलमैन्ड

0

मैं इस पृष्ठ के माध्यम से पढ़ने की सलाह देता हूं: http://developer.android.com/reference/android/app/Activity.html

संक्षेप में, आपकी गतिविधि onStop()को कॉल किए जाने के बाद दिखाई नहीं देता है ।


3
मेरे आवेदन में लगभग 10 गतिविधियाँ हैं। इसलिए मैं यह जानना चाहता हूं कि क्या उनमें से कोई भी अगर उपयोगकर्ता को दिखाई देगा। कुल मिलाकर, मैं यह जानना चाहता हूं कि क्या मेरा पूरा आवेदन पृष्ठभूमि में चल रहा है
cppdev

तो फिर आप सभी 10-ईश का ट्रैक रखें। या, जैसा कि कॉमन्सवेयर ने सुझाव दिया था, समझाएं कि आप क्या करने की कोशिश कर रहे हैं।
मुख्य

3
यह सही नहीं है। आपकी गतिविधि तब तक दिखाई देती है onStop; के बीच onPauseऔर onStopयह दृश्यमान है , लेकिन अग्रभूमि में नहीं है
निकरिम

@nickgrim: क्या सही नहीं है? मैंने कहा कि एक गतिविधि दिखाई देने के बाद नहीं दिखाई देती onStop()है, जिसे आपने लिखा है।
की

@Key: आपने मूल रूप से कहा onPauseजाता है जब तक कहा जाता है: एक हालिया संपादन ने आपको सही किया है।
20'16


0

मेरी राय में, कई उत्तर कोड के भारी भार का परिचय देते हैं और बहुत सारी जटिलता और गैर-पठनीयता लाते हैं।

जब लोग एसओ से पूछते हैं कि ए Serviceऔर ए के बीच कैसे संवाद करना है Activity, तो मैं आमतौर पर लोकलब्रॉडकास्टमैन का उपयोग करने की सलाह देता हूं


क्यों?

डॉक्स के हवाले से:

  • आप जानते हैं कि आप जो डेटा प्रसारित कर रहे हैं, वह आपके ऐप को नहीं छोड़ेगा, इसलिए निजी डेटा को लीक करने के बारे में चिंता करने की ज़रूरत नहीं है।

  • अन्य एप्लिकेशन के लिए इन प्रसारणों को अपने ऐप पर भेजना संभव नहीं है, इसलिए आपको सुरक्षा छेद होने की चिंता करने की आवश्यकता नहीं है जो वे शोषण कर सकते हैं।

  • यह प्रणाली के माध्यम से एक वैश्विक प्रसारण भेजने की तुलना में अधिक कुशल है।

डॉक्स में नहीं:

  • इसमें बाहरी पुस्तकालयों की आवश्यकता नहीं होती है
  • कोड न्यूनतम है
  • इसे लागू करना और समझना तेज है
  • कोई कस्टम स्व-कार्यान्वित कॉलबैक / अल्ट्रा-सिंगलटन / इंट्रा-प्रक्रिया पैटर्न जो भी ...
  • कोई मजबूत संदर्भ पर Activity, Application...

विवरण

तो, आप जांचना चाहते हैं कि Activityक्या वर्तमान में कोई भी अग्रभूमि में है। आप आमतौर पर ऐसा करते हैं Service, या आपकी Applicationकक्षा में।

इसका मतलब है, आपकी Activityवस्तुएँ एक सिग्नल का प्रेषक बन जाती हैं (मैं चालू / बंद हूँ)। Serviceदूसरी ओर आपका , बन जाता है Receiver

कर रहे हैं दो , जिसमें देर में अपनाActivity आपको बताता है कि अगर यह अग्रभूमि में या पृष्ठभूमि (हाँ केवल दो ... नहीं 6) में जा रहा है।

जब Activityअग्रभूमि में जाता है, तो onResume()विधि चालू हो जाती है (जिसे बाद में भी कहा जाता है onCreate())।

जब Activityपीठ में जाता है, onPause()कहा जाता है।

ये ऐसे क्षण हैं जिनमें आपको अपने राज्य का वर्णन Activityकरने के लिए संकेत भेजना चाहिए Service

कई के मामले में Activity, एक याद हैActivity पहले एक पृष्ठभूमि में जाना , फिर एक और एक अग्रभूमि में आता है।

तो स्थिति यह होगी: *

Activity1 -- send --> Signal:OFF
Activity2 -- send --> Signal:ON

Service/ Applicationबस उन संकेतों में सुनते रहें और उसके अनुसार कार्य करेंगे।


कोड (TLDR)

संकेतों को सुनने के लिए आपका आदेश Serviceलागू होना चाहिए BroadcastReceiver

this.localBroadcastReceiver = new BroadcastReceiver() {
    @Override
    public void onReceive(Context context, Intent intent) {
        // received data if Activity is on / off
    }
}

public static final IntentFilter SIGNAL_FILTER = new IntentFilter("com.you.yourapp.MY_SIGNAL") 

रजिस्टर ReceiverमेंService::onCreate()

@Override
protected void onCreate() {
    LocalBroadcastManager.getInstance(getApplicationContext()).registerReceiver(this.localBroadcastReceiver, SIGNAL_FILTER);
}

इसमें अन-रजिस्टर करें Service::onDestroy()

@Override
protected void onDestroy() {
    // I'm dead, no need to listen to anything anymore.
    LocalBroadcastManager.getInstance(getApplicationContext()).unregisterReceiver(this.localBroadcastReceiver);
}

अब आपके Activityराज्य का संचार होना चाहिए।

में Activity::onResume()

Intent intent = new Intent();
intent.setAction(SomeActivity.SIGNAL_FILTER); // put ON boolean in intent    
LocalBroadcastManager.getInstance(getApplicationContext()).sendBroadcast(intent);

में Activity::onPause()

Intent intent = new Intent();
intent.setAction(SomeActivity.SIGNAL_FILTER); // put OFF boolean in intent    
LocalBroadcastManager.getInstance(getApplicationContext()).sendBroadcast(intent);

एक बहुत ही सामान्य स्थिति

डेवलपर: मैं अपने से डेटा भेजना चाहता हूं Serviceऔर अपडेट करना चाहता हूं Activity। अगर मैं Activityअग्रभूमि में है तो मैं कैसे जांच करूं ?

आमतौर पर यह जांचने की आवश्यकता नहीं Activityहै कि अग्रभूमि में है या नहीं। बस LocalBroadcastManagerअपने माध्यम से डेटा भेजें Service। यदि Activityचालू है, तो यह प्रतिक्रिया देगा और कार्य करेगा।

इस बहुत ही सामान्य स्थिति के लिए, Serviceप्रेषक बन जाता है और आम Activityलागू होता है BroadcastReceiver

तो, एक बनाने के Receiverअपने में Activity। इसे रजिस्टर करें onResume()और इसे अन-रजिस्टर करें onPause()अन्य जीवन-चक्र विधियों का उपयोग करने की कोई आवश्यकता नहीं है

Receiverव्यवहार को परिभाषित करें onReceive()(सूची दृश्य को अपडेट करें, ऐसा करें, ऐसा करें, ...)।

इस तरह से यह Activityकेवल तभी सुनेगा जब यह अग्रभूमि में हो और कुछ भी नहीं होगा यदि यह पीछे है या नष्ट हो गया है।

एकाधिक के मामले में Activity, जो भी Activityजवाब देगा (यदि वे भी लागू होते हैं Receiver)।

यदि सभी पृष्ठभूमि में हैं, तो कोई भी प्रतिक्रिया नहीं करेगा और संकेत बस खो जाएगा।

से डेटा भेजने Serviceके माध्यम से Intent(ऊपर कोड देखें) संकेत आईडी निर्दिष्ट करने के द्वारा।



0
fun isAppInForeground(): Boolean {
    val activityManager = getSystemService(Context.ACTIVITY_SERVICE) as ActivityManager ?: return false

    val appProcesses = activityManager.runningAppProcesses ?: return false

    val packageName = packageName
    for (appProcess in appProcesses) {
        if (appProcess.importance == ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND && appProcess.processName == packageName) {
            return true
        }
    }

    return false
}

0

यदि कोई विशेष गतिविधि फ़ोरग्राउंड में है और यदि आप SDK हैं, तो एप्लिकेशन को सीधे पहुंच के बिना यदि आपको पता चल जाए कि आपके द्वारा देखे गए उत्तरों में से किसी ने भी विशिष्ट मामले को फिट नहीं किया है। मेरे लिए मैं बैकग्राउंड थ्रेड में था, बस एक नए चैट संदेश के लिए एक पुश नोटिफिकेशन प्राप्त किया और केवल एक सिस्टम नोटिफिकेशन प्रदर्शित करना चाहता था यदि चैट स्क्रीन अग्रभूमि में नहीं है।

का उपयोग करते हुए ActivityLifecycleCallbacks जैसा कि अन्य उत्तरों में सुझाया गया है, मैंने एक छोटा सा उपयोग वर्ग बनाया है जो तर्क देता है कि MyActivityफोरग्राउंड में है या नहीं।

class MyActivityMonitor(context: Context) : Application.ActivityLifecycleCallbacks {

private var isMyActivityInForeground = false

init {
    (context.applicationContext as Application).registerActivityLifecycleCallbacks(this)
}

fun isMyActivityForeground() = isMyActivityInForeground

override fun onActivityPaused(activity: Activity?) {
    if (activity is MyActivity) {
        isMyActivityInForeground = false
    }
}

override fun onActivityResumed(activity: Activity?) {
    if (activity is MyActivity) {
        isMyActivityInForeground = true
    }
}

}


-1

अपनी गतिविधियों में onResume और onPause मैं SharedPrefences में एक अदृश्य बूलियन लिखता हूं।

    SharedPreferences sharedPrefs = PreferenceManager.getDefaultSharedPreferences(this);
    Editor editor = sharedPrefs.edit();
    editor.putBoolean("visible", false);
    editor.commit();

और जरूरत पड़ने पर इसे कहीं और पढ़ें।

    // Show a Toast Notification if App is not visible (ie in background. Not running, etc) 
    SharedPreferences sharedPrefs = PreferenceManager.getDefaultSharedPreferences(context);
    if(!sharedPrefs.getBoolean("visible", true)){...}

शायद सुरुचिपूर्ण नहीं है, लेकिन यह मेरे लिए काम करता है ...


-1

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

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

मैंने कॉमन्सवेयर द्वारा सुझाए गए कुछ किया था, "यदि सेवा निर्धारित करती है कि कोई गतिविधियां दिखाई नहीं दे रही हैं, और यह कुछ समय के लिए उस तरह से बनी हुई है , तो अगले तार्किक रोक बिंदु पर डेटा स्थानांतरण रोकें।"

बोल्ड में लाइन महत्वपूर्ण है और इसका उपयोग दूसरी वस्तु को प्राप्त करने के लिए किया जा सकता है। इसलिए मैं एक बार onActivityPaused () प्राप्त करने के लिए क्या करता हूं, डॉन को सीधे झूठे में नहीं बदलते हैं, इसके बजाय 3 सेकंड का टाइमर है (यह अधिकतम है कि अगली गतिविधि शुरू की जानी चाहिए), और अगर onActivity नहीं है (तो ) अगले 3 सेकंड में कॉल करें, झूठ को दृश्यमान बदलें। इसी तरह onActivityResumed () अगर कोई टाइमर है तो मैं उसे रद्द कर देता हूं। योग करने के लिए, दृश्यमान isAppInBackground हो जाता है।

क्षमा करें, कोड को कॉपी-पेस्ट नहीं कर सकते ...


-3

मैं आपको ऐसा करने के लिए दूसरे तरीके का उपयोग करने की सलाह देना चाहूंगा।

मुझे लगता है कि आप प्रोग्राम शुरू करते समय स्टार्ट स्क्रीन दिखाना चाहते हैं, अगर यह पहले से ही बैकएंड में चल रहा है, तो इसे न दिखाएं।

आपका एप्लिकेशन किसी विशिष्ट फ़ाइल में लगातार वर्तमान समय लिख सकता है। जब आपका आवेदन शुरू हो रहा है, तो अंतिम टाइमस्टैम्प की जांच करें, यदि current_time-last_time> समय आपके नवीनतम समय को लिखने के लिए निर्दिष्ट है, तो इसका मतलब है कि आपका आवेदन बंद हो गया है, या तो सिस्टम या उपयोगकर्ता द्वारा खुद को मार दिया गया है।

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