I wish to create an app, which would change the wallpaper of the Android device at fixed intervals, say every hour or so. Currently in my code, I start a service and am using a Timer object. The Timer object would be invoked at regular intervals and change the wallpaper.
This is the code I am using currently. The wallpaper gets changed only once and not after that. Please let me know what should I do?
public class Wallpaper extends Service {
Timer mytimer;
int interval=60000;
Drawable drawable;
WallpaperManager wpm;
int prev=1;
#Override
public void onCreate() {
super.onCreate();
mytimer=new Timer();
wpm=WallpaperManager.getInstance(Wallpaper.this);
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
mytimer.schedule(new TimerTask() {
#Override
public void run() {
if(prev==1){
drawable = getResources().getDrawable(R.drawable.two);
prev=2;
}
else if(prev==2){
drawable = getResources().getDrawable(R.drawable.three);
prev=3;
}
else{
drawable = getResources().getDrawable(R.drawable.one);
prev=1;
}
Bitmap wallpaper=((BitmapDrawable)drawable).getBitmap();
try {
wpm.setBitmap(wallpaper);
} catch (IOException e) {
e.printStackTrace();
}
}
}, interval);
return super.onStartCommand(intent, flags, startId);
}
#Override
public IBinder onBind(Intent arg0) {
return null;
}
}
Also, do I need to use an AlarmManager or Handler to achieve this ? I am quite new to Android and a bit confused.
It looks like you're using the timer wrong. If you want to have it recur, you need to specify an initial delay as the second argument, and an interval as the third. Timer.schedule(timertask, initial delay, interval between recurrences);
Note: I'm talking about your call to myTimer.schedule(object, interval);
Try instead of Timer class ScheduledFuture
This helped for me to resolve all problems with timer tasks
Good luck!
private ScheduledFuture mytimer;
//...
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
ScheduledExecutorService timer = Executors.newScheduledThreadPool(1);
mytimer = timer.scheduleWithFixedDelay(new TimerTask() {
#Override
public void run() {
//...
}
}, 0, interval, TimeUnit.MILLISECONDS);
return super.onStartCommand(intent, flags, startId);
}
//...
#Override
public void onDestroy() {
super.onDestroy();
if (mytimer != null) {
mytimer.cancel(true);
}
//...
}
Related
I am developing an application that shows the different photos from server and user can set select photos as wallpaper of its device i used given code to set wallpaper it working but i want to wallpaper set automatically every day. I used this code.
Java
private void setAsWallpaper()
{
Picasso.get().load(imageUrl).into(new Target()
{
#Override
public void onBitmapLoaded(Bitmap bitmap, Picasso.LoadedFrom from)
{
progressBar.bringToFront();
progressBar.setVisibility(View.VISIBLE);
WallpaperManager wallpaperManager = WallpaperManager.getInstance(SetWallPaperFullScreenActivity.this);
try
{
wallpaperManager.setBitmap(bitmap);
}
catch (IOException e)
{
e.printStackTrace();
}
Toast.makeText(SetWallPaperFullScreenActivity.this, "Wallpaper set successfully.", Toast.LENGTH_SHORT).show();
progressBar.setVisibility(View.INVISIBLE);
}
#Override
public void onBitmapFailed(Exception e, Drawable errorDrawable)
{
Log.d("TAG", "Failed: ");
}
#Override
public void onPrepareLoad(Drawable placeHolderDrawable)
{
Log.d("TAG", "Prepare Load: ");
}
});
}
1) first you need to Schedule job which called every 24 hour. reference link
2) now use below method to set wallpaper
public void setWallpaper {
WallpaperManager myWallpaperManager =
WallpaperManager.getInstance(getApplicationContext());
try {
myWallpaperManager.setResource(R.drawable.wallpaper);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
Try this out,
Create a sticky service as shown below then i have created a TimerTask(Scheduler) which will run after every 24hrs there you can add your code for setting wallpaper. Don't forget to register the service in Manifest. Start this service from any activity.
You can refer the sticky service from here to know more
private Timer timer;
private TimerTask timerTask;
#Override
public IBinder onBind(Intent intent) {
return null;
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
startTimer();
return START_STICKY;
}
public void startTimer() {
timer = new Timer();
initializeTimerTask();
//schedule the timer, after the first **5000ms** the TimerTask will run in every **24hrs**
timer.schedule(timerTask, 5000, 86400000);
}
public void initializeTimerTask() {
timerTask = new TimerTask() {
public void run() {
//ToDo set wallapaper here
}
};
}
#Override
public void onDestroy() {
super.onDestroy();
if (timer != null) {
timer.cancel();
timer = null;
}
}
I have tried to stop my service, even my destroy method also executed but my service is not stopping. I have done my best. Please help me.
my code is mentioned below:
MainActivity
Intent intent=new Intent(this,Myservice.class);
startService(intent); //in start button.
Intent intent=new Intent(this,Myservice.class);
stopService(intent); //in stop button.
Myservice
public class Myservice extends Service {
#Nullable
#Override
public IBinder onBind(Intent intent) {
return null;
}
#Override
public void onCreate() {
super.onCreate();
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
Toast.makeText(this,"runing",Toast.LENGTH_LONG).show();
{
myTherad th=new myTherad();
Thread thread=new Thread(th);
thread.start();
}
return super.onStartCommand(intent, flags, startId);
}
#Override
public void onDestroy() {
Toast.makeText(this,"stop",Toast.LENGTH_LONG).show();
super.onDestroy();
}
class myTherad implements Runnable {
#Override
public void run() {
synchronized (this)
{
try {
for(int i=0;i<10;i++)
{
wait(1000);
Log.d("mfnhsdgjkfn","===="+String.valueOf(i));
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
stopSelf();
}
}
}
I think your service is stopped, but not your Thread. Cancel your Thread as well in onDestroy of your service by introducing for e.g. some kind of state variable:
class myTherad implements Runnable {
// Indicates that the runnable should stop.
private boolean shouldStop = false;
#Override
public void run() {
synchronized (this)
{
try {
for(int i=0;i<10 && !shouldStop;i++)
{
wait(1000);
Log.d("mfnhsdgjkfn","===="+String.valueOf(i));
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
stopSelf();
}
and declare your runnable as class attribute:
private myTherad runnable;
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
runnable=new myTherad();
Thread thread=new Thread(runnable);
thread.start();
return super.onStartCommand(intent, flags, startId);
}
and stop the runnable within your onDestroy:
#Override
public void onDestroy() {
Toast.makeText(this,"stop",Toast.LENGTH_LONG).show();
runnable.shouldStop = true;
super.onDestroy();
}
At least after the latest wait was executed, your thread should stop. You can optimize that, with an interruption.
We have to inturrpt thread that is running , thread.interrupt() will do that and give java.lang.InterruptedException , Try below code :
public class MyService extends Service {
public MyService() {}
myTherad th;
Thread thread;
#Nullable
#Override
public IBinder onBind(Intent intent) {
return null;
}
#Override
public void onCreate() {
super.onCreate();
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
Toast.makeText(this,"runing",Toast.LENGTH_LONG).show();
{
th=new myTherad();
thread=new Thread(th);
thread.start();
}
return super.onStartCommand(intent, flags, startId);
}
#Override
public void onDestroy() {
super.onDestroy();
Toast.makeText(this,"stop",Toast.LENGTH_LONG).show();
thread.interrupt();
}
class myTherad implements Runnable {
#Override
public void run() {
synchronized (this)
{
try {
for(int i=0;i<10;i++)
{
wait(1000);
Log.d("LOG","===="+String.valueOf(i));
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
stopSelf();
}
}
}
I want to update user location in every 30 second for which i am using volley request with Service.
The code in bellow:
public class CarLocationUpdateService extends Service {
Context context;
long delay = 1000; // delay for 1 sec.
long period = 10000; // repeat every 10 sec.
#Nullable
#Override
public IBinder onBind(Intent intent) {
return null;
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
context = this;
Handler ha=new Handler();
ha.postDelayed(new Runnable() {
#Override
public void run() {
//call function
CarLocationUpdateVolleyClass carLocationUpdateVolleyClass=new CarLocationUpdateVolleyClass(context);
carLocationUpdateVolleyClass.carLocationRequest();
}
}, delay);
return START_STICKY;
}
#Override
public void onDestroy() {
super.onDestroy();
}
}
use JobScheduler with firbaseJobDispatcher
https://developer.android.com/topic/performance/scheduling.html
You can use fused location service to get location updates.I have created a service to get location updates.This code will give you the location in onLocationChanged method.
Check out my answer here here
try this :
mHandler = new Handler();
Runnable r = new Runnable() {
#override
public void run() {
f();
mHandler.postDelayed(this, 30000);
}
};
mHandler.postDelayed(r, 30000);
you have to call the handler.postDelayed() method again inside the runnable because it´s executed only once, that´s a normal behaviour. Seperate the runnable from the handler like this:
Handler ha = new Handler();
private Runnable yourRunnable = new Runnable() {
#Override
public void run() {
CarLocationUpdateVolleyClass carLocationUpdateVolleyClass=new CarLocationUpdateVolleyClass(context);
carLocationUpdateVolleyClass.carLocationRequest();
ha.postDelayed(yourRunnable, 30000);
}
};
ha.post(yourRunnable);
by the way, your question tells us something about 30 seconds, but you just call it every 10 seconds.
Try this it works
public void doWork(){
new Handler().postDelayed(new Runnable() {
#Override
public void run() {
// This method will be executed once the timer is over
// insert your data to db here
// close this activity
doWork();
Toast.makeText(MainActivity.this, "LOL", Toast.LENGTH_SHORT).show();
}
}, TIME_OUT);
}
And then simple call this method in onStartCommand()
doWork();
final Handler ha=new Handler();
Runnable runnable = new Runnable() {
#Override
public void run() {
// ...
ha.postDelayed(this,30000);
}
};
ha.post(runnable);
i'm basicaly tying to open up a service, that every 10 seconds, will show up a toast to say "10 seconds passed"
this is what i'm trying to do,
and after many research ive found out that to loop a service i'm
going to need to use while (true) - sleep... method...
but the service or my app crashes every time i start the service
(or to be exact every time the timer runs out)
what is my problem ?
my guess is that maybe the contaxt i'm passing to the toast is wrong ?
maybe there is another way to show toast every 10 seconds in loop (inside a serivice) ?
here is my service code >
package com.greenroad.candidate.mywallpaperchanger;
import android.app.Service;
import android.content.Intent;
import android.os.IBinder;
import android.widget.Toast;
/**
* Created by pitsponet on 31/08/2015.
*/
public class myService extends Service {
#Override
public IBinder onBind(Intent intent) {
return null;
}
#Override
public void onCreate() {
super.onCreate();
Toast.makeText(getApplicationContext(), "service created",
Toast.LENGTH_LONG).show();
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
//try to run loop for showing up a toast
new Thread(new Runnable(){
public void run() {
// TODO Auto-generated method stub
while(true)
{
try {
Thread.sleep(10000);
} catch (InterruptedException e) {
e.printStackTrace();
}
//REST OF CODE HERE//
Toast.makeText(getApplicationContext(), "service started",
Toast.LENGTH_LONG).show();
}
}
}).start();
return super.onStartCommand(intent, flags, startId);
}
#Override
public void onDestroy() {
super.onDestroy();
Toast.makeText(getApplicationContext(), "service stoped",
Toast.LENGTH_LONG).show();
}
}
The reason for the crash, as explained by Brad, is because you are trying to perform UI operation from a non-UI Thread.
To achieve what you're trying to do, use the code below in your service. First of all remove your Thread in onStartCommand()
public class MyService extends Service {
private Handler mHandler;
#Override
public IBinder onBind(Intent intent) {
return null;
}
#Override
public void onCreate() {
super.onCreate();
mHandler = new Handler();
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
mHandler.postDelayed(ToastTask, 10000); // Starts the loop here
super.onStartCommand(intent, flags, startId);
}
#Override
public void onDestroy() {
// Stop the loop
mHandler.removeCallbacks(ToastTask);
super.onDestroy();
}
private Runnable ToastTask = new Runnable() {
#Override
public void run() {
Toast.makeText(MyService.this, "10 Seconds have passed", Toast.LENGTH_SHORT).show();
// Schedule this Runnable to run again after 10 sec
mHandler.postDelayed(this, 10000);
}
}
}
The reason that the service is crashing is because you're trying to run UI tasks (Toasts) outside of the main thread. Since you are creating a secondary thread for the infinite while loop, you'll need to post your Toast calls to the main looper as follows:
final Handler mainHandler = new Handler(getApplicationContext().getMainLooper());
mainHandler.post(new Runnable() {
#Override
public void run() {
Toast.makeText(getApplicationContext(), "Text to display", Toast.LENGTH_LONG).show();
}
});
That being said, I highly discourage using Thread.sleep() in any code that will run on a device, as this could lead to some serious issues. You should be able to accomplish the same thing (and also get rid of the infinite while-loop) using a Timer instead.
To use a Timer, you should be able to do something like the following:
// Schedules a TimerTask to execute every 10 seconds after a 10 second delay.
final Timer timer = new Timer();
timer.schedule(new TimerTask() {
#Override
public void run() {
// Your Toast code here.
}
}, 10000, 10000);
Here's a complete example:
public class MyService extends Service {
private Handler mainHandler;
private Timer timer;
public void onStartCommand(final Intent intent, final int flags, final int startId) {
mainHandler = new Handler(getApplicationContext().getMainLooper());
timer = new Timer();
timer.schedule(new MyTimerTask(), 10000, 10000);
}
public void onDestroy() {
timer.cancel();
}
private class MyTimerTask extends TimerTask {
#Override
public void run() {
mainHandler.post(new Runnable() {
#Override
public void run() {
Toast.makeText(getApplicationContext(), "Text to display", Toast.LENGTH_LONG).show();
}
});
}
}
}
I am showing toast message after every 20 seconds from current time but if I going out the app it is not working. Here is my code:
public class Main extends Activity {
final static private long ONE_SECOND = 1000;
final static private long TWENTY_SECONDS = ONE_SECOND * 20;
PendingIntent pi;
BroadcastReceiver br;
AlarmManager am;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
br = new BroadcastReceiver() {
#Override
public void onReceive(Context c, Intent i) {
Toast.makeText(c, "Rise and Shine!", Toast.LENGTH_LONG).show();
Log.i("Receive message in every five seconds", "message");
}
};
registerReceiver(br, new IntentFilter("com.authorwjf.wakeywakey"));
pi = PendingIntent.getBroadcast(this, 0, new Intent(
"com.authorwjf.wakeywakey"), 0);
am = (AlarmManager) (this.getSystemService(Context.ALARM_SERVICE));
am.setRepeating(AlarmManager.RTC_WAKEUP, SystemClock.elapsedRealtime(),
TWENTY_SECONDS, pi);
}
#Override
protected void onDestroy() {
am.cancel(pi);
unregisterReceiver(br);
super.onDestroy();
}
}
My question is if the app is not running but still it can show toast message? How can it possible in android?
you must create a Class Updater which contain a Handler
it will be executed periodically (you can define this periode) like that:
import android.os.Handler;
public class Updater {
private Handler mHandler = new Handler();
private Runnable mStatusChecker;
final static private long TWENTY_SECONDS = 20000;
private int UPDATE_INTERVAL = TWENTY_SECONDS;
public Updater(final Runnable updater){
mStatusChecker = new Runnable() {
#Override
public void run() {
updater.run();
mHandler.postDelayed(this, UPDATE_INTERVAL);
}
};
}
public Updater(Runnable updater, int interval){
this(updater);
UPDATE_INTERVAL = interval;
}
public void startUpdates(){
mStatusChecker.run();
}
public void stopUpdates(){
mHandler.removeCallbacks(mStatusChecker);
}}
than create a service "ServiceOn" :
public class ServiceOn extends Service {
Updater updater = new Updater(new Runnable() {
#Override
public void run() {
// put your code here
// toast or what you want
}});
#Override
public IBinder onBind(Intent arg0)
{
return null;
}
#Override
public void onCreate()
{
updater.startUpdates();
}
#Override
public int onStartCommand(Intent intent, int flags, int startId)
{
return super.onStartCommand(intent, flags, startId);
}
#Override
public void onDestroy()
{
updater.stopUpdates();
super.onDestroy();
}}
and finally in your activity you can call this service:
context.startService(new Intent(context, ServiceOn.class));
this will work for every 20 seconds even if the app stop running
Try This Code i hope its working...
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
final Handler h=new Handler();
final Runnable r=new Runnable() {
public void run() {
// TODO Auto-generated method stub
Toast.makeText(getBaseContext(),"Example OF Practicle 8",Toast.LENGTH_SHORT).show();
}
};
Timer t=new Timer();
t.scheduleAtFixedRate(new TimerTask() {
#Override
public void run() {
// TODO Auto-generated method stub
h.post(r);
}
},2000, 5000);
You can use setTimeout
setTimeout( function(){
toastr.clear(); // User to Clear the Toast Message Popup
}, 1000 ); // We can set our own time interval to disappear the popup
Hope it will help you