কোনও অ্যান্ড্রয়েড অ্যাপ্লিকেশন পটভূমিতে চলছে কিনা তা পরীক্ষা করা হচ্ছে


329

ব্যাকগ্রাউন্ডে, আমি বলতে চাইছি অ্যাপ্লিকেশনটির কোনওটিই বর্তমানে ব্যবহারকারীর কাছে দৃশ্যমান নয়?



7
আমি এখানে বিভ্রান্ত হয়েছি .. অ্যান্ড্রয়েড কেন এর জন্য অ্যাপ্লিকেশন ক্লাসে একটি সাধারণ ওভাররাইড সরবরাহ করতে পারে না? প্ল্যাটফর্ম পর্যায়ে এটি জানা কি খুব কঠিন? অ্যাপ্লিকেশনসেন্টটোব্যাকগ্রাউন্ড () {}
চক ডি

2
@ চকডি - এটি অর্থবহ হয়ে উঠবে, যা অ্যান্ড্রয়েড এসডিকে মাঝে মাঝে করা এড়াতে পছন্দ করে বলে মনে হয়। : /
চিহ্নিত করুন


1
গুগল এটি এত কঠিন করে তোলে কেন তা নিশ্চিত নন আইওএস-এর স্পিডস রয়েছে। এটি যেমন একটি সুস্পষ্ট প্রয়োজন।
জেরি ডাস্ট্র্যাম্পস

উত্তর:


388

আপনার অ্যাপ্লিকেশনটি ব্যাকগ্রাউন্ডে চলছে কিনা তা সনাক্ত করার কয়েকটি উপায় রয়েছে তবে তাদের মধ্যে কেবল একটিই সম্পূর্ণ নির্ভরযোগ্য:

  1. সঠিক সমাধান (ক্রেডিট যেতে ড্যান , CommonsWare এবং NeTeInStEiN )
    নিজের দ্বারা আপনার অ্যাপ্লিকেশন ব্যবহার করে ট্র্যাক দৃশ্যমানতা 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রেকর্ডের একটি তালিকা দেয় returns যদি আপনার আবেদনটি ফোরগ্রাউন্ড চেক কিনা তা নির্ধারণ করতে RunningAppProcessInfo.importanceকরতে সমতার জন্য ক্ষেত্র RunningAppProcessInfo.IMPORTANCE_FOREGROUNDযখনRunningAppProcessInfo.processName আপনার আবেদন প্যাকেজের নাম সমান।

    এছাড়াও আপনি যদি ActivityManager.getRunningAppProcesses()আপনার অ্যাপ্লিকেশন UI থ্রেড থেকে কল করেন তবে এটি IMPORTANCE_FOREGROUNDআপনার কাজের জন্য গুরুত্বটি ফিরিয়ে দেবে তা প্রকৃতপক্ষে অগ্রভাগে রয়েছে কিনা তা। এটিকে পটভূমির থ্রেডে কল করুন (উদাহরণস্বরূপ মাধ্যমে AsyncTask) এবং এটি সঠিক ফলাফল আসবে।

    যদিও এই সমাধানটি কার্যকর হতে পারে (এবং এটি সত্যই বেশিরভাগ সময় কাজ করে) আমি দৃ strongly়ভাবে এটি ব্যবহার থেকে বিরত থাকার পরামর্শ দিই। এবং কেন এখানে। যেমন ডায়ান হ্যাকবোন লিখেছেন :

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

    হ্যাঁ এই বিষয়গুলির জন্য স্মৃতিতে রাখা একটি তালিকা রয়েছে। তবে এটি অন্য প্রক্রিয়াতে বন্ধ রয়েছে, আপনার থেকে পৃথকভাবে চলমান থ্রেডগুলি পরিচালনা করে এবং আপনি (ক) সঠিক সিদ্ধান্ত নেওয়ার জন্য সময় দেখে বা (খ) আপনি ফিরে আসার সাথে ধারাবাহিক চিত্র রাখার মতো কিছু নয়। এছাড়াও "পরবর্তী" ক্রিয়াকলাপটি কী যাবেন সে সম্পর্কে সিদ্ধান্তটি সর্বদা সেই স্থানে করা হয় যেখানে স্যুইচটি ঘটতে হবে, এবং এটি সঠিক বিন্দু (যেখানে ক্রিয়াকলাপের স্ট্যান্ডটি সংক্ষেপে স্যুইচটি করতে লক করা আছে) না হওয়া পর্যন্ত আমরা তা করি না পরের জিনিসটি কী হবে তা নিশ্চিতভাবেই জানেন know

    এবং এখানে বাস্তবায়ন এবং বৈশ্বিক আচরণ ভবিষ্যতে একই থাকার গ্যারান্টিযুক্ত নয়।

    আশা করি এসও-তে কোনও উত্তর পোস্ট করার আগে আমি এটি পড়েছি তবে আশা করি আমার ত্রুটিটি স্বীকার করতে খুব বেশি দেরি হয়নি।

  3. এর আরেকটি ভুল সমাধান
    ড্রয়েড-ফু গ্রন্থাগার ActivityManager.getRunningTasksতার isApplicationBroughtToBackgroundপদ্ধতির জন্য একটির উত্তরে উল্লেখ করেছে । উপরে ডায়ান্নের মন্তব্য দেখুন এবং সেই পদ্ধতিটি ব্যবহার করবেন না।


