Service which continuously runs in the background - android

I want to develop a voice application which has to respond when the user speaks some commands. I think I need a service to accomplish my task.But I have learnt from several resources that a service cannot run for a long time.The android system automatically destroys a service if it sits idle.
So my question is whether it is possible to run a service continuously without being destroyed and respond to user actions?
I am new to Android development.So if there is anything wrong in the question, please correct me.
Thanks for the help!

You can use startForeground.
Notification notification = new Notification(R.drawable.icon, getText(R.string.ticker_text),
System.currentTimeMillis());
Intent notificationIntent = new Intent(this, ExampleActivity.class);
PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, notificationIntent, 0);
notification.setLatestEventInfo(this, getText(R.string.notification_title),
getText(R.string.notification_message), pendingIntent);
startForeground(ONGOING_NOTIFICATION_ID, notification);
They are killed only as a last resort—if memory is so low that they cannot all continue to run.
https://developer.android.com/guide/components/processes-and-threads.html
1st priority.

Related

android Local notification while app is stopped

I have followed some tutorials from SO to generate a local notification using AlertManager some time after my app closes by broadcasting to a custom BroadcastReceiver impl of mine. It works well, I can see the notification come up in the notification area of the device.
However, it only works if the app's main activity is paused. If the app is stopped (via Settings->apps), there is no notification, the broadcast receiver is never called. I had the impression that AlertManager registers my notification request in some OS service - not related to my app, that's the whole point, to have some sort of notification through which the user can restart my app. I am testing on Android 4.2.1 BTW. Any chance I am simply doing something wrong and there is actually a way to get AlertManager to successfully broadcast something out?
Here is my AlertManager code, called from my main activity's onPause (set to 10 seconds, just for testing). 'ctx' is the main activity
Calendar cal = Calendar.getInstance();
cal.add(Calendar.SECOND, 10);
Intent intent = new Intent(ctx, MyAlarmReceiver.class);
intent.putExtra("alarm_message", "hey, wake up this app!");
// note: 192837 is just some test ID:
PendingIntent sender = PendingIntent.getBroadcast(ctx, 192837, intent, PendingIntent.FLAG_UPDATE_CURRENT);
// Get the AlarmManager service
AlarmManager am = (AlarmManager) ctx.getSystemService(Context.ALARM_SERVICE);
am.set(AlarmManager.RTC_WAKEUP, cal.getTimeInMillis(), sender);
And here is MyAlarmReceiver.onReceive(context, intent):
try {
Bundle bundle = intent.getExtras();
String message = bundle.getString("alarm_message");
NotificationCompat.Builder mBuilder =
new NotificationCompat.Builder(context)
.setSmallIcon(R.drawable.ic_launcher)
.setContentTitle("Title!!!")
.setContentText(message);
Intent resultIntent = new Intent(context, MainActivity.class);
PendingIntent resultPendingIntent =
PendingIntent.getActivity(context, 192838, resultIntent,
PendingIntent.FLAG_UPDATE_CURRENT);
mBuilder.setContentIntent(resultPendingIntent);
NotificationManager mNotificationManager =
(NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
mNotificationManager.notify(123423, mBuilder.build());
} catch (Exception e) {
Toast.makeText(context, "There was an error somewhere, but we still received an alarm", Toast.LENGTH_SHORT).show();
e.printStackTrace();
}
To summarize, Force closing your app means that the user explicitly said that he
didn't want to run your app anymore
Starting with 3.1 when applications are installed they are in a “stopped” state so they will not be able to run until the user explicitly launches them. Pressing Force Stop will return them to this state, so if the user force-stops your application, all the components of your app (BroadcastReceivers, Services, AlarmManager...) will no longer work again until the user manually run your application again. And this is documented at the 3.1 release notes here.
Although the documentation for AlarmManager states that
Note: The Alarm Manager is intended for cases where you want to have
your application code run at a specific time, even if your application
is not currently running. For normal timing operations (ticks,
timeouts, etc) it is easier and much more efficient to use Handler.
It will not work also after your application is force closed and this is not a bug it's a feature.
This behavior is confirmed by the Android framework developers https://groups.google.com/forum/?fromgroups=#!topic/android-developers/anUoem0qrxU

Android: how to run AsyncTask at regular interval in background service

How do I run an AsyncTask at regular interval of 2 mins sleep for 10 times in the background service?
As VM stops my service at any time, my AsyncTask is also getting closed.
I have tried ScheduledThreadPoolExecutor, Timer, TimerTask all gets stopped once Service gets stopped.
Is there a good option start with?
Any help is appreciated.
Your service will never get stopped but you should show notification. Try implementing foreground service. foreground service
Foreground service displays notification and is never stopped.
Implement this code snippet in your service
Notification notification = new Notification(R.drawable.icon, getText(R.string.ticker_text),
System.currentTimeMillis());
Intent notificationIntent = new Intent(this, ExampleActivity.class);
PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, notificationIntent, 0);
notification.setLatestEventInfo(this, getText(R.string.notification_title),
getText(R.string.notification_message), pendingIntent);
startForeground(ONGOING_NOTIFICATION_ID, notification);
Have you tried the Handler? U can read more about this in this link

