Running countdown timer faster when i back to activity - android

I make a service for countdown timer, in activity i put a text view for show time every seconds: 100 - 0, but when i leave activity and back to that. i see timer as run very fast, but i want to this run just every second. where is problem ?
MainActivity:
public static final String mBroadcastIntegerAction = "com.example.broadcast.integer";
private IntentFilter mIntentFilter;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
showTime = (TextView) findViewById(R.id.textView1);
mIntentFilter = new IntentFilter();
mIntentFilter.addAction(mBroadcastIntegerAction);
Intent serviceIntent = new Intent(this, AppServiceDay.class);
startService(serviceIntent);
}
#Override
public void onResume() {
super.onResume();
registerReceiver(mReceiver, mIntentFilter);
}
private BroadcastReceiver mReceiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
if (intent.getAction().equals(mBroadcastIntegerAction)) {
int second = intent.getIntExtra("Time", 0);
showTime.setText("" + second);
}
}
};
#Override
protected void onPause() {
registerReceiver(mReceiver, mIntentFilter);
// unregisterReceiver(mReceiver);
super.onPause();
}
Service:
public class AppServiceDay extends Service {
CountDownTimer cdt;
public static Handler mHandler;
int downer = 1000;
int time = 100;
int mainTime = 100000;
#Override
public void onCreate() {
super.onCreate();
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
cdt = new CountDownTimer(mainTime, downer) {
#Override
public void onTick(long millisUntilFinished) {
time -= 1;
Intent broadcastIntent = new Intent();
broadcastIntent.setAction(MainActivity.mBroadcastIntegerAction);
broadcastIntent.putExtra("Time", time);
sendBroadcast(broadcastIntent);
}
#Override
public void onFinish() {
time = 100;
this.start();
}
};
cdt.start();
return super.onStartCommand(intent, flags, startId);
}
#Override
public IBinder onBind(Intent arg0) {
return null;
}
}

onStartCommand is triggered everytime startService is called and in onStartCommand you are creating new countdown object,
Add a null check before creating new countdown object it will fix your duplicate timer running at same time.
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
If(cdt == null) {
cdt = new CountDownTimer(mainTime, downer) {
#Override
public void onTick(long millisUntilFinished) {
time -= 1;
Intent broadcastIntent = new Intent();
broadcastIntent.setAction(MainActivity.mBroadcastIntegerAction);
broadcastIntent.putExtra("Time", time);
sendBroadcast(broadcastIntent);
}
#Override
public void onFinish() {
time = 100;
this.start();
}
};
cdt.start();
}
return super.onStartCommand(intent, flags, startId);
}

Related

Counrdown timer with service not working in the fragment

I wanna implement a Countdown timer with updating TextView and a service so the counting can keep going if the app is in background, foreground or even fully closed.
I examined these codes in a simple project and they worked very well
Service
public class MyService extends Service {
#Nullable
#Override
public IBinder onBind(Intent intent) {
return null;
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
final Integer[] timeRemaining = {intent.getIntExtra("TimeValue", 0)};
final Timer timer = new Timer();
timer.scheduleAtFixedRate(new TimerTask() {
#Override
public void run() {
Intent intent1local = new Intent();
intent1local.setAction("Counter");
timeRemaining[0]--;
if (timeRemaining[0] <= 0) {
timer.cancel();
}
intent1local.putExtra("TimeRemaining", timeRemaining[0]);
sendBroadcast(intent1local);
}
},
0, 1000);
return super.onStartCommand(intent, flags, startId);
}
}
Main Activity
public class MainActivity extends AppCompatActivity {
private TextView textView;
private EditText editText;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ActivityCompat.requestPermissions(this,
new String[]{FOREGROUND_SERVICE},
PackageManager.PERMISSION_GRANTED);
textView = findViewById(R.id.textView);
editText = findViewById(R.id.editText);
IntentFilter intentFilter = new IntentFilter();
intentFilter.addAction("Counter");
BroadcastReceiver broadcastReceiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
Integer integerTime = intent.getIntExtra("TimeRemaining",
0);
textView.setText(integerTime.toString());
}
};
registerReceiver(broadcastReceiver, intentFilter);
}
public void startButton(View view) {
Intent intentService = new Intent(this, MyService.class);
Integer integerTimeSet =
Integer.parseInt(editText.getText().toString());
intentService.putExtra("TimeValue", integerTimeSet);
startService(intentService);
}
}
But when i implement these codes in an app with fragments (Service codes are in a seperate service class and i put MainActivity codes in a fragment), if you close the app, everything will gone off and you will get an error.
Please help me
I need your detailed advices.

