Set alarm when activity is destroyed - android

I am trying to set an alarm when activity is destroyed. But it is not working. If I set an alarm when activity is stopped, it is working. But for the destroying method, it is not working. I don't know if I am missing something or what ? If it is possible,how can I set an alarm when activity is destroyed?
Following is my code:
#Override
protected void onDestroy() {
databaseHandler.updatePreference(Keys.Pref.APP_CRASH_STATUS, "TRUE");
setAlarmToOpenApp();
super.onDestroy();
}
private void setAlarmToOpenApp(){
Intent alarmIntent = new Intent(ActivityDisplay.this, AppCrashReceiver.class);
PendingIntent pendingIntent = PendingIntent.getBroadcast(ActivityDisplay.this, 0, alarmIntent, 0);
AlarmManager manager = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
int interval = 10000;
manager.set(AlarmManager.RTC_WAKEUP, System.currentTimeMillis() + 10000, pendingIntent);
Display.log(TAG, "Alarm is set to Broadcast app crash");
}

onDestroy would distort all your app activity which means all the code in the specific method will not be performed. in onStop activity stops for a moment it isn't destroyed so any activity except visual will take in action, however with onDestroy you will never be able to do that, you can create an activity for notifications and maybe that'll work out. Or go for OS programming but you would move away from pure android, my suggestion would be try to set that alarm on the notification activity, I'm not sure but it is possible

Related

How to stop a repeating alarm manually(without code) using android monitor of android studio.

I am trying to use AlarmManager class in android and i set the time of repeat to after every 10 seconds.Now after running the app the activity which i mentioned in my code after the alarm is set gets called after every 10 seconds properly.
But the problem is even after i press the back button(to call onStop method) of my phone,the app again calls the activity.So,i pressed the "close" button in android monitor of android studio,but then also the activity gets called after every 10 seconds.
So,i want to know how can i manually close this app and why is this happening ?
Here is the code.
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
alarmMgr = (AlarmManager)this.getSystemService(Context.ALARM_SERVICE);
Intent intent = new Intent(this, AlarmReceiver.class);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
alarmIntent = PendingIntent.getActivity(this, 0, intent,0);
Log.d("asd","initialized alarmintent");
alarmMgr.setRepeating(AlarmManager.RTC_WAKEUP,
SystemClock.elapsedRealtime(),10000, alarmIntent);
Log.d("asd", "alarm set");
}
You need to cancel the alarm in onDestroy() of your activity.
AlarmManager alarmManager = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
alarmManager.cancel(<your_pending_intent>);

How to keep a service alive using AlarmManager.setInexactRepeating()?

I have some existing code that spawns a service intent which does a bunch of stuff in the background. This code does work...
Intent serviceIntent = new Intent(context, APMService.class);
serviceIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.startService(serviceIntent);
My question is: how to change this to use the AlarmManager.setInexactRepeating(...) methods?
I have changed the above code to this:
Intent serviceIntent = new Intent(context, APMService.class);
serviceIntent.putExtra("STARTED_BY", starter);
serviceIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
//Set up recurring alarm that restarts our service if
// it crashes or if it gets killed by the Android OS
AlarmManager am = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
PendingIntent pi = PendingIntent.getService(context, 0, serviceIntent, 0);
//am.cancel(pi);
am.setInexactRepeating(
AlarmManager.ELAPSED_REALTIME_WAKEUP //wake up the phone if it's asleep
, cal.getTimeInMillis()
, 10000
, pi);
And I have added these permissions to AndroidManifest.xml...
<uses-permission android:name="com.android.alarm.permission.SET_ALARM"/>
<uses-permission android:name="com.android.alarm.permission.WAKE_LOCK"/>
My understanding is that this is supposed to start the service immediately and then try to restart it again every 10 seconds. But this code isn't working properly.
Using this new code, the service never starts at all and I cannot see why not. To complicate matters the debugger never seems to attach to the app in time to see what's going on.
Can anyone see what I'm doing wrong?
Put AlarmManager code under onDestroy() function of service to schedule start of service as below:
#Override
public void onDestroy() {
/**
* Flag to restart service if killed.
* This flag specify the time which is ued by
* alarm manager to fire action.
*/
final int TIME_TO_INVOKE = 5 * 1000; // try to re-start service in 5 seconds.
// get alarm manager
AlarmManager alarms = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
Intent intent = new Intent(context, AutoStartServiceReceiver.class);
PendingIntent pendingIntent = PendingIntent
.getBroadcast(context, 0, intent, PendingIntent.FLAG_CANCEL_CURRENT);
// set repeating alarm.
alarms.setRepeating(AlarmManager.RTC_WAKEUP, System.currentTimeMillis() +
TIME_TO_INVOKE, TIME_TO_INVOKE, pendingIntent);
}
And handle starting of your service in AutoStartServiceReceiver as below:
public class AutoStartServiceReceiver extends BroadcastReceiver {
private static final String TAG = AutoStartServiceReceiver.class.getSimpleName();
#Override
public void onReceive(Context context, Intent intent) {
// check broadcast action whether action was
// boot completed or it was alarm action.
if (intent.getAction().equals(AppConstants.ACTION_ALARM_INTENT)) {
context.startActivity(new Intent(context, YourActivity.class));
// handle service restart event
LockerServiceHelper.handleServiceRestart(context);
}
}
}
Kindly note that, your service will not restart if you stop it manually from settings-apps-running apps-your app.
Your service is not starting because of AlarmManager.ELAPSED_REALTIME_WAKEUP, while it should be using AlarmManager.RTC_WAKEUP
If you want to run every 10s keep in mind that above API 21 alarm intervals below 60s are rounded up to 60s.
Also, consider using WakefulIntentService
https://github.com/commonsguy/cwac-wakeful