4
আপনি হোম বোতাম টিপলে বা অন্য কোনও অ্যাপ ফোকাস অর্জন করেছে কিনা তা জানতে: 1) ভাল সমাধানটি প্রয়োগ করুন । 2) OnStopঅনুরোধে isActivityVisible
ব্রাইস গাবিন

28
দুর্ভাগ্যক্রমে আপনার 'সঠিক' সমাধানটি আমার পক্ষে কার্যকর হয় না। আপনার অ্যাপ্লিকেশন মধ্যে ক্রিয়াকলাপ মাধ্যমে আপনি চক্র বিবেচনা করুন। তারপরে যা ঘটে তা হ'ল আপনার 'ইনফোরগ্রাউন্ড' পতাকাটি এরকম হয়: সত্য, মিথ্যা (প্রথম ক্রিয়াকলাপের অনপেজ এবং ২ য় ক্রিয়াকলাপের মধ্যকার পুনঃসূচনা) তারপর আবার সত্য, ইত্যাদি You
রাদু

14
আপনি সরাসরি সমস্ত ক্রিয়াকলাপ নিয়ন্ত্রণ করতে না পারলে এই সমাধানটি কাজ করে না। উদাহরণস্বরূপ, যদি আপনার কোনও তৃতীয় পক্ষের এসডিকে থেকে কোনও ক্রিয়াকলাপ থাকে বা এমনকি ACTION_VIEW অভিপ্রায় চালু করা হয়।
ব্যবহারকারী 123321

66
অ্যান্ড্রয়েড যেমন একটি freaking নষ্ট। কেউ ভাবেন নি যে কেউ অ্যাপ স্তরের ডেটা চালিয়ে যেতে চাইবে? আমাকে বিরতি দিন

8
এই প্রশ্নের আসল উত্তরটি দেখে মনে হচ্ছে "আপনি এটি সঠিকভাবে পরীক্ষা করতে পারবেন না"। তথাকথিত 'সঠিক' সমাধানটি সর্বোত্তমভাবে কাজ করা, তাই অ্যাক্টিভিটিফাইসাইকেলক্যালব্যাকগুলি ব্যবহার করা হয়। আপনার এখনও এমন ক্রিয়াকলাপগুলির মধ্যে পাল্টানো বিবেচনা করতে হবে যা "অগ্রভাগে নয়" হিসাবে নিবন্ধিত হবে। এটা যে আপনি যে মত সরল জিনিস পরীক্ষা করতে পারছি না আমার মন হাতাহাতি ...
serine

263

এই উত্তরটি ব্যবহার করবেন না

ব্যবহারকারী 1269737 এর উত্তর হ'ল এটি করার উপযুক্ত (গুগল / অ্যান্ড্রয়েড অনুমোদিত) উপায় । তাদের উত্তর পড়ুন এবং তাদের একটি +1 দিন।

উত্তরসূরির জন্য আমি এখানে আমার আসল উত্তরটি রেখে যাব। এটি ২০১২ সালে সবচেয়ে ভাল উপলভ্য ছিল তবে এখন এর জন্য অ্যান্ড্রয়েডের উপযুক্ত সমর্থন রয়েছে support

আসল উত্তর

কীটি ব্যবহার করছে ActivityLifecycleCallbacks(নোট করুন এটির জন্য অ্যান্ড্রয়েড এপিআই স্তর 14 (অ্যান্ড্রয়েড 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()বলার জন্য :

নোট করুন যে এই পদ্ধতিটি কখনই ডাকা যাবে না, কম স্মৃতি পরিস্থিতিতে যেখানে আপনার কার্যকলাপের প্রক্রিয়াটি অনপেজ () পদ্ধতিটি কল করার পরে চলমান রাখতে পর্যাপ্ত মেমরির ব্যবস্থা নেই।

এখানে মূল কীটি হ'ল "আপনার ক্রিয়াকলাপের প্রক্রিয়া চালিয়ে যান ..." যদি এই কম স্মৃতি পরিস্থিতি পৌঁছে যায় তবে আপনার প্রক্রিয়াটি আসলে নিহত হয় (কেবল আপনার কার্যকলাপ নয়)। এর অর্থ হ'ল ব্যাকগ্রাউন্ড-নেস চেক করার এই পদ্ধতিটি এখনও বৈধ কারণ ক) আপনার প্রক্রিয়াটি মারা গেলে আপনি যেভাবেই ব্যাকগ্রাউন্ডিং পরীক্ষা করতে পারবেন না, এবং খ) আপনার প্রক্রিয়াটি আবার শুরু হয় (কারণ একটি নতুন ক্রিয়াকলাপ তৈরি করা হয়েছে), সদস্য এর জন্য ভেরিয়েবল (স্থির হোক বা না) MyLifecycleHandlerপুনরায় সেট করা হবে 0

এটি কি কনফিগারেশন পরিবর্তনের জন্য কাজ করে?

