2016-08-24 2 views
1

Я установил таймер на AccountActivity.class, чтобы гарантировать, что пользователь не нажимает кнопку «домой», если не начнет обратный отсчет, чтобы выйти из системы, или если пользователь заблокирует его экран.Таймер не останавливается на старой активности

Но теперь я столкнулся с проблемой из-за метода . Когда мой пользователь нажимает кнопку, которая вызывает метод getaccounttask(), и он перенаправляет моего пользователя на AccountInformationActivity.class, также активируется метод , и таймер начинает обратный отсчет.

Есть ли какое-либо решение, чтобы предотвратить метод от отсчета или таймер, который будет отменен на моем AccountInformationActivity.class?

Я попытался сделать отмена таймера до того, как начнется мое намерение, но все еще не работает.

Я пробовал использовать обработчик, но столкнулся с той же проблемой, я все еще пытаюсь понять, как работает Android, поэтому ваша помощь или решение глубоко оценены.

public class AccountActivity extends AppCompatActivity { 

    private Timer timer; 

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

    private class getaccounttask extends AsyncTask<String, Void, String> 
    { 
     @Override 
     protected String doInBackground(String... urlaccount) 
     { 
     StringBuilder result = new StringBuilder(); 
     try 
     { 
      //My Codes 
     } 
     catch (Exception e) 
     { 
      e.printStackTrace(); 
     } 
     return result.toString(); 
     } 

     @Override 
     protected void onPostExecute(String result) 
     { 
     Intent intent = new Intent(); 
     intent.setClass(getApplicationContext(), AccountInformationActivity.class); 
     startActivity(intent); 
     } 
    } 

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

     timer = new Timer(); 
     Log.i("Main", "Invoking logout timer"); 
     LogOutTimerTask logoutTimeTask = new LogOutTimerTask(); 
     timer.schedule(logoutTimeTask, 300000); //auto logout in 5 minutes 
    } 

    @Override 
    protected void onResume() { 
     super.onResume(); 
     if (timer != null) { 
      timer.cancel(); 
      Log.i("Main", "cancel timer"); 
      timer = null; 
     } 
    } 

    private class LogOutTimerTask extends TimerTask { 

     @Override 
     public void run() { 

      //redirect user to login screen 
      Intent i = new Intent(AccountActivity.this, MainActivity.class); 
      i.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); 
      startActivity(i); 
      finish(); 
     } 
    } 
} 

ответ

0

Ну, архитектура реализации, которую вы выбрали, может быть улучшена. Я приду к этому позже. Сначала примените это быстрое исправление, чтобы исправить вашу архитектуру.

Очевидно, что вы хотите начать Timer, когда вы выходите из Activity с помощью домашнего экрана. Но пользователь может также выйти из Activity, используя Intent, чтобы переключиться на AccountActivity. Это можно отслеживать. Поэтому держите булевский флаг как shouldNavigate, изначально он должен быть false. когда onResume, он должен быть установлен в false, но когда getcounttask идет в onPostExecute, он должен быть установлен в true. Итак, в , если вы идете через getcounttask, shouldNavigate будет true, а если есть true, отмените свой таймер еще, запустите свой Timer.

Код:

public class AccountActivity extends AppCompatActivity { 

    private Timer timer; 
    private volatile boolean shouldNavigate = false; 

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

    private class getaccounttask extends AsyncTask<String, Void, String> 
    { 
     @Override 
     protected String doInBackground(String... urlaccount) 
     { 
     StringBuilder result = new StringBuilder(); 
     try 
     { 
      //My Codes 
     } 
     catch (Exception e) 
     { 
      e.printStackTrace(); 
     } 
     return result.toString(); 
     } 

     @Override 
     protected void onPostExecute(String result) 
     { 
     shouldNavigate = true; 
     Intent intent = new Intent(); 
     intent.setClass(getApplicationContext(), AccountInformationActivity.class); 
     startActivity(intent); 
     } 
    } 

    @Override 
    protected void onPause() { 
     super.onPause(); 
     if (!shouldNavigate){ 
      timer = new Timer(); 
      Log.i("Main", "Invoking logout timer"); 
      LogOutTimerTask logoutTimeTask = new LogOutTimerTask(); 
      timer.schedule(logoutTimeTask, 300000); 
     }else{ 
      if (timer != null){ 
        timer.cancel(); 
        timer = null; 
      } 
     } 
    } 

    @Override 
    protected void onResume() { 
     super.onResume(); 
     shouldNavigate = false; 
     if (timer != null) { 
      timer.cancel(); 
      Log.i("Main", "cancel timer"); 
      timer = null; 
     } 
    } 

    private class LogOutTimerTask extends TimerTask { 

     @Override 
     public void run() { 

      //redirect user to login screen 
      shouldNavigate = false; 
      Intent i = new Intent(AccountActivity.this, MainActivity.class); 
      i.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); 
      startActivity(i); 
      finish(); 
     } 
    } 
} 