Android AlarmService repeating alarm repeats once more after cancel is called

First off,this site is great and everyone is so helpfull. This is my first post so forgive me if i have ommited anything.
I create an alarm like so:
private void startLocation() {
AlarmManager alarm = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
Intent i = new Intent(context, MyWeatherUpdateService.class);
PendingIntent service = PendingIntent.getService(context, 0, i,
PendingIntent.FLAG_CANCEL_CURRENT);
alarm.setRepeating(AlarmManager.RTC, SystemClock.elapsedRealtime() + (60 * 1000),
Long.parseLong(prefs.getString("listpref", "60000")), service);
}
In this method which is called inside a fragment, context is from getApplication (), listpref is a string update interval in milliseconds.
I cancel it by:
public void endLocation() {
Intent i = new Intent(context, MyWeatherUpdateService.class);
PendingIntent service = PendingIntent.getService(context, 0, i,
PendingIntent.FLAG_CANCEL_CURRENT);
alarm.cancel(service);
}
Ensuring that the intent/pending intent is the same.
Now i have 2 issues:
1) the alarm fires almost imediately after creation, even though i tell it to start after 1min.
2) when i call cancel, the alarm fires once more before the alarm is cancelled.
With question 1) why does the alarm fire so soon? And with 2) is this working as intended or should the alarm cancel immediately like i want it to.
If i have not supplied enough info, ill add more code if required.
Thanks in advance.
the alarm fires almost imediately after creation, even though i tell it to start after 1min
That is because you are using RTC with an elapsedRealtime() starting time. Those need to match. The simplest solution is to switch to ELAPSED_REALTIME.
when i call cancel, the alarm fires once more before the alarm is cancelled.
Try replacing PendingIntent.FLAG_CANCEL_CURRENT with 0, at least in the PendingIntent for your cancel() call.

Is there a way to kill an activity when PendingIntent is fired?

In Android to kill an activity, you just use finish(). But in my case I want to kill the activity when the PendingIntent is fired.
My code is as follow:
Intent intent = new Intent(MainActivity.this, NextActivity.class);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
intent.putExtra(Utils.KEY_RECORD_TIME, recordLength);
PendingIntent pintent = PendingIntent.getActivity(MainActivity.this,
piNumber, intent, 0);
AlarmManager alarm = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
alarm.set(AlarmManager.RTC_WAKEUP, cal.getTimeInMillis(), pintent);
If I add finish() beneath, the activity will be killed before the time set up in the AlarmManager.
I want the activity to be visible until the time goes off and kill it. Are there any ways to do this? I did some searches in Stack Overflow, Google but could not find an answer.
Inside a timer you get the time delay of the pending intent.
new Timer().schedule(new TimerTask() {
#Override
public void run() {
// TODO Auto-generated method stub
}
},pending intent delay);
Please try this.It work for me
You can register a BroadcastReceiver dynamically in your activity. With the pending intent, you use getBroadcast(). So you can call finish() inside the broadcast receiver when it is invoked by the alarm manager. Note that you must unregister the receiver when you don't need it anymore, you do that in onDestroy() for example.
Look at onNewIntent(Intent). If you can start your activity as a single top, then your instance should receive the pending intent through that call.
If you can't use singel top, and a new instance of your activity is being launched, you could use a shared static to get the original instance in onCreate() of the new one and finish() both.

How to prevent AlarmManager from being recreated with Server?

I have this Service that do other stuff in the background and must always be running. On its onCreate i've set an Alarm that sends an email once a day. The server is not running in foreground, so sometimes its get killed by the system, and then created again, and when that happens its creates the alarm again, and sends another email every time it happens. So my question is, is there a way to prevent it from triggering the alarm if its already set for repeating in the system? Or is there another "place" in the Service where i can create the alarm once and prevent it for being recreated with the it?
public class ObserverService extends Service {
private String BABAS = "babas";
#Override
public void onCreate() {
setRecurringAlarm(this);
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
return START_STICKY;
}
#Override
public IBinder onBind(Intent intent) {
return null;
}
private void setRecurringAlarm(Context context) {
Log.i(BABAS, "entrou no set alarme");
Calendar updateTime = Calendar.getInstance();
updateTime.setTimeZone(TimeZone.getDefault());//getTimeZone("GMT"));
updateTime.set(Calendar.HOUR_OF_DAY, 00);
updateTime.set(Calendar.MINUTE, 00);
Intent downloader = new Intent("ALARME");//context, AlarmReceiver.class);
PendingIntent recurringDownload = PendingIntent.getBroadcast(context,
0, downloader, PendingIntent.FLAG_UPDATE_CURRENT);
AlarmManager alarms = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
alarms.setInexactRepeating(AlarmManager.RTC_WAKEUP, updateTime.getTimeInMillis(), AlarmManager.INTERVAL_DAY, recurringDownload);
}
}
If that code is everything your Service does you can completely get rid of the Service.
The only thing the service does is schedule a Broadcast once a day on the alarm manager, why not do this schedule directly from the Activity?
edit:
Given your comment, my original answer remains:
The Alarm set on the AlarmManager is permanent until the device is turned off or rebooted.
So you can set the first alarm via Activity and mark it as active on the SharedPreferences. Create a BroadcastReceiver to receive onBoot events, this receiver will check the SharedPreferences for if the alarm is active and in case it is, re-register it on the AlarmManager.
Your service still does the same ContentObserver stuff, but have no association with the recurring AlarmManager event.
I reckon that would be cleanest solution.
Alternatively (but I don't think it's a good/clean solution), you can use the AlarmManager.cancel() to remove the existing PendinIntent, and then re-trigger it
http://developer.android.com/reference/android/app/AlarmManager.html#cancel(android.app.PendingIntent)

Categories

Resources