ডিফল্টরূপে, না। আপনাকে আপনার ম্যানিফেস্ট ফাইলে স্পষ্টভাবে সেট করতে হবে configChanges=orientation|screensize( |আপনার অন্য কোনও কিছুর সাথে) এবং কনফিগারেশন পরিবর্তনগুলি পরিচালনা করতে হবে, অন্যথায় আপনার কার্যকলাপ ধ্বংস হয়ে যাবে এবং পুনরায় তৈরি হবে। আপনি এই সেট না থাকে, তাহলে আপনার কার্যকলাপের এর পদ্ধতি এই অনুক্রমে ডাকা হবে: onCreate -> onStart -> onResume -> (now rotate) -> onPause -> onStop -> onDestroy -> onCreate -> onStart -> onResume। আপনি দেখতে পাচ্ছেন যে কোনও ওভারল্যাপ নেই (সাধারণত, দু'জনের মধ্যে স্যুইচ করার সময় দুটি ক্রিয়াকলাপ খুব সংক্ষেপে ওভারল্যাপ হয়, যা এই পটভূমি-সনাক্তকরণ পদ্ধতিটি কীভাবে কাজ করে)। এটি কাছাকাছি যাওয়ার জন্য, আপনাকে অবশ্যই সেট করতে হবে configChangesযাতে আপনার ক্রিয়াকলাপ ধ্বংস না হয়। ভাগ্যক্রমে, আমি সেট করতে হয়েছিলconfigChangesইতিমধ্যে আমার সমস্ত প্রকল্পে কারণ আমার সম্পূর্ণ ক্রিয়াকলাপটি স্ক্রিনে ঘোরানো / পুনরায় আকার দেওয়ার কারণে ধ্বংস হওয়া অনাকাঙ্ক্ষিত ছিল, তাই আমি কখনই এটিকে সমস্যাযুক্ত বলে মনে করি না। (এটি সম্পর্কে আমার স্মৃতি সতেজ করার জন্য এবং আমাকে সংশোধন করার জন্য ডিপিমকাকে ধন্যবাদ!)

এক নোট:

আমি যখন এই উত্তরে "পটভূমি" বলেছি, তখন আমি বুঝিয়েছি "আপনার অ্যাপ্লিকেশনটি আর দৃশ্যমান নয়।" অ্যান্ড্রয়েড ক্রিয়াকলাপগুলি অগ্রভাগে দৃশ্যমান হতে পারে (উদাহরণস্বরূপ, যদি স্বচ্ছ নোটিফিকেশন ওভারলে থাকে)। এজন্যই আমি এই উত্তরটি প্রতিফলিত করতে আপডেট করেছি।

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

আপনি না পরীক্ষা করতে যদি আপনার অ্যাপ আপনার পুরোভূমিতে থাকা Activity'র onPause()পদ্ধতি পরে super.onPause() । আমি কেবল অদ্ভুত লিম্বো রাষ্ট্রের কথা মনে করেছিলাম about

আপনি (অর্থাত যদি এটা পটভূমিতে নয়) পরীক্ষা করতে পারেন আপনার অ্যাপ দৃশ্যমান আপনার Activity'র onStop()পদ্ধতি পরে super.onStop()


1
এটি আকর্ষণীয় দেখায় - তবে কম স্মৃতির পরিস্থিতিতে কী ঘটে? এটি নিশ্চয়তা দেয় না যে অনস্টপ () কল করা হবে। আমরা কি কখনও এমন পরিস্থিতিতে পড়তে পারি যেখানে অনসটপ () না বলা হয় এবং বন্ধ হওয়া কাউন্টারটি বাড়ানো হয় না - এর অর্থ ব্যাকগ্রাউন্ড চেকটি আর নির্ভরযোগ্য নয়? নাকি কখনও তা ঘটবে না?
মেওয়াজার

1
এছাড়াও, এটি কি কনফিগারেশন পরিবর্তনগুলিকে উপেক্ষা করবে? বা কনফিগারেশনের পরিবর্তনের ফলে কোনও ক্রিয়াকলাপ পুনরায় তৈরি করা হলে (যেমন ওরিয়েন্টেশন পরিবর্তন)? অ্যাপ্লিকেশনটিকে পটভূমি হিসাবে বিবেচনা করা হবে? দুঃখিত, প্রশ্নের জন্য তবে আমি মনে করি আপনি কোনও কিছুর দিকে রয়েছেন এবং এই প্রান্তের ক্ষেত্রে এটি কাজ করে কিনা তা জানতে আগ্রহী।
মেওয়াজার

1
@ মেভেজার: আমি একটি মন্তব্য হিসাবে প্রতিক্রিয়া জানাতে যাচ্ছিলাম, তবে এই উত্তরগুলি পেতে এটি কিছুটা টাইপ করতে চলেছে, তাই কয়েক মিনিটের মধ্যে আবার পরীক্ষা করে দেখুন এবং আমি আমার উত্তরটি সম্পাদনা করব।
কর্নস্টালক

1
@ মেভেজার: আপনার উত্তরগুলি এখনই খুঁজে পাওয়া উচিত। অন্য কোন প্রশ্ন থাকলে আমাকে জানাবেন!
কর্নস্টালক

2
@Mewzer: আমি শুধুমাত্র একটি নোট যে আপনার আগ্রহী হতে পারে যোগ বিশেষত, এ backgrounding জন্য চেক করুন। onStop()পরে super.onStop()। ইন ব্যাকগ্রাউন্ডিং জন্য চেক করবেন না onPause()
কর্নস্টালক

186

গুগল সমাধান - পূর্ববর্তী সমাধানগুলির মতো হ্যাক নয়। প্রসেসলিফাইসাইকেলআপনার কোটলিন ব্যবহার করুন

:

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/libraries/architecture/lifecycle


10
এটি অবশ্যই সঠিক উত্তর হওয়া উচিত! এটি একটি
কবজির

2
এটি নিখুঁতভাবে কাজ করে, আমি কিছুটা পরিবর্তনও করেছি যাতে আমি এই শ্রেণীর বাইরে খুব সহজেই অগ্রভাগ / পটভূমির রাজ্যে অ্যাক্সেস companion object { private var foreground = false fun isForeground() : Boolean { return foreground } }করতে পারি : তারপরে আপনি অগ্রভাগের রাজ্যটি পেতে পারেনArchLifecycleApp.isForeground()
জোসে জেট

2
ওহ মানুষ, এটি আমার পুরানো উত্তরের চেয়ে অনেক ভাল। আমার কাছ থেকে একটি +1 করুন। আমি আপনার উত্তর লোককে আপনার কাছে নির্দেশ করার জন্য আপডেট করেছি।
কর্নস্টালক

2
যদিও এটি একটি সঠিক উত্তর কলব্যাকগুলি বাস্তবায়নের প্রয়োজন নেই, আপনি যখনই চাইবেন কেবলমাত্র প্রসেসলিফাইসাইকেলউইনারকে জিজ্ঞাসা করতে পারেন। পরীক্ষা করে দেখুন 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 শুরু করে আপনি প্রসেসলিফাইসাইকেল ওউনারটি ব্যবহার করতে পারেন , কেবল এখানে বর্ণিত মত আপনার নির্ভরতাতে এটি যুক্ত করুন , উদাহরণস্বরূপ:

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

যদি অ্যাপ্লিকেশন পুরোপুরি বন্ধ হয়ে যায় তবে প্রথম পদ্ধতিটি কী ফিরে আসবে?
এভেজেনি মিশুস্টিন

@ অ্যাভেজিনিমিশুস্টিন যা অ্যাপ্লিকেশনটির বর্তমান অবস্থার উপর নির্ভর করে তবে আপনি সাধারণত তৈরি হন এবং তখন ধ্বংস হয়ে যান এবং তার পরে আপনি কোনও নতুন ইভেন্ট পাবেন না।
কেভান এসবাতি

তাহলে আইএফ অ্যাপটি ব্যাকগ্রাউন্ডে (ফোরগ্রাউন্ডে) আছে এমন কোনও "আইএফ" বিবৃতি কোথায় আছে ???
ekashking

@ লুকানো পুরো বিবৃতিটি কেবল-ইফ-ক্লজে রেখে দেয় put উদাহরণস্বরূপ: যদি (প্রসেসলিফাইসাইকেলঅউনার.জেট ()। GetLifecycle ()। GetCenterState ()। IsAtLeast (লাইফসাইकल.স্টেট.এসটিআরটিড)) => অ্যাপটি অগ্রভাগে রয়েছে
কেভান এসবতি

20

অ্যান্ড্রয়েড এপিআই 16 যেহেতু অ্যাপ্লিকেশনটি অগ্রভাগে রয়েছে কিনা তা পরীক্ষা করার একটি সহজ উপায় রয়েছে is এটি বুদ্ধিমান নাও হতে পারে তবে অ্যান্ড্রয়েডের কোনও পদ্ধতিও বুদ্ধিমানের নয়। এই পরিষেবাটি ব্যবহার করার জন্য যথেষ্ট ভাল যখন আপনার পরিষেবাটি সার্ভার থেকে আপডেট গ্রহণ করে এবং বিজ্ঞপ্তিটি প্রদর্শন করা হবে কি না তা সিদ্ধান্ত নিতে হবে (কারণ যদি UI অগ্রভাগ হয়, ব্যবহারকারী বিজ্ঞপ্তি ছাড়াই আপডেটটি লক্ষ্য করবেন)।

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

এই কোডটি পরিষেবা বর্গের মধ্যে বা অন্যান্য শ্রেণীর মধ্যে থাকা উচিত? যেমন অ্যাপ্লিকেশন শ্রেণির? অনেক ধন্যবাদ.
Woppi

..যে যেখানেই আপনি এটি চূড়ান্ত লাইন হিসাবে ব্যবহার করতে চান কেবল এমন একটি বুলিয়ান যা আপনি পরীক্ষা করতে চান।
এও_

পুশ বিজ্ঞপ্তিগুলির জন্য এটি একই পদ্ধতি AWS Android SDK।
স্পাকমাদ

সচেতন থাকুন যে "পরিষেবা সীমাবদ্ধতার উদ্দেশ্যে ব্যাকগ্রাউন্ডের সংজ্ঞা মেমরি পরিচালনার দ্বারা ব্যবহৃত সংজ্ঞা থেকে পৃথক; কোনও অ্যাপ্লিকেশন মেমরি পরিচালনার সাথে ব্যাকগ্রাউন্ডে থাকতে পারে তবে অগ্রণীতে পরিষেবাগুলি চালু করার দক্ষতার সাথে সম্পর্কিত)" " বিকাশকারী.অ্যান্ড্রয়েড.
com

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

2
এই না একটি অব্যর্থ সমাধান পারেন। এক দৃশ্যকল্প হলে ব্যবহারকারী বিজ্ঞপ্তি প্যানেল নিচে টানা, তারপর তন্ন তন্ন onPause, onStopকিংবা onResumeঘটনা বলা হয়। তাহলে এই ইভেন্টগুলির কোনওটিই যদি বরখাস্ত না করা হয় তবে আপনি কি করবেন ?!

এটি আমাকে এই প্রশ্নের দিকে পরিচালিত করেছে: stackoverflow.com/questions/33657102/…
রুচির বড়োনিয়া

দুঃখের বিষয়, তবে কোনও স্ক্রিন বন্ধ থাকাকালীন কোনও ক্রিয়াকলাপ শুরু হলে এই কোডটি ভুল কাজ করে। এক্ষেত্রে অনারিউম এবং অনপজকে বলা হয় ইস্কিং = ভুয়া
কুলমাইন্ড

@ কুলমাইন্ড আপনি দয়া করে ব্যাখ্যা করতে পারেন যে ব্যাকগ্রাউন্ডে থাকার সময় আপনি কোনও কার্যকলাপ চালু করবেন এমন ব্যবহারের ক্ষেত্রে কী?
neteinstein

11

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

এগুলির সমাধানের মূল বিষয়টি হ'ল বোঝার সত্যতা হল যে আমাদের যদি অ্যাক্টিভিএ এবং অ্যাক্টিভিবি থাকে এবং আমরা ক্রিয়াকলাপ থেকে ক্রিয়াকলাপকে কল করি (এবং কল করি না 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 : বন্ধ হওয়া সংখ্যা শুরু হওয়া ক্রিয়াকলাপগুলির সংখ্যার সমান, যার অর্থ অ্যাপ্লিকেশনটি পটভূমিতে চলছে is
  2. stateCounter > 0 : শুরু হওয়া সংখ্যাটি থামানো সংখ্যার চেয়ে বড়, যার অর্থ এই অ্যাপ্লিকেশনটি অগ্রভাগে চলছে।

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

আপনি যেতে প্রস্তুত। আপনার অ্যাপ্লিকেশনটি ভিতরের পটভূমিতে রয়েছে কিনা তা আপনার পরীক্ষা করা উচিত onStop()


আমি নড়তেও চাই if(Utilities.isApplicationOnBackground()) …থেকে Utilities। কারণ অন্যথায় কেবলমাত্র একটি নির্দিষ্ট ক্রিয়াকলাপ ইভেন্টটিতে প্রতিক্রিয়া জানাবে।
নাম প্রদর্শন করুন

10

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


2
অ্যান্ড্রয়েডে, আমাদের কাছে "ব্যাকগ্রাউন্ড ডেটা" নামে একটি সেটিং রয়েছে। অ্যাপ্লিকেশন ব্যাকগ্রাউন্ডে চলাকালীন এই সেটিংটি যে কোনও ব্যাকগ্রাউন্ড ডেটা সংযোগে পরিণত হয়। আমি আমার অ্যাপ্লিকেশনটির জন্য "ব্যাকগ্রাউন্ড ডেটা" টগল প্রয়োগ করতে চাই, সুতরাং যখন আমার কোনও কার্যক্রম ব্যবহারকারীর কাছে দৃশ্যমান না হয়, তখন আমি আমার পরিষেবাটি কোনও ডেটা ট্রান্সফার করা বন্ধ করে দেওয়া চাই, তবে যে মুহুর্তে আমার একটি কার্যক্রম আবার শুরু হবে, আমি চাই ডেটা স্থানান্তর পুনরায় শুরু করুন
সিপিপিদেব

1
@ সিপিপিদেব: আশা করি, "ডেটা স্থানান্তর" এ দ্বারা পরিচালিত হচ্ছে Service। যদি তা হয় তবে আপনার ক্রিয়াকলাপগুলি পরিষেবাটি প্রদর্শিত হবে এবং অদৃশ্য হওয়ার সাথে সাথে তাদের অবহিত করুন। যদি Serviceনির্ধারণ করে যে কোনও ক্রিয়াকলাপ দৃশ্যমান নয় এবং এটি কিছু সময়ের জন্য একইভাবে থেকে যায় তবে পরবর্তী যৌক্তিক স্টপিং পয়েন্টে ডেটা স্থানান্তর বন্ধ করুন। হ্যাঁ, এটিতে আপনার প্রতিটি ক্রিয়াকলাপের জন্য কোডের প্রয়োজন হবে তবে এখনই এটি অনিবার্য আফ্রিক।
কমন্সওয়্যার

1
আপনি যদি আপনার সমস্ত ক্রিয়াকলাপের মধ্যে সাধারণ কোডটি অনুলিপি করতে এড়াতে চান তবে আপনি জীবনচক্র পদ্ধতি MyActivityClassথেকে উত্তরাধিকারসূত্রে একটি বর্গ তৈরি করতে পারেন Activityএবং আপনার সমস্ত ক্রিয়াকলাপ উত্তরাধিকার সূত্রে তৈরি করতে পারেন MyActivityClass। এটি (যদিও এই প্রশ্নটি দেখুন )PreferenceActivityMapActivity
গুইলিউম ব্রুনেরি

@ কমন্সওয়্যার আমি অনপজ () অনরেজিউম () দিয়ে চেষ্টা করেছি যে এটি সক্রিয় আছে বা না তবে আমার অ্যাপটি যদি পর্দার মধ্যে না দেখায় এটি যদি সক্রিয় আছে কি না তা পরীক্ষা করে দেখুন
মনোজ ২

@ কমন্সওয়্যার আমি অনপজ () অনরেজিউম () দিয়ে চেষ্টা করেছি যে এটি সক্রিয় আছে বা না তবে আমার অ্যাপটি যদি পর্দার মধ্যে না দেখায় এটি যদি সক্রিয় আছে কি না তা পরীক্ষা করে দেখুন
মনোজ ২

5

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

4

বেশ কয়েকটি দরকারী বৈশিষ্ট্য অন্তর্ভুক্ত করার জন্য @ কর্নস্টালকের জবাব দেওয়া হচ্ছে Building

অতিরিক্ত সুবিধাগুলি:

  • সিঙ্গেলটন প্যাটার্নটি প্রবর্তন করেছে যাতে আপনি অ্যাপ্লিকেশনটিতে যে কোনও জায়গায় এটি করতে পারেন: অ্যাপলাইফাইসাইকেলহ্যান্ডলিআরআইস অ্যাপ্লিকেশনভিজিবল () এবং অ্যাপলিফাইসাইকেলহ্যান্ডলিআর অ্যাপ্লিকেশনআইনফোরগ্রাউন্ড ()
  • সদৃশ ইভেন্টগুলির হ্যান্ডলিং যুক্ত করা হয়েছে (মন্তব্য দেখুন // দৃশ্যমানতার পরিবর্তনে কিছু পদক্ষেপ নিন এবং // অগ্রভাগে পরিবর্তন নিয়ে কিছু পদক্ষেপ নিন)

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 সেকেন্ডের পরে (বা আপনার যেটুকু অন্তর যথাযথ বলে মনে হয়) চালানোর পরে চালিত হবে, যখন টাইমার ফায়ার করে আপনি একটি পতাকাটি সেট করেন যা অ্যাপ্লিকেশনটিকে ব্যাকগ্রাউন্ডে রয়েছে বলে চিহ্নিত করে।

টাইমার বাতিল করার আগে অনারিউম () পদ্ধতিতে আপনি কোনও স্টার্টআপ ক্রিয়াকলাপ সম্পাদনের জন্য ব্যাকগ্রাউন্ড পতাকাটি জিজ্ঞাসা করতে পারেন (যেমন ডাউনলোডগুলি শুরু করতে বা অবস্থান পরিষেবাগুলি সক্ষম করুন)।

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

আপনি যদি কোনও ইভেন্ট বাসও ব্যবহার করেন তবে এই সমাধানটি ভালভাবে কাজ করে, কারণ আপনার টাইমার কেবল কোনও ইভেন্টটিকেই আগুন দিয়ে দিতে পারে এবং আপনার অ্যাপের বিভিন্ন অংশ ততক্ষণে প্রতিক্রিয়া জানাতে পারে।


আমি ভাবতে শুরু করছি এটি সেরা (যদিও দুর্ভাগ্যজনক) সমাধান
dhaag23

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

3

যদি আপনি বিকাশকারী সেটিংস চালু করেন "ক্রিয়াকলাপগুলি রাখবেন না" - কেবল তৈরি করা ক্রিয়াকলাপগুলির গণনা পরীক্ষা করা যথেষ্ট নয়। আপনার অবশ্যই সেভআইনস্ট্যান্সস্টেট পরীক্ষা করা উচিত । আমার কাস্টম পদ্ধতিটি অ্যাপ্লিকেশন রানিং () চেকটি হচ্ছে অ্যান্ড্রয়েড অ্যাপ চলছে:

এখানে আমার কাজের কোড:

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) {
            ...
        }
    }

}

