I am creating an app that vibrate and beep every 30 sec and when I log out the vibrate and beep must be cancelled and when I log in the vibrate and beep should resume.
NOTE: it must vibrate and beep for every 30 sec until I log out
In my app I am using TimerTask for this implementation
this is the code for vibrate and beep using TimerTask
static TimerTask Task;
final static Handler handler = new Handler();
static Timer t = new Timer();
public static void vib() {
Task = new TimerTask() {
public void run() {
handler.post(new Runnable() {
public void run() {
Vibrator vibrator = (Vibrator) ApplicationUtils.getContext().getSystemService(Context.VIBRATOR_SERVICE);
vibrator.vibrate(3000);
playSound();
Log.d("TIMER", "Timer set on");
}
});
}
};
t.schedule(Task, 0, 30000);
}
This is the code I'm using in logout section
public void stopvib() {
if (Task != null) {
// Log.d("TIMER", "timer canceled");
t.cancel();
Task.cancel();
}
}
Note: I also removed the Task.cancel(); but still I am getting same error
My vibrate working fine before logout and again login I am geting error
java.lang.IllegalStateException: Timer was cancelled
at java.util.Timer.scheduleImpl(Timer.java:562)
at java.util.Timer.schedule(Timer.java:481)
at com.vib(AlertListActivity.java:724)
can any one help me with this coding. Where did I go wrong?
i have recently run this code and is working fine. This can be achieved using broadcast Receiver.You have to implement separate CustomTimer task that extend TimerTask:
Activity mActivity=null;
public MyCustomTimer(Activity mActivity) {
this.mActivity=mActivity;
}
#Override
public void run() {
this.mActivity.runOnUiThread(new Runnable() {
#Override
public void run() {
Toast.makeText(mActivity, "Write you code here",Toast.LENGTH_LONG).show();
Log.d("MyCustomTimer","Call");
}
});
}
After this you have to implement BroadCast Receive in that class where you want to implement " vib() " method.:
Let say, in my case (just for example ) is MainActivity:
public class MainActivity extends Activity {
private MyCustomTimer myCustomTimer = null;
BroadcastReceiver mBr_Start = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
if (intent.getAction().equals("START_VIBRATION")) {
System.out.println("onreceive :START_VIBRATION");
vib();
}
}
};
BroadcastReceiver mBr_Stop = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
if (intent.getAction().equals("STOP_VIBRATION")) {
stopVibration();
}
}
};
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
IntentFilter mIntentFilter = new IntentFilter();
mIntentFilter.addAction("START_VIBRATION");
registerReceiver(mBr_Start, mIntentFilter);
IntentFilter mIntentFilter2 = new IntentFilter();
mIntentFilter2.addAction("STOP_VIBRATION");
registerReceiver(mBr_Stop, mIntentFilter2);
Button b1 = (Button) findViewById(R.id.button1);
b1.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
Intent i = new Intent(MainActivity.this, MySecondActivity.class)
.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(i);
}
});
}
#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_main, menu);
return true;
}
private void vib() {
myCustomTimer = new MyCustomTimer(MainActivity.this);
Timer timer = new Timer();
timer.scheduleAtFixedRate(myCustomTimer, 0, 30000);
}
private void stopVibration() {
Log.d("MainActivity", "Before Cancel");
if (null != myCustomTimer)
myCustomTimer.cancel();
Log.d("MainActivity", "After Cancel");
}
}
Now,you can start Or stop vibration by implementing these lines:
To start vibration:
Intent i=new Intent("START_VIBRATION");
mActivity.sendBroadcast(i);
To Stop:
Intent i=new Intent("STOP_VIBRATION");
mActivity.sendBroadcast(i);
Note:
onDestroy() of MainActivity (in your case,Where you implement Broadcast Receiver,unregister BroadcastReceiver.)
Set timer instance to null when you logout and then initialize it everytime user logged in the app. This will fix the "Timer was cancelled" related issues.
Why do you need a static TimerTask.You can give like this which works fine for me.
timer.schedule(new TimerTask() {
#Override
public void run() {
//your code
}
}, 0, 30000);
While logout use, timer.cancel().
Here you can simply cancel the timer.No need to cancel the TimerTask.
Related
I try to run a method in my service every two seconds, but when i start the services just run one time
This is the relevant code:
the start service:
mViewHolder.mLinearLayoutContainer.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Intent launchIntent = view.getContext().getPackageManager().getLaunchIntentForPackage(mListStorage.get(position).getAdrress());
mApkPackage = mListStorage.get(position).getAdrress();
Intent intent = new Intent(view.getContext(), KillerService.class);
if(mApkPackage != null){
intent.putExtra("NAMEAPK", mApkPackage);
view.getContext().startService(new Intent(view.getContext().getApplicationContext(), KillerService.class));
view.getContext().bindService(intent,mServiceConnection, Context.BIND_AUTO_CREATE);
}
if (launchIntent != null) {
view.getContext().startActivity(launchIntent);//null pointer check in case package name was not found
}
}
});
And this is from my Service class:
#Override
protected void onHandleIntent(#Nullable Intent intent) {
final Handler handler = new Handler();
handler.postDelayed(new Runnable() {
#Override
public void run() {
//mAppsNames();
Log.d("SYSTEMRUNNIGKILLI", "matandoapps");
}
}, 2000);
}
#Nullable
#Override
public IBinder onBind(Intent intent) {
mApkName = intent.getStringExtra("NAMEAPK");
Log.d("HOLAXD", mApkName);
return null;
}
#Override
public void onCreate() {
super.onCreate();
}
The part of Log.d("SYSTEMRUNNIGKILLI", "matandoapps"); just run one time and not every 2 seconds.
You are using wrong method to call code after every 2 seconds . Try to use this method
new Timer().scheduleAtFixedRate(new TimerTask() {
#Override
public void run() {}
}, 0, 1000); //1000 miliseconds equal to 1 second
Another way just add handler.postDelayed(this,2000);
final Handler handler = new Handler();
handler.postDelayed(new Runnable() {
#Override
public void run() {
//mAppsNames();
Log.d("SYSTEMRUNNIGKILLI", "matandoapps");
handler.postDelayed(this,2000);
}
}, 2000);
I need to write an application to open the browser (sample site www.onet.pl), which will restart every 3 hours. The commotion of restart was displayed. I managed to create such a layout, but I can not handle the cyclical restart. Please help where to add and what code? One class is enough.
This is my code:
public class MainActivity extends AppCompatActivity {
private Object v;
Handler mHandler;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
start(null);
m_Runnable.run();
}
public void start(View v) {
Uri uri = Uri.parse("http://onet.pl");
Intent i = new Intent(Intent.ACTION_VIEW, uri);
startActivity(i);
this.mHandler = new Handler();
}
private final Runnable m_Runnable = new Runnable() {
public void run() {
Toast.makeText(MainActivity.this, "odświezenie strony", Toast.LENGTH_SHORT).show();
MainActivity.this.mHandler.postDelayed(m_Runnable, 15000);
}
};
}
You could use a timer instead of Runnable.
Timer timer = new Timer();
timer.scheduleAtFixedRate(new TimerTask() {
#Override
public void run() {
Toast.makeText(MainActivity.this, "odświezenie strony", Toast.LENGTH_SHORT).show();
//and put the rest of your code here
}
},0,5000);
So I have this code, that has a countdown timer in a service with a 10 second timer. What I want to do is in the onFinish() method I want to launch the Activity (which is called MainActivity) automatically even when I am outside the app.
public class TimeDisplayTimerTask extends TimerTask{
CountDownTimer timer;
NotificationCompat.Builder notification;
private static final String TAG="com.timer";
private Handler mHandler = new Handler();
#Override
public void run() {
// run on another thread
mHandler.post(new Runnable() {
#Override
public void run() {
// display toast
timer = new CountDownTimer(10000, 1000) {
#Override
public void onFinish(){
}
#Override
public void onTick(long millisUntilFinished) {
Log.i(TAG,"" + millisUntilFinished/1000);
}
};
timer.start();
}
});
}
}
Try This to open your main activty after 10 second.
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
new Handler().postDelayed(new Runnable() {
#Override
public void run() {
// launch your main activity here and finish your current activity
}
}, 10000);
}
Probably you will have to override lifecycle method's and also use PARTIAL_WAKE_LOCK to keep cpu running untill you finish execution, in case user lock screen.
If you are inside a service then simply launch you activity using intent. Put this code in your onFinish() method:
Intent i = new Intent();
i.setClass(this, MainActivity.class);
i.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(i);
You neet to pass an activity context to your TimeDisplayTimerTask :
public class TimeDisplayTimerTask extends TimerTask{
CountDownTimer timer;
NotificationCompat.Builder notification;
private static final String TAG="com.timer";
private Handler mHandler = new Handler();
private Activity mActivity;
public TimeDisplayTimerTask(Activity activity){
mActivity = activity;
super();
}
#Override
public void run() {
// run on another thread
mHandler.post(new Runnable() {
#Override
public void run() {
// display toast
timer = new CountDownTimer(10000, 1000) {
#Override
public void onFinish(){
if (activity != null {
Intent startIntent = new Intent(activity, MainActivity.class);
startIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
activity.startActivity(startIntent);
}
}
#Override
public void onTick(long millisUntilFinished) {
Log.i(TAG,"" + millisUntilFinished/1000);
}
};
timer.start();
}
});
}
}
So I have a very stupid problem. I am able to create a simple timer task that ticks every second:
final Timer timer = new Timer();
timer.schedule(new TimerTask() {
#Override
public void run() {
runOnUiThread(new Runnable() {
#Override
public void run() {
if (counter == 0) {
//Reload Map...
timer.cancel();
Intent intent = new Intent(MapsActivity.this, MapsActivity.class);
startActivity(intent);
} else {
TimeLabel.setText(Integer.toString(counter));
counter = counter - 1;
}
}
});
}
}, 0, 1000);
After one minute, it will reload my google map. But when I try to open other activity, and try to go back to Map, my MapsActivity is not killed, (even though I used finish();). That's is why my timer is overlapping.
I have a guess that I should create the timer OUTSIDE onCreate, but didn't success in doing so. Can you help me guys?
Try this
public class MainActivity extends Activity {
//Global Variables
Timer timer;
TimerTask task;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//Make a method to make it cleaner
setTimer();
}
private void setTimer() {
timer = new Timer();
task = new TimerTask() {
#Override
public void run() {
runOnUiThread(new Runnable() {
#Override
public void run() {
if (counter == 0) {
//Reload Map...
timer.cancel();
Intent intent = new Intent(MapsActivity.this, MapsActivity.class);
startActivity(intent);
} else {
TimeLabel.setText(Integer.toString(counter));
counter = counter - 1;
}
}
});
}
};
}
#Override
protected void onResume() {
super.onResume();
//This will be called after onCreate or your activity is resumed
timer.schedule(task, 0, 1000);
}
#Override
protected void onPause() {
super.onPause();
//This will be called if the app is sent to background or the phone is locked
//Also this prevent you from duplicating the instance of your timer
timer.cancel();
}
}
/**
* Send Button click event.
**/
send.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
NetAsync(view);
}
});
}
On click event the "NetAsync(view)" execute and send the gps coordinates to server, but what i want is that instead of using button click event when user start the app "NetAsync(view)" execute automatically after every 10 minutes. Please tell me how to do this as i am new to android programming.
you can do it using TimerTask and Timer class like this
final Handler handler = new Handler();
Timer timer = new Timer();
TimerTask doAsynchronousTask = new TimerTask() {
#Override
public void run() {
handler.post(new Runnable() {
public void run() {
try {
//your method here
} catch (Exception e) {
}
}
});
}
};
timer.schedule(doAsynchronousTask, 0, 600000); //execute in every 10 minutes
Try Something like below:
TimerTask scanTask;
final Handler handler = new Handler();
Timer t = new Timer();
public void doWifiScan(){
scanTask = new TimerTask() {
public void run() {
handler.post(new Runnable() {
public void run() {
NetAsync(view);
}
});
}};
t.schedule(scanTask, 300, 600000);
}
Using Handler You can easily achieve your goal please follow bellow code,
Handler handler = new Handler();
handler.postDelayed(new Runnable() {
#Override
public void run() {
if (!isSyncStart) {
startSyncProcess(true); //write Your Method Here!
}
}
}, 600000);
Use AlarmManager with Broadcast Receiver
private PendingIntent mPingAlarmPendIntent;
private static final String PING_ALARM = "com.sithagi.PING_ALARM";
private Intent mPingAlarmIntent = new Intent(PING_ALARM);
private BroadcastReceiver mPingAlarmReceiver = new PingAlarmReceiver();
mPingAlarmPendIntent = PendingIntent.getBroadcast(getApplicationContext(), 0, mPingAlarmIntent,
PendingIntent.FLAG_UPDATE_CURRENT);
// Each and every 15 minutes will trigger onReceive of your BroadcastReceiver
((AlarmManager)getSystemService(Context.ALARM_SERVICE)).setInexactRepeating(AlarmManager.RTC_WAKEUP,
System.currentTimeMillis() + (AlarmManager.INTERVAL_FIFTEEN_MINUTES), AlarmManager.INTERVAL_FIFTEEN_MINUTES, mPingAlarmPendIntent);
// Register the receiver
registerReceiver(mPingAlarmReceiver, new IntentFilter(PING_ALARM));
// To cancel Alarm Service
((AlarmManager)getSystemService(Context.ALARM_SERVICE)).cancel(mPingAlarmPendIntent);
// unregister the receiver onDestroy or if you want stop
unregisterReceiver(mPingAlarmReceiver);
/**
* BroadcastReceiver will trigger
*/
private class PingAlarmReceiver extends BroadcastReceiver {
public void onReceive(Context ctx, Intent i) {
// Do your work here
}
}