Android Service stops after 1 minute when called onPause - android

I am trying to use a countdown timer which will run when the activity onPause is triggered. However, the service stops after 1 minute. But if I start the service with the activity working it works.
public class TimerService extends Service {
private static CountDownTimer countDownTimer;
#Nullable
#Override
public IBinder onBind(Intent intent) {
return null;
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
startTimer(2*60 * 1000);
return START_STICKY;
}
#Override
public void onDestroy() {
countDownTimer.cancel();
super.onDestroy();
}
private void startTimer(int noOfMinutes) {
countDownTimer=new CountDownTimer(noOfMinutes, 1000) {
public void onTick(long millisUntilFinished) {
long millis=millisUntilFinished;
String hms=String.format("%02d:%02d:%02d", TimeUnit.MILLISECONDS.toHours(millis), TimeUnit.MILLISECONDS.toMinutes(millis) - TimeUnit.HOURS.toMinutes(TimeUnit.MILLISECONDS.toHours(millis)), TimeUnit.MILLISECONDS.toSeconds(millis) - TimeUnit.MINUTES.toSeconds(TimeUnit.MILLISECONDS.toMinutes(millis)));
Log.d("Long Seconds", hms);
}
public void onFinish() {
//timerOn=false;
new Handler().postDelayed(new Runnable() {
#Override
public void run() {
Intent i=new Intent(getApplicationContext(), Splash_Loader.class);
i.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(i);
}
}, 1000);
}
}.start();
}
}
Starting it onPause from an activity
#Override
protected void onPause() {
super.onPause();
startService(new Intent(this,TimerService.class));
}
Manifest file decleration
<service android:name = ".TimerService"/>

Related

countdown time in android studio

I want to run the service when the countdown time has finished, but when I exit the application the command does not work, what's the solution?
time.java
private void startTimer() {
mEndTime = System.currentTimeMillis() + mTimeLeftInMillis;
mCountDownTimer = new CountDownTimer(mTimeLeftInMillis, 1000) {
#Override
public void onTick(long millisUntilFinished) {
mTimeLeftInMillis = millisUntilFinished;
updateCountDownText();
}
#Override
public void onFinish() {
mTimerRunning = false;
updateWatchInterface();
startService(new Intent(getBaseContext(), alert1.class));
}
}.start();
mTimerRunning = true;
updateWatchInterface();
}
this is the service class
alert1.java
public class alert1 extends Service {
#Nullable
#Override
public IBinder onBind(Intent intent) {
return null;
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
try{
Handler handler = new Handler();
handler.postDelayed(new Runnable() {
public void run() {
FirebaseDatabase database = FirebaseDatabase.getInstance();
final DatabaseReference myRef = database.getReference("RELAY1_STATUS");
myRef.setValue("OFF");
Toast.makeText(getBaseContext(),"off",Toast.LENGTH_LONG).show();
}
}, 0);
} catch (Exception e) {
e.printStackTrace();
}
return START_STICKY;
}
#Override
public void onDestroy() {
super.onDestroy();
}
}
You can try like this. First, send your counter time as a parameter. When time finished just start your service.
private void setTimerForStartService(int timeInMillis){
countDownTimer = new CountDownTimer(timeInMillis, 1000){
#Override
public void onTick(long millisUntilFinished) {
String text = String.format(Locale.getDefault(), "%02d",
TimeUnit.MILLISECONDS.toSeconds(millisUntilFinished) % 60);
updateCountDownText(text);
}
#Override
public void onFinish() {
mTimerRunning = false;
updateWatchInterface();
startService(new Intent(getBaseContext(), alert1.class));
}
}.start();
}

how to manage timer in a Service to run in background

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

Chronometer keep in background time spent

i would developing a feature in my app that when click on button on my activity launch a service that start,pause and resume a Chronometer.
But I have a problem how start and stop in my background service.
I created my Activity
public class StartWorkActivity extends ActivityGeneralToolbar {
protected final void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState, R.layout.activity_start_work);
Chronometer chronometer = (Chronometer) findViewById(R.id.chronometer);
}
#Override
protected void onStop() {
super.onStop();
}
public void startWork(View v){
Intent msgIntent = new Intent(StartWorkActivity.this, WorkTimerService.class);
msgIntent.setAction("START_TIMER");
getBaseContext().startService(msgIntent);
}
public void pauseWork(View v){
Intent msgIntent = new Intent(StartWorkActivity.this, WorkTimerService.class);
msgIntent.setAction("PAUSE_TIMER");
}
public void resumeWork(View v){
//call service
Intent msgIntent = new Intent(StartWorkActivity.this, WorkTimerService.class);
msgIntent.setAction("RESUME_TIMER");
}
#Override
protected void onPause() {
super.onPause();
}
#Override
protected void onResume() {
super.onResume();
}
}
And my WorkTimerService
public class WorkTimerService extends IntentService {
long timeWhenStopped = 0;
Chronometer chronometer;
public WorkTimerService() {
super("SystemService");
}
#Nullable
#Override
public IBinder onBind(Intent intent) {
return null;
}
#Override
protected void onHandleIntent(Intent intent) {
if(intent.getAction() == "START_TIMER"){
startWork();
}
if(intent.getAction() == "PAUSE_TIMER"){
pauseWork();
}if(intent.getAction() == "RESUME_TIMER"){
resumeWork();
}
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
super.onStartCommand(intent, flags,startId);
return START_STICKY;
}
public void pauseWork(){
timeWhenStopped = chronometer.getBase() - SystemClock.elapsedRealtime();
chronometer.stop();
}
public void resumeWork(){
chronometer.setBase(SystemClock.elapsedRealtime() + timeWhenStopped);
timeWhenStopped = 0;
chronometer.start();
}
public void startWork(){
chronometer.start();
}
}
But my problem is that Chronometer obviously is null in my service, because I read that is not possible, in the service, interact with the ui.
And so, how i can send, or work with Chronometer in background?
Chronometer is a UI widget (actually a TextView) in Android. So, you can't use it for non-UI purposes. Try to use Timer or CountDownTimer instead.
See this for an example usage of Timer inside Service: https://stackoverflow.com/a/3819721/5250273

