I'd start by completely filling in the Notification
. Here is a sample project demonstrating the use of startForeground()
.
From your main activity, start the service with the following code:
Intent i = new Intent(context, MyService.class);
context.startService(i);
Then in your service for onCreate()
you would build your notification and set it as foreground like so:
Intent notificationIntent = new Intent(this, MainActivity.class);
PendingIntent pendingIntent = PendingIntent.getActivity(this, 0,
notificationIntent, 0);
Notification notification = new NotificationCompat.Builder(this)
.setSmallIcon(R.mipmap.app_icon)
.setContentTitle("My Awesome App")
.setContentText("Doing some work...")
.setContentIntent(pendingIntent).build();
startForeground(1337, notification);
I've encountered some problems such as RemoteServiceException because of invalid channel id with most recent versions of Android. This is how i solved it:
Activity:
override fun onCreate(savedInstanceState: Bundle?) {
val intent = Intent(this, BackgroundService::class.java)
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
startForegroundService(intent)
} else {
startService(intent)
}
}
BackgroundService:
override fun onCreate() {
super.onCreate()
startForeground()
}
private fun startForeground() {
val channelId =
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
createNotificationChannel()
} else {
// If earlier version channel ID is not used
// https://developer.android.com/reference/android/support/v4/app/NotificationCompat.Builder.html#NotificationCompat.Builder(android.content.Context)
""
}
val notificationBuilder = NotificationCompat.Builder(this, channelId )
val notification = notificationBuilder.setOngoing(true)
.setSmallIcon(R.mipmap.ic_launcher)
.setPriority(PRIORITY_MIN)
.setCategory(Notification.CATEGORY_SERVICE)
.build()
startForeground(101, notification)
}
@RequiresApi(Build.VERSION_CODES.O)
private fun createNotificationChannel(): String{
val channelId = "my_service"
val channelName = "My Background Service"
val chan = NotificationChannel(channelId,
channelName, NotificationManager.IMPORTANCE_HIGH)
chan.lightColor = Color.BLUE
chan.importance = NotificationManager.IMPORTANCE_NONE
chan.lockscreenVisibility = Notification.VISIBILITY_PRIVATE
val service = getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
service.createNotificationChannel(chan)
return channelId
}
JAVA EQUIVALENT
public class YourService extends Service {
// Constants
private static final int ID_SERVICE = 101;
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
super.onStartCommand(intent, flags, startId);
return START_STICKY;
}
@Override
public void onCreate() {
super.onCreate();
// do stuff like register for BroadcastReceiver, etc.
// Create the Foreground Service
NotificationManager notificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
String channelId = Build.VERSION.SDK_INT >= Build.VERSION_CODES.O ? createNotificationChannel(notificationManager) : "";
NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(this, channelId);
Notification notification = notificationBuilder.setOngoing(true)
.setSmallIcon(R.mipmap.ic_launcher)
.setPriority(PRIORITY_MIN)
.setCategory(NotificationCompat.CATEGORY_SERVICE)
.build();
startForeground(ID_SERVICE, notification);
}
@RequiresApi(Build.VERSION_CODES.O)
private String createNotificationChannel(NotificationManager notificationManager){
String channelId = "my_service_channelid";
String channelName = "My Foreground Service";
NotificationChannel channel = new NotificationChannel(channelId, channelName, NotificationManager.IMPORTANCE_HIGH);
// omitted the LED color
channel.setImportance(NotificationManager.IMPORTANCE_NONE);
channel.setLockscreenVisibility(Notification.VISIBILITY_PRIVATE);
notificationManager.createNotificationChannel(channel);
return channelId;
}
}
This is my code to set the service to foreground:
private void runAsForeground(){
Intent notificationIntent = new Intent(this, RecorderMainActivity.class);
PendingIntent pendingIntent=PendingIntent.getActivity(this, 0,
notificationIntent, Intent.FLAG_ACTIVITY_NEW_TASK);
Notification notification=new NotificationCompat.Builder(this)
.setSmallIcon(R.drawable.ic_launcher)
.setContentText(getString(R.string.isRecording))
.setContentIntent(pendingIntent).build();
startForeground(NOTIFICATION_ID, notification);
}
I need to build a notification using PendingIntent, so that I can start my main activity from the notification.
To remove the notification, just call the stopForeground(true);
It is called in the onStartCommand(). Please refer to my code at : https://github.com/bearstand/greyparrot/blob/master/src/com/xiong/richard/greyparrot/Mp3Recorder.java
In addition to RAWA answer, this peace of code:
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
startForegroundService(intent)
} else {
startService(intent)
}
You can change to:
ContextCompat.startForegroundService(context, yourIntent);
If you will look inside this method then you can see that this method do all checking work for you.
then you should override onHandleIntent()
like this
Override
protected void onHandleIntent(@Nullable Intent intent) {
startForeground(FOREGROUND_ID,getNotification()); //<-- Makes Foreground
// Do something
stopForeground(true); // <-- Makes it again a normal Service
}
simple. Here is the getNotification()
Method
public Notification getNotification()
{
Intent intent = new Intent(this, SecondActivity.class);
PendingIntent pendingIntent = PendingIntent.getActivity(this,0,intent,0);
NotificationCompat.Builder foregroundNotification = new NotificationCompat.Builder(this);
foregroundNotification.setOngoing(true);
foregroundNotification.setContentTitle("MY Foreground Notification")
.setContentText("This is the first foreground notification Peace")
.setSmallIcon(android.R.drawable.ic_btn_speak_now)
.setContentIntent(pendingIntent);
return foregroundNotification.build();
}
This happens
A foreground service,
makes sure that user is actively aware of that something is going on in the background by providing the notification.
(most importantly) is not killed by System when it runs low on memory
Implementing song download functionality in a Music App
Add given code Service class for "OS >= Build.VERSION_CODES.O" in onCreate()
@Override
public void onCreate(){
super.onCreate();
.................................
.................................
//For creating the Foreground Service
NotificationManager notificationManager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
String channelId = Build.VERSION.SDK_INT >= Build.VERSION_CODES.O ? getNotificationChannel(notificationManager) : "";
NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(this, channelId);
Notification notification = notificationBuilder.setOngoing(true)
.setSmallIcon(R.mipmap.ic_launcher)
// .setPriority(PRIORITY_MIN)
.setCategory(NotificationCompat.CATEGORY_SERVICE)
.build();
startForeground(110, notification);
}
@RequiresApi(Build.VERSION_CODES.O)
private String getNotificationChannel(NotificationManager notificationManager){
String channelId = "channelid";
String channelName = getResources().getString(R.string.app_name);
NotificationChannel channel = new NotificationChannel(channelId, channelName, NotificationManager.IMPORTANCE_HIGH);
channel.setImportance(NotificationManager.IMPORTANCE_NONE);
channel.setLockscreenVisibility(Notification.VISIBILITY_PRIVATE);
notificationManager.createNotificationChannel(channel);
return channelId;
}
Add this permission in manifest file:
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With