How to keep a service running when it's swiped in recent tasks (Like pandora)

When I swipe my app from recent tasks, my service stops, then restarts in a few seconds. I'd like it to behave more like pandora.
When you're playing music with pandora and swipe pandora out of recent tasks, the music continues to play without stopping at all. I'm trying to implement this behavior in my app.
I saw this post: Android: keeping a background service alive (preventing process death) which seems to indicate that the way to do this was to use the startForeground method.
I copied this code from http://developer.android.com/guide/components/services.html#Foreground
Notification notification = new Notification(R.drawable.icon, getText(R.string.ticker_text),
System.currentTimeMillis());
Intent notificationIntent = new Intent(this, ExampleActivity.class);
PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, notificationIntent, 0);
notification.setLatestEventInfo(this, getText(R.string.notification_title),
getText(R.string.notification_message), pendingIntent);
startForeground(ONGOING_NOTIFICATION_ID, notification);
And made sure that my notification id was not zero (it's 1). I also return START_STICKY. Any clue what I'm doing wrong?
EDIT: The above behavior happens on 4.2. On 4.4, the notification doesn't go away. However, the thread I'm running inside the service stops and does not restart. At least on 4.2 it restarts :/

Scheduled Notifications are not shown when process is killed

I have a scheduler kind of app that sends a notification to the user at a specified time in the morning and in the evening. I have done this using Alarm Manager. On the emulator the application works just fine as far as this is concerned. However in my device I use "Advanced Task Killer" application to kill running apps and free the device's memory. I noticed that on killing this application the notifications are not shown at the scheduled time. This definitely seems logical but is not at all what I want. I want the notifications to be shown at the scheduled time even though the process is killed. Is there a way to do so?
I figured a little bit of code might be helpful to realize my problem :
I have this in my Main Activity
public void setAlarm(){
Intent intent = new Intent(MainActivity.this, AlarmReceiver.class);
PendingIntent pendingIntent = PendingIntent.getBroadcast(MainActivity.this, 0, intent, PendingIntent.FLAG_CANCEL_CURRENT);
am.cancel(pendingIntent);
Cursor tempcursor = db.getAlarmTime();
tempcursor.moveToFirst();
int hour = tempcursor.getInt(tempcursor.getColumnIndex("Hour"));
int minute = tempcursor.getInt(tempcursor.getColumnIndex("Minute"));
tempcursor.close();
db.close();
GregorianCalendar alarmtime = new GregorianCalendar();
alarmtime.set(GregorianCalendar.HOUR_OF_DAY, hour);
alarmtime.set(GregorianCalendar.MINUTE, minute);
alarmtime.set(GregorianCalendar.SECOND, 0);
alarmtime.set(GregorianCalendar.MILLISECOND, 0);
if(alarmtime.before(new GregorianCalendar()))alarmtime.add(GregorianCalendar.DAY_OF_MONTH, 1);
am.set(AlarmManager.RTC_WAKEUP, alarmtime.getTimeInMillis(), pendingIntent);
}
And this in my AlarmReceiver class that extends BroadcastReceiver :
public void onReceive(Context context, Intent intent) {
notificationManager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
Intent i = new Intent(context, Schedule_Today.class);
PendingIntent pi = PendingIntent.getActivity(context, 0, i, PendingIntent.FLAG_CANCEL_CURRENT);
AlarmManager am = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
PendingIntent pi2 = PendingIntent.getBroadcast(context, 0, intent, PendingIntent.FLAG_CANCEL_CURRENT);
am.set(AlarmManager.RTC_WAKEUP, System.currentTimeMillis() + AlarmManager.INTERVAL_DAY, pi2); //Setting another notification after 1 day as soon this notification broadcast is received.
CharSequence from = "Scheduler_3";
CharSequence message = "Test Notification";
notification = new Notification(R.drawable.ic_launcher, "Attention",System.currentTimeMillis());
notification.setLatestEventInfo(context, from, message, pi);
notificationManager.notify(1, notification);
}
I want to prevent the application from being killed or at least a module of it running that can broadcast the alarmmanager at the required time so that the user receives notifications
This is not strictly possible, except by making your own version of Android in your own ROM mod.
On Android 2.1 and earlier, third-party task managers, like "Advanced Task Killer", had the ability to "force stop" an application. On Android 2.2 and higher, that ability was reserved for the OS itself, and is available to users via the "Force Stop" button on the app's screen in the list of applications in Settings.
When an app is "force stopped", among other things, all scheduled alarms are removed. In addition, on Android 3.1+, nothing of that app will ever run again, until the user manually launches one of your activities (or something else manually runs one of your components).
You are welcome to write two applications, one that is the main app and the other than ensures that, if the first one appears to have been force-stopped, the alarms are rescheduled. However, there is nothing stopping the user from force-stopping both of those applications.
Also, bear in mind that some devices, like the SONY Xperia Z, block _WAKEUP alarms in general, if the user has activated "STAMINA Mode". See this blog post for more about this.
Hence, I recommend that you redesign your application to take into account that your alarms are not guaranteed to run at all, let alone at the time you expect.

Android Delayed Notification

I am trying to create a Notification using Android's Notification Manager, however, the trick is that I want the notification to show up 30 days in the future. In my code I'm doing this:
Intent notificationIntent = new Intent(this, MyClass.class);
PendingIntent contentIntent = PendingIntent.getActivity(this, 0, notificationIntent, 0);
long when = System.currentTimeMillis() + (30 * 24 * 3600 * 1000);
Notification notification = new Notification(R.drawable.some_image, "A title", when);
notification.setLatestEventInfo(getApplicationContext(), "You're late", "Some description", contentIntent);
NotificationManager nm = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
nm.notify(NOTIFY_ATTEND_ID, notification);
However, the notification is still showing up instantaneously. From what I read, the "when" parameter to the Notification constructor is only used to sort the notifications in the StatusBar. Is there anyway to make the notification show up in at a future date/time? Thanks in advance.
Is there anyway to make the notification show up in at a future date/time?
No.
As Falmarri suggests, you will need to handle this yourself, though I disagree with his approach. You will need to use AlarmManager. However, I am skeptical that AlarmManager will work for 30-day durations, though you can try it. You may need to use AlarmManager for a daily/weekly task to schedule that day's/week's notifications via separate alarms. You will also need to reconstitute this roster of alarms on a reboot, since they get wiped, as Falmarri suggests.

Categories

Resources