The service works normally when is started from the MainActivity however when the application is removed from the recent apps or when activity is closed, the service is restarted instead of continuing from where it left off.
public class ServiceExample extends Service {
#Override
public IBinder onBind(Intent intent) {
// TODO: Implement this method
return null;
}
#Override
public void onCreate() {
// TODO: Implement this method
super.onCreate();
//Do Something
}
I need to perform an action in the background but it can not be stopped or restarted when the activity ends. The Service Statement is the best to Use?
Try putting this inside your service class.
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
return START_STICKY;
}
Add below code to service and override onStartCommand and return START_STICKY
#Override
public void onTaskRemoved(Intent rootIntent){
Intent restartServiceTask = new Intent(getApplicationContext(),this.getClass());
restartServiceTask.setPackage(getPackageName());
PendingIntent restartPendingIntent = PendingIntent.getService(getApplicationContext(), 1,restartServiceTask, PendingIntent.FLAG_ONE_SHOT);
AlarmManager myAlarmService = (AlarmManager) getApplicationContext().getSystemService(Context.ALARM_SERVICE);
myAlarmService.set(
AlarmManager.ELAPSED_REALTIME,
SystemClock.elapsedRealtime() + 1000,
restartPendingIntent
);
super.onTaskRemoved(rootIntent);
}
Related
I am developing an Android application which calls API's to fetch data. Now I want to perform this task in background and each time data is changed in the List view, a notification should be generated.
How can I achieve this?
How can I make my API called in background and how can i generate notification.
I am new to Services and BroadcastReceivers so help me
I am calling the service this way:
startService(new Intent(this, MyService.class).putExtra("Background",true));
I created this code to testing purpose. To check if notifications can be called in background even if the app is closed.
My Service Class
public class MyService extends Service {
private Boolean isShowingNotification = true ;
NotificationManager notificationManager;
#Nullable
#Override
public IBinder onBind(Intent intent) {
return null;
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
super.onStartCommand(intent, flags, startId);
if (intent.hasExtra("Background")) {
if (isShowingNotification) {
StopImportantJob();
stopSelf();
} else
DoImportantJob();
} else {
DisplayNotification("Now showing the demo");
}
return START_NOT_STICKY;
}
#Override
public void onCreate() {
super.onCreate();
notificationManager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
Toast.makeText(this, "On Create Called", Toast.LENGTH_SHORT).show();
}
#Override
public void onDestroy() {
super.onDestroy();
notificationManager.cancelAll();
}
public void DisplayNotification(String message){
PendingIntent pendingIntent = PendingIntent.getActivity(this, 0,
new Intent(this, MainActivity.class), 0);
Notification notification = new Notification.Builder(this)
.setContentTitle(message)
.setContentText("Touch to off Service")
.setSmallIcon(R.mipmap.ic_launcher)
.setContentIntent(pendingIntent)
.setOngoing(false)
.build();
notificationManager.notify(0,notification);
}
public void DoImportantJob(){
PendingIntent pendingIntent = PendingIntent.getActivity(this, 0,
new Intent(this, MainActivity.class), 0);
Notification notification = new Notification.Builder(this)
.setContentTitle("New mail from " + "test#gmail.com")
.setContentText("Subject")
.setSmallIcon(R.mipmap.ic_launcher)
.setContentIntent(pendingIntent)
.setOngoing(false)
.build();
startForeground(1992, notification);
isShowingNotification =true;
}
public void StopImportantJob(){
stopForeground(true);
isShowingNotification = false;
if(false){
if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.N ){
stopForeground(STOP_FOREGROUND_DETACH);
stopForeground(STOP_FOREGROUND_REMOVE);
}
}
}
}
What I believe I should do is listed below, please correct me if I am wrong.
Start Service in the onCreate() of the MainAcitivity of Application.
In the Service call I will create a method which will do the API call.
On notifyDataSetChanged(); will call the Notification method.
Now here is the question: In Service class the API method will be called in onCreate() or onStartCommand().
Now i want to perform this task in background and each time data is
changed in the List view, a notification should be generated. How can
i achieve this? How can i make my API called in background and how can
i generate notification.
First Decide, whether you want this operation when your application is in Foreground OR Background. Now, if Foreground, you might not want to use Service class and use AsyncTask instead for making your webservice calls and generate the notification and updatethe listview once task is done. If Background, you can create IntentService and do your API operation there. However, in background mode, your application do not need to be notified as your app will not be visible to client.
I am developing android application, so I am starting a service with alarm:
public void scheduleLocationCheckerAlarm() {
Intent intent = new Intent(getApplicationContext(), LocationCheckerReceiver.class);
final PendingIntent pIntent = PendingIntent.getBroadcast(this, LocationCheckerReceiver.REQUEST_CODE, intent, PendingIntent.FLAG_UPDATE_CURRENT);
long firstMillis = System.currentTimeMillis();
AlarmManager alarm = (AlarmManager) this.getSystemService(Context.ALARM_SERVICE);
alarm.setInexactRepeating(AlarmManager.RTC_WAKEUP, firstMillis, 600000, pIntent);
}
LocationCheckerReceiver:
public class LocationCheckerReceiver extends BroadcastReceiver {
public static final int REQUEST_CODE = 12345;
#Override
public void onReceive(Context context, Intent intent) {
Intent i = new Intent(context, LocationNotificator.class);
context.startService(i);
}
Service:
public class LocationNotificator extends Service {
public LocationNotificator() {
}
#Override
public IBinder onBind(Intent intent) {
throw new UnsupportedOperationException("Not yet implemented");
}
public int onStartCommand(Intent intent, int flags, int startId) {
Log.d("Location checker", "Service running");
//My code is here
return START_STICKY;
}
#Override
public void onDestroy() {
super.onDestroy();
Log.d("Location checker", "Service destroyed");
}
So I want this service to be checking for something every 1 minute and to be running all the time, even when the application is closed by the user.
You must call startForeground(FOREGROUND_ID, buildForegroundNotification(filename)); in order to ensure that your service running continuously. Also, this will post a notification from your app to show the user about the service state. Please follow the reference.
Here is the code :
public class LocationNotificator extends Service {
private static int FOREGROUND_ID=1338;
public LocationNotificator() {
}
#Override
public IBinder onBind(Intent intent) {
throw new UnsupportedOperationException("Not yet implemented");
}
public int onStartCommand(Intent intent, int flags, int startId) {
Log.d("Location checker", "Service running");
//My code is here
startForeground(FOREGROUND_ID,
buildForegroundNotification(filename));
stopForeground(true);
return START_STICKY;
}
#Override
public void onDestroy() {
super.onDestroy();
Log.d("Location checker", "Service destroyed");
}
private Notification buildForegroundNotification(String filename) {
NotificationCompat.Builder b=new NotificationCompat.Builder(this);
b.setOngoing(true);
b.setContentTitle("Some Title")
.setContentText("some File name")
.setSmallIcon(android.R.drawable.stat_sys_download)
.setTicker("downloading");
return(b.build());
}
You need to read this first. https://developer.android.com/guide/components/services.html
In a nutshell, start your service as a foreground service so there's lesser chance of Android killing your service. As a foreground service, you need to display an on-going notification in the status bar.
There's no direct way of making sure your service is never killed by the Android system. A workaround is to send a broadcast in onDestroy() of your service, and have a Receiver in your Android application start the service upon receiving the broadcast.
By the way, it seems that your service is sending location updates periodically to your backend server. This might be better implemented using Firebase Job Dispatcher library or Evernote's Android-Job library.
Background info: I'm trying to create a service. I create it in my main activity. I know the service is running because the notification is showing. So the service doesn't stop at any point.
What i want to happen: when the screen is locked/turned off i want a certain activity to be displayed for when the screen is turned back on.
What is happening: first, When the screen is turned back on the main activity shows and then the activity i want shows over that. I dont want the main activity to show at all when the screen is turned on .
Then i changed a few things: and now the desired activity flickers on the main screen and then vanishes. It seems very unreliable and only comes a few times.
That should be enough info, here is the code so far (specifically onReceive())
public class OverlayService extends Service{
//IN THIS CLASS CHECK WHETHER LOCK BUTTON WAS PRESSED OR IF PHONE WHEN TO SLEEP.. UPON AWAKENING START THE OVERLAY ACTIVITY...
private BroadcastReceiver mReceiver;
private boolean isShowing = false;
#Override
public IBinder onBind(Intent intent) {
// TODO Auto-generated method stub
return null;
}
private WindowManager windowManager;
WindowManager.LayoutParams params;
#Override
public void onCreate() {
super.onCreate();
windowManager = (WindowManager)getSystemService(WINDOW_SERVICE);
//Register receiver for determining screen off and if user is present
mReceiver = new OverlayStateReceiver();
IntentFilter filter = new IntentFilter(Intent.ACTION_SCREEN_OFF);
filter.addAction(Intent.ACTION_USER_PRESENT);
filter.addAction(Intent.ACTION_SCREEN_ON);
registerReceiver(mReceiver, filter);
makeNotification();
}
void makeNotification() {
Notification notification = new NotificationCompat.Builder(this)
//TODO change icon
.setSmallIcon(R.drawable.test)
.setContentTitle("App")
.setContentText("service is running...")
.setPriority(Notification.PRIORITY_LOW)
.build();
startForeground(1, notification);
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
return START_STICKY;
}
public class OverlayStateReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
if (intent.getAction().equals(Intent.ACTION_SCREEN_OFF)) {
Log.i("app", "load view");
showOverlayActivity(context);
}
}
}
private void showOverlayActivity(Context context) {
Intent intent = new Intent(context, OverlayActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
intent.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.startActivity(intent);
}
#Override
public void onDestroy() {
//unregister receiver when the service is destroy
if (mReceiver != null) {
unregisterReceiver(mReceiver);
}
//TODO remove view if it is showing and the service is destroy
super.onDestroy();
}
}
i need a service in my app that starts first time and runs forever, even if user restart his phone, my service starts automatically without running my app. i write this code but when user restart his phone, my service doesn't start again!!
public class notifService extends Service {
#Override
public IBinder onBind(Intent arg0) {
return null;
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
super.onStart(intent, startId);
return Service.START_STICKY;
}
#Override
public void onDestroy() {
super.onDestroy();
}
}
and in the main activity i start service like this:
// start service
Intent service = new Intent(MainActivity.this, notifService.class);
MainActivity.this.startService(service);
thanks for you help.
Listen for android.intent.action.BOOT_COMPLETED in BroadcastReceiver and start your service.
For example
public class YourDefinedBootReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
Intent service = new Intent(context, notifService.class);
context.startService(service);
}
}
Also, you must hold the permission:
RECEIVE_BOOT_COMPLETED
Ref: Automatically starting Services in Android after booting and Android Start Service on Boot Automatically
It's code here:
public class MyServeice extends Service
{
private Timer pushTimer;
private final int NOTEF_ID = 1234;
NotificationManager manager;
#Override
public IBinder onBind(Intent arg0)
{
return null;
}
#Override
public void onCreate()
{
Log.i("MyActivity", "1");
//pushTimer = new Timer();
manager = (NotificationManager)getSystemService(NOTIFICATION_SERVICE);
}
#Override
public void onDestroy()
{
Log.i("MyActivity", "2");
//pushTimer.cancel();
}
#Override
public void onStart(Intent intent, int startid)
{
Log.i("MyActivity", "3");
//pushTimer.schedule(new TimerTask()
//{
// #Override
// public void run()
// {
Notification not = new Notification(R.drawable.ic_launcher, "Custom notification", System.currentTimeMillis());
PendingIntent notIntent = PendingIntent.getActivity(this , 0, new Intent(this, MainActivity.class), 0);
not.setLatestEventInfo(this, "Title", "Text", notIntent);
manager.notify(NOTEF_ID, not);
manager.cancel(NOTEF_ID);
// }
//}, 0L, 60L * 1000);
}
}
I try to start it from my MainActivity activity class (before I thought that problem is in timer, but now I comment it).
Starting code here:
startService(new Intent(this, MyServeice.class));
Log from Service class is not shown, so I decided that Service is not started at all. Application doesn't crash and started normaly. Can you check my code?
You made a mistake in MyServeice Class
You use
#Override
public void onStart(Intent intent, int startid)
& in Service Life cycle there is no onStart(..) Method
Try this method instead of above
#Override
public int onStartCommand(Intent intent, int flags, int startId)
EDIT:
& second One you have to declare service in Manifest File Like:
<manifest ... >
...
<application ... >
<service android:name=".MyServeice" />
...
</application>
</manifest>
For more Information About Service Refer this Documentation
http://developer.android.com/guide/components/services.html
Use this method :
#Override
public int onStartCommand(Intent intent, int flags, int startId) {}
Here is good tutorial about services : Click here !
Question closed. Adding info about my service class into manifest solved my problem.