আমার অ্যাপ্লিকেশনটি ব্যাকগ্রাউন্ডে বা সম্মুখভাগে রয়েছে কিনা তা এই সমাধানটি আমার ক্রিয়াকলাপের (বা টুকরো টুকরো) বিবৃতিতে কোনও সাধারণ প্রশ্নের উত্তর কীভাবে দিতে পারে তা আমি দেখতে পাচ্ছি না। "আইএফ" বিবৃতিটি কোথায় ???
ekashking

2

কমন্সওয়্যার এবং কী কী বলেছে সে সম্পর্কে পিগব্যাক করার জন্য, আপনি সম্ভবত অ্যাপ্লিকেশন ক্লাসটি প্রসারিত করতে পারেন এবং আপনার সমস্ত ক্রিয়াকলাপকে তাদের অনপেজ / অন রিসুম পদ্ধতিতে কল করতে পারেন। এটি আপনাকে কোন ক্রিয়াকলাপ (আইস) দৃশ্যমান তা জানার অনুমতি দেয় তবে সম্ভবত এটি আরও ভালভাবে পরিচালনা করা যেতে পারে।

আপনার মনে কী আছে তা কি আপনি বিশদভাবে বলতে পারেন? আপনি যখন ব্যাকগ্রাউন্ডে চলমান বলছেন, আপনার পর্দায় বর্তমানে না থাকা সত্ত্বেও কী আপনার অ্যাপ্লিকেশনটি স্মৃতিতে এখনও রয়েছে? আপনার অ্যাপ্লিকেশনটি যখন ফোকাসে নেই তখন কী আপনি পরিষেবাগুলি আরও নিরবচ্ছিন্ন উপায় হিসাবে ব্যবহার করার বিষয়টি দেখেছেন?


