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.
Related
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
I am trying to call from my BroadcastReceiver(ReceiverSchedule) to call a method (CancelSchedules) in my Activity(ViewScheduleActivity). The main problem I have is that it the Activity becomes null on the onReceive. I think I'm simply passing it into the intent wrong. I have tried the following link: Call an activity method from a BroadcastReceiver class.
First there is an alarmanager that will get called at the correct time then in the Receiver I want to cancel all alarms. Here is the code in the Activity to set the alarm (this part will work fine).
AlarmManager alarmManager = (AlarmManager)getSystemService(ALARM_SERVICE);
Intent myIntent = new Intent(this, RecieverSchedule.class);
myIntent.setClass(this, recieverSchedule.getClass());
myIntent.putExtra("scheduleJson", gs.toJson(schedule));
myIntent.putExtra("LoginUserAsString", gs.toJson(loginUser));
myIntent.putExtra("PatientAsString", gs.toJson(patientResult));
PendingIntent pendingIntent = PendingIntent.getBroadcast(this, 0, myIntent, i);
alarmManager.set(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), pendingIntent);
Toast.makeText(ViewScheduleActivity.this, "Set One Time Alarm at: "+ hour +":" + min, Toast.LENGTH_LONG).show();
Now to pass the Activity over in my BroadCastReceiver I have:
public void setMainActivityHandler(ViewScheduleActivity main) {
viewScheduleActivity = main;
}
with the declaration on top:
ViewScheduleActivity viewScheduleActivity = null;
Now on create I would like to call the method CancelSchedules which is in my ViewScheduleActivity:
public void CancelSchedules()
{
for (int i =0; i< 10; ++i)
{
AlarmManager alarmManager = (AlarmManager)getSystemService(ALARM_SERVICE);
Intent myIntent = new Intent(this, RecieverSchedule.class);
PendingIntent pendingIntent = PendingIntent.getBroadcast(this, 0, myIntent, i);
alarmManager.cancel(pendingIntent);
}
}
In my onReceive in RecieverSchedule I have:
public void onReceive(Context context, Intent intent) {
viewScheduleActivity.CancelSchedules();
}
The problem is that viewScheduleActivity is null causing me to be unable to call it.
I have the following code to pass over the Activity with ReciverSchedule created as a member in the Activity:
recieverSchedule = new RecieverSchedule();
recieverSchedule.setMainActivityHandler(this);
IntentFilter callInterceptorIntentFilter = new IntentFilter("android.intent.action.ANY_ACTION");
registerReceiver(recieverSchedule, callInterceptorIntentFilter);
The setMainActivityHandler will get called and created, but I suspect that I am passing a new RecevierSchedule rather than the set receiverSchdule. If I am correct, how do I pass receiverSchedule into the Alarmmanager? I thought registerReceiver would fix this issue but maybe the placement is wrong.
Your Activity will likely be long killed and dead by the time the AlarmManager triggers your BroadcastReceiver. When that happens, Android will create a new process for your application, instantiate your BroadcastReceiver and call onReceive(). This is why the variable viewScheduleActivity is null.
As #Athena suggested, you don't need to call back into your Activity in order to cancel alarms.
In my App I use an AlarmManager to start an Activty at a certain days of the week and at a certain hour.
So I have an AlarmManager that an MON, TUE, WED.. at 12:00 fires off an Activity...
Now, the point is that I need to stop the same activity at a precise time (again using the AlarmManager if it is possible).
Please how do I achieve that: AlarmManager to STOP an Activity?
you can register a broadcastReceiver in that activity. if you wanna stop it, send a broadcast notification to that Activity, and trigger relevant callback function to finish the activity.
As Pankaj said use services and u can unregister the broadcast reciever
public void stopService() {
Log.d("TAG", "CancelAlarm Start");
Intent intent = new Intent(context, PullNotification.class);
PendingIntent sender = PendingIntent
.getBroadcast(context, 0, intent, 0);
AlarmManager alarmManager = (AlarmManager) context
.getSystemService(Context.ALARM_SERVICE);
alarmManager.cancel(sender);
}
I set an AlarmManager object to start a service.
AlarmManager am = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE); //context = getApplicationContext();
Intent alarmServiceIntent = new Intent(context, AlarmHandlingService.class);
alarmServiceIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
alarmServiceIntent.putExtra("alarmId", _id); //_id is a "long" value
PendingIntent pi = PendingIntent.getService(context, (int)_id, alarmServiceIntent, 0);
am.set(AlarmManager.RTC_WAKEUP, time, pi);
The onStartCommand(..., ..., ...) of AlarmHandlingService works as it has to work and when it has to work. There isn't any problem:
public int onStartCommand(Intent intent, int flags, int startId)
{
long alarmId = intent.getLongExtra("alarmId", -1);
Intent someActivityIntent = new Intent(this, SomeActivity.class);
someActivityIntent.putExtra("alarmId", alarmId);
someActivityIntent.setFlags(Intent.FLAG_ACTIVITY_REORDER_TO_FRONT | Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(someActivityIntent);
return START_NOT_STICKY;
}
But then, when a new activity is opened (SomeActivity) and I call stopService(...), the service is not stopped:
stopService(new Intent(context, AlarmHandlingService.class)); //context = getApplicationContext();
This is the declaration of my service class in the manifest:
<service android:name="***myPackageName***.AlarmHandlingService"></service>
I tried to debug and noticed only that the registerReceiver (BroadcastReceiver receiver, IntentFilter filter) function of android.content.ContextWrapper class is called when I call the stopService.
From you comments you are not doing anything when your stopService is being called.
When you call stopService it will actually give a call to the function stopService().(which is being done in your application).
You must use onDestroy Method.
public void onDestroy ()
Added in API level 1
Called by the system to notify a Service that it is no longer used and is being removed. The service should clean up any resources it holds (threads, registered receivers, etc) at this point. Upon return, there will be no more calls in to this Service object and it is effectively dead.
(Do not call this method directly).
and the other problem is you are not calling anything to stop your alarm manager.
you must have called cancel method for AlarmManager.
please try with new activity.
stopService(new Intent(this, AlarmHandlingService.class));
I have an ImageView in my activity that shows an "active" symbol when a service is activated.
After the Service has been executed the ImageView should go back to the "inactive" Symbol.
AlarManager that starts Service:
context = this;
Intent intent = new Intent(context, AlarmReceiver.class);
sender = PendingIntent.getBroadcast(context, INTENT_CODE, intent,
PendingIntent.FLAG_UPDATE_CURRENT);
am = (AlarmManager) getSystemService(ALARM_SERVICE);
am.set(AlarmManager.RTC_WAKEUP, calNew.getTimeInMillis(), sender);
setImage(active);
AlarmManager:
#Override
public void onReceive(Context context, Intent intent) {
Intent wakeupIntent = new Intent(context, WakeupActivity.class);
context.startService(wakeupIntent);
}
How can I make the Image change back to inactive after the service has been executed? I tried to create a new Runnable and then postDelayed(runnable, calNew.getTimeInMillis()) using a handler. Actually it didn't work, nothing happened. Is there a better way to do this?
How can I make the Image change back to inactive after the service has been executed?
Step #1: Add the Android Support package to your application.
Step #2: Have your activity register a BroadcastReceiver with LocalBroadcastManager in onResume() and unregister it in onPause().
Step #3: Have your service send a broadcast via LocalBroadcastManager when its work is complete, to be picked up by the activity's BroadcastReceiver.
Here is a sample project demonstrating this technique.