In this android service I wanna display a toast of value of second at current time. but this again and again show the same value. timer is scheduled to update at interval of 1 second but the value don't refresh and toast shows the previous value again. I don't what the issue.
package net.learn2develop.Services;
import java.util.Calendar;
import java.util.Timer;
import java.util.TimerTask;
import android.app.Service;
import android.content.Intent;
import android.os.Handler;
import android.os.IBinder;
import android.os.Message;
import android.widget.Toast;
public class MyService extends Service{
Handler handler = new Handler();
Calendar c = Calendar.getInstance();
Timer t = new Timer();
int second = c.get(Calendar.SECOND);
int temp = 6;
#Override
public void onCreate() {
super.onCreate();
Toast.makeText(this, "Service Created", Toast.LENGTH_SHORT).show();
}
#Override
public IBinder onBind(Intent arg0) {
return null;
}
public int onStartCommand(Intent intent, int flags, int startId){
Toast.makeText(this,"service started",Toast.LENGTH_SHORT).show();
TimerTask task = new TimerTask() {
#Override
public void run() {
second = timeSecond();
handler.post(new Runnable() {
#Override
public void run() {
// Toast.makeText(getBaseContext(),String.valueOf(second), Toast.LENGTH_SHORT).show();
}
});
}
};
t.scheduleAtFixedRate(task, 0, 4* 1000);
return START_STICKY;
}
public void onDestroy(){
super.onDestroy();
t.cancel();
Toast.makeText(this, "Service Stopped", Toast.LENGTH_SHORT).show();
}
public int timeSecond() {
handler.post(new Runnable() {
#Override
public void run() {
Toast.makeText(getBaseContext(),String.valueOf(c.get(Calendar.SECOND)), Toast.LENGTH_SHORT).show();
}
});
return c.get(Calendar.SECOND);
}
}
This statement:
Calendar c = Calendar.getInstance();
returns a calendar whose time fields have been initialized with the current date and time. Those values do not then change as time passes. So when you use:
String.valueOf(c.get(Calendar.SECOND))
you are getting the same values every time. You need a new instance of calendar in each iteration of your timer.
Related
I want to start count time in my service, when an special event occurred. And i want to do this in worker thread.
even use CountDownTimer() can do this for me.
Problem is here that when i use this method in OnHandleIntent() of IntentService class, i receive an error:
java.lang.IllegalStateException: Handler (android.os.CountDownTimer$1) {235e78c} sending message to a Handler on a dead thread.
Is this the best way to count time and do special work when time arrive to destination? if not how i can? if it is, how solve? Thanks.
My service code is:
import android.app.IntentService;
import android.content.Context;
import android.content.Intent;
import android.os.CountDownTimer;
import android.os.Environment;
import android.util.Log;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.io.OutputStreamWriter;
public class TimeService extends IntentService {
public TimeService(){
super("");
}
#Override
protected void onHandleIntent(Intent intent) {
new CountDownTimer(20000,1000){
#Override
public void onTick(long millisUntilFinished) {
System.out.println("Time remaining: "+millisUntilFinished/1000);
}
#Override
public void onFinish() {
System.out.println("done");
}
}.start();
}
}
I can not recommend to you to use IntentService. You should use
regular service.
When intent service started, it create a new worker thread and when their task is finished then it terminated. But in your case your are using Countdowntimer, that is running after termination of worker thread, so it throw exception.
One solution you can try:
protected void onHandleIntent(Intent intent) {
Looper.prepare();
new CountDownTimer(20000,1000){
#Override
public void onTick(long millisUntilFinished) {
System.out.println("Time remaining: "+millisUntilFinished/1000);
}
#Override
public void onFinish() {
System.out.println("done");
Looper.myLooper().quit();
}
}.start();
Looper.loop() ;
}
Trying using your countdown timer in Service class as
CountDownTimer countDownTimerVariable;
In #Override
public int onStartCommand(Intent intent, int flags, int startId) {
super.onStartCommand(intent, flags, startId);
// based on your condition
if(condition)
{
performCountDown();
}
}
public void performCountDown()
{
countDownTimerVariable = new CountDownTimer(remainingMillisForCountDown, 1000) {
#Override
public void onFinish() {
//Action for when the timer has finished.
Log.i("timer finish", "finished");
}
#Override
public void onTick(long millisUntilFinished) {
//Action for every tick of the countdown.
// timeCalculate((millisUntilFinished / 1000));
Log.i("timer finish", "finished" + (millisUntilFinished / 1000) + " Countdown");
}
};
countDownTimerVariable.start();
}
and in destroy of service
#Override
public void onDestroy() {
// TODO Auto-generated method stub
this.unregisterReceiver(notifyServiceReceiver);
super.onDestroy();
if(countDownTimerVariable != null)
countDownTimerVariable.cancel();
}
I'm supposed to add a timer to my service class that prints a message to LogCat every 10 seconds. Nothing in the service class is printing once I call the startService method and I have no idea why.. Any ideas?
package com.murach.reminder;
import android.content.Intent;
import android.os.Bundle;
import android.app.Activity;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.Toast;
public class ReminderActivity extends Activity implements OnClickListener {
private Button startServiceButton;
private Button stopServiceButton;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_reminder);
startServiceButton = (Button) findViewById(R.id.startServiceButton);
stopServiceButton = (Button) findViewById(R.id.stopServiceButton);
startServiceButton.setOnClickListener(this);
stopServiceButton.setOnClickListener(this);
}
#Override
public void onClick(View v) {
Intent serviceIntent = new Intent(this, ReminderService.class);
switch (v.getId()) {
case R.id.startServiceButton:
// put code to start service and display toast here
startService(serviceIntent);
Toast.makeText(this, "Service started", Toast.LENGTH_SHORT).show();
break;
case R.id.stopServiceButton:
// put code to stop service and display toast here
stopService(serviceIntent);
Toast.makeText(this, "Service stopped", Toast.LENGTH_SHORT).show();
break;
}
}
}
package com.murach.reminder;
import android.app.Service;
import android.content.Intent;
import android.os.IBinder;
import android.util.Log;
import java.util.Timer;
import java.util.TimerTask;
public class ReminderService extends Service
{
private Timer timer;
public void onCreate()
{
Log.d("Reminder", "Service created");
startTimer();
}
#Override
public IBinder onBind(Intent intent)
{
Log.d("Reminder", "No binding for this activity");
return null;
}
public void onDestroy()
{
Log.d("Reminder", "Service destroyed");
stopTimer();
}
private void startTimer() {
TimerTask task = new TimerTask() {
public void run() {
Log.d("Reminder", "Timer task executed");
}
};
timer = new Timer(true);
int delay = 1000 * 10;
int interval = 1000 * 10;
timer.schedule(task, delay, interval);
}
private void stopTimer()
{
if (timer != null)
{
timer.cancel();
}
}
}
And here is how I register the service in the Manifest (in a service element, it wouldn't let me type it out completely)
android:name="com.murach.reminder.ReminderService"
The package names do not match. There is a spelling mistake in the word murach in your Manifest declaration.
i was wondering if the IntentService has thread blocking limit like calling Thread.sleep(); and if so what's the maximum time limit for it?
so i wrote the following code snippet:
package net.yassin.aaaservice;
import android.app.IntentService;
import android.content.Intent;
import android.os.Handler;
import android.os.SystemClock;
import android.widget.Toast;
public class MyService extends IntentService {
private Thread t;
private static int i = 0;
private static final int SLEEP_DURATION = 2000;
private Handler handler;
public MyService() {
super("MyService");
}
#Override
public void onStart(Intent intent, int startId) {
super.onStart(intent, startId);
this.handler = new Handler();
}
#Override
protected void onHandleIntent(Intent arg0) {
this.t = new Thread(new Runnable() {
#Override
public void run() {
while (true) {
MyService.this.handler.post(new Runnable() {
#Override
public void run() {
Toast.makeText(MyService.this,
"This is toast #" + (++i),
Toast.LENGTH_SHORT).show();
}
});
try {
Thread.sleep(SLEEP_DURATION);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
});
this.t.start();
}
}
and i found that whenever i change the time SLEEP_DURATION constant to over than 2000 Milis the service will stop showing Toasts if i removed the app form the recent menu?
am i right or there is another time limit or behavior ?
thnx :)
I've been looking for a way to change an icon in my view by broadcast receiver, but I'm not managing to find a way to do so.
First, I created a receiver:
public class BroadcastChangeReceiver extends BroadcastReceiver{
#Override
public void onReceive(Context context, final Intent intent) {
NetworkStatus conStatus = new NetworkActivity().getConnectionType(context);
String status = "Connection type: " + conStatus.getType().toString() + " -- Internet: " + conStatus.isConnected();
Toast.makeText(context, status, Toast.LENGTH_LONG).show();
}
}
it works fine when a network shows up. But now I need to check if there is a connectivity from time to time. To make that, I created a method that will ping my service that is somewhere in the internet each 5 seconds, but I don`t know how, from the broadcast receiver, will I change the icon in my activity. I cant use findViewById. This is my sample code to change and Icon (which is not working):
private void startInternetMonitoring(Context context) {
ScheduledExecutorService scheduleTaskExecutor = Executors
.newScheduledThreadPool(5);
// Run task every 5 seconds
scheduleTaskExecutor.scheduleAtFixedRate(new Runnable() {
int count = 0;
public void run() {
ImageView img = (ImageView) findViewById(R.id.networkStatusIcon);
switch (count) {
case 0:
img.setImageResource(R.drawable.connecting_icon);
count = 1;
break;
case 1:
img.setImageResource(R.drawable.offline_icon);
count = 2;
break;
case 2:
img.setImageResource(R.drawable.online_icon);
count = 0;
break;
}
}
}, 0, 5000, TimeUnit.MILLISECONDS);
}
any help or tips will be appreciated.
First off, I think a TimerTask is a better use for this case.
From http://android-er.blogspot.com/2013/12/example-of-using-timer-and-timertask-on.html
package com.example.androidtimer;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Timer;
import java.util.TimerTask;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.CheckBox;
import android.widget.TextView;
import android.app.Activity;
public class MainActivity extends Activity {
CheckBox optSingleShot;
Button btnStart, btnCancel;
TextView textCounter;
Timer timer;
MyTimerTask myTimerTask;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
optSingleShot = (CheckBox)findViewById(R.id.singleshot);
btnStart = (Button)findViewById(R.id.start);
btnCancel = (Button)findViewById(R.id.cancel);
textCounter = (TextView)findViewById(R.id.counter);
btnStart.setOnClickListener(new OnClickListener(){
#Override
public void onClick(View arg0) {
if(timer != null){
timer.cancel();
}
//re-schedule timer here
//otherwise, IllegalStateException of
//"TimerTask is scheduled already"
//will be thrown
timer = new Timer();
myTimerTask = new MyTimerTask();
if(optSingleShot.isChecked()){
//singleshot delay 1000 ms
timer.schedule(myTimerTask, 1000);
}else{
//delay 1000ms, repeat in 5000ms
timer.schedule(myTimerTask, 1000, 5000);
}
}});
btnCancel.setOnClickListener(new OnClickListener(){
#Override
public void onClick(View v) {
if (timer!=null){
timer.cancel();
timer = null;
}
}
});
}
class MyTimerTask extends TimerTask {
#Override
public void run() {
Calendar calendar = Calendar.getInstance();
SimpleDateFormat simpleDateFormat =
new SimpleDateFormat("dd:MMMM:yyyy HH:mm:ss a");
final String strDate = simpleDateFormat.format(calendar.getTime());
runOnUiThread(new Runnable(){
#Override
public void run() {
textCounter.setText(strDate);
}});
}
}
}
The issue seems to be that you "cant use findViewById".
Perhaps move your broadcastreceiver into your activity and register it there. That way you have access to you activity and views from the receiver when it is called.
I am trying to implement a service in Android that displays a toast message every 1 minute in Android. I am new to Android development and learned about AlarmManager that will help me do this. I have implemented the code in the following way:
This is my IIManagerActivity class
package com.example.iimanager;
import android.app.Activity;
import android.app.AlarmManager;
import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.os.SystemClock;
import android.view.Menu;
import android.widget.Toast;
public class IIManagerActivity extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_iimanager);
AlarmManager mgr=(AlarmManager)getSystemService(Context.ALARM_SERVICE);
Intent i=new Intent(this, SampleService.class);
PendingIntent pi=PendingIntent.getService(this, 0, i, 0);
mgr.setInexactRepeating(AlarmManager.ELAPSED_REALTIME_WAKEUP, SystemClock.elapsedRealtime(), AlarmManager.INTERVAL_FIFTEEN_MINUTES/900, pi);
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.activity_iimanager, menu);
return true;
}
}
And this is my SampleService that is meant to display a toast message.
For some reason I cannot get to see a toast message no matter how long I wait.
package com.example.iimanager;
import android.app.IntentService;
import android.app.Notification;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;
import android.widget.Toast;
public class SampleService extends IntentService {
public SampleService() {
super("SimpleService");
//Toast.makeText(getApplicationContext(), "this is my Toast message!!! =)", Toast.LENGTH_LONG).show();
}
#Override
protected void onHandleIntent(Intent intent) {
//do something
Toast.makeText(getApplicationContext(), "this is my Toast message!!! =)", Toast.LENGTH_LONG).show();
}
}
Can you please tell me what's wrong and what needs to be done to get it corrected?
Thank you very much in advance.
Copy the below 3 lines for toast call
Timer timer = new Timer();
TimerTask updateProfile = new SampleService(SampleService.this);
timer.scheduleAtFixedRate(updateProfile, 10,1000);
class CustomTimerTask extends TimerTask {
private Context context;
private Handler mHandler = new Handler();
// Write Custom Constructor to pass Context
public CustomTimerTask(Context con) {
this.context = con;
}
#Override
public void run() {
new Thread(new Runnable() {
#Override
public void run() {
mHandler.post(new Runnable() {
#Override
public void run() {
Toast.makeText(getApplicationContext(), "this is my Toast message!!! =)", Toast.LENGTH_LONG).show();
}
});
}
}).start();
}
}
Try following code,
MainActivity.java
public class MyService extends Service {
public static final long INTERVAL=60000;//variable for execute services every 1 minute
private Handler mHandler=new Handler(); // run on another Thread to avoid crash
private Timer mTimer=null; // timer handling
#Nullable
#Override
public IBinder onBind(Intent intent) {
throw new UnsupportedOperationException("unsupported Operation");
}
#Override
public void onCreate() {
// cancel if service is already existed
if(mTimer!=null)
mTimer.cancel();
else
mTimer=new Timer(); // recreate new timer
mTimer.scheduleAtFixedRate(new TimeDisplayTimerTask(),0,INTERVAL);// schedule task
}
#Override
public void onDestroy() {
Toast.makeText(this, "In Destroy", Toast.LENGTH_SHORT).show();//display toast when method called
mTimer.cancel();//cancel the timer
}
//inner class of TimeDisplayTimerTask
private class TimeDisplayTimerTask extends TimerTask {
#Override
public void run() {
// run on another thread
mHandler.post(new Runnable() {
#Override
public void run() {
// display toast at every 1 minute
Toast.makeText(getApplicationContext(), "Notify", Toast.LENGTH_SHORT).show();
}
});
}
}
}
MainActivity.java
public class MainActivity extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);//load the layout file
startService(new Intent(this,MyService.class));//use to start the services
}
}
Also add this code in your manifest file
AndroidManifest.xml
<service android:name=".MyService"
android:enabled="true"/>
Try to create a Timer object.Then use the scheduleAtFixedRate(TimerTask) to repeat the Toast message.
You can just make a looping thread which contains your code.
Like this:
public class Toaster extends Thread{
public void run(){
//Your code to loop
thread.sleep(60000)
}
}
Hope it helps!