অ্যান্ড্রয়েডে, আমাদের কাছে "ব্যাকগ্রাউন্ড ডেটা" নামে একটি সেটিং রয়েছে। অ্যাপ্লিকেশন ব্যাকগ্রাউন্ডে চলাকালীন এই সেটিংটি যে কোনও পটভূমি ডেটা সংযোগকে ঘুরিয়ে দেয়। আমি আমার অ্যাপ্লিকেশনটির জন্য "ব্যাকগ্রাউন্ড ডেটা" টগল প্রয়োগ করতে চাই, সুতরাং যখন আমার কোনও কার্যক্রম ব্যবহারকারীর কাছে দৃশ্যমান না হয়, তখন আমি আমার পরিষেবাটি কোনও ডেটা ট্রান্সফার করা বন্ধ করে দেওয়া চাই, তবে যে মুহুর্তে আমার একটি কার্যক্রম আবার শুরু হবে, আমি চাই ডেটা স্থানান্তর পুনরায় শুরু করুন
সিপিপিদেব

1
Applicationনেই onPause()বা onResume()
কমন্সওয়্যার

1
@ কমন্সওয়্যার আপনি ঠিক বলেছেন, আমি প্রতিটি বিরতি / পুনরারম্ভের সাথে অ্যাপ্লিকেশনটির সাথে যোগাযোগ করা প্রতিটি ক্রিয়াকলাপ উল্লেখ করছি। এটি কেবলমাত্র আপনার উত্তরের মন্তব্যে আপনি যে মন্তব্যটি ভাগ করেছেন তা হ'ল যদিও আপনি যে পরিষেবাগুলি আমি কল্পনা করেছিলাম এটি একটি চতুর পদক্ষেপ।
ড্যান

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

}

