I am building a native android app, where I want the user to be automatically logged out (kind of session timeout) after a period of inactivity say 5 mins.
It is a standalone app and there are multiple screens in the App. I am not maintaining any user session with a server.
P.S: I found a possible solution in writing a time out event for android. But that is suitable only for a single Activity application. Can anyone suggest a similar solution for a multi-activity app ?
Ok so in response to the link you posted, why not follow that approach but create some sort of abstract base activity, that all of your other activities extend. So essentially you are adding a timeout to each activity, but your base activity will handle this, your child activities will not need to know what is going on.
public class LogoutService extends Service {
public static CountDownTimer timer;
#Override
public void onCreate(){
// TODO Auto-generated method stub
super.onCreate();
timer = new CountDownTimer(1 *60 * 1000, 1000) {
public void onTick(long millisUntilFinished) {
//Some code
Log.v(Constants.TAG, "Service Started");
}
public void onFinish() {
Log.v(Constants.TAG, "Call Logout by Service");
// Code for Logout
stopSelf();
}
};
}
#Override
public IBinder onBind(Intent intent) {
// TODO Auto-generated method stub
return null;
}
}
And then Add the below code in every activity.
#Override
protected void onResume() {
// TODO Auto-generated method stub
super.onResume();
LogoutService.timer.start();
}
#Override
protected void onStop() {
// TODO Auto-generated method stub
super.onStop();
LogoutService.timer.cancel();
}
Related
I was wondering, how can I keep the device listening for voice commands with voice recognition while the device is asleep? The idea I have is that I would like the device to respond to my voice, even if I have the screen locked or the screen has timed out.
Is this possible? I have tried using this as a service and an interface and it stops listening once the screen locks. Can I receive any help with this? This is my class.
public class VoiceEngineService extends Activity {
private boolean isSpeakingDone = false; // default setting
private SpeechRecognizer sr = SpeechRecognizer.createSpeechRecognizer(this);
private AudioManager mAudioManager;
#Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE);
setContentView(R.layout.wait_for_speech);
// mute beep sound
mAudioManager.setStreamSolo(AudioManager.STREAM_VOICE_CALL, true);
sr.setRecognitionListener(new listener());
Intent i = new Intent(RecognizerIntent.ACTION_RECOGNIZE_SPEECH);
i.putExtra(RecognizerIntent.EXTRA_LANGUAGE_MODEL,
RecognizerIntent.LANGUAGE_MODEL_FREE_FORM); // LANGUAGE_MODEL_WEB_SEARCH
i.putExtra(RecognizerIntent.EXTRA_CALLING_PACKAGE, getApplication()
.getClass().getName());
i.putExtra(RecognizerIntent.EXTRA_MAX_RESULTS, 6);
i.putExtra(RecognizerIntent.EXTRA_PROMPT, "");
i.putExtra(RecognizerIntent.EXTRA_SPEECH_INPUT_MINIMUM_LENGTH_MILLIS, 5500);
sr.startListening(i);
}
class listener implements RecognitionListener {
#Override
public void onReadyForSpeech(Bundle params) {
// TODO Auto-generated method stub
}
#Override
public void onBeginningOfSpeech() {
// TODO Auto-generated method stub
}
#Override
public void onRmsChanged(float rmsdB) {
// TODO Auto-generated method stub
}
#Override
public void onBufferReceived(byte[] buffer) {
// TODO Auto-generated method stub
}
#Override
public void onEndOfSpeech() {
// TODO Auto-generated method stub
}
#Override
public void onError(int error) {
// TODO Auto-generated method stub
if (SharedPref.getVoiceController() == false) {
sr.cancel();
Intent i = new Intent();
sr.startListening(i);
} else {
sr.stopListening();
sr.destroy();
finish();
}
}
#Override
public void onResults(Bundle results) {
// TODO Auto-generated method stub
isSpeakingDone = true;
ArrayList<String> mDataList = results
.getStringArrayList(SpeechRecognizer.RESULTS_RECOGNITION);
Intent i = new Intent();
i.putStringArrayListExtra(RecognizerIntent.EXTRA_RESULTS, mDataList);
setResult(RESULT_OK, i);
finish();
}
#Override
public void onPartialResults(Bundle partialResults) {
// TODO Auto-generated method stub
}
#Override
public void onEvent(int eventType, Bundle params) {
// TODO Auto-generated method stub
}
} // end listener class
#Override
protected void onPause() {
if ((isSpeakingDone == false)) {
finish();
}
super.onPause();
}
#Override
protected void onStop() {
// when speaking is true finish() has already been called
if (isSpeakingDone == false) {
finish();
}
super.onStop();
}
#Override
protected void onDestroy() {
sr.stopListening();
sr.destroy();
super.onDestroy();
}
}
You have to implement your voice listener in a service. Create a class that extends 'Service' and make up some logic to take care of recording.
If you tried already the service, then it might be that you tried to redirect commands to an activity which most likely has been stopped by Android OS. Generally when talking about doing stuff when phone is in lock mode, you only can hope to accomplish tasks in one or more services coupled togethe.
When you are in Activity, of course wen the activity goes out of scope it will be shut down by Android OS. but services can still run in background unless shut dow mm explicitly by your own code or in rare cases that Android will recognize that it needs memory and processor power for other tasks.
I am developing an application that will be running in Kiosk Mode. In this application, if the user didn't do anything in the application within 5 minutes, the application will show a screen saver that is the logo of the application.
My question is, how can I code on detecting IDLE within 5 minutes?
A BETTER SOLUTION HERE...... VERY SIMPLE
I used countdown timer as bellow:
private long startTime = 15 * 60 * 1000; // 15 MINS IDLE TIME
private final long interval = 1 * 1000;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
countDownTimer = new MyCountDownTimer(startTime, interval);
}
#Override
public void onUserInteraction(){
super.onUserInteraction();
//Reset the timer on user interaction...
countDownTimer.cancel();
countDownTimer.start();
}
public class MyCountDownTimer extends CountDownTimer {
public MyCountDownTimer(long startTime, long interval) {
super(startTime, interval);
}
#Override
public void onFinish() {
//DO WHATEVER YOU WANT HERE
}
#Override
public void onTick(long millisUntilFinished) {
}
}
CHEERS..........:)
You should try this, It will Notify with a toast on detecting IDLE 5 minutes.
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 Idle 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);
}
I think you could use http://developer.android.com/reference/android/app/Activity.html#dispatchTouchEvent(android.view.MotionEvent) and http://developer.android.com/reference/android/app/Activity.html#dispatchKeyEvent(android.view.KeyEvent) in your App to set a timestamp everytime a userinteraction takes place (simply override the methods and return false at the end so that the events will be propagated to underlying views) - then you can use some kind of timer which checks for the last timestamp of interaction recurringly and trigger your screen saver if your 5 minutes IDLE time are reached.
So in an Activity you simply override the before mentioned Methods like this:
#Override
public boolean dispatchTouchEvent (MotionEvent ev) {
timestamp = System.getCurrentTimeMilis();
return false; // return false to indicate that the event hasn't been handled yet
}
The dispatchKeyEvent and the other methods which you can override to determine user-activity should work fairly similar.
If you're using more than one Activity you may want to create a base class which extends Activity and Override all the dispatchXXXEvent you want to handle and which you than use as base class of all your Activities. But I guess the details of your implementation may be a little bit out of scope for the actual question :)
For the different possibilities of timers you may find useful info here: Scheduling recurring task in Android
try with:
private void startCount(int time) {
new Handler().postDelayed(new Runnable() {
#Override
public void run() {
// Add here the code for showing the fullscreenlogo
}
}, time);
}
then, whenever you want to start the count you should add:
startCount(time); // Replace time with 60*5*1000 for 5 mins
if you want to start the count when the app got minimized, then use this:
#Override
public void onPause() {
super.onPause();
startCount(time);
}
I have implemented Twilio thrid party SDK for making outgoing calls in android. When i make a call when the number is switched off or refused the call gets disconnected after some time automatically i have been trying to fetch this event.To fetch this event i tried implementing The ConnectionListener interface and has override all the method but when the call gets disconnected or connected i was not able to get any logs printed. After implementing the ConnectionListener i have implemented the following method in my code.
#Override
public void onConnected(Connection arg0) {
// TODO Auto-generated method stub
Log.i("test", "onconnected");
}
#Override
public void onConnecting(Connection arg0) {
// TODO Auto-generated method stub
Log.i("test", "onconnecting");
}
#Override
public void onDisconnected(Connection arg0) {
// TODO Auto-generated method stub
Log.i("test", "onDisconnected");
}
#Override
public void onDisconnected(Connection arg0, int arg1, String arg2) {
// TODO Auto-generated method stub
Log.i("test", "onDisconnected");
}
Can anyone help me on this issue. Thank in advance.
check if you have callbacks to notify your app of outgoing connections.
you should have something like this:
connection = device.connect(params, this);
Just implementing the override functions of Connection listener is not sufficient.
But you need to set the listener to the connection. Like
either
connection = device.connect(parameters, this /* ConnectionListener */);
or
connection.setConnectionListener(this /*ConnectionListener */);
Hope this helps...
In my project I am using binder mechanism to communicate to remote service. The remote service class will call JNI function and updates to UI for every 10 seconds. The JNI function has below code
static int n = 100;
return ++n;
This JNI function calling in Service class and updating to UI like below
public class MyService extends Service{
private static final String TAG = "MyService";
private final Handler serviceHandler = new Handler();
#Override
public void onCreate() {
// TODO Auto-generated method stub
super.onCreate();
System.out.println("inside service onCreate");
Log.d(TAG, "entered onStart");
serviceHandler.removeCallbacks(sendUpdatesToUI);
serviceHandler.postDelayed(sendUpdatesToUI, 1000); // 1 second
}
1. private IMyService.Stub bioStub = new IMyService.Stub() {
2.
3. #Override
4. public int intFromJNI() throws RemoteException {
5. // TODO Auto-generated method stub
6. int libData = Abcd.intFromJNI();
7. System.out.println("inside ****** stub"+libData);
8. return libData;
}
};
#Override
public IBinder onBind(Intent arg0) {
// TODO Auto-generated method stub
System.out.println("inside binder ");
return bioStub;
}
private Runnable sendUpdatesToUI = new Runnable() {
public void run() {
Log.d(TAG, "entered Runnable");
try {
bioStub.intFromJNI();
serviceHandler.postDelayed(this, 10000);
} catch (RemoteException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
};
}
This service class is calling in Activty
#Override
protected void onResume() {
// TODO Auto-generated method stub
super.onResume();
Intent serviceIntent=new Intent();
serviceIntent.setClass(context, MyService.class);
boolean ok=bindService(serviceIntent, mServiceConnection , Context.BIND_AUTO_CREATE);
Log.v("ok", String.valueOf(ok));
}
private ServiceConnection mServiceConnection=new ServiceConnection(){
#Override
public void onServiceConnected(ComponentName arg0, IBinder service) {
// TODO Auto-generated method stub
System.out.println("inside ServiceConnection");
myService = IMyService.Stub.asInterface(service);
try {
Log.d("Client", "entered mServiceConnection");
8. int jniValue = myService.intFromJNI();
9. System.out.println("value if JNI==>"+jniValue);
10.
} catch (RemoteException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
#Override
public void onServiceDisconnected(ComponentName arg0) {
// TODO Auto-generated method stub
}
};
Here my problem is, The service class is not updating UI for every 10 seconds and the value is not incremeting in UI but the value is incrementing for every 10 seconds in service class i.e the print statement below is updating for every 10 seconds which is in line Number 7 in above code(Service).
System.out.println("inside ****** stub"+libData);
But I want to it update in UI also. i.e the statement line num 10.
System.out.println("value if JNI==>"+jniValue);
I`t is not happening in my code . How to solve this one .`
You are missing any way for the Service to tell the Activity about new events. The call from the Activity to the Service, intFromJNI, is a one-off function call which happens just once - it has no ongoing responsibility for telling the UI about changes in future.
You should add some listener class. For example, add IMyServiceListener.aidl with something like this:
package com.something;
interface IMyServiceListener {
void valueUpdated(int newValue);
}
And then in IMyService.aidl add this:
import com.something.IMyServiceListener;
void addListener(in IMyServiceListener newListener);
Then, within your IMyService.Stub class you will need to implement addListener - you should add the resulting object to some array of listeners, and call valueUpdated on each listener, each time the value changes.
Within the activity, you should call myService.addListener and pass in some object which receives notification of the changes. You can then display that on the UI within the activity.
This question already has answers here:
Execute AsyncTask several times
(5 answers)
Closed 9 years ago.
I am new to Android and am now working on the counter thing using the AsyncTask.
So the thing is I'm having one button and with that button OnClickListener.
button.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
boolean check;
check=check_button_status();
if(check==true){
rec_forward_task.execute();
}
else
{
rec_forward_task.cancel();
}
}
});
So here the rec_forward_task is the class that extends the AsyncTask. The AsyncTask class is here.
//
private class CounterForwardTask extends AsyncTask<Void, Integer, Integer>
{
TextView record_counter_display;
int rec_counter,count;
int last_value;
#Override
protected void onPreExecute() {
// TODO Auto-generated method stub
record_counter_display=(TextView) findViewById(R.id.rec_voice_counter);
rec_counter=0;
record_counter_display.setText(String.valueOf(rec_counter));
count=0;
}
public void cancel() {
// TODO Auto-generated method stub
onCancelled();
}
#Override
protected Integer doInBackground(Void... params) {
// TODO Auto-generated method stub
while(rec_status)
{
publishProgress(count);
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
last_value=count;
count=count+1;
}
return 1;
}
#Override
protected void onCancelled() {
// TODO Auto-generated method stub
record_counter_display.setText(String.valueOf(0));
}
#Override
protected void onProgressUpdate(Integer... values) {
// TODO Auto-generated method stub
runOnUiThread(new Runnable() {
#Override
public void run() {
// TODO Auto-generated method stub
record_counter_display.setText(String.valueOf(count));
}
});
}
#Override
protected void onPostExecute(Integer result) {
// TODO Auto-generated method stub
record_counter_display.setText(String.valueOf(last_value));
}
}
I'm making the object for that class in the oncreate method only so now the question is.
When user press first time the counter is starting and displaying in the textview and again pressing that same button the counter progress is stop due to oncancel method is called.but if user again pressing the same button app force closing and exception that u can't start the task which is already started.so what will be the way to perform this kind of operation.Thanks for any reply.
if(check==true){
rec_forward_task = new CounterForwardTask();
rec_forward_task.execute();
}
else
{
rec_forward_task.cancel();
}
Instead of instantiating AsyncTask in onCreate instaniate it when you need to start it. Hope this helps.
You will have to create a new AsyncTask object.
AsyncTasks are meant to run only once.
Check this answer.
The async task is designed to run only once. But you can run it by creating new instances of the asynctask class. See the answer of Passionate Androiden
Threading rules
There are a few threading rules that must be followed for this class to work properly:
The AsyncTask class must be loaded on the UI thread. This is done automatically as of JELLY_BEAN.
The task instance must be created on the UI thread.
execute(Params...) must be invoked on the UI thread.
Do not call onPreExecute(), onPostExecute(Result), doInBackground(Params...), onProgressUpdate(Progress...) manually.
The task can be executed only once (an exception will be thrown if a second execution is attempted.)
pls findout more in Developer site