How to Startforeground() Without Showing Notification

How to startForeground() without showing notification?

As a security feature of the Android platform, you cannot, under any circumstance, have a foregrounded service without also having a notification. This is because a foregrounded service consumes a heavier amount of resources and is subject to different scheduling constraints (i.e., it doesn't get killed as quickly) than background services, and the user needs to know what's possibly eating their battery. So, don't do this.

However, it is possible to have a "fake" notification, i.e., you can make a transparent notification icon (iirc). This is extremely disingenuous to your users, and you have no reason to do it, other than killing their battery and thus creating malware.

Android Foreground service without notification - how to?

Here is the implementation of Karsten Planz

You should either use the WorkManager API to
implement a background sync mechanism. Then you can use the
NotificationBuilder to create a "local" notifiction.

Start the Task in your main activity by this:

  WorkRequest uploadWorkRequest =
new OneTimeWorkRequest.Builder(NotificationWorker.class)
.build();
WorkManager
.getInstance(MainActivity.this)
.enqueue(uploadWorkRequest);

Now Create a class NotificationWorker and extends Worker. Place your startMyOwnForeground in doWork by returning Result.retry(), this will make a recursive function.

public class NotificationWorker extends Worker {

Context context;

public NotificationWorker(
@NonNull Context context,
@NonNull WorkerParameters params) {
super(context, params);
this.context=context;
}

@Override
public Result doWork() {
startMyOwnForeground();
return Result.retry();
}
private void startMyOwnForeground() {
Log.e("", "service running");
get_notification();
}

private void get_notification() {
Call<ArrayList> call = apiInterface.getnotification(ApiClient.pin, id);
call.enqueue(new Callback<ArrayList>() {
@RequiresApi(api = Build.VERSION_CODES.N)
@Override
public void onResponse(Call<ArrayList> call, Response<ArrayList> response) {
if (response.body() != null) {
for (int i = 0; i < response.body().size(); i = i + 1) {
ArrayList<String> getdata = (ArrayList<String>) response.body().get(i);
String[] data = getdata.toArray(new String[0]);
if (data[5].equals("0")) {
switch (data[4]) {
case "comment":
send_comment_notification(data[1], data[2], data[3], data[0]);
break;
case "question":
send_question_notification(data[3], data[0], data[1]);
break;
case "answer":
send_answer_notification(data[3], data[0], data[1]);
break;
}
}
}
}
}

@Override
public void onFailure(Call<ArrayList> call, Throwable t) {

}
});
}
}

foreground service without notification

Generally, you can not define foreground service without a notification. However, user can hide the notification of your app, so you can ask, but if the service gets started with no notification, it'll be killed by OS as soon as OS felt that it needs to be stopped.

TL; DR

No. For background task execution, the Android WorkManager is the newest and most reliable.

i need to remove notification without affecting foreground service

Android OS don’t like you to do this because users are entitled to know you are running a foreground serivce on their devices.
But if you must remove notification of foreground service :
In order to remove the notification icon in the notification area (the status bar) while foreground service still running :
Just set the priority to minimum (-2) in the notification builder:

for example:

/* (Notification.PRIORITY_MIN) will remove the notification in statusbar */ 
builder.setPriority(Notification.PRIORITY_MIN)
.setSmallIcon(R.drawable.ic_launcher)
.setContentTitle("Service Started")
.setTicker("Music Playing")
.setWhen(System.currentTimeMillis());

This will only remove the small notification icon in the notification area.

if you also need to get rid of the detail notification rectangle in the notification drawer :

then what you need to do is more complex:
you need to start your service as foreground, then start another foreground service with the same notification ID as you have in your original service.
Then close ( stopself() ) the new foreground service, and Android system will remove the notification (while your original service that started previously will stay in foreground without the notification).

This works fine in 5.1.1, I don’t know if android team already close this breach in marshmallow .

BTW:

  1. In order to do this there is also a non-programmatically way :
    Go to settings -> applications -> application manager find your application and press on it.
    You will get inside your application info.
    Disable the “show notifications” option in your application info.
    This will get rid of all notifications for your app but it also disable toast messages..
    I don’t think there is a way to disable this option in settings programmatically from inside the application - I think android prevent it for security reasons. If anyone knows how to change this programmatically please tell..

  2. if while trying to avoid the notification detail rectangle in the drawer you will remove these lines in your notification builder:

     .setSmallIcon(R.drawable.ic_launcher)
    .setContentTitle("Service Started")
    .setTicker("Music Playing")
    .setWhen(System.currentTimeMillis());

    Then Android system will keep on showing a notification rectangle about your service (with the title “This service is running, touch for more information or stop the service ” ) and pressing on this rectangle will lead the user to Your application info on settings -> applications -> application manager with option to “force stop” this service.
    Regarding that you can read more here https://plus.google.com/105051985738280261832/posts/MTinJWdNL8t

hope it helps :-)

Is notification mandatory while app is running(visible) for the foreground service in API 25

It's not possible to remove the notification while the foreground service is running, but it is possible to change your foreground service back into a "regular" service. This removes the need for a notification. In fact, the function to use,

stopForeground(boolean removeNotification)

...includes a removeNotification parameter just for that purpose. You service can switch from being "foreground" to "regular" on demand, by alternating calls to startForeground() and stopForeground().

In case it's not clear, you'd probably want to call stopForeground() whenever you have at least one Activity in a "started" state. This is something you'd have to track manually. Then, when the number of "started" activities reaches 0, you'd call startForeground().

EDIT

One approach is to use a bound service. Then, it's easy to call stopForeground() on it when you want.

Assume you have a single Activity. You can bind it to the service (see this doc or use one of these examples). Then your onServiceConnected() function could look like this (adapted from the Google example):

//MyActivity.java:

@Override
public void onServiceConnected(ComponentName className, IBinder service) {
LocalBinder binder = (LocalBinder) service;
mService = binder.getService();
mService.stopForeground(true); //This makes the notification go away
bound = true;
}

...

@Override
protected void onStart() {
super.onStart();
// Bind to the service
bindService(new Intent(this, MyService.class), this, Context.BIND_AUTO_CREATE);
}

@Override
protected void onStop() {
super.onStop();
// Unbind from the service
if (bound) {
Notification.Builder builder = new Notification.Builder(this, ANDROID_CHANNEL_ID)
.setContentTitle(getString(R.string.app_name))
.setContentText(text)
.setAutoCancel(true);

Notification notification = builder.build();
mService.startForeground(1, notification); //This brings the notification back! Service is already running, and continues to run.

unbindService(this);
bound = false;
}
}

startForeground Notification does not show Title or Content

I found the issue:

You need to set a valid small icon. Otherwise the notification display will fail silently during startForeground.

val notification: Notification = NotificationCompat.Builder(applicationContext, MainActivity.RECORDING_NOTIFICATION_CHANNEL.id)
.setOngoing(true)
.setSmallIcon(R.mipmap.ic_launcher)
.setContentTitle("MyService")
.setContentText("Recording Service Ready")
.setContentIntent(pendingIntent)
.build()

I discovered this when trying to display the notification manually using NotificationManager.notify.



Related Topics



Leave a reply



Submit