এখন, লগকটে আপনি মাই অ্যাপ্লিকেশনটিতে তৈরি ইন্টারফেস বাস্তবায়নে লগগুলি প্রোগ্রাম করা দেখতে পাবেন।


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

অ্যাক্টিভিটিডাস্ট্রয়েড ফাংশনে মন্তব্যটি দেখুন।

এসডিকে লক্ষ্য সংস্করণ 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

সম্পত্তি সঞ্চয় করতে আপনার ভাগ করা পছন্দ ব্যবহার করা উচিত এবং আপনার ক্রিয়াকলাপ থেকে পরিষেবা বাঁধাই ব্যবহার করে এটিতে কাজ করা উচিত । আপনি যদি কেবল বাঁধাই ব্যবহার করেন, (এটি কখনই স্টার্ট সার্ভিস ব্যবহার করে না), তবে আপনার পরিষেবা কেবল তখনই চলবে যখন আপনি এটি বেঁধে রাখবেন, (onResume এবং unbind অনপজ বন্ধ করুন) এটি কেবল অগ্রভাগে চালিত করবে এবং আপনি যদি কাজ করতে চান তবে পটভূমি আপনি নিয়মিত স্টার্ট স্টপ পরিষেবাটি ব্যবহার করতে পারেন।


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/references/android/app/Activity.html

