অ্যান্ড্রয়েডে কীভাবে ব্যবহারকারীর নিষ্ক্রিয়তা সনাক্ত করা যায়


101

ব্যবহারকারীরা আমার অ্যাপ্লিকেশনটি শুরু করে এবং লগ ইন করে
5
অ্যাপটিতে কিছু অপারেশন করে। (সমস্ত অগ্রভাগে)
এখন ব্যবহারকারী Myapp কে পটভূমিতে নিয়ে আসে এবং অন্য কোনও অ্যাপ্লিকেশন শুরু করে।
----> কাউন্ট ডাউন টাইমার শুরু হয় এবং 5 মিনিটের পরে ব্যবহারকারী লগ আউট করে
বা ব্যবহারকারী স্ক্রিনটি বন্ধ করে দেয়।
----> কাউন্ট ডাউন টাইমার শুরু হয় এবং 5 মিনিটের পরে ব্যবহারকারীকে লগ আউট করে

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


1
আপনি কি সর্বদা সেই টাইমারটি চালিয়ে যেতে পারেন এবং যখনই ব্যবহারকারী কিছু করেন তবে তা পুনরায় সেট করতে পারেন?
কাইল পি

উত্তর:


111

ফ্রেড্রিক ওয়ালেনিয়াসের উত্তরের উপর ভিত্তি করে আমি এমন একটি সমাধান নিয়ে এসেছি যা আমি বেশ সহজ পাই। এটি একটি বেস ক্রিয়াকলাপ শ্রেণি যা সমস্ত ক্রিয়াকলাপ দ্বারা প্রসারিত করা দরকার।

public class MyBaseActivity extends Activity {

    public static final long DISCONNECT_TIMEOUT = 300000; // 5 min = 5 * 60 * 1000 ms


    private static Handler disconnectHandler = new Handler(new Handler.Callback() {
        @Override
        public boolean handleMessage(Message msg) {
            // todo
            return true;
        }
    });

    private static Runnable disconnectCallback = new Runnable() {
        @Override
        public void run() {
            // Perform any required operation on disconnect
        }
    };

    public void resetDisconnectTimer(){
        disconnectHandler.removeCallbacks(disconnectCallback);
        disconnectHandler.postDelayed(disconnectCallback, DISCONNECT_TIMEOUT);
    }

    public void stopDisconnectTimer(){
        disconnectHandler.removeCallbacks(disconnectCallback);
    }

    @Override
    public void onUserInteraction(){
        resetDisconnectTimer();
    }

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

    @Override
    public void onStop() {
        super.onStop();
        stopDisconnectTimer();
    }
}

