我在AccountActivity.class
设置了一个计时器,以确保用户不按下主页按钮,否则将开始倒计时以退出用户或用户锁定他的屏幕。
但是由于onPause
方法,我现在面临一个问题。当我的用户点击调用getaccounttask()
方法的按钮并将其用户重定向到AccountInformationActivity.class
时,onPause
方法也会被激活并且计时器开始倒计时。
是否有任何解决方案可以阻止onPause
方法倒计时或在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 :(得分:0)
嗯,您选择的实施架构可以改进。我稍后会谈到这个。首先应用此快速修复程序来修复您的体系结构。
显然,当您使用主屏幕离开Timer
时,您想要启动Activity
。但是,使用Activity
切换为Intent
,用户也可以退出AccountActivity
。这可以跟踪。所以保留一个像shouldNavigate
这样的布尔标志,最初它应该是false
。在onResume
时,应将其设置为false
,但当getcounttask
转到onPostExecute
时,应将其设置为true
。因此,在onPause
中,如果您通过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
类。
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);
当转到onPause
时会做
Singleton.getInstance().activityMap.remove(tag, this);
因此,当服务发现Singleton.getInstance().activityMap
的大小为零时,前景中显然没有活动,因此它启动了一个计时器。当计时器到期时再次检查计数是否仍为零,如果为零,则执行注销。
答案 1 :(得分: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;
}