Foreground Notification

Foreground Service in Android [Update 2020]

Foreground Service in Android – Android Tutorial

This article has been updated on 2/1/2020 to make sure that the Foreground Services are working fine even with the Android Pie and above also.

Service in Android is a very important concept. Foreground Service is part of the Service, that decides how your application can be made robust. The primary use case of a Foreground Service is to provide a better sticky service(more of this in the next section) that runs along with the Application while the user still knows there is some action that the application is doing. Best examples for Foreground services will be, Google Maps showing the Route or Music application playing music, etc.

Like we saw in the Services in the Android article, there are three main Services available in Android.

  • Background Service
  • Foreground Service
  • Bounded Service.

In this tutorial, we will see how to create a Foreground service and understand how effective it is in order to create a robust Android application.

Why use a Foreground Service?

The answer for this question lies in the above example. The Google Map Application and the Music App which is constantly streaming music has to let the user know that there is some action happening inspite of the User controlling it, this is possible only by running a Foreground Service. It is impossible to make use of the App to run a program continuously(Music keeps playing continuously by streaming content from the Cloud) without letting the user know about it. That is the main purpose of the Foreground Service.

Creating a Foreground Service takes the following steps.

  • Start a Service – Usually called as a Sticky Service that sticks to the Application. This way, the Android OS knows what are the Application that is going to make use of the resources continuously.
  • Let the Android OS know about the Sticky service by creating the Notification that should come up on the banner
  • Once Notification is created Create your Logic for the Foreground Service. This could be where you load the music from cloud or maybe Map direction from cloud.
  • Show the Progress to the user continuously. Note: Until the Foreground service is completely killed the Notification Banner is going to be shown
  • Once the work is done, kill your Notification followed by the Service.

The above steps act as a simple Template to create any Foreground Notification. But how do you really create them!

Foreground Service – Creation

Like we saw in the Services in Android article, we will be needing the class Service for creating any type of service. ForegroundService, in addition, provides notification on the top (Think about a music app, that sticks the notification on the top while playing music!!). This provides the user with additional information about the Service that is running.

We will be creating our First Foreground Service by extending the Service class.

public class ForegroundService extends Service {}

Foreground Service Activity

Time to Look at the Activity that is responsible for the Foreground Activity. Key points to remember,

  • Override the onCreate to Show a Toast or Information that the Activity is starting
  • Override the onStartCommand to start the Notification. This step is crucial because, ForegroundService cannot be continued unless a Notification is shown to the user
  • Be Sure to clean up the service by overriding the onDestroy

Foreground Service – Example in Android Studio

For this example, we will be creating the Class named the ForegroundService.class.

I will be reusing the layout from the Service in Android Example. Be sure to give that a read before coming here. This is the simplest of all implementations to create Foreground Service in Android(I have literally stripped out everything!!)

main_layout.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">
    <TextView
        android:id="@+id/text_service"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center"
        android:text="Service Example"
        android:layout_marginTop="10dp" />
    <Button
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center"
        android:id="@+id/start"
        android:text="Start Service"/>
    <Button
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center"
        android:id="@+id/stop_Service"
        android:text="Stop Service"/>

</LinearLayout>
ServiceActivity.java
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.support.design.widget.FloatingActionButton;
import android.support.design.widget.Snackbar;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.Toolbar;
import android.view.View;
import android.widget.Button;

public class ServiceActivity extends Activity{
    Button startService;
    Button stopService;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main_layout);
        startService = (Button) findViewById(R.id.start);
        stopService = (Button) findViewById(R.id.stop_Service);

        startService.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                startService(new Intent(v.getContext(),ForegroundService.class));
            }
        });
        stopService.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                stopService(new Intent(v.getContext(),ForegroundService.class));
            }
        });
    }
}
ForegroundService.java
import android.app.Notification;
import android.app.Service;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.IBinder;
import android.support.annotation.Nullable;
import android.support.v4.app.NotificationCompat;
import android.widget.Toast;

public class ForegroundService extends Service {

    @Nullable
    @Override
    public IBinder onBind(Intent intent) {
        return null;
    }
    @Override
    public void onCreate() {
        Toast.makeText(this, "Service Created", Toast.LENGTH_LONG).show();

    }
    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        Bitmap icon = BitmapFactory.decodeResource(getResources(),
                R.drawable.ic_shape_1);

        Toast.makeText(this,"Creating Notification",Toast.LENGTH_SHORT).show();

        Notification notification = new NotificationCompat.Builder(this)
                .setContentTitle("AndroidMonks Sticker")
                .setTicker("AndroidMonks Sticker")
                .setContentText("Example")
                .setSmallIcon(R.drawable.ic_shape_1)
                .setLargeIcon(Bitmap.createScaledBitmap(icon, 128, 128, false))
                .setOngoing(true).build();

        startForeground(1001,notification);
        return START_STICKY;
    }
    @Override
    public void onDestroy() {
        Toast.makeText(this, "Service Stopped", Toast.LENGTH_LONG).show();
    }
}

Explanation

Jumping straight to the explanation of what we have done here. There are 2 important things to know about the Foreground Service.

  1. The Foreground Service in Android cannot be started without passing a Notification to it! (Creating a Notification is very very important to let the user know there is a service run by the App)
  2. Service Lifecycle decides if a Service should be running or not. When it comes to overriding the onStartCommand() method, we are required to provide return modes which are
    1. START_STICKY: This is used for services that are explicitly started and stopped as needed.
    2. START_NOT_STICKY: This is used to let the OS know that there is a need to stay alive only when there is a command that has to be run. This can mean that the OS can kill the service if a higher priority Service has to be run.
    3. START_REDELIVER_INTENT: This has the same property as that of the START_NOT_STICKY, except if the OS kills it, the Service gets fired once again! This is really important if you are going to be creating a long-running ForegroundService (Might also be a bounded service).

With the understanding from the above, there is a clear picture of how the ForegroundService in android is created. Notification creation is another important topic that has to be known. You can refer the Article on Creating Notifications in Android for a clearer understanding of how the Notifications can be created and the ways in which it can be integrated with a ForegroundService also.

Final Foreground Service Application:

 

"<yoastmark
The application running on the Emulator

Foreground Service – Conclusion

This Service is often highly used along with Music, Tracking (Google Maps) type of applications. You can check out my application here (FollowMyFriend – Universal Mobile Tracker to follow friends and family in one button push), Creating the application taught me the nitty gritty things about Services!

Drop in any comments you have below.

“Learn and be Curious”

Leave a Comment