I am having a problem getting my pendingIntent to fire. I have done some troubleshooting using the logcat etc. and in the end I am almost positive that my problem is actually in my pendingIntent method. The times I have set are correct, and the method is getting called, but nothing happens at the scheduled times.
Here is the method that I use to create the pendingIntent
public void scheduleAlarm(){
Log.d("Alarm scheduler","Alarm is being scheduled");
Intent changeVol = new Intent();
changeVol.setClass(this, VolumeService.class);
PendingIntent sender = PendingIntent.getService(this, 0, changeVol, 0);
AlarmManager alarmManager = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
alarmManager.set(AlarmManager.RTC_WAKEUP, time, sender);
//Toast.makeText(this, "Volume Adjusted!", Toast.LENGTH_LONG).show();
}
Here is the service class:
public class VolumeService extends Service{
#Override
public void onCreate() {
super.onCreate();
Log.d("Service", "Service has been called.");
Toast.makeText(getApplicationContext(), "Service Called!", Toast.LENGTH_LONG).show();
}
#Override
public IBinder onBind(Intent arg0) {
// TODO Auto-generated method stub
return null;
}
}
The log in the scheduleAlarm() class is working as I planned but then nothing happens, so I assume it is my pendingIntent.
Thanks in advance!
Figured it out! The problem was in the Service class, I changed a few other things around too.
However, I believe the main problem was that in my service class in the onCreate method I was trying to run my code. But this needed to be done in the onStartCommand method
public class VolumeService extends Service{
#Override
public void onCreate() {
super.onCreate();
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
Toast.makeText(getApplicationContext(), "Service started", Toast.LENGTH_LONG).show();
return START_NOT_STICKY;
}
#Override
public IBinder onBind(Intent arg0) {
// TODO Auto-generated method stub
return null;
}
}
and a few changes were made in the class starting the service as seen here:
public void scheduleAlarm(){
Log.d("Alarm scheduler","Alarm is being scheduled");
Intent intent = new Intent(AlarmSettings.this, VolumeService.class);
PendingIntent pintent = PendingIntent.getService(AlarmSettings.this, 0, intent, 0);
AlarmManager alarm = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
alarm.set(AlarmManager.RTC_WAKEUP, time, pintent);
}
Related
I ring alarm at particular user entered time. The problem is that after some time, the alarm rings again even if no time is set. This repeated alarm does not ring after after a fixed time. Sometimes it rings after 2 minutes, sometimes after 7 minutes and so on..I don't want this, It is ruining my project. Below is my code, can you help me:
Intent myIntent = new Intent(ReminderService.this, MyReceiver.class);
int randomPIN = (int)(Math.random()*9000)+1000;
pendingIntent = PendingIntent.getBroadcast(ReminderService.this, randomPIN, myIntent,pendingIntent.FLAG_ONE_SHOT);
AlarmManager alarmManager = (AlarmManager)getSystemService(ALARM_SERVICE);
alarmManager.set(AlarmManager.RTC, System.currentTimeMillis() , pendingIntent);
MyReceiver.java:
package app.aguai.medieazy;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
public class MyReceiver extends BroadcastReceiver
{
#Override
public void onReceive(Context context, Intent intent)
{
Intent service1 = new Intent(context, MyAlarmService.class);
context.startService(service1);
}
}
And My AlarmService.java:
public class MyAlarmService extends Service
{
private NotificationManager mManager;
#Override
public IBinder onBind(Intent arg0)
{
// TODO Auto-generated method stub
return null;
}
#Override
public void onCreate()
{
// TODO Auto-generated method stub
super.onCreate();
}
#SuppressWarnings("static-access")
#Override
public void onStart(Intent intent, int startId)
{
super.onStart(intent, startId);
Calendar c = Calendar.getInstance();
int hour = c.get(Calendar.HOUR_OF_DAY);
int min=c.get(Calendar.MINUTE);
int sec=c.get(Calendar.SECOND);
String currenttime= String.valueOf(hour)+" : "+String.valueOf(min)+" : "+String.valueOf(sec);
PrescribedDB db=new PrescribedDB(getApplicationContext());
Intent i=new Intent(MyAlarmService.this,ReminderPopUp.class);
i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
i.putExtra("name",db.getMed(currenttime));
i.putExtra("time",currenttime);
startActivity(i);
}
#Override
public void onDestroy()
{
// TODO Auto-generated method stub
super.onDestroy();
}
}
I have to launch this project tomorrow and this is the only small bug in my big project. Please help. Thanx.
I have implemented an Alarm manager and receiver in my application, all is working perfectly. The issue I am having is when I press the back button to close the application, the alarm doesn't run at the time specified. Below is the code I am using:
My Receiver Code
public class MyReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
// TODO Auto-generated method stub
System.out.println("SERVICE RECIEVED");
Intent service1 = new Intent(context, MyAlarmService.class);
context.startService(service1);
}
}
My Alarm Service Code
public class MyAlarmService extends Service {
#Override
public IBinder onBind(Intent arg0) {
// TODO Auto-generated method stub
return null;
}
#Override
public void onCreate() {
// TODO Auto-generated method stub
super.onCreate();
}
#SuppressWarnings("static-access")
#Override
public void onStart(Intent intent, int startId) {
super.onStart(intent, startId);
Intent _intent = new Intent(getBaseContext(), FirstCallActivity.class);
_intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
getApplication().startActivity(_intent);
}
#Override
public void onDestroy() {
// TODO Auto-generated method stub
super.onDestroy();
}
}
Start Alarm Code
public void startAlarm(Calendar cal) {
// Create a new PendingIntent and add it to the AlarmManager
Intent intent = new Intent(this, FirstCallActivity.class);
PendingIntent pendingIntent = PendingIntent.getActivity(this, 12345,
intent, PendingIntent.FLAG_CANCEL_CURRENT);
AlarmManager am = (AlarmManager) getSystemService(Activity.ALARM_SERVICE);
am.set(AlarmManager.RTC_WAKEUP, cal.getTimeInMillis(), pendingIntent);
}
Manifest Code (within application tags)
<service
android:name=".MyAlarmService"
android:enabled="true" />
<receiver android:name=".MyReceiver" />
Could anyone explain why this is happening? I know if the application is fully closed nothing is going to happen, but I it seems strange the back button causing this issue because the application is still running in the background.
Thanks
It turns out that the app was being closed on the back button. By stopping the app closing on the back button press with the code below, the function required for the set alarm run correctly.
#Override
public void onBackPressed() {
System.out.println("BACK PRESS");
moveTaskToBack(true);
}
I would like to know if this is the proper way for stopping my periodically called service or not. I have a static boolean variable isServiceStopped in my MainActivity where I can start or stop the ongoing service by clicking on a button. As you see I reschedule my service in the onDestroy() method with AlarmManager, so if I called stopService() in my MainActvity it would just destroy the service but reschedule it again so there would not be any effect.
This is why I am using a flag, a static boolean variable that I can set in my MainActivity: if I click the button to stop the service I set this flag true and the service will not be rescheduled again as it will not run in the onDestroy() method.
This is working, but I personally believe that this is just a bad workaround since if I close the app how would the system find the static variable if only the service is running? So what is the proper way doing this? Should I put the reschedule part in the onStartCommand()?
Thanks!
public class AsyService extends Service {
#Override
public IBinder onBind(Intent i) {
return null;
}
#Override
public void onCreate() {
super.onCreate();
}
#Override
public void onStart(Intent intent, int startId) {
super.onStart(intent, startId);
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
Toast.makeText(this, "service starting", Toast.LENGTH_SHORT).show();
return START_NOT_STICKY;
}
#Override
public void onDestroy() {
//Right now I have a static variable defined in MainActivity to set the boolean isServiceStopped
if (!MainActivity.isServiceStopped){
AlarmManager alarm = (AlarmManager)getSystemService(ALARM_SERVICE);
alarm.set(
AlarmManager.RTC_WAKEUP,
System.currentTimeMillis() + (1000 * 15),
PendingIntent.getService(this, 0, new Intent(this, AsyService.class), 0)
);
}
}
}
MainAcvitiy:
btn2.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
PendingIntent pendingIntent = PendingIntent.getBroadcast(MainActivity.this, 1, new Intent(MainActivity.this, AsyService.class), PendingIntent.FLAG_UPDATE_CURRENT);
AlarmManager alarm = (AlarmManager)getSystemService(ALARM_SERVICE);
alarm.cancel(pendingIntent);
}
});
The correct approach would be to recreate the original pending intent, cancel it, and remove the service from the Alarm Manager. I dont know why you would want to terminate the service from within itself.
PendingIntent pendingIntent = PendingIntent.getBroadcast(mContext, id, intent, PendingIntent.FLAG_UPDATE_CURRENT);
alarmManager.cancel(pendingIntent);
I have a service which should be run for example every 1 minute. I used a broadcast receiver and AlarmManager to make this work. And also I call PowerManger.aquire() to make sure cpu doesn't sleep before the service starts. For first 2 or 3 days the app runs okay but after that the service doesn't get started. Sounds alarmManager doesn't start it. Any Idea why?
public class MyReceiver extends BroadcastReceiver {
PowerManager pawerManager;
public static PowerManager.WakeLock wakeLock=null;
#Override
public void onReceive(Context context, Intent intent) {
// TODO Auto-generated method stub
pawerManager = (PowerManager) context.getSystemService(Context.POWER_SERVICE);
wakeLock = pawerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "");
wakeLock.acquire();
Intent serviceIntent=new Intent(context,MyService.class);
context.startService(serviceIntent);
}
}
And The Service:
public class MyService extends Service {
void releaseTheLock(){
if (MyReceiver.wakeLock != null){
MyReceiver.wakeLock.release();
MyReceiver.wakeLock=null;
}
}
#Override
public IBinder onBind(Intent intent) {
// TODO Auto-generated method stub
return null;
}
#Override
public void onCreate() {
// TODO Auto-generated method stub
super.onCreate();
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
// TODO Auto-generated method stub
final Context serviceContext=this;
new Thread(new Runnable() {
#Override
public void run() {
// TODO Auto-generated method stub
/*
Do something
*/
//Now set the timer
long currntTime = System.currentTimeMillis();
AlarmManager mgr=(AlarmManager)getApplicationContext().getSystemService(Context.ALARM_SERVICE);
Intent i= new Intent(serviceContext, MyReceiver.class);
PendingIntent pi=PendingIntent.getBroadcast(serviceContext, 0, i, 0);
mgr.set(AlarmManager.RTC_WAKEUP, currntTime + 60000 , pi);
stopSelf();
releaseTheLock();
return;
}
}).start();
return START_STICKY;
}
}
And here's the receiver registration in manifest:
<receiver android:name=".TimeReceiver"></receiver>
I suspect you're running into a race condition where the Service object (Context) is being cleaned up and destroyed, but is being used as the Context for your PendingIntent. Here are a couple of options:
Change your creation of PendingIntent to use the application context. This context is the the one in which your PendingIntent is sent. So if you use a transient context, like the Service object itself, it may no longer be valid.
Revise this to not use the BroadcastReceiver at all. You can create a PendingIntent for your Service via the PendingIntent.getService() method. Again, use your application context here rather than the Service object itself.
Have you tried with setRepeating?
alarmMgr.setRepeating(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(),
1000 * 60, alarmIntent);
I am trying to set up an alarm that will run in the background and trigger (eventually) a save event. At the moment I simply have this code attached to a button. Press the button and the alarm should start leaving Toast messages behind as an indication that it is functioning. At the moment everything runs except the onReceive in the BroadcastReceiver is never triggered.
Here is my code:
The class setting up the alarm:
//FIXME - rename (ie BackgroundSave; more descriptive)
public class AlarmReceiver extends Service{
//FIXME - make sure you kill the service
public void onCreate() {
super.onCreate();
Toast.makeText(getApplication().getApplicationContext(), "Service onCreate called", Toast.LENGTH_SHORT).show();
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
Toast.makeText(getApplication().getApplicationContext(), "Service started", Toast.LENGTH_SHORT).show();
setAlarm(AlarmReceiver.this);
// We want this service to continue running until it is explicitly
// stopped, so return sticky.
return START_STICKY;
}
public void setAlarm(Context c) {
AlarmManager alarmManager = (AlarmManager)c.getSystemService(Context.ALARM_SERVICE);
Intent i = new Intent(c, Alarm.class);
PendingIntent pi = PendingIntent.getBroadcast(c, 0, i, 0);
alarmManager.setRepeating(AlarmManager.ELAPSED_REALTIME_WAKEUP, System.currentTimeMillis() + 1000, 1000, pi);
Toast.makeText(c.getApplicationContext(), "setAlarm called", Toast.LENGTH_SHORT).show();
}
public void cancelAlarm(Context context) {
Intent intent = new Intent(context, Alarm.class);
PendingIntent sender = PendingIntent.getBroadcast(context, 0, intent, 0);
AlarmManager alarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
alarmManager.cancel(sender);
}
#Override
public IBinder onBind(Intent arg0) {
// TODO Auto-generated method stub
return null;
}
}
Here is the BroadcastReceiver:
public class Alarm extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
Toast.makeText(context, "Alarm", Toast.LENGTH_SHORT).show();
}
}
And here is my manifest:
<!-- Alarm -->
<service android:name="com.xxxx.android.tools.AlarmReceiver" android:enabled="true" />
<receiver android:name="com.xxxx.android.tools.Alarm" ></receiver>
The alarm onReceive is never triggered.
You have to use android.os.SystemClock.elapsedRealtime() as your base time when using AlarmManager.ELAPSED_REALTIME_WAKEUP.
That said i think to use the AlarmManager for your saving purpose is not the best approach. The alarm manager is pretty heavyweight. You should consider using a simple Handler to trigger your save action.
Have a look at Handler.postAtTime().