2

I have created a Service in my android application which starts automatically on BOOT_COMPLETE through BroadcastReceiver. And That is working perfectly fine. But this service performs the task that I have define inside onCreate() method, only once. On the Other hand I want to run the Service forever in background. Actually inside onCreate() method I am reading data from my database and I am generating notifications if required. And the notifications can be generated any time, so therefore I want to run my service forever. I am new to Android, and I have seen may examples & tutorial but they did not helped. So kindly Answer that how can I run my Service forever.

This is code of Service:

package com.example.abc.project1;

import android.app.*;
import android.content.Intent;
import android.os.IBinder;
import android.util.*;
import org.json.*;
import java.io.*;
import java.net.*;
import java.util.*;


public class HelloService extends Service {

    private static final String TAG = "HelloService";
    public static boolean isRunning  = false;

    @Override
    public IBinder onBind(Intent arg0) {
        return null;
    }


    @Override
    public void onCreate() {
        isRunning = true;
        new Thread(new Runnable() {
            @Override
            public void run() {
                /*Here I want to do my task forever (reading from database & generate notifications)*/
            }
        }).start();
    }


    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        return Service.START_STICKY;
    }

    @Override
    public void onDestroy() {
        isRunning = false;
    }

}

This is code of BroadcastReceiver

package com.example.abc.project1;

import android.content.*;
import android.util.Log;

public class MyBroadcastreceiver extends BroadcastReceiver {
    @Override
    public void onReceive(Context context, Intent intent) {
        Intent startServiceIntent = new Intent(context, HelloService.class);
        context.startService(startServiceIntent);
    }
}

This is part of AndroidManifest.xml

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.abc.project1">

    <uses-permission android:name="android.permission.INTERNET" />
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
    <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
    <uses-permission android:name="com.google.android.providers.gef.permission.READ_GSERVICES" />
    <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"></uses-permission>
    <uses-permission android:name="android.permission.ACCESS_COARSE_CATION" />
    <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />

    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:supportsRtl="true"
        android:theme="@style/AppTheme">

        <meta-data
            android:name="com.google.android.geo.API_KEY"
            android:value="@string/google_maps_key" />

        <service android:name=".HelloService"></service>

        <receiver android:name="com.example.abc.project1.MyBroadcastreceiver" android:enabled="true" android:exported="false">
            <intent-filter>
                <action android:name="android.intent.action.BOOT_COMPLETED"/>
            </intent-filter>
            <intent-filter>
                <action android:name="android.intent.action.PACKAGE_REPLACED" />
                <data android:scheme="package" />
            </intent-filter>
            <intent-filter>
                <action android:name="android.intent.action.PACKAGE_ADDED" />
                <data android:scheme="package" />
            </intent-filter>
        </receiver>

    </application>

</manifest>
Zoe
  • 27,060
  • 21
  • 118
  • 148
Sajal Ali
  • 427
  • 1
  • 10
  • 21
  • I've posted a pretty clean nifty solution here. Hope it helps. http://stackoverflow.com/questions/9029040/how-to-run-an-android-app-in-background/43555050#43555050 – user2288580 Apr 22 '17 at 04:00
  • I think if you create a bound service it will always remain running until you call Context.stopService(). The standard services can be destroyed by Android unless you put them in the foreground using Notifications. – TheRealChx101 Mar 13 '19 at 14:47

5 Answers5

2

According to Service documentation

The service will at this point continue running until Context.stopService() or stopSelf() is called.

So your service will run forever until system will not decide to kill it because of lack of resources.

Lina Shyshova
  • 546
  • 5
  • 12
  • but when I am running this Service it is executing the task only once. why is it so? – Sajal Ali May 07 '16 at 16:16
  • Because your task is inside onCreate and this code called only once on Service create. So you want your code run infinitely? But why? If your database data can be updated and when it's updated you need to create notification you can simply create IntentService every time you need to create notification. – Lina Shyshova May 07 '16 at 16:33
  • notification can be generated even when my application is not running. so how can I continuously check my database even when my application is not running? – Sajal Ali May 07 '16 at 16:48
  • Sure, but what event precede creating of notification? When your database is updated? Maybe you should start your service every time your database is updated? – Lina Shyshova May 07 '16 at 18:28
2

It is very simple.
steps:
1.create a Service class.
2.create a BroadcastReceiver class
3.call BroadReceiver in onDestroy method of service
4.In onReceive method of BroadReceiver class start service once again.
refer this link

Community
  • 1
  • 1
Vignesh VRT
  • 399
  • 3
  • 15
  • But onDestroy is not always guaranteed to be run when a service is killed due to system resources being low. – Goku Dec 01 '20 at 06:02
2

So there are 2 ways to achieve this

1. Restart the service in onTaskRemoved with startService(new Intent(this, <your.class>))
Warning: The onCreate will be called once

2. Use the startForeground(NOTIFICATION_ID, notification) for targeting above Android N , this way service won't be stopped and if using any Broadcast receivers won't be killed (preferred way).

@RequiresApi(Build.VERSION_CODES.O)
private void startMyOwnForeground() {
    NotificationChannel chan = new NotificationChannel(NOTIFICATION_CHANNEL_ID, getClass().getSimpleName(), NotificationManager.IMPORTANCE_NONE);
    chan.setLightColor(Color.WHITE);
    chan.setLockscreenVisibility(Notification.VISIBILITY_PRIVATE);

    notifManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
    notifManager.createNotificationChannel(chan);

    NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(this, NOTIFICATION_CHANNEL_ID);
    Notification notification = notificationBuilder.setOngoing(true)
            .setContentTitle("App is running in background")
            .setPriority(NotificationManager.IMPORTANCE_MIN)
            .setCategory(Notification.CATEGORY_SERVICE)
            .build();
    startForeground(NOTIFICATION_ID, notification);
}


For lower APIs

if (Build.VERSION.SDK_INT > Build.VERSION_CODES.O) {
   startMyOwnForeground();
} else {
   startForeground(NOTIFICATION_ID, new Notification());
}
Satyam Sharma
  • 21
  • 1
  • 2
0

Write your handler code in onStartCommand. But remember, your service will be paused when device goes in "sleep mode".

Ahmad Shahwaiz
  • 1,432
  • 1
  • 17
  • 35
0

According to documentation.

Reasons your service is killed:

The Android system stops a service only when memory is low and it must recover system resources for the activity that has user focus.

So as long as the above condition isn't met, your service will run forever.

Kwnstantinos Nikoloutsos
  • 1,832
  • 4
  • 18
  • 34