সংক্ষেপে, আপনার ক্রিয়াকলাপ ডাকার পরে আর দৃশ্যমান নয় onStop()


3
আমার আবেদনে আমার প্রায় 10 টি কার্যক্রম রয়েছে। সুতরাং আমি যদি তাদের কারও কাছে ব্যবহারকারীর কাছে দৃশ্যমান হয় তবে তা জানতে চাই। সব মিলিয়ে, আমি জানতে চাই যে সামগ্রিকভাবে আমার অ্যাপ্লিকেশনটি পটভূমিতে চলছে
কিনা

সুতরাং আপনি সমস্ত 10 ইশ ট্র্যাক রাখা। অথবা, কমন্সওয়্যারের পরামর্শ অনুসারে, আপনি কী করার চেষ্টা করছেন তা ব্যাখ্যা করুন।
কী

3
এটি সঠিক নয়। আপনার কার্যকলাপ অবধি দৃশ্যমান onStop; এর মধ্যে onPauseএবং onStopএটি দৃশ্যমান , তবে অগ্রভাগে নয়
নিকগ্রিম

@ নিকগ্রিম: কী সঠিক নয়? আমি বলেছি যে কোনও ক্রিয়াকলাপ onStop()বলা হওয়ার পরে আর দৃশ্যমান হয় না , যা আপনি যা লিখেছেন তার সাথে সামঞ্জস্য করা হয়েছে।
কী

@ কে: আপনি বলা না হওয়া পর্যন্ত আপনি মূলত বলেছিলেন onPause: সাম্প্রতিক সম্পাদনা আপনাকে সংশোধন করেছে।
নিকগ্রিম

0

গেট অ্যাপ্লিকেশন স্টেট () .আইইনফোরগ্রাউন্ড () ব্যবহার করার বিষয়ে কী?


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কেবল এই সব সংকেতের শুনতে থাকুন এবং সেই অনুযায়ী কাজ করবে।


কোড (টিএলডিআর)

