my application requires a service that changes the system wallpaper in a particular time interval how should I implement this, please help???
Create your service class
class WallpaperService extends IntentService {
#Override
protected void onHandleIntent(Intent intent) {
Timer progressTimer = new Timer();
timeTask = new ProgressTimerTask();
progressTimer.scheduleAtFixedRate(timeTask, 0, 1000);
}
private class ProgressTimerTask extends TimerTask {
#Override
public void run() {
runOnUiThread(new Runnable() {
#Override
public void run() {
int currenMinutes = 0; // set your time here
changeWallpapers(currentMinutes);
}
});
}
}
private void changeWallpapers(int minutes) {
if(minutes == 1)
layout.setBackGround(Color.RED);
if(minutes == 2)
layout.setBackGround(Color.BLUE);
}
}
}
And then call your service Intent where your want
Well, I have implemented this function. I register an Alarm in the system and connect it to a BroadcastReceiver. When the BroadcastReceiver is triggered, in the OnReceive() method, you can set a wallpaper for the system.
Related
I am building a toast every 5 sec using some sample found.
The code works ok, but the service wont stop even i stopped the app.
Can anyone point out what is wrong?
public class MyService extends Service {
public static final long INTERVAL=5000;//variable to execute services every 5 second
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 5second
Toast.makeText(getApplicationContext(), "Notify", Toast.LENGTH_SHORT).show();
}
});
}
}
}
I keep receiving the toast Notify even the app had been closed.
add onTaskRemoved() method in your MyService,like this
#Override
public void onTaskRemoved(Intent rootIntent) {
stopSelf();///its will stop service
super.onTaskRemoved(rootIntent);
}
In your Activity onStop() you should call stopService(new Intent(context,YourService.class)); in order to stop your service
Run a service in background continuously. For example, a service has to be kicked off which will display a toast message 20 seconds once even if the app is closed.
public class AppService extends IntentService {
public int onStartCommand(Intent intent, int flags, int startId) {
return START_STICKY;
}
public AppService() {
super("AppService");
}
#Override
protected void onHandleIntent(Intent workIntent) {
Toast.makeText(getApplicationContext(), "hai", Toast.LENGTH_SHORT).show();
SystemClock.sleep(20000);
}
}
Below code works for me...
public class AppService extends Service {
#Override
public IBinder onBind(Intent intent) {
// TODO Auto-generated method stub
return null;
}
#Override
public void onCreate() {
Toast.makeText(this, " MyService Created ", Toast.LENGTH_LONG).show();
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
Toast.makeText(this, " MyService Started", Toast.LENGTH_LONG).show();
return START_STICKY;
}
}
Accepted answer will not work on from Android 8.0 (API level 26), see the android's background limitations here
Modification in Accepted Answer:
1: You have to invoke the service's startForeground() method within 5 seconds after starting the service. To do this, you can call startForeground() in onCreate() method of service.
public class AppService extends Service {
....
#Override
public void onCreate() {
startForeground(9999, Notification())
}
....
}
2: You must call startForegroundService() instead of startService() by checking API level from where you want to start the service.
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
context.startForegroundService(intent);
} else {
context.startService(intent);
}
This code work for me..
public class ServiceClass extends Service {
public static final int notify = 300000; //interval between two services(Here Service run every 5 Minute)
private Handler mHandler = new Handler(); //run on another Thread to avoid crash
private Timer mTimer = null; //timer handling
#Override
public IBinder onBind(Intent intent) {
throw new UnsupportedOperationException("Not yet implemented");
}
#Override
public void onCreate() {
if (mTimer != null) // Cancel if already existed
mTimer.cancel();
else
mTimer = new Timer(); //recreate new
mTimer.scheduleAtFixedRate(new TimeDisplay(), 0, notify); //Schedule task
}
#Override
public void onDestroy() {
super.onDestroy();
mTimer.cancel(); //For Cancel Timer
Log.d("service is ","Destroyed");
}
//class TimeDisplay for handling task
class TimeDisplay extends TimerTask {
#Override
public void run() {
// run on another thread
mHandler.post(new Runnable() {
#Override
public void run() {
Log.d("service is ","running");
}
});
}
}
}
In your manifest, where you declare your service, add:
android:process=":processname"
This lets the service run on a separate process and thus it will not be killed with the app.
You can then chose if you want to use foreground. It will show a persistent notification, but reduces the likelihood if the service being killed.
Further, if you want to create a continuously running service, use Service, NOT IntentService. IntentService stops when it is finished doing its action.
The service runs when I press home button or back button but the service is not running in background when app is closed. Moreover the service runs in background in some(LG Nexus 5) phones, but in most of the phones(Samsung,Xioami) service is not running when app is closed. When i goto Settings > Apps > Running, It always shows as app running and displays 1 service 1 thread. I am calling the service from MainActivity.java
I want the service always running in background even if the app is closed. Any help will be appreciated.
Here is code for service TimeService.java
public class TimeService extends Service implements
ConnectionCallbacks, OnConnectionFailedListener {
// constant
public static final long NOTIFY_INTERVAL = 30 * 60 * 1000; // 30 minutes
// run on another Thread to avoid crash
private Handler mHandler = new Handler();
// timer handling
private Timer mTimer = null;
#Override
public void onCreate() {
// cancel if already existed
if (mTimer != null) {
mTimer.cancel();
} else {
// recreate new
mTimer = new Timer();
}
// schedule task
mTimer.scheduleAtFixedRate(new TimeDisplayTimerTask(), 0, NOTIFY_INTERVAL);
}
#Override
public IBinder onBind(Intent intent) {
return null;
}
class TimeDisplayTimerTask extends TimerTask {
#Override
public void run() {
// run on another thread
mHandler.post(new Runnable() {
#Override
public void run() {
// Send message in background
sendSMS(number,msg)
}
});
}
}
MainActivity.java
public class MainActivity extends Activity
{
Button btnIn;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
btnIn = (Button) findViewById(R.id.btnIn);
btnIn.setOnClickListener(new View.OnClickListener() {
boolean enable = true;
#Override
public void onClick(View v) {
Intent intent = new Intent(MainActivity.this, TimeService.class);
startService(intent);
}
}
}
Android manifest
<service android:name=".TimeService" />
You should use a foreground service if you want keep alive your service.
To make it you must run the service in foreground
private void runForeground(){
//... Pending intent if you want attach it to the notification
Notification notification=new NotificationCompat.Builder(this)
.setSmallIcon(R.drawable.ic_launcher)
.setContentText(getString(R.string.string))
.setContentIntent(pendingIntent).build();
startForeground(NOTIFICATION_ID, notification);
}
NOTIFICATION_ID is a number for identify it, return sticky the service.
I was running the background task in a separate thread, while it should be in the main thread, that was the reason app was not running in background in some Phones.
class TimeDisplayTimerTask extends TimerTask {
#Override
public void run() {
// Send message in background
sendSMS(number,msg);
}
}
Currently im writing a camera app which should take pictures in a regular time intervall. For this my activity creates a IntentService, which starts a TimerTask with the desired delay. First time I start my app everything works fine. The pictures are taken in an regular time intervall of 10 seconds. But if i pause and resume my application the pictures are taken more frequently.
Here is my activity:
public class AndroidCameraExample extends Activity implements PictureTakenListener {
private static String CLASSTAG = "Android Surveillance Camera";
private Button captureButton;
private Context context;
private LinearLayout layoutForPreview;
private SurveillanceCamera camera;
// for calling the background service
private Intent backgroundServiceIntent = null;
// will send a notification if time has lapsed and we should
// take a new picture
private SurveillanceBroadcastReceiver receiver = null;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
context = this;
layoutForPreview = (LinearLayout) findViewById(R.id.camera_preview);
camera = new SurveillanceCamera(this, layoutForPreview);
captureButton = (Button) findViewById(R.id.button_capture);
captureButton.setOnClickListener(PictureCaptureListener);
camera.addPictureTakenListener(this);
startSurveillance();
}
private void startSurveillance() {
Settings.surveillanceIsActive = true;
camera.start();
startBackroundService();
registerBroadcastReceiver();
}
private void stopSurveillance() {
Settings.surveillanceIsActive = false;
if (receiver != null) {
unregisterReceiver(receiver);
receiver = null;
}
if (backgroundServiceIntent != null) {
stopService(backgroundServiceIntent);
backgroundServiceIntent = null;
}
camera.stop();
}
private void startBackroundService() {
if (isServiceRunning(SurveillanceBackgroundService.class)) {
Log.d(Settings.APPTAG, "The Service is already running");
}
if (backgroundServiceIntent == null) {
backgroundServiceIntent = new Intent(this, SurveillanceBackgroundService.class);
startService(backgroundServiceIntent);
}
}
private boolean isServiceRunning(Class<?> serviceClass) {
ActivityManager manager = (ActivityManager) getSystemService(Context.ACTIVITY_SERVICE);
for (RunningServiceInfo service : manager.getRunningServices(Integer.MAX_VALUE)) {
if (serviceClass.getName().equals(service.service.getClassName())) {
return true;
}
}
return false;
}
private void registerBroadcastReceiver() {
if (receiver == null) {
IntentFilter filter = new IntentFilter(SurveillanceBroadcastReceiver.ACTION_RESP);
filter.addCategory(Intent.CATEGORY_DEFAULT);
receiver = new SurveillanceBroadcastReceiver();
registerReceiver(receiver, filter);
}
}
public void onResume() {
super.onResume();
startSurveillance();
}
#Override
protected void onPause() {
super.onPause();
stopSurveillance();
}
class SurveillanceBroadcastReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
camera.takePicture();
}
}
My Service
public class SurveillanceBackgroundService extends IntentService {
#Override
protected void onHandleIntent(Intent intent) {
Timer t = new Timer();
t.schedule(new TimerTask() {
#Override
public void run() {
notifyTimeLapsed();
}
}, 100, Settings.timeIntervall * 1000);
}
private void notifyTimeLapsed() {
Intent broadcastIntent = new Intent();
broadcastIntent.setAction(SurveillanceBroadcastReceiver.ACTION_RESP);
broadcastIntent.addCategory(Intent.CATEGORY_DEFAULT);
sendBroadcast(broadcastIntent);
}
}
I aleady checked that the service isn't running (in background) while the app is paused and started again afterwards, so I don't see any reason why the pictureTaking Event should be triggered more ofter after resuming.
I also use a small wrapper class for camera handling but i don't think this causes the problem. if you need to code for suggesting any solutions i will post it here anyway.
Any hints or help for this`?
EDIT: I overwrite onDestroy and onStart to Cancel the Timer and start it again but the problem stays the same. After resume more pictures are taken than before.
UPDATE: If I remove the method onStart the timer seems to get canceled directly and isn't started again? I added some Logger output in the methods and get this information:
05-15 18:56:03.478: I/com.test.androidcameraexample(10061): SurveillanceBackgroundService onHandleIntent
05-15 18:56:03.498: I/com.test.androidcameraexample(10061): SurveillanceBackgroundService onDestroy
#Override
protected void onHandleIntent(Intent intent) {
if (t == null) {
t = new Timer();
t.schedule(new TimerTask() {
#Override
public void run() {
notifyTimeLapsed();
}
}, 100, Settings.timeIntervall * 1000);
}
}
#Override
public void onStart(Intent intent, int startId) {
super.onStart(intent, startId);
if (t == null) {
t = new Timer();
t.schedule(new TimerTask() {
#Override
public void run() {
notifyTimeLapsed();
}
}, 100, Settings.timeIntervall * 1000);
}
}
#Override
public void onDestroy() {
super.onDestroy();
t.cancel();
t = null;
}
My original answer was this:
You need to call either Timer.cancel() or TimerTask.cancel()
on the Timer or TimerTask that the service created, or else the
timer task will keep running in a background thread.
And then I added this:
To get this to work reliably, you could specify one Intent action
for starting the timer, and another action for stopping the timer.
But, there is actually a big (and subtle) problem with storing a Timer variable in an IntentService. An IntentService creates its own background thread, and it quickly kills itself (after onHandleIntent () returns) if there are no intents in its queue -- which would also mean your Timer value would be lost. So, even if you have 2 intent actions (for starting and stopping the timer), there is no way to guarantee that the stop action would have access to the original Timer value (since it could very well be creating a brand new IntentService instance)!
So, I recommend that you use the AlarmManager to schedule periodic alarms. See here for some training on how to do that.
I am building an android app and when it is running I need to make a call to the my web server at each minute if the user is connected to a certain network.
I plan to use a service to make that call but how do I call it at each minute?.
I think i need to use alaarm manager but where do I initalize it? in my start activity? I only need to execute the service when my app is running.
Thanks for your help.
If you want to call server only if app is running then no need to use alarm manager. there are other options like
CoundDownTimer
Thread
I prefer CoundownTimer in that scenario and you can use like this
CountDownTimer countDownTimer = new CountDownTimer(1000000, 60 * 1000) {
#Override
public void onTick(long millisUntilFinished) {
// Do something on a tick.
}
#Override
public void onFinish() {
// Do something, maybe?
this.start();
}
};
countDownTimer.start();
Try this ::
You can call this timer in your activity where you want it
private Timer autoUpdate;
#Override
public void onResume() {
super.onResume();
autoUpdate = new Timer();
autoUpdate.schedule(new TimerTask() {
#Override
public void run() {
runOnUiThread(new Runnable() {
public void run() {
//call your service from here
}
});
}
}, 0, 60000);//set time interval according to your requirement
}
Feel free to ask if you have any query :)
in Activity:
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
TestAlarmMessageReceiver almesr = new TestAlarmMessageReceiver(this, time);
}
BroadcastReceiver:
public class TestAlarmMessageReceiver extends BroadcastReceiver {
public TestAlarmMessageReceiver() {
}
public TestAlarmMessageReceiver(Context context, int timeout) { //timeout in seconds
AlarmManager alarmMgr = (AlarmManager)context.getSystemService(Context.ALARM_SERVICE);
Intent intent = new Intent(context, TestAlarmMessageReceiver.class);
PendingIntent pendingIntent = PendingIntent.getBroadcast(context, 0, intent,
PendingIntent.FLAG_CANCEL_CURRENT);
Calendar time = Calendar.getInstance();
time.setTimeInMillis(System.currentTimeMillis());
alarmMgr.setRepeating(AlarmManager.RTC_WAKEUP, time.getTimeInMillis(),
timeout*60*1000, pendingIntent);
}
#Override
public void onReceive(Context arg0, Intent arg1) {
arg0.startService(new Intent(arg0, TestMessageService.class));
}
}
Service:
public class TestMessageService extends Service {
#Override
public IBinder onBind(Intent intent) {
return null;
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
messageUpdateTask();
return super.onStartCommand(intent, flags, startId);
}
private void messageUpdateTask(){
GetMessagesUpdateAsyncTak getMessUpd = new GetMessagesUpdateAsyncTak();
getMessUpd.execute(this);
}
}
Call your web server using AsynTask http://developer.android.com/reference/android/os/AsyncTask.html
In onPost method in AsynTask class wait for one minute and call AsynTask.
You can call AsynTask by using below code :
BLSyncingProcedure objSyncingProcedure=new BLSyncingProcedure();
objSyncingProcedure.execute(HomeScreen.this);
BLSyncingProcedure is your AsynTask class name.