3
এটি প্রতিটি তৈরির জন্য Handlerএবং একাধিক উদাহরণ তৈরি করবে । আমরা যদি এই দুই সদস্যকে রূপান্তর করি তবে এটি এড়ানো হবে। এছাড়াও, আপনি আমাকে বলতে পারেন কেন আপনি ফোন করেছেন ? `RunnableActivitystaticstopDisconnectTimer()onStop()
গৌরভ ভোর

@ গৌরব আমার ক্ষেত্রে, এটি কেবলমাত্র একটি ক্রিয়াকলাপে প্রয়োগ করা হয়েছে (সুতরাং আমি সমস্যাটি staticসংশোধনকারীটির সাথে ধরিনি)। onStop()আমি যা মনে করি সেগুলি থেকে আমি onBackPressed()সংযোগ বিচ্ছিন্ন কলব্যাকের একটি লগইন স্ক্রিনে ফিরে আসার জন্য কল করি যা ঘুরে ফিরে onStop()পদ্ধতিটিকে কল করে । ব্যবহারকারী যখন লগইন স্ক্রিনে ম্যানুয়ালি ফিরে আসে, ফিরে টিপে, টাইমারটি পাশাপাশি বন্ধ stopDisconnectTimer()করে দেওয়া দরকার onStop()। আমার ধারণা এই অংশটি আপনার প্রয়োজন এবং বাস্তবায়নের উপর নির্ভর করে।
জিফ্রিগন

@ জিফ্রিগন কি লগইন ক্রিয়াকলাপে ব্যবহারকারীকে পুনর্নির্দেশ করা সম্ভব?
Apostrofix

@ এপোস্ট্রিফিক্স, অবশ্যই এটি সম্ভব। আমার ক্ষেত্রে শুধুমাত্র একটি ক্রিয়াকলাপ ছিল: onBackPressed()ভাসকে কল করা যথেষ্ট। আপনার স্ট্যাকে যদি একাধিক ক্রিয়াকলাপ থাকে তবে আপনাকে কেবলমাত্র সেই বিষয়ে একটি অভিপ্রায় তৈরি করতে হবে। : আপনি অর্ডার ভ্রমণ টাস্ক পরিষ্কার নিম্নলিখিত উত্তর তাকান (এবং একটি ব্যাক অন সংযোগ পুনরায় থেকে ব্যবহারকারীদের বাধা দেয়) চাইতে পারেন stackoverflow.com/questions/7075349/...
gfrigon

মহান কাজ! আমি রানআনেবলের জন্য গেটর এবং সেটার যুক্ত করেছি এবং তারপরে এটি অনক্রিট পদ্ধতিটি ব্যবহার করে প্রয়োজনীয় বর্ধিত শ্রেণিতে সেট করেছি ... নিখুঁত, আবার আপনাকে ধন্যবাদ।
CrandellWS

90

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

@Override
public void onUserInteraction(){
    MyTimerClass.getInstance().resetTimer();
}

যদি আপনার অ্যাপ্লিকেশনটিতে বেশ কয়েকটি ক্রিয়াকলাপ রয়েছে, তবে কেন এই পদ্ধতিটিকে একটি বিমূর্ত সুপার ক্লাসে (প্রসারিত করা Activity) রাখবেন না এবং তারপরে আপনার সমস্ত ক্রিয়াকলাপগুলি এটি প্রসারিত করুন।


1
হ্যাঁ এটি করার এটি একটি উপায় ... তবে আমার অ্যাপ্লিকেশনটিতে 30 টি আলাদা ক্রিয়াকলাপ রয়েছে এবং ব্যবহারকারী সক্রিয় থাকাকালীন খুব বেশি ইন্টারঅ্যাকশন হবে ... তাই প্রতিবারের সাথে টাইমার ওডটিকে পুনরায় সেট করা একটি ব্যয়বহুল ক্রিয়াকলাপ ... যা সবচেয়ে খারাপ পরিস্থিতি এক মিনিটে 50 থেকে 60 বার করতে পারে।
আখ

3
আমি এটির টাইম করি নি তবে আমি এটির মতো টাইমারের পুনরায় সেট করতে বলব ইনস্ট্রাকশন = সিস্টেম.কন্ট্রেনটাইমমিলিস (); বলুন, 2 এমএস। এটি একটি মিনিটে 60 বার করুন এবং আপনি 120 মিমি "আলগা" করুন। 60000 এর মধ্যে
ফ্রেডরিক ওয়ালেনিয়াস

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

3
onUserInteration () কিছু ক্ষেত্রে বলা হয় না (সংলাপগুলি এটি বলে না, এবং স্পিনারগুলিতে স্ক্রোলিং) এই পরিস্থিতিতে কি কোনও কাজ রয়েছে?
AndroidNoob

আপনি কি আপনার MyTimerClass ভাগ করতে পারেন?
সিবিলেয়াস সেরাপিনি

19

আমার মনে হয় আপনার এই কোডটি নিয়ে চলতে হবে, এটি 5 মিনিটের নিষ্ক্রিয় সেশনের সময়সীমা জন্য: ->

Handler handler;
Runnable r;
@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    handler = new Handler();
    r = new Runnable() {

       @Override
       public void run() {
            // TODO Auto-generated method stub
            Toast.makeText(MainActivity.this, "user is inactive from last 5 minutes",Toast.LENGTH_SHORT).show();
        }
    };
    startHandler();
}
@Override
public void onUserInteraction() {
     // TODO Auto-generated method stub
     super.onUserInteraction();
     stopHandler();//stop first and then start
     startHandler();
}
public void stopHandler() {
    handler.removeCallbacks(r);
}
public void startHandler() {
    handler.postDelayed(r, 5*60*1000); //for 5 minutes 
}

আপনি ইউজার
ইন্টেরাকশন

10
public class MyApplication extends Application {
      private int lastInteractionTime;
      private Boolean isScreenOff = false; 
      public void onCreate() {
        super.onCreate();
        // ......   
        startUserInactivityDetectThread(); // start the thread to detect inactivity
        new ScreenReceiver();  // creating receive SCREEN_OFF and SCREEN_ON broadcast msgs from the device.
      }

      public void startUserInactivityDetectThread() {
        new Thread(new Runnable() {
          @Override
          public void run() {
            while(true) {
              Thread.sleep(15000); // checks every 15sec for inactivity
              if(isScreenOff || getLastInteractionTime()> 120000 ||  !isInForeGrnd)
                {
                  //...... means USER has been INACTIVE over a period of
                  // and you do your stuff like log the user out 
                }
              }
          }
        }).start();
      }

      public long getLastInteractionTime() {
        return lastInteractionTime;
      }

      public void setLastInteractionTime(int lastInteractionTime) {
        this.lastInteractionTime = lastInteractionTime;
      }

      private class ScreenReceiver extends BroadcastReceiver {

        protected ScreenReceiver() {
           // register receiver that handles screen on and screen off logic
           IntentFilter filter = new IntentFilter();
           filter.addAction(Intent.ACTION_SCREEN_ON);
           filter.addAction(Intent.ACTION_SCREEN_OFF);
           registerReceiver(this, filter);
        }

        @Override
        public void onReceive(Context context, Intent intent) {
          if (intent.getAction().equals(Intent.ACTION_SCREEN_OFF)) {
            isScreenOff = true;
          } else if (intent.getAction().equals(Intent.ACTION_SCREEN_ON)) {
            isScreenOff = false;
          }
        }
      }
    }

isInForeGrnd ===> যুক্তি এখানে প্রশ্নের দেখানোর বাইরে না থাকায় এটি দেখানো হয়নি

আপনি নীচের ডিভাইস কোড ব্যবহার করে সিপিইউতে লকটি জাগাতে পারেন-

  if(isScreenOff || getLastInteractionTime()> 120000 ||  !isInForeGrnd)
    {
      //...... means USER has been INACTIVE over a period of
      // and you do your stuff like log the user out 

      PowerManager pm = (PowerManager) context.getSystemService(Context.POWER_SERVICE);

      boolean isScreenOn = pm.isScreenOn();
      Log.e("screen on.................................", "" + isScreenOn);

      if (isScreenOn == false) {

        PowerManager.WakeLock wl = pm.newWakeLock(PowerManager.FULL_WAKE_LOCK | PowerManager.ACQUIRE_CAUSES_WAKEUP | PowerManager.ON_AFTER_RELEASE, "MyLock");

        wl.acquire(10000);
        PowerManager.WakeLock wl_cpu = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "MyCpuLock");

        wl_cpu.acquire(10000);
      }
    }

4
@ ন্যাপি: তারপরে দয়া করে এটি করার সঠিক উপায়টি ব্যাখ্যা করুন। আপনার মন্তব্য অস্পষ্ট এবং অনিবার্য।
আখ

2
@ কিঃ অন্যান্য উত্তরগুলি ইতিমধ্যে সম্ভাবনাগুলি দেখায়। আপনার সমাধানে, আমি প্রতি 15 সেকেন্ডে ভোট দেওয়ার মাধ্যমে কোনও সুবিধা দেখতে পাচ্ছি না। আপনি 0-15 সেকেন্ড থেকে এলোমেলো সময়সীমা নিয়ে "ACTION_SCREEN_OFF" এ টাইমার শুরু করার সাথে সাথে এটির একই প্রভাব থাকবে। এটি ঠিক বোঝায় না ..
ন্যাপি

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

আপনার মন্তব্য সম্পূর্ণ করুন। .... "যদি আপনার স্ক্রিনের বুলিয়ান হয়?" এবং এছাড়াও অ্যাপ্লিকেশন ফোরগার্ড স্থিতি আমলে নিতে হবে।
আখ

1
এই কোডটি ভুল সহ পূর্ণ, কিছু পরিবর্তনশীল আরম্ভ হয় না।
বিগ.চিল্ড

8
@Override
public void onUserInteraction() {
    super.onUserInteraction();
    delayedIdle(IDLE_DELAY_MINUTES);
}

Handler _idleHandler = new Handler();
Runnable _idleRunnable = new Runnable() {
    @Override
    public void run() {
        //handle your IDLE state
    }
};

private void delayedIdle(int delayMinutes) {
    _idleHandler.removeCallbacks(_idleRunnable);
    _idleHandler.postDelayed(_idleRunnable, (delayMinutes * 1000 * 60));
}

এটি সমাধানের ভিত্তি, আপনার আংশিক প্রয়োজন এবং অ্যাপ্লিকেশন আর্কিটেকচার জটিলতার উপর নির্ভর করে আপনার সংশোধন করা যেতে পারে! উত্তর করার জন্য ধন্যবাদ!
হ্যাক06

এটি কীভাবে আবেদন শ্রেণিতে প্রয়োগ করবেন
গাজু কল্লুর

6

ওএস স্তরে সম্প্রচার ACTION_SCREEN_OFFACTION_USER_PRESENTসম্প্রচারের বাইরে "ব্যবহারকারীর নিষ্ক্রিয়তার" কোনও ধারণা নেই । আপনার নিজের প্রয়োগের মধ্যে আপনাকে কোনওভাবে "নিষ্ক্রিয়তা" নির্ধারণ করতে হবে।


6

এমনকি আপনি @gfrigon বা @AK সমাধানের মাধ্যমে আপনার প্রয়োজনীয়তা পরিচালনা করতে পারেন ।

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

প্রথমে আমি আপনাকে বলি আপনি টাইমার বা হ্যান্ডলার ব্যবহার করলে আপনার কী পরিচালনা করতে হবে।

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

অবশেষে আমি একটি সমাধান বাস্তবায়িত যা হয়

  1. কোনও হ্যান্ডলার বা টাইমার
  2. কোন এলার্ম ব্যবস্থাপক।
  3. অ্যাপ লাইফ সাইকেল পরিচালনা করছেন না।
  4. কোন ACTION_SCREEN_ON/ ACTION_SCREEN_OFFসম্প্রচারক রিসিভার।

সবচেয়ে সহজ নির্ভরযোগ্য সমাধান

আমরা ব্যবহারকারীর ক্রিয়াকলাপে শেষ ক্রিয়াকলাপটি যাচাই করব তার চেয়ে আমরা টাইমারদের দ্বারা ব্যবহারকারীর নিষ্ক্রিয়তা পর্যবেক্ষণ করব না। সুতরাং যখন ব্যবহারকারীরা পরের বার অ্যাপ্লিকেশনের সাথে যোগাযোগ করে, আমি শেষ ইন্টারঅ্যাকশন সময়টি যাচাই করি।

BaseActivity.classআপনি আপনার ক্রিয়াকলাপের পরিবর্তে প্রতিটি ক্রিয়াকলাপ থেকে প্রসারিত করবেন এটি এখানে LoginActivity। আপনি TIMEOUT_IN_MILLIএই শ্রেণীর ক্ষেত্রে আপনার লগআউট সময়টি নির্ধারণ করবেন ।

import android.content.Intent;
import android.content.SharedPreferences;
import android.support.v7.app.AppCompatActivity;
import android.widget.Toast;

public class BaseActivity extends AppCompatActivity {
    public static final long TIMEOUT_IN_MILLI = 1000 * 20;
    public static final String PREF_FILE = "App_Pref";
    public static final String KEY_SP_LAST_INTERACTION_TIME = "KEY_SP_LAST_INTERACTION_TIME";

    @Override
    public void onUserInteraction() {
        super.onUserInteraction();
        if (isValidLogin())
            getSharedPreference().edit().putLong(KEY_SP_LAST_INTERACTION_TIME, System.currentTimeMillis()).apply();
        else logout();
    }

    public SharedPreferences getSharedPreference() {
        return getSharedPreferences(PREF_FILE, MODE_PRIVATE);
    }

    public boolean isValidLogin() {
        long last_edit_time = getSharedPreference().getLong(KEY_SP_LAST_INTERACTION_TIME, 0);
        return last_edit_time == 0 || System.currentTimeMillis() - last_edit_time < TIMEOUT_IN_MILLI;
    }

    public void logout() {
        Intent intent = new Intent(this, LoginActivity.class);
        intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK | Intent.FLAG_ACTIVITY_CLEAR_TOP);
        startActivity(intent);
        finish();
        Toast.makeText(this, "User logout due to inactivity", Toast.LENGTH_SHORT).show();
        getSharedPreference().edit().remove(KEY_SP_LAST_INTERACTION_TIME).apply(); // make shared preference null.
    }
}

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

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

2

আমার ক্রিয়াকলাপ বেস শ্রেণিতে আমি সুরক্ষিত শ্রেণি তৈরি করেছি:

protected class IdleTimer
{
    private Boolean isTimerRunning;
    private IIdleCallback idleCallback;
    private int maxIdleTime;
    private Timer timer;

    public IdleTimer(int maxInactivityTime, IIdleCallback callback)
    {
        maxIdleTime = maxInactivityTime;
        idleCallback = callback;
    }

    /*
     * creates new timer with idleTimer params and schedules a task
     */
    public void startIdleTimer()
    {
        timer = new Timer();            
        timer.schedule(new TimerTask() {

            @Override
            public void run() {             
                idleCallback.inactivityDetected();
            }
        }, maxIdleTime);
        isTimerRunning = true;
    }

    /*
     * schedules new idle timer, call this to reset timer
     */
    public void restartIdleTimer()
    {
        stopIdleTimer();
        startIdleTimer();
    }

    /*
     * stops idle timer, canceling all scheduled tasks in it
     */
    public void stopIdleTimer()
    {
        timer.cancel();
        isTimerRunning = false;
    }

    /*
     * check current state of timer
     * @return boolean isTimerRunning
     */
    public boolean checkIsTimerRunning()
    {
        return isTimerRunning;
    }
}

protected interface IIdleCallback
{
    public void inactivityDetected();
}

সুতরাং পুনরায় সূচনা পদ্ধতিতে - আপনি এটির সাথে কী করতে চান তা আপনার কলব্যাকটিতে ক্রিয়া নির্দিষ্ট করতে পারেন ...

idleTimer = new IdleTimer(60000, new IIdleCallback() {
            @Override
            public void inactivityDetected() {
                ...your move...
            }
        });
        idleTimer.startIdleTimer();

ব্যবহারকারী কীভাবে নিষ্ক্রিয় আছে তা পরীক্ষা করবেন ?? সিস্টেম থেকে কোন ইনপুট?
মহসিনসাইড

2

আমার অনুসন্ধানের সময় আমি অনেক উত্তর পেয়েছি তবে এটি আমার সেরা উত্তর। তবে এই কোডটির সীমাবদ্ধতা হ'ল এটি সম্পূর্ণ ক্রিয়াকলাপের জন্য নয় কেবল ক্রিয়াকলাপের জন্য কাজ করে। এটি একটি রেফারেন্স হিসাবে নিন।

myHandler = new Handler();
myRunnable = new Runnable() {
    @Override
    public void run() {
        //task to do if user is inactive

    }
};
@Override
public void onUserInteraction() {
    super.onUserInteraction();
    myHandler.removeCallbacks(myRunnable);
    myHandler.postDelayed(myRunnable, /*time in milliseconds for user inactivity*/);
}

যেমন আপনি 8000 ব্যবহার করেছেন, ব্যবহারকারীর নিষ্ক্রিয়তার 8 সেকেন্ড পরে কাজটি করা হবে।


2

ব্যবহারকারী নিষ্ক্রিয়তা onUserInteraction()অ্যান্ড্রয়েডে ওভাররাইড পদ্ধতি ব্যবহার করে সনাক্ত করতে পারে

  @Override
    public void onUserInteraction() {
        super.onUserInteraction();

    }

ব্যবহারকারী নিষ্ক্রিয় থাকাকালীন 3 মিনিটের পরে এখানে নমুনা কোড, সাইনআউট (হোমঅ্যাক্টিভিটি -> লগইনঅ্যাক্টিভিটি) দেওয়া আছে

public class HomeActivity extends AppCompatActivity {

    private static String TAG = "HomeActivity";
    private Handler handler;
    private Runnable r;


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


        handler = new Handler();
        r = new Runnable() {

            @Override
            public void run() {

                Intent intent = new Intent(getApplicationContext(), LoginActivity.class);
                startActivity(intent);
                Log.d(TAG, "Logged out after 3 minutes on inactivity.");
                finish();

                Toast.makeText(HomeActivity.this, "Logged out after 3 minutes on inactivity.", Toast.LENGTH_SHORT).show();
            }
        };

        startHandler();

    }

    public void stopHandler() {
        handler.removeCallbacks(r);
        Log.d("HandlerRun", "stopHandlerMain");
    }

    public void startHandler() {
        handler.postDelayed(r, 3 * 60 * 1000);
        Log.d("HandlerRun", "startHandlerMain");
    }

    @Override
    public void onUserInteraction() {
        super.onUserInteraction();
        stopHandler();
        startHandler();
    }

    @Override
    protected void onPause() {

        stopHandler();
        Log.d("onPause", "onPauseActivity change");
        super.onPause();

    }

    @Override
    protected void onResume() {
        super.onResume();
        startHandler();

        Log.d("onResume", "onResume_restartActivity");

    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        stopHandler();
        Log.d("onDestroy", "onDestroyActivity change");

    }

}

2

কেটলিনে ইন্টারঅ্যাকশন সময়সামগ্রীতে ব্যবহারকারীকে পরিচালনা করছেন:

     //Declare handler
      private var timeoutHandler: Handler? = null
      private var interactionTimeoutRunnable: Runnable? = null

 override fun onCreate(savedInstanceState: Bundle?) {
      super.onCreate(savedInstanceState)
      setContentView(R.layout.activity_aspect_ratio)

       //Initialise handler
      timeoutHandler =  Handler();
      interactionTimeoutRunnable =  Runnable {
         // Handle Timeout stuffs here
          }

      //start countdown
      startHandler()
}

// reset handler on user interaction
override fun onUserInteraction() {
      super.onUserInteraction()
      resetHandler()
}

 //restart countdown
fun resetHandler() {
      timeoutHandler?.removeCallbacks(interactionTimeoutRunnable);
      timeoutHandler?.postDelayed(interactionTimeoutRunnable, 10*1000); //for 10 second

}

 // start countdown
fun startHandler() {
    timeoutHandler?.postDelayed(interactionTimeoutRunnable, 10*1000); //for 10 second
}

1

এখানে একটি সম্পূর্ণ সমাধান রয়েছে যা কয়েক মিনিট পরে (যেমন 3 মিনিট) ব্যবহারকারীর নিষ্ক্রিয়তা পরিচালনা করে। অ্যাপটি সময় শেষ হওয়ার পরে ব্যাকগ্রাউন্ডে থাকা অবস্থায় অ্যাক্টিভিটি অগ্রভাগে লাফিয়ে ফেলার মতো সাধারণ সমস্যাগুলি সমাধান করে।

প্রথমত, আমরা একটি বেসঅ্যাক্টিভিটি তৈরি করি যা অন্যান্য সমস্ত ক্রিয়াকলাপ প্রসারিত করতে পারে।

এটি বেসঅ্যাক্টিভিটি কোড।

package com.example.timeout;

import android.app.Activity;
import android.app.Dialog;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.text.TextUtils;
import android.view.View;
import android.view.Window;
import android.widget.TextView;

import androidx.appcompat.app.AppCompatActivity;


import javax.annotation.Nullable;

public class BaseActivity extends AppCompatActivity implements LogoutListener {

    private Boolean isUserTimedOut = false;
    private static Dialog mDialog;



    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        ((TimeOutApp) getApplication()).registerSessionListener(this);
        ((TimeOutApp) getApplication()).startUserSession();

    }

    @Override
    public void onUserInteraction() {
        super.onUserInteraction();


    }

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

        if (isUserTimedOut) {
            //show TimerOut dialog
            showTimedOutWindow("Time Out!", this);

        } else {

            ((TimeOutApp) getApplication()).onUserInteracted();

        }

    }

    @Override
    public void onSessionLogout() {


        isUserTimedOut = true;

    }


    public void showTimedOutWindow(String message, Context context) {


        if (mDialog != null) {
            mDialog.dismiss();
        }
        mDialog = new Dialog(context);


        mDialog.requestWindowFeature(Window.FEATURE_NO_TITLE);
        mDialog.setContentView(R.layout.dialog_window);

        mDialog.setCancelable(false);
        mDialog.setCanceledOnTouchOutside(false);

        TextView mOkButton = (TextView) mDialog.findViewById(R.id.text_ok);
        TextView text_msg = (TextView) mDialog.findViewById(R.id.text_msg);

        if (message != null && (!TextUtils.isEmpty(message)) && (!message.equalsIgnoreCase("null"))) {
            text_msg.setText(message);

        }


        mOkButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {

                if (mDialog != null){

                    mDialog.dismiss();

                    Intent intent = new Intent(BaseActivity.this, LoginActivity.class);
                    intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
                    startActivity(intent);

                    finish();
                }


            }
        });

        if(!((Activity) context).isFinishing())
        {
            //show dialog
            mDialog.show();
        }

    }

}

এরপরে, আমরা আমাদের "লগআউট শ্রোতাদের" জন্য একটি ইন্টারফেস তৈরি করি

package com.example.timeout;

public interface LogoutListener {

    void onSessionLogout();

}

অবশেষে, আমরা একটি জাভা ক্লাস তৈরি করি যা "অ্যাপ্লিকেশন" প্রসারিত করে

package com.example.timeout;

import android.app.Application;

import java.util.Timer;
import java.util.TimerTask;

public class TimeOutApp extends Application {

    private LogoutListener listener;
    private Timer timer;
    private static final long INACTIVE_TIMEOUT = 180000; // 3 min


    public void startUserSession () {
        cancelTimer ();

        timer = new Timer ();
        timer.schedule(new TimerTask() {
            @Override
            public void run() {

                listener.onSessionLogout ();

            }
        }, INACTIVE_TIMEOUT);

    }

    private void cancelTimer () {
        if (timer !=null) timer.cancel();
    }

    public void registerSessionListener(LogoutListener listener){
        this.listener = listener;
    }

    public void onUserInteracted () {
        startUserSession();
    }


}

দ্রষ্টব্য: আপনার মেনিফেস্ট ফাইলের ভিতরে আপনার অ্যাপ্লিকেশন ট্যাগটিতে "টাইমআউট অ্যাপ" শ্রেণিটি যুক্ত করতে ভুলবেন না

<application
        android:name=".TimeOutApp">
        </application>

0

আমি মনে করি এটি শেষ অ্যাক্টিভিটি সময়ের সাথে টাইমার সংযুক্ত করে হওয়া দরকার।

সুতরাং এটি পছন্দ:

  1. অনক্রিয়েটে (বান্ডেল সেভড ইনস্ট্যান্সস্টেট) একটি টাইমার শুরু করুন, 5 মিনিট বলুন

  2. OnUserInteration () এ কেবলমাত্র বর্তমান সময় সঞ্চয় করুন

এখনও পর্যন্ত খুব সহজ।

এখন যখন টাইমার পপটি এটি করে:

  1. টাইমডেল্টা পেতে বর্তমান সময় নিন এবং সঞ্চিত ইন্টারঅ্যাকশন সময়কে বিয়োগ করুন
  2. টাইমডেল্টা যদি হয় = = 5 মিনিট, আপনি সম্পন্ন করেছেন
  3. যদি টাইমডেল্টা <5 মিনিট আবার টাইমার শুরু করে তবে এই সময়টি 5 মিনিট ব্যবহার করে - সঞ্চিত সময়। অন্য কথায়, 5 মিনিট সর্বশেষ মিথস্ক্রিয়া গঠন করে

0

আমারও একই প্রশ্ন ছিল, যেখানে আমার 1 মিনিটের জন্য ব্যবহারকারীর নিষ্ক্রিয়তা ট্র্যাক করতে হবে এবং তারপরে ক্রিয়াকলাপ শুরু করার জন্য ব্যবহারকারীকে পুনর্নির্দেশ করতে হবে, আমার ক্রিয়াকলাপের স্ট্যাকটি সাফ করার জন্যও প্রয়োজন ছিল needed

@ জিফ্রিগন উত্তরের ভিত্তিতে আমি এই সমাধানটি নিয়ে আসছি।

ActionBar.java

public abstract class ActionBar extends AppCompatActivity {

    public static final long DISCONNECT_TIMEOUT = 60000; // 1 min

    private final MyHandler mDisconnectHandler = new MyHandler(this);

    private Context mContext;


    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        mContext = this;
    }



    /*
    |--------------------------------------------------------------------------
    | Detect user inactivity in Android
    |--------------------------------------------------------------------------
    */

    // Static inner class doesn't hold an implicit reference to the outer class

    private static class MyHandler extends Handler {

        // Using a weak reference means you won't prevent garbage collection

        private final WeakReference<ActionBar> myClassWeakReference;

        public MyHandler(ActionBar actionBarInstance) {

            myClassWeakReference = new WeakReference<ActionBar>(actionBarInstance);
        }

        @Override
        public void handleMessage(Message msg) {

            ActionBar actionBar = myClassWeakReference.get();

            if (actionBar != null) {
                // ...do work here...
            }
        }
    }


    private Runnable disconnectCallback = new Runnable() {

        @Override
        public void run() {

            // Perform any required operation on disconnect

            Intent startActivity = new Intent(mContext, StartActivity.class);

            // Clear activity stack

            startActivity.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);

            startActivity(startActivity);
        }
    };

    public void resetDisconnectTimer() {

        mDisconnectHandler.removeCallbacks(disconnectCallback);
        mDisconnectHandler.postDelayed(disconnectCallback, DISCONNECT_TIMEOUT);
    }

    public void stopDisconnectTimer() {

        mDisconnectHandler.removeCallbacks(disconnectCallback);
    }

    @Override
    public void onUserInteraction(){

        resetDisconnectTimer();
    }

    @Override
    public void onResume() {

        super.onResume();
        resetDisconnectTimer();
    }

    @Override
    public void onStop() {

        super.onStop();
        stopDisconnectTimer();
    }
}

পরিপূরক সম্পদ

অ্যান্ড্রয়েড: ক্রিয়াকলাপের স্ট্যাক

এই হ্যান্ডলারের শ্রেণিটি স্থির হওয়া উচিত বা ফাঁস হতে পারে


0

AppLifecycleCallbacksঅ্যাপ্লিকেশন ক্যালাসে নিবন্ধভুক্ত করে আপনার সম্পূর্ণ অ্যাপ্লিকেশন জুড়ে (আপনার একাধিক ক্রিয়াকলাপ অনুমান করে) ধরে নেওয়া সেরা জিনিস । আপনি registerActivityLifecycleCallbacks()নিম্নলিখিত কলব্যাকগুলি সহ অ্যাপ্লিকেশন শ্রেণিতে ব্যবহার করতে পারেন (আমি একটি অ্যাপলিফাইসাইক্যালব্যাকস ক্লাস তৈরি করার পরামর্শ দিচ্ছি যা ক্রিয়াকলাপটিচাইক্যালক্যালব্যাকগুলি প্রসারিত করে):

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

0
open class SubActivity : AppCompatActivity() {
    var myRunnable:Runnable
    private var myHandler = Handler()

    init {
        myRunnable = Runnable{
            toast("time out")
            var intent = Intent(this, MainActivity::class.java)
            startActivity(intent)

        }
    }

    fun toast(text: String) {
        runOnUiThread {
            val toast = Toast.makeText(applicationContext, text, Toast.LENGTH_SHORT)
            toast.show()
        }
    }

   override fun onUserInteraction() {
        super.onUserInteraction();
        myHandler.removeCallbacks(myRunnable)
        myHandler.postDelayed(myRunnable, 3000)
    }

    override fun onPause() {
        super.onPause()
        myHandler.removeCallbacks(myRunnable)
    }

    override fun onResume() {
            super.onResume()
            myHandler.postDelayed(myRunnable, 3000)
    }
}

এর সাথে আপনার ক্রিয়াকলাপ প্রসারিত করুন

YourActivity:SubActivity(){}

মেইনএ্যাকটিভিটিতে যেতে যখন ব্যবহারকারী আপনারঅ্যাক্টিভিটিতে 3000 মিলিসেকের পরে নিষ্ক্রিয় থাকে

আমি আগের উত্তরটি ব্যবহার করে এটিকে কোটলিনে রূপান্তর করেছি।

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