সংকেত শোনার জন্য আপনার 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এবং আপডেট করতে চাই ActivityActivityঅগ্রভাগে আছে কিনা তা আমি কীভাবে পরীক্ষা করব ?

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

কোনও বিশেষ ক্রিয়াকলাপ ভুলে গেছে কিনা তা আপনি যদি সন্ধান করেন এবং আপনি যদি অ্যাপ্লিকেশনটিতে সরাসরি অ্যাক্সেস ছাড়াই কোনও এসডিকে থাকেন তবে উত্তরগুলির কোনওটিতেই নির্দিষ্ট ক্ষেত্রে উপযুক্ত নয়। আমার জন্য আমি ব্যাকগ্রাউন্ড থ্রেডে ছিলাম একটি নতুন চ্যাট বার্তার জন্য সবেমাত্র একটি পুশ বিজ্ঞপ্তি পেয়েছি এবং চ্যাট স্ক্রিনটি পূর্বগ্রাউন্ডে না থাকলে কেবলমাত্র একটি সিস্টেম বিজ্ঞপ্তি প্রদর্শন করতে চাই।

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

আমার কর্মসূচি এবং পুনরায় চালু করার সময়ে আমি শেয়ারডপ্রিফেন্সগুলিতে একটি ভিজিবল বুলিয়ান লিখি।

    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

উত্তর দিতে দেরি হতে পারে তবে কেউ যদি এখানে আসেন তবে আমার সমাধানটির সমাধানটি এখানে দেওয়া পরামর্শ, কারণ কোনও অ্যাপ্লিকেশন তার পটভূমির অবস্থান বা অগ্রভাগে আসার অবস্থা জানতে চায় তার কারণ অনেকগুলি হতে পারে, কয়েকটি হ'ল, ১। ব্যবহারকারী যখন বিজি তে থাকে তখন টোস্টগুলি এবং বিজ্ঞপ্তিগুলি দেখানোর জন্য। ২. প্রথমবারের মতো কিছু কাজ সম্পাদনের জন্য ব্যবহারকারী বিজি থেকে আসে, যেমন একটি পোল, পুনর্নির্মাণ ইত্যাদি from

আইডলন এবং অন্যান্যদের সমাধান প্রথম অংশটির যত্ন নেয় তবে দ্বিতীয়টির জন্য হয় না। যদি আপনার অ্যাপ্লিকেশনটিতে একাধিক ক্রিয়াকলাপ থাকে এবং ব্যবহারকারী তাদের মধ্যে স্যুইচ করে চলেছে তবে আপনি দ্বিতীয় ক্রিয়াকলাপের সাথে সাথে দৃশ্যমান পতাকাটি মিথ্যা হবে। সুতরাং এটি নির্বিচারে ব্যবহার করা যাবে না।

কমন্সওয়্যার দ্বারা প্রস্তাবিত এমন কিছু আমি করেছি, "যদি পরিষেবাটি নির্ধারণ করে যে কোনও ক্রিয়াকলাপ দৃশ্যমান নয়, এবং এটি কিছু সময়ের জন্য এইভাবে থেকে যায় , তবে পরবর্তী যৌক্তিক স্টপিং পয়েন্টে ডেটা স্থানান্তর বন্ধ করুন।"

গা bold় রেখাটি গুরুত্বপূর্ণ এবং এটি দ্বিতীয় আইটেমটি অর্জন করতে ব্যবহার করা যেতে পারে। তাই আমি যা করি তা হ'ল একবার আমি অ্যাক্টিভিটি পজড () পেয়েছি, সরাসরি দৃশ্যকে মিথ্যাতে বদলে না, পরিবর্তে 3 সেকেন্ডের টাইমার রাখি (এটি পরবর্তী ক্রিয়াকলাপটি চালু করা সর্বাধিক) এবং যদি অ্যাক্টিভিটি পুনরায় চালু না করা হয় ( ) পরবর্তী 3 সেকেন্ডে কল করুন, মিথ্যাতে দৃশ্যমান পরিবর্তন করুন। একইভাবে onActivityResume () এ যদি টাইমার থাকে তবে আমি এটিকে বাতিল করি। সংক্ষিপ্তসার হিসাবে, দৃশ্যমান হয় অ্যাপ্লিকেশনব্যাকগ্রাউন্ড।

দুঃখিত কোডটি অনুলিপি করতে পারবেন না ...


-3

আমি আপনাকে এটি করার জন্য অন্য উপায়টি ব্যবহার করার জন্য সুপারিশ করতে চাই।

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

আপনার অ্যাপ্লিকেশন একটি নির্দিষ্ট ফাইলটিতে অবিচ্ছিন্নভাবে বর্তমান সময় লিখতে পারে। আপনার অ্যাপ্লিকেশন শুরু হওয়ার সময়, সর্বশেষ টাইমস্ট্যাম্পটি পরীক্ষা করুন, যদি বর্তমান_টাইম-শেষ_কাল> সর্বশেষ সময় লেখার জন্য আপনার নির্দিষ্ট সময়সীমাটি নির্দিষ্ট করে থাকে, তার অর্থ আপনার অ্যাপ্লিকেশনটি বন্ধ হয়ে গেছে, হয় সিস্টেম বা ব্যবহারকারী নিজেই মেরেছেন।

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