I have little problem with overlap of time in ProgressBar. I have list card. When click this item show activity with display detail Card show progress bar with counts down the time. When time is over, Counts again. When add next Card and click this card show time previous Card. I don't idea why new Card
has the same time as old Card.
ProgressBarService.class
public class ProgressBarService extends IntentService {
private int interval;
public static final String KEY_EXTRA_PROGRESS = "progress";
public ProgressBarService() {
super(ProgressBarService.class.getSimpleName());
}
#Override
protected void onHandleIntent(Intent intent) {
Intent broadcastIntent = new Intent();
broadcastIntent.setAction(ProgressBarService.KEY_EXTRA_PROGRESS);
if (intent != null) {
interval = intent.getIntExtra("interval", 0);
for (int i = interval; i >= 0; i--) {
broadcastIntent.putExtra("progress", i);
sendBroadcast(broadcastIntent);
SystemClock.sleep(1000);
}
}
}
}
CardDeatlisActitvty.class
public class CardDetailsActivity extends AppCompatActivity {
private Intent service;
private ResponseReceiver receiver = new ResponseReceiver();
private ProgressBar progressBar;
private TextView secondTimeTextView;
private int interval;
public class ResponseReceiver extends BroadcastReceiver {
// on broadcast received
#Override
public void onReceive(Context context, Intent intent) {
// Check action name.
if (intent.getAction().equals(ProgressBarService.KEY_EXTRA_PROGRESS)) {
int value = intent.getIntExtra("progress", 0);
new ShowProgressBarTask().execute(value);
}
}
}
class ShowProgressBarTask extends AsyncTask<Integer, Integer, Integer> {
#Override
protected Integer doInBackground(Integer... args) {
return args[0];
}
#Override
protected void onPostExecute(Integer result) {
super.onPostExecute(result);
progressBar.setProgress(result);
secondTimeTextView.setText(" " + result + " ");
if (result == 0) {
service = new Intent(CardDetailsActivity.this, ProgressBarService.class);
service.putExtra("interval", interval);
startService(service);
}
}
}
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
getWindow().setFlags(WindowManager.LayoutParams.FLAG_SECURE,
WindowManager.LayoutParams.FLAG_SECURE);
setContentView(R.layout.activity_card_details);
Bundle extras = getIntent().getExtras();
if (extras != null) {
intervalTotpEncrypt = extras.getString("intervalTotp");
}
interval = Integer.parseInt(intervalTotpDecrypt);
progressBar.setMax(interval);
progressBar.setProgress(interval);
service = new Intent(this, ProgressBarService.class);
service.putExtra("interval", interval);
startService(service);
}
#Override
protected void onResume() {
super.onResume();
registerReceiver(receiver, new IntentFilter(
ProgressBarService.KEY_EXTRA_PROGRESS));
}
#Override
protected void onDestroy() {
super.onDestroy();
unregisterReceiver(receiver);
}
}
Your ProgressBarService doesn't know that the "Card" CardDetailsActivity was changed. If for (int i = interval; i >= 0; i--) {...} loop doesn't run out and if (result == 0) { } is not true then it will behave as you described becouse ProgressBarService counter still counts.
#Override
protected void onPause() {
// notify ProgressBarService that the card will be changed (reset the counter)
}
Mind that when you call CardDetailsActivity for the second time (next card) onCreate() could be not called.
Related
I am trying to show a waiting screen in my app while it's trying to connect my server. For some reason, the screen shows only in the middle of the while loop and sometimes even after the while loop has done its work. Also, even after the while loop gets to its end the code after it doesn't executed (it doesn't print the values). Does anyone know how to fix it?
This is the code:
public class LoadingActivity extends AppCompatActivity {
public static final long SEC_IN_MS = 1000;
public static final int CONNECT_LOOP_TIME = 5; //In seconds
DataSender dataSender = new DataSender();
DataCenter dataCenter = DataCenter.getInstance();
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_loading);
dataSender.execute();
dataCenter.connect();
}
#Override
protected void onResume() {
super.onResume();
moveToMenu();
}
public void moveToMenu() {
long loopStartTime = System.currentTimeMillis();
boolean didConnect = false;
while(!didConnect &&
System.currentTimeMillis()-loopStartTime <= SEC_IN_MS*CONNECT_LOOP_TIME) {
//Wait until connected or 5 seconds pass
System.out.println(System.currentTimeMillis()-loopStartTime);
if(dataCenter.getRespond().equals(dataCenter.okMsg())) {
didConnect = true;
}
}
System.out.println("111111111111111111");
System.out.println(didConnect);
if(didConnect) {
Intent nextIntent = new Intent(this, MenuActivity.class);
startActivity(nextIntent);
}
else {
System.out.println("OOPS");
}
}
}
I am Trying to Implement a service where when I a select a time, the timer starts and runs in the background. the thing is working fine. but when I select another time, the timer overlaps on one another. I want my app to work in such a way that different services should run for different time. also, when I kill the app and reopen it, I get the remaining time in all the services.
however my data is coming from a web service and this web service contains a field with time. when I click the time, the above concept should start.
I have implemented my code as,
BroadCastService.java
public class BroadCastService extends Service {
private long totalTimeCountInMilliseconds;
private long timeBlinkInMilliseconds;
private CountDownTimer countDownTimer;
private boolean blink;
String getTime;
public static final String COUNTDOWN_BR = "project.uop.assignment8";
Intent bi = new Intent(COUNTDOWN_BR);
public BroadCastService() {
}
#Override
public IBinder onBind(Intent intent) {
// TODO: Return the communication channel to the service.
throw new UnsupportedOperationException("Not yet implemented");
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
//return super.onStartCommand(intent, flags, startId);
getTime = intent.getStringExtra("time");
setTimer();
startTimer();
Log.i("madhura","madhura");
return START_STICKY;
}
#Override
public void onCreate() {
super.onCreate();
}
private void setTimer() {
int time = 0;
//if (getTime.equals("")) {
time = Integer.parseInt(getTime);
// } else
/* Toast.makeText(BroadCastService.this, "Please Enter Minutes...",
Toast.LENGTH_LONG).show();*/
totalTimeCountInMilliseconds = 60 * time * 1000;
timeBlinkInMilliseconds = 30 * 1000;
}
private void startTimer() {
countDownTimer = new CountDownTimer(totalTimeCountInMilliseconds, 500) {
#Override
public void onTick(long leftTimeInMilliseconds) {
long seconds = leftTimeInMilliseconds / 1000;
if (leftTimeInMilliseconds < timeBlinkInMilliseconds) {
if (blink) {
// mTextField.setVisibility(View.VISIBLE);
// if blink is true, textview will be visible
} else {
// mTextField.setVisibility(View.INVISIBLE);
}
blink = !blink;
}
String a = String.format("%02d", seconds / 60) + ":" + String.format("%02d", seconds % 60);
bi.putExtra("countdown", a);
sendBroadcast(bi);
}
#Override
public void onFinish() {
Toast.makeText(BroadCastService.this, "Finished", Toast.LENGTH_SHORT).show();
}
}.start();
}
}
and my TimerActivity.class
public class TimerActivity extends AppCompatActivity {
TextView mTextField;
TextView hotel;
private long totalTimeCountInMilliseconds;
private long timeBlinkInMilliseconds;
private CountDownTimer countDownTimer;
private boolean blink;
String getTime;
SessionManager sessionManager;
Toolbar toolbar;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_timer);
InitializeToolbar();
Intent in = getIntent();
getTime = in.getStringExtra("time");
Intent intent = new Intent(this,BroadCastService.class);
intent.putExtra("time",getTime);
this.startService(intent);
sessionManager = new SessionManager(this);
hotel = findViewById(R.id.textView);
hotel.setText(sessionManager.getUserName());
Log.i("started", "Started service");
mTextField = findViewById(R.id.timer);
}
public void InitializeToolbar(){
toolbar = findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
getSupportActionBar().setDisplayShowHomeEnabled(true);
getSupportActionBar().setTitle("Order Notification");
}
private BroadcastReceiver br = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
updateGUI(intent); // or whatever method used to update your GUI fields
}
};
#Override
public void onResume() {
super.onResume();
registerReceiver(br, new IntentFilter(BroadCastService.COUNTDOWN_BR));
Log.i("efgh", "Registered broacast receiver");
}
#Override
public void onPause() {
super.onPause();
unregisterReceiver(br);
Log.i("abcd", "Unregistered broadcast receiver");
}
#Override
public void onStop() {
try {
unregisterReceiver(br);
} catch (Exception e) {
// Receiver was probably already stopped in onPause()
}
super.onStop();
}
#Override
public void onDestroy() {
stopService(new Intent(this, BroadCastService.class));
Log.i("Stopped", "Stopped service");
super.onDestroy();
}
private void updateGUI(Intent intent) {
if (intent.getExtras() != null) {
String millisUntilFinished = intent.getStringExtra("countdown");
mTextField.setText(millisUntilFinished);
}
}
}
thanks in advance.
Use Handler and #Overide its method Handler#handleMessage(Message msg)
See this: https://gist.github.com/mjohnsullivan/403149218ecb480e7759
I managed to start a conference call cut it closes right after I start it with HUNG_UP cause and I got this in my log:
11-03 17:28:08.940: E/sinch-android-rtc(19101): peermediaconnection: virtual void rebrtc::SetSDPObserver::OnFailure(const string&)Failed to set remote answer sdp: Offer and answer descriptions m-lines are not matching. Rejecting answer.
11-03 17:28:08.940: E/sinch-android-rtc(19101): mxp: Failed to set remote answer sdp: Offer and answer descriptions m-lines are not matching. Rejecting answer.
can anybody help me solve this please?
Edit:
my scenario is when a user clicks the call button I ask him if he wants to start a new call or join an already created one.
I managed to make my code from this question (Sinch conference call error) work as my GroupService class had some bugs.
I start my call like this:
Intent intent1 = new Intent(CreateGroupCallActivity.this,SinchClientService.class);
intent1.setAction(SinchClientService.ACTION_GROUP_CALL);
String id = String.valueOf(uid) + "-" + call_id.getText().toString();
intent1.putExtra(SinchClientService.INTENT_EXTRA_ID,id);
startService(intent1);
and in my SinchClientService:
if(intent.getAction().equals(ACTION_GROUP_CALL))
{
String id = intent.getStringExtra(INTENT_EXTRA_ID);
if(id != null)
groupCall(id);
}
public void groupCall(String id) {
if (mCallClient != null) {
Call call = mCallClient.callConference(id);
CurrentCall.currentCall = call;
Log.d("call", "entered");
Intent intent = new Intent(this, GroupCallService.class);
startService(intent);
}
}
nd here is my GroupCallService
public class GroupCallScreenActivity extends AppCompatActivity implements ServiceConnection {
private SinchClientService.MessageServiceInterface mMessageService;
private GroupCallService.GroupCallServiceInterface mCallService;
private UpdateReceiver mUpdateReceiver;
private ImageButton mEndCallButton;
private TextView mCallDuration;
private TextView mCallState;
private TextView mCallerName;
//private TextView locationview;
private ImageView user_pic;
private long mCallStart;
private Timer mTimer;
private UpdateCallDurationTask mDurationTask;
ImageButton chat;
ImageButton speaker;
ImageButton mic;
boolean speaker_on = false;
boolean mic_on = true;
PowerManager mPowerManager;
WakeLock mProximityWakeLock;
final static int PROXIMITY_SCREEN_OFF_WAKE_LOCK = 32;
com.galsa.example.main.ImageLoader mImageLoader;
/*String location;
String longitude;
String latitude;*/
private class UpdateCallDurationTask extends TimerTask {
#Override
public void run() {
GroupCallScreenActivity.this.runOnUiThread(new Runnable() {
#Override
public void run() {
updateCallDuration();
}
});
}
}
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
getWindow().addFlags(WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD);
getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
getWindow().addFlags(WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED);
setContentView(R.layout.callscreen);
doBind();
mCallDuration = (TextView) findViewById(R.id.callDuration);
mCallerName = (TextView) findViewById(R.id.remoteUser);
mCallState = (TextView) findViewById(R.id.callState);
//locationview = (TextView) findViewById(R.id.location);
mEndCallButton = (ImageButton) findViewById(R.id.hangupButton);
chat = (ImageButton) findViewById(R.id.chat);
chat.setVisibility(View.GONE);
speaker = (ImageButton) findViewById(R.id.speaker);
mic = (ImageButton) findViewById(R.id.mic);
user_pic = (ImageView) findViewById(R.id.user_pic);
/*location = getIntent().getStringExtra("location");
longitude = getIntent().getStringExtra("longitde");
latitude = getIntent().getStringExtra("latitude");
locationview.setText(location);*/
mImageLoader = new com.galsa.example.main.ImageLoader(GroupCallScreenActivity.this, R.dimen.caller_image_height);
//mCallerName.setText(mCall.getRemoteUserId());
mPowerManager = (PowerManager) getSystemService(Context.POWER_SERVICE);
mProximityWakeLock = mPowerManager.newWakeLock(PROXIMITY_SCREEN_OFF_WAKE_LOCK, Utils.TAG);
/*chat.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
Intent intent = new Intent(GroupCallScreenActivity.this, MessagingActivity.class);
intent.putExtra(SinchClientService.INTENT_EXTRA_ID, mCallService.getCallerId());
intent.putExtra(SinchClientService.INTENT_EXTRA_NAME, mCallService.getCallerName());
startActivity(intent);
}
});*/
speaker.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
if(speaker_on)
{
mMessageService.speakerOn(speaker_on);
speaker_on = false;
speaker.setImageResource(R.drawable.speaker_off);
}
else
{
mMessageService.speakerOn(speaker_on);
speaker_on = true;
speaker.setImageResource(R.drawable.speaker_on);
}
}
});
mic.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
if(mic_on)
{
mMessageService.micOn(mic_on);
mic_on = false;
mic.setImageResource(R.drawable.mic_off);
}
else
{
mMessageService.micOn(mic_on);
mic_on = true;
mic.setImageResource(R.drawable.mic_on);
}
}
});
mEndCallButton.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
mCallService.endCall();
}
});
mCallStart = System.currentTimeMillis();
}
private void doBind() {
Intent intent = new Intent(this, SinchClientService.class);
bindService(intent, this, BIND_AUTO_CREATE);
intent = new Intent(this, GroupCallService.class);
bindService(intent, this, BIND_AUTO_CREATE);
}
private void doUnbind() {
unbindService(this);
}
#Override
protected void onStart() {
super.onStart();
mUpdateReceiver = new UpdateReceiver();
IntentFilter filter = new IntentFilter();
filter.addAction(GroupCallService.ACTION_FINISH_CALL_ACTIVITY);
filter.addAction(GroupCallService.ACTION_CHANGE_AUDIO_STREAM);
filter.addAction(GroupCallService.ACTION_UPDATE_CALL_STATE);
LocalBroadcastManager.getInstance(this).registerReceiver(mUpdateReceiver, filter);
}
#Override
public void onResume() {
super.onResume();
if(mProximityWakeLock != null && !mProximityWakeLock.isHeld()){
mProximityWakeLock.acquire();
}
mTimer = new Timer();
mDurationTask = new UpdateCallDurationTask();
mTimer.schedule(mDurationTask, 0, 500);
}
#Override
public void onPause() {
super.onPause();
if(isFinishing() && mProximityWakeLock != null && mProximityWakeLock.isHeld()){
mProximityWakeLock.release();
}
mDurationTask.cancel();
}
#Override
protected void onStop() {
super.onStop();
if(isFinishing() && mProximityWakeLock != null && mProximityWakeLock.isHeld()){
mProximityWakeLock.release();
}
if(mUpdateReceiver != null)
{
LocalBroadcastManager.getInstance(this).unregisterReceiver(mUpdateReceiver);
mUpdateReceiver = null;
}
}
#Override
public void onBackPressed() {
// User should exit activity by ending call, not by going back.
}
private void updateCallDuration() {
mCallDuration.setText(Utils.formatTimespan(System.currentTimeMillis() - mCallStart));
}
#Override
public void onServiceConnected(ComponentName componentName, IBinder iBinder) {
if(iBinder instanceof GroupCallService.GroupCallServiceInterface)
{
mCallService = (GroupCallService.GroupCallServiceInterface) iBinder;
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
getSupportActionBar().setDisplayShowHomeEnabled(true);
ActionBar actionBar = getSupportActionBar();
if(mCallService.getCallerName() != null)
actionBar.setTitle(mCallService.getCallerName());
else
actionBar.setTitle("Group call");
actionBar.setIcon(R.drawable.callscreen);
if(mCallService.getCallerName() != null)
mCallerName.setText(mCallService.getCallerName());
else
mCallerName.setText("Group call");
mCallState.setText(mCallService.getCallState());
String pic = ChatDatabaseHandler.getInstance(this).getFriendpic(mCallService.getCallerId());
mImageLoader.displayImage(UserFunctions.hostImageDownloadURL + pic, user_pic);
}
else
mMessageService = (SinchClientService.MessageServiceInterface) iBinder;
mMessageService.enableMic();
mMessageService.disableSpeaker();
}
#Override
public void onServiceDisconnected(ComponentName componentName) {
mMessageService = null;
mCallService = null;
}
#Override
public void onDestroy() {
if(mUpdateReceiver != null)
{
LocalBroadcastManager.getInstance(this).unregisterReceiver(mUpdateReceiver);
mUpdateReceiver = null;
}
doUnbind();
super.onDestroy();
}
private class UpdateReceiver extends BroadcastReceiver
{
#Override
public void onReceive(Context context, Intent intent)
{
if(GroupCallService.ACTION_FINISH_CALL_ACTIVITY.equals(intent.getAction()))
{
finish();
}
else if(GroupCallService.ACTION_CHANGE_AUDIO_STREAM.equals(intent.getAction()))
{
setVolumeControlStream(intent.getIntExtra("STREAM_TYPE", AudioManager.USE_DEFAULT_STREAM_TYPE));
}
else if(GroupCallService.ACTION_UPDATE_CALL_STATE.equals(intent.getAction()))
{
mCallState.setText(intent.getStringExtra("STATE"));
}
}
}
}
I start the call with the same way whether the user will start a new call or join a created one.
I'm developing a tracking app. and i have problem with GPS module. The app must record a route. App work fine, but sometimes when the device is not moving, GPS still receive
continuous coordinate that don't indicate my position, error is within a radius of 20 meter, and when I'm moving again work fine.
Please give me some tips that can help me to fix this problem. Thanks a lot.
I have 3 calsses
1 - GPSReceiver here is method for get location
public void getMyLoction(){
_locationManager = (LocationManager) _context.getSystemService(LOCATION_SERVICE);
_isGPSEnabled =_locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER);
if (_isGPSEnabled) {
if (_location == null) {
_locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER,0,0, this);
if (_locationManager != null) {
_location = _locationManager.getLastKnownLocation(LocationManager.GPS_PROVIDER);
setLocation(_location);
}
}
}
}
2 RecordingActivity (take coordonates form services and processes then) work fine, a comment in method what they do.
public class RecordingActivity extends FragmentActivity {
public final static String BROADCAST_ACTION = "map.trackv";
public BroadcastReceiver receiver;
private GoogleMap map;
private TextView _messageToUser;
private Coordinate _pointFromService;
private long _timeWhenStartButtonWasPressed;
private List<Coordinate> _unprocessedCoords;
private List<Coordinate> _processedCoords;
private Button _stopButton;
private Button _startButton;
private String _startRecordingDate;
private String _stopRecordingDate;
private GPSReceiver _gps;
private DataBaseOperations _dataSource;
private boolean _recording;
private boolean _gpsStatus;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_recording_route);
initActvity();
checkIfGPSisOn();
try {
Runtime.getRuntime().exec("logcat -f" + " /sdcard/Logcat.txt");
} catch (IOException e) {
// TODO Auto-generated catch block
Log.d("nu pot", "DDDDD");
e.printStackTrace();
}
receveirWork();
IntentFilter intentFilt = new IntentFilter(BROADCAST_ACTION);
registerReceiver(receiver, intentFilt);
}
public void checkIfGPSisOn() {
//check on start
}
public void receveirWork() {
receiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
// request points and process then,
}
};
}
#Override
protected void onDestroy() {
super.onDestroy();
if (_stopButton.isEnabled())
{
stopService(new Intent(this, RecordingService.class));
_unprocessedCoords = null;
_processedCoords = null;
}
unregisterReceiver(receiver);
}
#Override
protected void onResume() {
if (!_stopButton.isEnabled()) {
_startButton.setEnabled(true);
_messageToUser.setText(Constants.PRESS_START_BUTTON);
map.clear();
}
super.onResume();
}
// actiune buton start;
public void startButtonEvent(View V) {
buttonsStateAndMessageToShow(false, true, Constants.MESSAGE_TO_WAIT);
_timeWhenStartButtonWasPressed = System.currentTimeMillis();
startService(new Intent(this, RecordingService.class));
// start service to get position
}
public void stopButtonEvent(View V) {
stopService(new Intent(this, RecordingService.class));
// stop service
// save route in BD
// resetData;
}
public void initActvity() {
// init date
}
#Override
protected void onSaveInstanceState(Bundle outState) {
// save state
}
}
3 RecordingServices class, ii think here is the problem.
public class RecordingService extends Service {
private Thread _backgroundWork;
private boolean _threadCanRun;
private GPSReceiver _gps;
private Coordinate _pointToSent;
public void onCreate() {
super.onCreate();
_threadCanRun = true;
_backgroundWork = new Thread(new Runnable() {
#Override
public void run() {
Looper.prepare();
getLocationFromGPS();
Looper.loop();
}
});
}
public int onStartCommand(Intent intent, int flags, int startId) {//
_backgroundWork.start();
return super.onStartCommand(intent, flags, startId);
}
public void onDestroy() {
_threadCanRun = false;
super.onDestroy();
}
public IBinder onBind(Intent intent) {
return null;
}
public void getLocationFromGPS() {
while (_threadCanRun) {
Intent _intent = new Intent(RecordingActivity.BROADCAST_ACTION);
_gps = new GPSReceiver(this);
_gps.getMyLoction();
if (_gps.getIsGPSEnabled()) {
try {
TimeUnit.SECONDS.sleep(2);
} catch (InterruptedException e) {}
sentPoint(_intent);
} else {
try {
TimeUnit.MILLISECONDS.sleep(500);
} catch (InterruptedException e) {}
_intent.putExtra("latitude", 0);
_intent.putExtra("longitude", 0);
_intent.putExtra("time", 0);
_intent.putExtra("GPSstatus", false);
sendBroadcast(_intent);
}
}
}
private void sentPoint(Intent _intent) {
_pointToSent = new Coordinate(_gps.getLatitude(), _gps.getLongitude(), _gps.getTime());
_intent.putExtra("latitude", _pointToSent.getLatitude());
_intent.putExtra("longitude", _pointToSent.getlongitude());
_intent.putExtra("time", _pointToSent.getTime());
_intent.putExtra("GPSstatus", _gps.getIsGPSEnabled());
sendBroadcast(_intent);
_pointToSent = null;
}
}
repeating the Location update request depends on how u implemented your tracking system
but in general(which is not recommended , just change your request update rate to save client Battery usage) you can find the distance between your locations by location1.distanceTo(location2) so if the distance is smaller than 30m then put the new location away
How to use timer in android for auto logout after 15 minutes due to inactivity of user?
I am using bellow code for this in my loginActivity.java
public class BackgroundProcessingService extends Service {
#Override
public IBinder onBind(Intent intent) {
// TODO Auto-generated method stub
timer = new CountDownTimer(5 *60 * 1000, 1000) {
public void onTick(long millisUntilFinished) {
//Some code
//inactivity = true;
timer.start();
Log.v("Timer::", "Started");
}
public void onFinish() {
//Logout
Intent intent = new Intent(LoginActivity.this,HomePageActivity.class);
startActivity(intent);
//inactivity = false;
timer.cancel();
Log.v("Timer::", "Stoped");
}
};
return null;
}
}
and onclick of login button I have called intent for service.
Intent intent1 = new Intent(getApplicationContext(),
AddEditDeleteActivity.class);
startService(intent1);
Please advice......
This type of error message is shown after 15 mins
Use CountDownTimer
CountDownTimer timer = new CountDownTimer(15 *60 * 1000, 1000) {
public void onTick(long millisUntilFinished) {
//Some code
}
public void onFinish() {
//Logout
}
};
When user has stopped any action use timer.start() and when user does the action do timer.cancel()
I am agree with Girish in above answer. Rash for your convenience i am sharing code with you.
public class LogoutService extends Service {
public static CountDownTimer timer;
#Override
public void onCreate(){
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) {
return null;
}
}
Add the following code in every activity.
#Override
protected void onResume() {
super.onResume();
LogoutService.timer.start();
}
#Override
protected void onStop() {
super.onStop();
LogoutService.timer.cancel();
}
First Create Application class.
public class App extends Application{
private static LogoutListener logoutListener = null;
private static Timer timer = null;
#Override
public void onCreate() {
super.onCreate();
}
public static void userSessionStart() {
if (timer != null) {
timer.cancel();
}
timer = new Timer();
timer.schedule(new TimerTask() {
#Override
public void run() {
if (logoutListener != null) {
logoutListener.onSessionLogout();
log.d("App", "Session Destroyed");
}
}
}, (1000 * 60 * 2) );
}
public static void resetSession() {
userSessionStart();
}
public static void registerSessionListener(LogoutListener listener) {
logoutListener = listener;
}
}
This App Class add into manifest
<application
android:name=".App"
android:allowBackup="false"
android:icon="#mipmap/ic_launcher"
android:label="#string/app_name"
android:roundIcon="#mipmap/ic_launcher_round"
android:supportsRtl="true"
android:usesCleartextTraffic="true"
android:theme="#style/AppTheme">
<activity android:name=".view.activity.MainActivity"/>
</application>
Then Create BaseActivity Class that is use in whole applications
class BaseActivity extends AppCompatActivity implements LogoutListener{
#Override
protected void onCreate(Bundle savedInstanceState) {
//setTheme(App.getApplicationTheme());
super.onCreate(savedInstanceState);
}
#Override
protected void onResume() {
super.onResume();
//Set Listener to receive events
App.registerSessionListener(this);
}
#Override
public void onUserInteraction() {
super.onUserInteraction();
//reset session when user interact
App.resetSession();
}
#Override
public void onSessionLogout() {
// Do You Task on session out
}
}
After that extend Base activity in another activity
public class MainActivity extends BaseActivity{
private static final String TAG = MainActivity.class.getSimpleName();
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
}
You can start a service and start a timer in it. Every 15 minutes, check if a flag, let's say inactivity flag is set to true. If it is, logout form the app.
Every time the user interacts with your app, set the inactivity flag to false.
you may need to create a BaseActivity class which all the other Activities in your app extend. in that class start your timer task (TimerTask()) in the onUserInteraction method:
override fun onUserInteraction() {
super.onUserInteraction()
onUserInteracted()
}
. The onUserInteracted class starts a TimerTaskService which will be an inner class for my case as below:
private fun onUserInteracted() {
timer?.schedule(TimerTaskService(), 10000)
}
The TimerTaskService class will be asfollows. Please note the run on UI thread in the case you want to display a DialogFragment for an action to be done before login the user out:
inner class TimerTaskService : TimerTask() {
override fun run() {
/**This will only run when application is in background
* it allows the application process to get high priority for the user to take action
* on the application auto Logout
* */
// val activityManager = applicationContext.getSystemService(Context.ACTIVITY_SERVICE) as ActivityManager
// activityManager.moveTaskToFront(taskId, ActivityManager.MOVE_TASK_NO_USER_ACTION)
runOnUiThread {
displayFragment(AutoLogoutDialogFragment())
isSessionExpired = true
}
stopLoginTimer()
}
}
You will realise i have a stopTimer method which you have to call after the intended action has be envoked, this class just has timer?.cancel() and you may also need to include it in the onStop() method.
NB: this will run in 10 seconds because of the 10000ms
Use the build-in function called: onUserInteraction() like below:
#Override
public void onUserInteraction() {
super.onUserInteraction();
stopHandler(); //first stop the timer and then again start it
startHandler();
}
I hope this will help
I found it on github https://gist.github.com/dseerapu/b768728b3b4ccf282c7806a3745d0347
public class LogOutTimerUtil {
public interface LogOutListener {
void doLogout();
}
static Timer longTimer;
static final int LOGOUT_TIME = 600000; // delay in milliseconds i.e. 5 min = 300000 ms or use timeout argument
public static synchronized void startLogoutTimer(final Context context, final LogOutListener logOutListener) {
if (longTimer != null) {
longTimer.cancel();
longTimer = null;
}
if (longTimer == null) {
longTimer = new Timer();
longTimer.schedule(new TimerTask() {
public void run() {
cancel();
longTimer = null;
try {
boolean foreGround = new ForegroundCheckTask().execute(context).get();
if (foreGround) {
logOutListener.doLogout();
}
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
}
}
}, LOGOUT_TIME);
}
}
public static synchronized void stopLogoutTimer() {
if (longTimer != null) {
longTimer.cancel();
longTimer = null;
}
}
static class ForegroundCheckTask extends AsyncTask < Context, Void, Boolean > {
#Override
protected Boolean doInBackground(Context...params) {
final Context context = params[0].getApplicationContext();
return isAppOnForeground(context);
}
private boolean isAppOnForeground(Context context) {
ActivityManager activityManager = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
List < ActivityManager.RunningAppProcessInfo > appProcesses = activityManager.getRunningAppProcesses();
if (appProcesses == null) {
return false;
}
final String packageName = context.getPackageName();
for (ActivityManager.RunningAppProcessInfo appProcess: appProcesses) {
if (appProcess.importance == ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND && appProcess.processName.equals(packageName)) {
return true;
}
}
return false;
}
}
}
Use above code in Activity as below :
public class MainActivity extends AppCompatActivity implements LogOutTimerUtil.LogOutListener
{
#Override
protected void onStart() {
super.onStart();
LogOutTimerUtil.startLogoutTimer(this, this);
Log.e(TAG, "OnStart () &&& Starting timer");
}
#Override
public void onUserInteraction() {
super.onUserInteraction();
LogOutTimerUtil.startLogoutTimer(this, this);
Log.e(TAG, "User interacting with screen");
}
#Override
protected void onPause() {
super.onPause();
Log.e(TAG, "onPause()");
}
#Override
protected void onResume() {
super.onResume();
Log.e(TAG, "onResume()");
}
/**
* Performing idle time logout
*/
#Override
public void doLogout() {
// write your stuff here
}
}