Android : How can I get int value form service and set in text View on activity

My app has a countDown timer for 24 hours in his service. And show time in TextView any time even user left the app.
On service, i put an int number = 5184000. this is 24 hours converted to milliseconds;
Problems:
TextView don't show time in Activity.
I want to when timer equals 00:00:00, timer reset and new time equals 23:59:59.
MainActiviy:
public class MainActivity extends Activity {
TextView tv;
BroadcastReceiver broad;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
tv = (TextView) findViewById(R.id.textView1);
Intent intent = new Intent(this, MyService.class);
startService(intent);
registerReceiver(broad, new IntentFilter(MyService.BROADCAST_ACTION));
broad = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
Intent intent1 = getIntent();
Bundle bundle = intent1.getExtras();
if (bundle != null) {
int data = bundle.getInt("DDDD");
tv.setText(data);
} else {
tv.setText("00:00:00");
}
}
};
}
Service:
public class MyService extends Service {
CountDownTimer cdt = null;
Intent intent1;
int h = 5184000;
public static final String BROADCAST_ACTION = "com.example.service";
#Override
public void onCreate() {
super.onCreate();
}
#Override
public void onDestroy() {
cdt.cancel();
Log.i("DDD", "Timer cancelled");
super.onDestroy();
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
Log.i("TIME", "Starting timer...");
cdt = new CountDownTimer(h, 1000) {
#Override
public void onTick(long millisUntilFinished) {
Log.i("TIME", "secondes: " + millisUntilFinished);
intent1 = new Intent(BROADCAST_ACTION);
intent1.putExtra("T", h);
sendBroadcast(intent1);
}
#Override
public void onFinish() {
Log.i("TIME", "Timer finished");
}
};
cdt.start();
return super.onStartCommand(intent, flags, startId);
}
#Override
public IBinder onBind(Intent arg0) {
return null;
}
}
xml:
<TextView
android:id="#+id/textView1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:layout_centerHorizontal="true"
android:layout_marginTop="134dp"
android:text="00:00:00"
android:textAppearance="?android:attr/textAppearanceLarge" />
You can use Alarm Manager for that.
Check out below links for AlarmManager.
AlarmManager
Scheduling Repeating Alarms

How to write an Android background service which never stops and keeps my variables values when I close my application?

I have to write an Android background service which never stops and keeps my variables alive.
Here is my service:
public class PollingService extends Service {
public static final String TAG = PollingService.class.getSimpleName();
public static int alap = 0;
public PollingService() {
}
#Override
public IBinder onBind(Intent intent) {
Log.d(TAG, "BIND");
return null;
}
#Override
public boolean onUnbind(Intent intent) {
Log.d(TAG, "UNBIND");
return true;
}
public class MyBinder extends Binder {
public PollingService getService() {
return PollingService.this;
}
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
//return super.onStartCommand(intent, flags, startId);
final Handler handler = new Handler();
final Runnable r = new Runnable() {
public void run() {
alap = alap+1;
Log.d(TAG, ": "+alap+"");
handler.postDelayed(this, 1000);
}
};
handler.postDelayed(r, 1000);
return START_STICKY;
}
#Override
public void onDestroy() {
Log.d(TAG, "DESTROY");
}
}
This is a counter service and it works well when my app is running, but when I close the app my variable "alap" start counting again from zero.
I bind and unbind when I navigate from an Activity to another, but I need my variables values when I close the app.
The only way is to use the method startForeground() in your service. Try something like this:
public int onStartCommand(Intent intent, int flags, int startId) {
startForeground(1, new Notification());
Try to store your variable value in "SharedPreference" in onDestory function.
SharedPreferences sharedpreferences;
sharedpreferences = getSharedPreferences(MyPREFERENCES, Context.MODE_PRIVATE);
public int onStartCommand(Intent intent, int flags, int startId) {
//return super.onStartCommand(intent, flags, startId);
final Handler handler = new Handler();
final Runnable r = new Runnable() {
public void run() {
alap = sharedpreferences.getString("alap",null);
alap = alap+1;
Log.d(TAG, ": "+alap+"");
handler.postDelayed(this, 1000);
}
};
handler.postDelayed(r, 1000);
return START_STICKY;
}
#Override
public void onDestroy() {
//storing data
SharedPreferences.Editor editor = sharedpreferences.edit();
editor.putString("alap", alap);
editor.commit();
Log.d(TAG, "DESTROY");
}

How to call another activity after destroy() of service is called

In this code I have created a service.After 3 seconds i want to destory this service and want to call another activity in destroy method.but this doesnt seem to work.
public class TimerService extends Service
{
#Override
public IBinder onBind(Intent intent)
{
return null;
}
#Override
public void onCreate()
{
super.onCreate();
}
#Override
public int onStartCommand(Intent intent,int flags,int startId)
{
new CountDownTimer(3000, 1000)
{
public void onTick(long millisUntilFinished)
{
}
public void onFinish()
{
stopSelf();
}
}.start();
return super.onStartCommand(intent,flags,startId);
}
#Override
public void onDestroy()
{
super.onDestroy();
Intent i = new Intent(this,Dummy.class);
i.putExtra("SessionTimedOut","Expire");
i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
getApplication().startActivity(i);
}
}
Activity which calls My Service
public class MainActivity extends Activity
{
#Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Intent i = new Intent(this,TimerService.class);
startService(i);
}
}
Try to insert the code to the finish method:
#Override
public int onStartCommand(Intent intent,int flags,int startId)
{
new Handler().postDelayed(new Runnable() {
#Override
public void run() {
Intent i = new Intent(this,Dummy.class);
i.putExtra("SessionTimedOut","Expire");
i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(i);
stopSelf();
}
}, 3000);
return super.onStartCommand(intent,flags,startId);
}

