I have seen many tutorials saying that to do this I have to use a service. After watching a youtube video, got this:
public class MyService extends Service {
public MyService() {
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
onTaskRemoved(intent);
Toast.makeText(this, "Service", Toast.LENGTH_SHORT).show();
return START_STICKY;
}
#Override
public IBinder onBind(Intent intent) {
// TODO: Return the communication channel to the service.
throw new UnsupportedOperationException("Not yet implemented");
}
#Override
public void onTaskRemoved(Intent rootIntent) {
Intent restartServiceIntent = new Intent(getApplicationContext(), this.getClass());
restartServiceIntent.setPackage(getPackageName());
startService(restartServiceIntent);
super.onTaskRemoved(rootIntent);
}
}
And I have to call this service in MainActivity using startService(new Intent(this, MyService.class));
This is working fine. Even if I close the app from the Recent Apps. But when I Force Stop the app from Settings, the service doesn't work anymore.
Is there any way to keep the app running even if the app is forcibly killed?
You can register your app to get push notifications from google play services normally firebase now. And you can start your service by sending push notifications to your app from firebase Amin ask on your server.
NOTE: since android pie there are changes in how you can run your service. So before doing anything go through android pie services docs
Related
In my application, I need to do some task at midnight of the everyday. I achieved this using AlarmManager and service, but when my task starts it wakeup the device and launches the app. How can I do that like WhatsApp in the background?
service used for it.
You have create another class then, you have extend Service
public class service extends Service {
// declaring object of MediaPlayer
private MediaPlayer player;
public service() {
}
#Override
public int onStartCommand(Intent intent, int flags, int startId){
onTaskRemoved(intent);
Toast.makeText(getApplicationContext(),"This is a Service running in Background",
Toast.LENGTH_SHORT).show();
player = MediaPlayer.create(getApplicationContext(),R.raw.ringtone);
player.start();
startForegroundService(intent);
return START_STICKY;
}
#Override
public IBinder onBind(Intent intent) {
// TODO: Return the communication channel to the service.
throw new UnsupportedOperationException("Not yet implemented");
}
#Override
public void onTaskRemoved(Intent rootIntent) {
Intent restartServiceIntent = new Intent(getApplicationContext(),this.getClass());
restartServiceIntent.setPackage(getPackageName());
startService(restartServiceIntent);
super.onTaskRemoved(rootIntent);
}
#Override
public ComponentName startForegroundService(final Intent service) {
return startForegroundService(service);
}
}
To run the source code you have write
Intent intent = new Intent(this, service.class);
ContextCompat.startForegroundService(this,intent);
Alternatively, you can use
startService(new Intent(getApplicationContext(),service.class));
Sometimes above source code works in background in API level 22. Sometimes it gives error. Sometimes it doesn't work.
Here's the git repo
You can use WorkManager, that is the best way IMHO.
I use it for background processing and it works like a charm.
https://developer.android.com/topic/libraries/architecture/workmanager
OK, here is my code, I'm trying to create a running service even when the app is closed.
In main activity, I have created a new button and call startMyService() to start the service as following:
public void startMyService(View view) {
Intent intent = new Intent(MainActivity.this, MyService.class);
startService(intent);
}
the Service class is simple :
public class MyService extends Service {
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
Log.e("MyService", "service is running");
final Uri uri = Settings.System.DEFAULT_RINGTONE_URI;
final Context x =(Context) MyService.this;
new Thread(new Runnable() {
#Override
public void run() {
MediaPlayer player = MediaPlayer.create(x,uri);
player.setLooping(true);
player.start();
}
}).start();
Toast.makeText(getApplicationContext(), "Service is running", Toast.LENGTH_LONG).show();
return START_STICKY;
}
#Nullable
#Override
public IBinder onBind(Intent intent) {
return null;
}
#Override
public void onDestroy() {
super.onDestroy();
Toast.makeText(this, "service done", Toast.LENGTH_SHORT).show();
Log.e("MyService", "service done");
}
}
Of course, I have added the service to manifest
<service android:name=".MyService" android:exported="false" android:description="#string/service_description" />
Now after running, I pressed the button to start the service, and close the activity, I supposed the music will be playing in the background but it stopped just after closing the activity.
How to solve this issue? How to make the service still running, and how to make it running again after an android OS destroying it?
I know there are too many topics about android services and START_STICKY
However, as you see this is not working in code above, why?
Note: This is not about playing music in the background, I used playing music because it is the simplest way to know when service is stopped, this is about how to make service keeps running in the background as supposed to be, for example, to do some task like tracking data changes from the server.
It's normal behavior when your application target from android O, if you want to remain your Service you should use startForgroundService with Notification. Read here
While an app is in the foreground, it can create and run both foreground and background services freely. When an app goes into the background, it has a window of several minutes in which it is still allowed to create and use services. At the end of that window, the app is considered to be idle. At this time, the system stops the app's background services, just as if the app had called the services' Service.stopSelf() methods.
The service gets killed after removing the app from recent apps.
But this should not be killed and run always on the background.
I see that the service is running when the app is open. It's still running when I minimize the app via home-button. But it will stop if I kill it as mentioned above. How do I solve this?
public class NotificationService extends Service {
#Nullable
#Override
public IBinder onBind(Intent intent) {
return null;
}
#Override
public void onCreate() {
Toast.makeText(getApplicationContext(),"service started",Toast.LENGTH_LONG).show();
}
#Override
public void onDestroy() {
Toast.makeText(getApplicationContext(),"service stopped",Toast.LENGTH_LONG).show();
}
#Override
public int onStartCommand(final Intent intent,
final int flags,
final int startId) {
onTaskRemoved(intent);
//code
return START_STICKY;
}
#Override
public void onTaskRemoved(Intent rootIntent) {
Intent myIntent = new Intent(getApplicationContext(), NotificationService.class);
myIntent.setPackage(getPackageName());
startService(myIntent);
super.onTaskRemoved(rootIntent);
}
}
I don't want any notification for service as in case of foreground service.
I got the answer for it the autostart for the app was off so that the service once killed was not able to restart. Thank you all for your time!
Direct quote from a blog that Google published:
In its continuous effort to improve user experience, the Android
platform has introduced strict limitations on background services
starting in API level 26. Basically, unless your app is running in the
foreground, the system will stop all of your app's background services
within minutes.
You should consider using WorkManager. There is a lot of resources on how to use it, including samples, code-labs and blogs.
i'm trying to create an app that communicates with my localhost and search in a database.
I already make the connection and find the data, but i need to stay connected and send a notification if there's any changes in the table, but I can't figure it out how to keep the connection even when I close the app, because it closes everything, even the service.
The service doesn't stay open.
This is my Class:
public class SensorService extends Service {
#Override
public IBinder onBind(Intent intent) {
return null;
}
#Override
public void onCreate() {
super.onCreate();
Toast.makeText(this,"Starting",Toast.LENGTH_SHORT).show();
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
boolean bandera = true;
Toast.makeText(this, "Checking data...", Toast.LENGTH_SHORT).show();
return START_STICKY;
}
#Override
public void onTaskRemoved(Intent rootIntent) {
super.onTaskRemoved(rootIntent);
stopService(new Intent(this,SensorService.class));
startService(new Intent(this,SensorService.class));
}
#Override
public void onDestroy() {
startService(new Intent(this,SensorService.class));
}
}
Every time I close the app, the service execute one more time and no more.
If you want the service to continue running after the app is closed, you need to call the startForeground(int, Notification) method from within the service. Android limits you to running longer running services in the background only as long as a notification is displayed to the user letting them know that a service is running (like a music player or a downloading service).
This is an intentional design constraint to ensure developers do not start services in the background that run indefinitely without the user being aware. Supply your own notification (can be anything) and you should be able to run the service in the background.
For more detailed information on this method, read it at: startForeground(int, Notification)
You can use onTaskRemoved and restart the service if needed.
#Override
public void onTaskRemoved(Intent rootIntent){
super.onTaskRemoved(rootIntent);
//restart your service
}
Please note that if you use onTaskRemoved, start your service as not sticky so it won't be restarted.
#Override
public int onStartCommand(Intent intent, int flags, int startId)
{
return START_NOT_STICKY;
}
Description of Truecaller/Whatsapp service
**Note: Here force close means killing the app by pressing and holding back button not just stopping the service from service manager/app manager (see Kill app back button).
After killing the truecaller app when I make a call it restarts automatically, same for whatsapp also, After killing it when a message is received it still shows the notification and restarts the service. These services also restarts after a few delay
What I have done so far to achieve this
I want to make a service like this so called my backgroundservice from onDestroy() of my backgroundservice class. Code for this: ServiceDemo 0.1
public class BackgroundService extends Service {
#Nullable
#Override
public IBinder onBind(Intent intent) {
return null;
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
Toast.makeText(BackgroundService.this, "Service Started...", Toast.LENGTH_SHORT).show();
return START_STICKY;
}
#Override
public void onDestroy() {
Intent intentService = new Intent(this,BackgroundService.class);
startService(intentService);
Toast.makeText(BackgroundService.this, "Service Will Be Restarted...", Toast.LENGTH_SHORT).show();
}
}
The service is restarting if I stop it from my service manager. But if I force close/kill it , it's gone.
After this I implemented Broadcast receiver which doesn't make any difference. Code for this: ServiceDemo 0.2
BackgroundService.java
public class BackgroundService extends Service {
#Nullable
#Override
public IBinder onBind(Intent intent) {
return null;
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
Toast.makeText(BackgroundService.this, "Service Started...", Toast.LENGTH_SHORT).show();
return START_STICKY;
}
#Override
public void onDestroy() {
Toast.makeText(BackgroundService.this, "Service Will Be Restarted...", Toast.LENGTH_SHORT).show();
sendBroadcast(new Intent("RestartMe"));
}
}
RestartBackgroundService.java
public class RestartBackgroundService extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
// I have also used AlarmManager , but it doesn't make any difference for me
// AlarmManager am = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
// PendingIntent pi = PendingIntent.getService(context, 0, new Intent(context, BackgroundService.class), PendingIntent.FLAG_UPDATE_CURRENT);
// int interval = 5000;
// am.setInexactRepeating(AlarmManager.RTC_WAKEUP, System.currentTimeMillis() + interval, interval, pi);
context.startService(new Intent(context.getApplicationContext(),BackgroundService.class));
}
}
As whatsapp is using gcm so I thought if I implement that it would help.
Then I implemented firebase cloud messaging (fcm) to receive push notification and I removed the code to restart background service from onDestroy().
Now if I stops the service from service manager it remains stopped then I sends a notification from my firebase console it receives the notification as google's gcm service is running. If I click the notification it restarts my service again.
But if I force close/kill my app no notifications are received though gcm service is running. Code for this: (I posted a link to make the description a bit short)
ServiceDemo 0.3
What I want
I want my service to be persistent like whatsapp/truecaller even if I force close it. They keep on starting after a few delays. And I want to achieve it without using third parties like fcm.
If someone can give any hints/solution about how to start my service when a particular system service/app (like dialer) starts that would be a great help.