I am new to android ,Here I am practicing my first app (Alarm App).
I have an issue in my app that I can't stop the alarm once a alarm is triggered it's keep on ringing can't get stopped.
In my app I have 2 activities and a AlarmReceiver .
From the AlarmActivity.java I have set the alarm ,when the specific time is reached the Alarmreceiver.java will get triggered and the alarm started to ring and showing a wakeup screen .
From the WakeUpScreen.java I have a stop button by using that I need to stop the current ringing alarm .
I don't have any issues in logcat too.
AlarmActivity.java
public void stopAlarm(Context context) {
Intent intent = new Intent(context,AlarmReceiver.class);
intent.setAction("ALARM_OFF");
PendingIntent pendingIntent = PendingIntent.getBroadcast(context, mAlarmId, intent,PendingIntent.FLAG_UPDATE_CURRENT);
AlarmManager alarmManager = (AlarmManager) context.getSystemService(ALARM_SERVICE);
alarmManager.cancel(pendingIntent);
}
I have this AlarmStop() function in my AlarmActivity.java which will get hit when I press the stop button in wakeupscreen.java
When I am try to debug the stop process the debugger moved all the lines in the stopAlarm() function but the Intent is not worked that's why the AlarmReceiver.java file is not get called ,I mean,The debugger moved all the lines in the aboved method but the AlarmReceiver.java is not get called
I tried lot of ways to solve this but I missed something that I can't figured it out.
Can anyone help me to stop the triggered alarm and it's ringing sound .
Your architecture is broken. You don't use a BroadcastReceiver for persistent processing. A BroadcastReceiver has a very short lifecycle, you use it to trigger other things.
You've created a MediaPlayer instance in your BroadcastReceiver and are trying to control that in onReceive(). This is wrong. You should use a Service to manage and maintain the state of your MediaPlayer.
See if you can find some HOWTO guides on the Internet for how to build such an application.
Related
I'd like to implement an Activity that launches a Service able to intercept/receive the daily scheduled clock alarm and dismiss it programmatically when an event is fired (i.e. a recognize speech event).
In practice I have:
public class MyReceiver extends BroadcastReceiver {
...
}
registered on a ALARM_ALERT_ACTION (com.android.deskclock.ALARM_ALERT) [i've read that this works only with the system clock app]
Now when the Alarm ring MyReceiver.onReceive(...) method is called correctly but i can't dismiss (neither snooze) the alarm by code.
I've founded many examples use AlarmManager instance with .cancel(PendingIntent) method call but probably this works only when the alarm is scheduled by a custom Intent.
I've tried also getting all running processes and kill the com.android.deskclock process but is a not working way.
So, to summarize, I've scheduled a daily alarm with the system android clock app and i'd like to have a service that intercept com.android.deskclock.ALARM_ALERT action/event and dismiss it by code.
Thanks in advance to all.
I've founded how to do...check the code below:
AlarmManager alrm = (AlarmManager)getApplicationContext().getSystemService(ALARM_SERVICE);
Intent intent = new Intent(MyService.ALARM_DISMISS_ACTION);
PendingIntent pi = PendingIntent.getBroadcast(getApplicationContext(), 0, intent, 0);
alrm.set(AlarmManager.RTC_WAKEUP, 1000, pi);
In practice with these instructions I launch a "dismiss" alert event and this produce a current alarm ring dismission ;)
Bye
I believe the only way to dismiss an alarm would be to either 1) intercept the alarm broadcast and redirect it to a false boolean, or 2) if the alarm app had an API to call.
My intention is to make an application that will track the movement of my android phone for every few minutes and send it to my server. I have read a lot online on how to do it with a service, AlarmManager and Partial_WakeLock. I have also gone through the commonsware examples in github.com but I was a bit confused because I am still not experienced in android.
I have been successful in getting my application to [get location and send it to my server]. How do I make my service wakeup every few minutes and do [work mentioned]? In the Wakeful example in commonsware, in which method do I mention my [work] and in which method do I keep calling it?
You need a Service and an AlarmManager. Your Service will handle getting the position and posting it to the server and AlarmManager will invoke your service basen on an interval you decide. You should initialize your AlarmManager with your Service roughly like this in onCreate or other place you want:
AlarmManager alarmMgr = (AlarmManager) this.getSystemService(Context.ALARM_SERVICE);
PendingIntent pendingIntent = PendingIntent.getBroadcast(this, 0, new Intent(this, YourAlarmReceiver.class),PendingIntent.FLAG_CANCEL_CURRENT);
// Use inexact repeating which is easier on battery (system can phase events and not wake at exact times)
alarmMgr.setInexactRepeating(AlarmManager.ELAPSED_REALTIME_WAKEUP, YOUR_ALARM_TRIGGER_AT_TIME,YOUR_ALARM_INTERVAL, pendingIntent);
YourAlarmReceiver gonna start your service
public class YourAlarmReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
context.startService(new Intent(context, YourService.class));
}
}
On how to use Services refer to the android website http://developer.android.com/guide/topics/fundamentals/services.html
you could use a partial wakeLock with a sleep(X) which when the sleep(x) is resolved the system will call the next line of code, but the problem is I am seeing a possible infinite cycle that might need a task kill action, or just crash the system.
I want to send data to server at some regular interval. So, I am using AlarmManager for the same. It works fine but the problem is that when I cancel the Alarm on Date/Time change. At that time Alarm fires again before getting cancelled, so that makes my application worse as an extra data is sent to server with irregular interval.
Here is my BroadCastReceiver class with AlarmManager.
public class MyReceiver extends BroadcastReceiver{
AlarmManager mgr;
PendingIntent pi;
Intent intent;
public static boolean flag = false;
#Override
public void onReceive(final Context arg0, Intent arg1) {
if(arg1.getAction().equals("android.intent.action.TIME_SET")){
Log.d("MyReceiver", "Time set");
mgr = (AlarmManager) arg0.getSystemService(Context.ALARM_SERVICE);
intent = new Intent(arg0, TestService.class);
intent.putExtra("test", "testvalue");
pi = PendingIntent.getService(arg0, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
if(!flag){
mgr.setRepeating(AlarmManager.RTC_WAKEUP, System.currentTimeMillis() + 10000, 5000, pi);
flag = true;
}
else{
mgr.cancel(pi);
pi.cancel();
flag = false;
}
}
}
}
Below is the Screen Shot with Logcat output that explains that after cancelling the Alarm it fires once more time just after cancelling.
As you can see in the Logcat output black arrow shows where I changed that time to cancel the Alarm and red arrow shows that after cancelling the Alarm once again it fired just before cancelling which should not happen. So, can anyone give my idea why that is happening and what should I do to restrict Alarm getting fired again before cancelling.
NOTE:- This only happens when I tried to increase date/time say from 10:00 to 11:00, works perfect when I decrease time say 10:00 to 9:00.
Not able to see the LogCat at my end, but looking at the code, I am not sure, how is the Service which gets invoked (TestService) gets killed / stopped ? I think you would need to stop it somehow. Also, its not recommended to do long running tasks within the broadcast receiver.
Have you verified that you service stop event is occuring after the mgr.cancel(pi) is fired?
Just try with some unique code with pending intent within activity and then cancel that intent using the same code.
setting pending intent in activity
PendingIntent.getBroadcast(this, code, intent, PendingIntent.FLAG_UPDATE_CURRENT);
for stopping that broadcast receiver
PendingIntent pendingIntent = PendingIntent.getBroadcast(getBaseContext(), code, intent, 0);
AlarmManager alarmManager = (AlarmManager)getSystemService(Context.ALARM_SERVICE);
alarmManager.cancel(pendingIntent);
why that is happening
First Thing is that you are using Intent Action android.intent.action.TIME_SET so It does mean that Everytime any how if the System date/time gets Changed your BroadcastReceiver will ne called Automatically.
Second you have used one static boolean flag in your Receiver class.
Now what is happening is Whenever you change your System timings the flag toggles it's state from false to true and from true to false.
That is what exactly happening in your code and logcat also shows the same that everything is working as per the code written.
So according to me there is nothing Wrong happening in the code and it's output.
what should I do to restrict Alarm getting fired again before cancelling
First thing as I think, you should not use Action TIME_SET like that to toggle flag on/off as users and developers might not remember for what they are changing time either to turn FLAG On or Off,
Better way is that,
you should handle the Service yourself by an Activity and show one ToggleButton there to manage the State of the FLAG and set and cancel the PendingIntent.
OR
And If you want to do the task of your service automatically then you just simply use the AlarmManager and set your Alarm Triggering time and Interval there only once say time is currenttime and Interval is 50000 miliseconds..
so it will obviously call the service from now onwards after every 5mins, then in your App you will only require one ToggelButton to indciate the Sync to ther server is On or Off , if user Toggle it on or off then write your AlarmManager code there in your Activity only in the toggleButtontb.setOnCheckedChangeListener(listener) , I suppose this is the better way then what you are actually implementing.
I don't understand what need to set the receiver for date change if your goal is only to send the data on server in some regular interval .
change date and time of device does not mean that your alarm wont work
at that time which you already have set before those changes .Alarmmanager work on that given duration of time which is excluding from local current date and time of device .
I have an App with a workflow that calls many activities, some of them it finishes and others leaves them active as the user progresses through it. BUT I cannot switch off my alarm service which continues even when the home button is actuated and the app killed.
Oh sure - the force close in settings will stop the alarm service very well (its the only way to kill it). I cannot stop alarm from my app program since nothing tells me when the app has been closed.
None of the life cycle methods onDestroy() or on Stop() work because the home button can be actuated during any of 15 activities and onDestroy() is not called for a long time after on any activity.
BUT I cannot switch off my alarm service which continues even when the home button is actuated and the app killed.
Then do not register the alarm. AlarmManager is designed to execute your code periodically when your code is not already running. For something that is purely within an activity, use postDelayed().
When you press the home button, your app isn't--and isn't supposed to--shut down. It is "frozen" by a call to onSaveInstanceState(Bundle). If you click on your app icon, it will be restarted and resumed just as if there had been a giant pause in the system clock (or, if it was killed off by the system, re-created from the bundle you set in onSaveInstanceState). Typically you would turn suspend or cancel time-related activity in onPause, because, in a sense, time stops for your app at that point.
What are you using alarms for that they need to be stopped when the app exits? The whole point of them, I thought, was to invoke something in your app up at a particular time even if it wasn't running.
Just do like this....
AlarmManager alarm;
PendingIntent pintent;
Calendar cal = Calendar.getInstance();
cal.add(Calendar.SECOND, 10);
Intent intent = new Intent(this, TestService.class);
pintent = PendingIntent.getService(this, 0, intent, 0);
alarm = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
int i;
i=30;
alarm.setRepeating(AlarmManager.RTC_WAKEUP, cal.getTimeInMillis(), i* 1000, pintent);
System.out.println("service going to start-----------");
startService(new Intent(getBaseContext(), TestService.class)); // Here start your service
If you want to stop your service means you should stop your alarm service once. In onBackPressed() method's ok button would be finish your activity. Within that button you should add the following code.
alarm.cancel(pintent);
This will stop your service add alarm when you exit from your application. All the best.
I want to set an alarm in my application which will be triggered each day. According to the doc, I have to set a one-time alarm, and in the BroadcastReceiver which will receive the alarm signal, reset the alarm for the day after.
Is that correct ?
My BroadcastReceiver handles well the wakelock and launch a service which releases this wakelock. Everything works fine here.
However I have problems. In my application there is a checkbox which is checked when alarm is up. To know if my alarm is up, I use the following condition :
Intent intent = new Intent( context, AlarmReceiver.class );
boolean alarmUp = (
PendingIntent.getBroadcast( context, 0, intent, PendingIntent.FLAG_NO_CREATE) != null)
But this doesn't seem to work very well, is that a good way to know if an alarm is up ?
Thanks in advance
For the first part of your question, you could just use a repeating alarm, or schedule a new alarm whenever one fires like you are doing. Either way works.
You may also want to setup a broadcast receiver that receives ACTION_BOOT_COMPLETED so you can reschedule your alarms when the phone reboots.
As for checking if the alarm exists, the PendingIntent with FLAG_NO_CREATE is exactly how you would do that.