How to restart Media player service from where it was paused?

I read docs at Android Developer and still cant pause my service and then start it from the paused state (Playing the song).
With my current code, it always restart from the beginning of the song, but I would like to restart where the song was paused (with the stopClick).
Now I understand problem. In the MainActivity using stopService() method fully destroys it.
So how could i say service to wait when i press stop button to pause?
The Service class:
public class BackgroundSoundService extends Service {
MediaPlayer player;
int currentPos;
public IBinder onBind(Intent arg0) {
return null;
}
#Override
public void onCreate() {
super.onCreate();
final int MAX_VOLUME = 100;
player = MediaPlayer.create(this, R.raw.lightmusic);
player.setLooping(true);
float soundVolume = 77;
final float volume = (float) (1 - (Math.log(MAX_VOLUME - soundVolume) / Math
.log(MAX_VOLUME)));
player.setVolume(volume, volume);
player.seekTo(currentPos);
player.start();
}
public int onStartCommand(Intent intent, int flags, int startId) {
player.seekTo(currentPos);
player.start();
return 1;
}
public void onStart(Intent intent, int startId) {
player.seekTo(currentPos);
player.start();
}
#Override
public void onRebind(Intent intent) {
player.seekTo(currentPos);
player.start();
super.onRebind(intent);
}
public IBinder onUnBind(Intent arg0) {
// TO DO Auto-generated method
return null;
}
public void onStop() {
currentPos = player.getCurrentPosition();
player.pause();
}
public void onPause() {
currentPos = player.getCurrentPosition();
player.pause();
}
#Override
public void onDestroy() {
currentPos = player.getCurrentPosition();
player.pause();
//player.release();
}
#Override
public void onLowMemory() {
}
}
And my main Activity:
public class MainActivity extends QuizActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.menu);
startService(new Intent(this, BackgroundSoundService.class));
}
public void stopClick(View v) {
stopService(new Intent(this, BackgroundSoundService.class));
}
public void playClick(View v) {
startService(new Intent(this, BackgroundSoundService.class));
}
#Override
protected void onResume() {
super.onResume();
}
}

continue service working when the application closes

I have a simple Service
public class UpdateService extends Service {
private int seconds;
final static String MY_ACTION = "MY_ACTION";
#Override
public void onCreate() {
super.onCreate();
}
#Override
public void onStart(Intent intent, int startId) {
timer.start();
}
#Override
public IBinder onBind(Intent intent) {
return null;
}
final CountDownTimer timer = new CountDownTimer(86400000, 1000) {
public void onTick(long millisUntilFinished) {
Util.saveInfo(getApplicationContext(), Util.SECONDS, seconds++);
Intent intent = new Intent();
intent.setAction(MY_ACTION);
sendBroadcast(intent);
}
public void onFinish() { }
};
}
When I close an application service stops working. But showing that the service is running.
What am I doing wrong?
Update
I changed CountDownTimer to Thread, but the problem remained
Thread t1 = new Thread(new Runnable() {
#Override
public void run() {
while (true) {
Util.saveInfo(getApplicationContext(), Util.SECONDS, seconds++);
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
});
OnStart()
if(!t1.isAlive())
t1.start();
Because CountDown Timer is working only foreground means app is running and not minimized or closed. You have to place a Thread in Service that executing at particular time of you want.
try this :
public class LocalService extends Service
{
private static Timer timer = new Timer();
private Context ctx;
public IBinder onBind(Intent arg0)
{
return null;
}
public void onCreate()
{
super.onCreate();
ctx = this;
startService();
}
private void startService()
{
timer.scheduleAtFixedRate(new mainTask(), 0, 5000);
}
private class mainTask extends TimerTask
{
public void run()
{
toastHandler.sendEmptyMessage(0);
}
}
public void onDestroy()
{
super.onDestroy();
Toast.makeText(this, "Service Stopped ...", Toast.LENGTH_SHORT).show();
}
private final Handler toastHandler = new Handler()
{
#Override
public void handleMessage(Message msg)
{
System.out.println("test");
}
};
}

Categories

Resources