Теперь лучший подход можно сохранить Service и Singleton класс. одноэлементных класс был бы

public Singleton{ 
    private static Singleton instance = null; 
    private Singleton(){ 
     activityMap = new HashMap<String, Activity>(); 
    } 

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

    public HashMap<String, Activity> activityMap; 

} 

Теперь каждое действие будет иметь метку (например, его имя), поэтому каждое действие, когда резюме будет делать

Singleton.getInstance().activityMap.put(tag, this); 

и когда идет в будет делать

Singleton.getInstance().activityMap.remove(tag, this); 

Итак, когда служба обнаруживает, что размер Singleton.getInstance().activityMap равен нулю, то, очевидно, на переднем плане нет активности, поэтому он запускает таймер. когда таймер снова истечет, если счетчик все равно равен нулю, если нуль затем выполнит выход из системы.

+0

Привет, Я тоже пытался обработчик, но я застрял в той же проблеме. Для части отслеживания shouldNavigate я все еще не совсем уверен, поскольку я все еще новичок в Android и Java, если бы вы могли предоставить некоторые коды, это будет потрясающе и поможет мне понять – iOSAndroid

+0

, пожалуйста, проверьте правильность, и исправьте исправить в соответствии с ваша потребность. –

+1

OMG..Наконец это сработало! Большое спасибо! Я застрял в этом вопросе как недели! Еще раз спасибо за все! – iOSAndroid

0

Я думаю, вы путаете onPause() и onResume() в жизненном цикле деятельности. enter image description here

В вашем случае, вы можете переключиться, что вы делаете в OnPause() в onResume()

@Override 
    protected void onPause() { 
     super.onPause(); 
     if (timer != null) { 
      timer.cancel(); 
      Log.i("Main", "cancel timer"); 
      timer = null; 
     } 

    } 

    @Override 
    protected void onResume() { 
     super.onResume(); 
     timer = new Timer(); 
     Log.i("Main", "Invoking logout timer"); 
     LogOutTimerTask logoutTimeTask = new LogOutTimerTask(); 
     timer.schedule(logoutTimeTask, 300000); //auto logout in 5 minutes 
    } 

Надеются, что это поможет!

+0

Привет, но (поправьте меня, если я ошибаюсь) OnPause только начинается, когда я фоне активности (например, я нажимаю домашняя кнопка), которая запустит таймер. и onResume, когда я возвращаюсь к активности, не так ли? Зачем вам начинать обратный отсчет, когда пользователь уже находится в этом мероприятии? Я пытаюсь достичь чего-то вроде таймаута, если пользователь больше не находится в моем приложении, и пользователь забыл выйти из системы. – iOSAndroid

+0

onResume() вызывается при запуске экрана или при повторном запуске экрана. Пример, когда вы нажимаете кнопку «Домой», и приложение не полностью закрыто. После того, как вы снова запустите приложение, оно вызовет onResume() В обратном случае onPause() рассматривает как состояние закрытия, это означает, что вы закрываете экран или запускаете новый экран. –

+0

Да, но тогда зачем вы ссылаетесь на обратный отсчет, когда пользователь находится в приложении? когда пользователь находится на экране? Если это так, то у пользователя будет только 5 минут на этом конкретном экране, и если пользователь нажимает кнопку «домой», он никогда не выведет пользователя из системы. Поскольку я пытаюсь достичь чего-то, что, когда пользователь нажимает кнопку «домой» и упускает выход из приложения, тайм-аут будет выходить из системы для пользователя. – iOSAndroid

0

сделать некоторые изменения в onPause() и добавить это разрешение

<uses-permission android:name="android.permission.GET_TASKS" />

@Override 
    protected void onPause() { 
     if (isApplicationSentToBackground(this)) { 
      // Do what you want to do on detecting Home Key being Pressed 
      timer = new Timer(); 
      Log.i("Main", "Invoking logout timer"); 
      LogOutTimerTask logoutTimeTask = new LogOutTimerTask(); 
      timer.schedule(logoutTimeTask, 300000); //auto logout in 5 minutes 
      Log.i("Main", "Invoking Home Key pressed"); 
     } 
     super.onPause(); 

    } 

    public boolean isApplicationSentToBackground(final Context context) { 
     ActivityManager am = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE); 
     List<ActivityManager.RunningTaskInfo> tasks = am.getRunningTasks(1); 
     if (!tasks.isEmpty()) { 
      ComponentName topActivity = tasks.get(0).topActivity; 
      if (!topActivity.getPackageName().equals(context.getPackageName())) { 
       return true; 
      } 
     } 
     return false; 
    } 
+0

Попробуйте это. –

 Смежные вопросы

  • Нет связанных вопросов^_^