0

Halo, the first i want to know the idle time at my android application. after that, i will do something if it is a idle time mode.

I follow this link. Application idle time

my program work properly, but suddenly the problem show up. I can't move to the other page (for example to the login page) or pop up a message using alertdialog because its in a thread. Do you have any solutions?

public class ControlActivity extends Activity {
private static final String TAG=ControlActivity.class.getName();

/**
 * Gets reference to global Application
 * @return must always be type of ControlApplication! See AndroidManifest.xml
 */
public ControlApplication getApp()
{
    return (ControlApplication )this.getApplication();
}

@Override
public void onUserInteraction()
{
    super.onUserInteraction();
    getApp().touch();
    Log.d(TAG, "User interaction to "+this.toString());

}

/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
}}

here is my ControlApplication.java

public class ControlApplication extends Application {
private static final String TAG=ControlApplication.class.getName();
private Waiter waiter;
@Override
public void onCreate() {
    super.onCreate();
    Log.d(TAG, "Starting application"+this.toString());
    //setContentView(R.layout.activity_main);
    waiter=new Waiter(5*60*1000); //5 mins
    waiter.start();
    Toast.makeText(ControlApplication.this, "start", Toast.LENGTH_LONG).show();
}

public void touch()
{
    waiter.touch();
    Toast.makeText(ControlApplication.this, "touch", Toast.LENGTH_LONG).show();
}   }

here is the Waiter.java

public class Waiter extends Thread implements Runnable{
private static final String TAG=Waiter.class.getName();
private long lastUsed;
private long period;
private boolean stop;
Context activity;

public Waiter(long period)
{
    this.period=period;
    stop=false;
}

@SuppressLint("ParserError")
public void run()
{
    long idle=0; 
    this.touch();
    do
    {
        idle=System.currentTimeMillis()-lastUsed;
        Log.d(TAG, "Application is idle for "+idle +" ms");
        try
        {
            Thread.sleep(5000); //check every 5 seconds
        }
        catch (InterruptedException e)
        {
            Log.d(TAG, "Waiter interrupted!");
        }
        if(idle > period)
        {
            idle=0;
            //do something here - e.g. call popup or so
            //Toast.makeText(activity, "Hello", Toast.LENGTH_LONG).show();
            stopCounter();
        }
    }
    while(!stop);

    Log.d(TAG, "Finishing Waiter thread");
}

public synchronized void touch()
{
    lastUsed=System.currentTimeMillis();
}

public synchronized void forceInterrupt()
{
    this.interrupt();
}

//soft stopping of thread
public synchronized void stopCounter()
{
    stop=true;
}

public synchronized void setPeriod(long period)
{
    this.period=period;
}}

I tried to create a new class and call a method to intent. Its also fail. tried to pop up a message from that method its also fail.

do you guys have any other solutions for idle time? thanks.

Regards, Alfred Angkasa

Community
  • 1
  • 1
Alfred Angkasa
  • 1,381
  • 3
  • 17
  • 35

2 Answers2

1

In you active activity, instead of this thread, do:

public class Graph extends Activity {
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
                while(idle = 0) {
                    idle = System.currentTimeMillis()-lastUsed;

                    if(idle != period) {
                        Intent goNextActivity = new Intent(com.package.theactivity);
                    else {
                        idle == 0;
                    }
                }
             }
           }
Henry
  • 486
  • 1
  • 5
  • 16
1

I just found by myself the answer by search on google and try for 5 hours.. :D

I hope my answer will help you too.

First, I mix the ControlApplication and Waiter with ControlActivity. Thats mean I don't need both files. My ControlActivity will extends the activity (its use for me to intent to the other page if in idle mode), and i will implements runnable(its use for me to run the thread).

after that i have a method called onUserInteraction(), this method help me to get the user interaction, whenever the user touch or click something. in the onCreate, i initiate all the variable including lastUsed, period, and stop.

why should I initiate that? because you need to know how many seconds to know that your apps is on idle mode or not. that was period use. Stop variable is use for me to iterate and searching every 5 seconds(you can also make it every second to check idle or not) my apps is idle or not. I initiate lastUsed by calling method touch. I copied touch method from ControlApplication into my ControlActivity. By calling touch method, I can know when is my lastused. After that I start my thread.

in my run method, i set idle = 0. and do some looping to check. i check every 5 seconds to know my apps is on idle mode or not. idle = System.System.currentTimeMillis()-lastUsed -> i used this to know if the idle is already suite with the period or not using if method. if the idle is greater than period, my apps must be in idle mode. after that i stop the iteration and using handler to manage it.

i set handler.sendEmptyMessage(0), and create Handler. At handler i move to the other page. this is my full code.

public class MainActivity extends Activity implements Runnable {
private static final String TAG= MainActivity.class.getName();
private long lastUsed;
private int period;
private boolean stop;

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    period = 10000;
    stop=false;
    touch();
    Thread currentThread = new Thread(this);
    currentThread.start();
    Toast.makeText(getApplicationContext(), "Start", Toast.LENGTH_SHORT).show();
}

@Override
public boolean onCreateOptionsMenu(Menu menu) {
    getMenuInflater().inflate(R.menu.activity_main, menu);
    return true;
}

@Override
public void onUserInteraction()
{
    super.onUserInteraction();
    touch();
    Log.d(TAG, "User interaction to "+this.toString());
}

public synchronized void touch()
{
    lastUsed=System.currentTimeMillis();
    Toast.makeText(getApplicationContext(), "touch", Toast.LENGTH_SHORT).show();
}

public void moveIntent() {
    Intent intent = new Intent(this, AfterIdle.class);
    startActivity(intent);
}

public void validate(View view) {
    switch (view.getId()) {
        case R.id.button1 :
            Intent intent = new Intent(this, AfterIdle.class);
            startActivity(intent);
            break;
    }
}

@Override
public void run() {
    // TODO Auto-generated method stub
    long idle;

    while (!stop) {
        idle=System.currentTimeMillis()-lastUsed;
        try
        {
            Thread.sleep(5000); //check every 5 seconds
        }
        catch (InterruptedException e)
        {
            Log.d(TAG, "Waiter interrupted!");
        }
        if (idle > period) {
            idle = 0;
            stop = true;
        }
    }
    handler.sendEmptyMessage(0);
}

public Handler handler = new Handler() {
    @Override
    public void handleMessage(Message msg) {
        moveIntent();
    }
};}

I hope this code will help another people if they have the same problem that i faced last time. I wish someone would correct the answer for me if my answer is wrong. thanks.

Regards, Alfred Angkasa

Alfred Angkasa
  • 1,381
  • 3
  • 17
  • 35