StartService returns null Android Service

I need to start a countdowntimer in backgroud service and show it on My fragment. This is where I am currently.
ComponentName c is null after calling startService.
I am not sure how I can debug this using debugger.
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.home_map, container, false);
setUpMapIfNeeded();
controlv = rootView.findViewById(R.id.controls_parked);
parker_info = (TextView)rootView.findViewById(R.id.parked_info);
take_to_car_btn= (Button)rootView.findViewById(R.id.walk_to_Car);
unPark = (Button)rootView.findViewById(R.id.un_park);
timer = (Button)rootView.findViewById(R.id.timer_btn);
myContext = getActivity();
mDpi = getActivity().getResources().getDisplayMetrics().densityDpi;
timer.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
ComponentName c = getActivity().startService(new Intent(getActivity(), TimerService.class));
Log.i(TAG, "Started service");
}
});
return rootView;
}
private BroadcastReceiver br = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
updateGUI(intent); // or whatever method used to update your GUI fields
}
};
private void updateGUI(Intent intent){
if (intent.getExtras() != null) {
long millisUntilFinished = intent.getLongExtra("countdown", 0);
Log.i(TAG, "Countdown seconds remaining: " + millisUntilFinished / 1000);
}
Toast.makeText(myContext, "Timer", Toast.LENGTH_SHORT).show();
}
This is my Service :
public class TimerService extends Service {
private final static String TAG = "TimerService";
public static final String TIMER_BR = "parking.group6.csc413.projectmap_timer";
Intent timer_intent = new Intent(TIMER_BR);
CountDownTimer cdt = null;
#Override
public void onCreate() {
super.onCreate();
Log.i(TAG, "Starting timer...");
cdt = new CountDownTimer(30000, 1000) {
#Override
public void onTick(long millisUntilFinished) {
Log.i(TAG, "Countdown seconds remaining: " + millisUntilFinished / 1000);
timer_intent.putExtra("countdown", millisUntilFinished);
sendBroadcast(timer_intent);
}
#Override
public void onFinish() {
Log.i(TAG, "Timer finished");
}
};
cdt.start();
}
#Override
public void onDestroy() {
cdt.cancel();
Log.i(TAG, "Timer cancelled");
super.onDestroy();
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
return super.onStartCommand(intent, flags, startId);
}
#Override
public IBinder onBind(Intent intent) {
return null;
}
}
And yes my manifest file has:
<service android:name=".TimerService"/>
ComponentName is not null only if the Service was already started or is already running. If the service doesn't exist yet, null is return. To start your CountDownTimer, you can use an action:
Intent intent = new Intent(getActivity(), TimerService.class);
intent.setAction("START");
getActivity().startService(intent);
when onStartCommand is invoked, check if the action is equals to START. If it is, start your CountDownTimer
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
if ("START".equals(intent.getAction()) {
// start CountDownTimer
}
return super.onStartCommand(intent, flags, startId);
}

Categories

Resources