So I have a section of code that schedules an alarm as follows
public void scheduleAlarm(){
Log.d("Scheduler","Alarm is being scheduled");
Intent intent = new Intent(AlarmSettings.this, VolumeService.class);
intent.putExtra("MODE", mode);
PendingIntent pintent = PendingIntent.getService(AlarmSettings.this, id, intent, PendingIntent.FLAG_UPDATE_CURRENT);
Log.d("Alarm ID:", String.valueOf(id));
Log.d("Time", "Time was set for today: " + String.valueOf(time));
if(time < System.currentTimeMillis()){
time += (DAY);
Log.d("Time", "Time was set for tomorrow: " + String.valueOf(time));
}
AlarmManager alarm = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
alarm.set(AlarmManager.RTC_WAKEUP, time, pintent);
}
The service that is being called is as follows
public class VolumeService extends Service{
#Override
public void onCreate() {
super.onCreate();
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
//My Service code goes here and makes changes to some settings
Log.d("Service", "settings have been changed");
return START_NOT_STICKY;
}
#Override
public IBinder onBind(Intent arg0) {
// TODO Auto-generated method stub
return null;
}
}
and finally the portion of code that is supposed to cancel the alarms (stay with me, I know its lengthy)
//Unschedule the alarm that is getting deleted
Log.d("Unscheduler", "Alarm is being unscheduled");
Intent uIntent = new Intent(AlarmSettings.this, VolumeService.class);
PendingIntent uPintent = PendingIntent.getService(AlarmSettings.this, id, uIntent, PendingIntent.FLAG_UPDATE_CURRENT);
AlarmManager uAlarm = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
uAlarm.cancel(uPintent);
uPintent.cancel();
Now, my problem is that when the user deletes an alarm and subsequently calls the unschedule portion of the code, the volumeService is immediately called and the settings are changed. However, this defeats the purpose of the user deleting the alarm as they will only delete it to prevent it from firing and changing the settings. I have checked everywhere imaginable over the course of weeks and am just beating my head against the wall. Now that I have posted it on here though, it will be that I have made a very simple mistake. In any case, thanks for the help in advance!
--edit #1--
Removed the line uPintent.cancel() in the unscheduler portion and still doesn't work.
Related
I have made a simple example where a toast message will be shown after a time gap. I am using alarmmanager for scheduling a service from where the toast message will be shown. Now the problem is when the app is running it works properly, but when I close the app from task-manager the service is not getting restarted. Below is my service code
public class AlarmService extends Service {
#Nullable
#Override
public IBinder onBind(Intent intent) {
return null;
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
Toast.makeText(this, "Alarm Alarm Alarm", Toast.LENGTH_SHORT).show();
return Service.START_STICKY;
}
}
and below is my alarmmanager code :
alarmManager = (AlarmManager) this.getSystemService(Context.ALARM_SERVICE);
Intent intent = new Intent(this, AlarmService.class);
pendingIntent = PendingIntent.getService(this, 0, intent, 0);
alarmManager.setRepeating(AlarmManager.RTC_WAKEUP, System.currentTimeMillis(), 1000 * 10, pendingIntent);
Now, what is the solution for this? I need to keep the alarm even I close the app.
You can actually implement BroadcastReceiver at onDestroy to restart the service once the app/service is close by the system/user.
You can check the post here, and a tutorial for you, check here.
Hope it helps!
Try with below :-
return Service.START_CONTINUATION_MASK;
Hi a read other question retated to this but the responses never resolve my issue.
I want to start a service after a specific time with an Alarm Manager
alarmMgr = (AlarmManager)getApplicationContext().getSystemService(Context.ALARM_SERVICE);
alarmServiceIntent=new Intent(ListActivity.this, AlarmLevelServiceImproved.class);
alarmServiceIntent.putExtra("username",usernameID);
alarmServiceIntent.putExtra("password",userPass);
alarmIntent = PendingIntent.getBroadcast(getApplicationContext(), 0, alarmServiceIntent, 0);
. . .
Calendar calendar = Calendar.getInstance();
calendar.setTimeInMillis(System.currentTimeMillis());
calendar.add(Calendar.SECOND,10);
//calendar.set(Calendar.HOUR_OF_DAY, 19);
//alarmMgr.setInexactRepeating(AlarmManager.RTC,calendar.getTimeInMillis(),
// AlarmManager.INTERVAL_HALF_HOUR,alarmIntent);
//alarmMgr.setRepeating(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(),
// 1000 * 10, alarmIntent);
alarmMgr.set(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), alarmIntent);
Log.d("MioLog", "Alarm setted");
My service is:
public class AlarmLevelServiceImproved extends Service {
#Override
public void onCreate() {
Log.d("MioLog","MyAlarmService.onCreate()");
Toast.makeText(this, "MyAlarmService.onCreate()", Toast.LENGTH_LONG).show();
}
#Override
public IBinder onBind(Intent intent) {
Log.d("MioLog","MyAlarmService.onBind()");
Toast.makeText(this, "MyAlarmService.onBind()", Toast.LENGTH_LONG).show();
return null;
}
#Override
public void onDestroy() {
super.onDestroy();
Log.d("MioLog","MyAlarmService.onDestroy()");
Toast.makeText(this, "MyAlarmService.onDestroy()", Toast.LENGTH_LONG).show();
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
Log.d("MioLog","MyAlarmService.onStart()");
Toast.makeText(this, "MyAlarmService.onStart()", Toast.LENGTH_LONG).show();
return super.onStartCommand(intent, flags, startId);
}
}
And I add this on AndroidManifest.xml (The service class is on the sub-package "services"):
<service
android:name=".services.AlarmLevelServiceImproved"
android:enabled="true" />
But the service don't start and no log is printed.
Any idea how to start a Service with the AlarmManager?
I also suived this tutorial but I don't find any difference to my code
Thanks
To start a service with a PendingIntent, you need to use the static method PendingIntent.getService() to retrieve the appropriate PendingIntent.
Your code seems to be using PendingIntet.getBroadcast() for whatever reason. If you intend to have the AlarmManager indeed send a broadcast, you can start your service in your BroadcastReceiver, else change that line to getService():
from
alarmIntent = PendingIntent.getBroadcast(getApplicationContext(), 0, alarmServiceIntent, 0);
to
alarmIntent = PendingIntent.getService(getApplicationContext(), 0, alarmServiceIntent, 0);
You are using getBroadcast() to create the PendingIntent, but the Intent points to a service. That combination will not work.
Since you are using RTC_WAKEUP, you need to use getBroadcast() and a WakeLock to get reliable results. One approach is to use WakefulBroadcastReceiver as the base class of your receiver, where you then forward the work onto an IntentService.
Also, please do not pass user names and passwords in extras, as those are visible to anything that gets its hands on the Intent or PendingIntent. In this case, that should just be your app and the core OS, but I would still aim to do something a bit more secure.
Hi i need to stop the Background service which is already started after particular time.I will get the duration from server for when to stop the service.I have tried the Alarm Manager in android.
Calendar cal = Calendar.getInstance();
Intent intent = new Intent(context, MyService.class);
PendingIntent pintent = PendingIntent.getService(context, 0, intent, 0);
AlarmManager alarm = (AlarmManager)context.getSystemService(Context.ALARM_SERVICE);
// Start every 30 seconds
alarm.setRepeating(AlarmManager.RTC_WAKEUP, cal.getTimeInMillis(), 60*1000, pintent);
Log.e(TAG, "Service started in Activity");
This above code is starting the service after every one minute.But i dont want to start the service.I need to stop the service after a minute.How to do that.Is that possible to do with Alarm Manager.Please guide me.
Try that:
add parameter to your pendingIntent
Intent intent = new Intent(context, MyService.class);
intent.putExtra("param_name", "end");
PendingIntent pintent = PendingIntent.getService(context, 0, intent, 0);
Override onStartCommand() method in your Service
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
try{
String parameter = intent.getStringExtra("param_name");
if(parameter.equals("end")){
stopSelf();
}
}catch(Exception ex){
}
}
Also you can try to use Handler in your service:
Handler variable:
private Handler handler = new Handler() {
#Override
public void handleMessage(Message msg) {
switch (msg.what) {
case 1: {
stopSelf();
}break;
}
}
}
Delayed task:
handler.sendEmptyMessageDelayed(1, 60 * 1000);
Create the timer task to stop the service and assign the delay time which you are getting from your server
Timer timer = new Timer ();
TimerTask hourlyTask = new TimerTask () {
#Override
public void run () {
// your code here to stop the service ...
}
};
// schedule the task to run assign the time (DelayTime) which you are getting from server
timer.schedule (hourlyTask, DelayTime);
So what is the particular time.
You can do 1 thing make note of the starting time of the service. and if you want to stop the service after a specified duration or the specific time get the system current time compare it with that time if it match's stop the service. this should resolve the problem.
Tell me if it works for you..
======>
Just Follow the steps provided steps below:
Use sharedprefrence to save the start time of the service.
If your not familiar to shearedprefrence URL:http://examples.javacodegeeks.com/android/core/content/android-sharedpreferences-example/
Then in the service onStart method get the system current time if it
matches the time stop the service.
You have to create an broadcast receiver:
Calendar cal = Calendar.getInstance(); // this will return current time
// if you want to trigger after 1 minute then add into calender object
cal.add(Calendar.MINUTE, 1);
Intent intentAlarm = new Intent(this, AlarmReciever.class);
intentAlarm.setAction("My_Action");
AlarmManager alarmManager = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
PendingIntent pendingIntent = PendingIntent.getBroadcast(
MainActivity.this, REQUEST_CODE, intentAlarm,
PendingIntent.FLAG_UPDATE_CURRENT);
// set the alarm for particular time
alarmManager.set(AlarmManager.RTC_WAKEUP, cal.getTimeInMillis(), pendingIntent);
AlarmReciever .java
public class AlarmReciever extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
// call method to stop service
}
}
Also declare this AlarmReceiver class in menifest file
<receiver android:name=".AlarmReciever" >
</receiver>
> here i used the countdowntime for 30second
after 30second call stopself() method it will stop your
services..u can also do what ever u want on finsih you can also pass a
notification to the user....
new CountDownTimer(30000, 1000) {
#Override
public void onTick(long l) {
}
#Override
public void onFinish() {
//r u can also pass a notification
stopSelf();
}
}.start();
I am working on an application that should download a file from the network every X seconds to check for any change, I use a service to do that, but its execution is not fixed with the delay time rate, here is my code for the service:
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
Toast.makeText(this, "service starting", Toast.LENGTH_SHORT).show();
checkUpdate();
return START_STICKY;
}
private Void checkUpdate() {
timer.scheduleAtFixedRate(new TimerTask() {
public void run() {
Log.i("Service", String.valueOf(++counter));
if(Helper.isNetworkAvailable(getBaseContext())) {
// download file
} else {
Log.e("ServiceHandler", "Couldn't get any data from the url");
}
}else {
Log.e("Connection", "No connection");
}
}
}, 10000, 10000);
return null;
}
The output isn't fixed, it is supposed to run every 10 seconds, while running the service run in a random manner
How about setting up an AlarmManager within an IntentService? Much more accurate.
Intent intent = new Intent(context, YourClass.class);
PendingIntent pi = PendingIntent.getService(context, 0, intent, 0);
AlarmManager am = (AlarmManager) c.getSystemService(Context.ALARM_SERVICE);
am.setRepeating(AlarmManager.RTC, System.currentTimeMillis(), 10*1000, pi);
Make sure within YourClass.class (which is an IntentService), put your logic in the handleIntent(Intent intent), which will be called every 10 seconds by the PendingIntent sent by the AlarmManager.
P.S. Update your manifest
Hope it helps
Instead of Timer Class, use AlarmManager class. It also performs the same repeating tasks you want. AlamrManager is light weight and it runs even if your device is in sleep mode.
Also see this link Android: How to repeat a service with AlarmManager
For repetitive jobs android provides simple api, called Timer please look it. Very simple to use.
Try this :
#Override
public void onStart(Intent intent, int startId) {
StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder().permitAll().build();
StrictMode.setThreadPolicy(policy);
Log.d("Internet Available: ", ""+flag);
Calendar cal = Calendar.getInstance();
cal.add(Calendar.SECOND, 10);
Intent intent1 = new Intent(this, UpdateWidgetServiceDemo.class);
PendingIntent pintent = PendingIntent.getService(this, 0, intent1, 0);
AlarmManager alarm = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
int i;
i=15;
alarm.set(AlarmManager.RTC_WAKEUP, cal.getTimeInMillis(), pintent);
super.onStart(intent, startId);
}
REMOVE return START_STICKY;
I have the following broadcast reciever that gets called when the phone boots up (Bootreciever.java) and I'm trying to start a service that runs intermittently using a repeating alarm.
public void onReceive(Context context, Intent intent) {
Toast.makeText(context,"Inside onRecieve() :D" , Toast.LENGTH_LONG).show();
Log.d(getClass().getName(), "Inside onRecieve() :D");
AlarmManager am = (AlarmManager) context
.getSystemService(Context.ALARM_SERVICE);
Intent i = new Intent(context, MyService.class);
PendingIntent pi = PendingIntent.getBroadcast(context, 0, i, 0);
am.setRepeating(AlarmManager.ELAPSED_REALTIME_WAKEUP,
SystemClock.elapsedRealtime() + 3000, 1000, pi);
}
Basically, I'm setting a repeating alarm to trigger 3 seconds and on every second after that. The bootup complete broadcast is received just fine - but the service does not start. MyService.java looks like this:
public class MyService extends Service {
#Override
public IBinder onBind(Intent arg0) {
return null;
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
Toast.makeText(this, "Hello from MyService!", Toast.LENGTH_LONG);
Log.d(getClass().getName(), "Hello from MyService!");
stopSelf();
return super.onStartCommand(intent, flags, startId);
}
What am I doing wrong when starting the service?
Logcat does not tell me anything and I have the service defined in my manifest. On its own this service works when called using startService() but seem to fail when used within a PendingIntent.
Instead of PendingIntent.getBroadcast() use PendingIntent.getService()
I think you should check your duration because android gets a bit picky with alarms that trigger too often. In order to start a service the best way is to set the alarm to broadcast the intent to a broacast receiver and then get it to start your services.
Example 1 the receiver:
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.util.Log;
public class QoutesReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
// log instruction
Log.d("SomeService", "Receiving Broadcast, starting service");
// start the qoute service
Intent newService = new Intent(context, SomeService.class);
context.startService(newService);
}
}
Example 2 the Function that sets the alarm (this example runs every 2 mins):
public void setAlarm(Context context) {
// Get the current time
Calendar currTime = Calendar.getInstance();
// Get the intent (start the receiver)
Intent startReceiver = new Intent(context, MyReceiver.class);
PendingIntent pendReceiver = PendingIntent.getBroadcast(context, 0,
startReceiver, PendingIntent.FLAG_CANCEL_CURRENT);
// call the Alarm service
AlarmManager alarms = (AlarmManager) context
.getSystemService(Context.ALARM_SERVICE);
//Setup the alarm
alarms.setRepeating(AlarmManager.RTC_WAKEUP,
currTime.getTimeInMillis() + (2 * 60 * 1000), 2 * 60 * 1000,
pendReceiver);
}