How to keep a Service alive? - android

How Whatsapp service keep working in background in huawei phones ?
I removed whatsapp of protected apps but Whatsapp service not closed in screen
off time.
I'm writing critical app that need to run every time but my service killed in screen off.
I want to write service like Whatsapp or AirDroid service
anyone can explain about that ?
I mean how to write service that specially not close by screen off in HUAWEI phones
This is my service code
AppLifeService
public class AppLifeService extends Service {
#Override
public IBinder onBind(Intent intent) {
return null;
}
#Override
public void onCreate() {
super.onCreate();
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
super.onStartCommand(intent, flags, startId);
startForeground(5, AppLifeReciever.createNotification(this));
return START_STICKY;
}
#Override
public void onDestroy() {
//startService(new Intent(this, AppLifeService.class)); Updated : not need
super.onDestroy();
}
}

You need to create a Service to "reopen" BroadcastService automatically when it's closed.
For example:
BroadcastService
public class MyBroadcastService extends BroadcastReceiver
{
#Override
public void onReceive(final Context context, Intent intent)
{
//do something
}
}
Service to "reopen" automatically
public class MyService extends Service
{
#Override
public void onCreate()
{
// Handler will get associated with the current thread,
// which is the main thread.
super.onCreate();
ctx = this;
}
#Override
public IBinder onBind(Intent arg0)
{
// TODO Auto-generated method stub
return null;
}
#Override
public int onStartCommand(Intent intent, int flags, int startId)
{
Log.i(TAG, "onStartCommand");
//Toast.makeText(this, "onStartCommand", Toast.LENGTH_LONG).show();
return START_STICKY;
}
//launch when its closed
#Override
public void onDestroy()
{
super.onDestroy();
sendBroadcast(new Intent("YouWillNeverKillMe"));
Toast.makeText(this, "YouWillNeverKillMe TOAST!!", Toast.LENGTH_LONG).show();
}
}
Declare on your AndroidManifest.XML
<receiver android:name=".BroadcastServicesBackground.MyBroadcastService">
<intent-filter>
<!--That name (YouWillNeverKillMe) you wrote on Myservice-->
<action android:name="YouWillNeverKillMe"/>
<data android:scheme="package"/>
</intent-filter>
<intent-filter>
<!--To launch on device boot-->
<action android:name="android.intent.action.BOOT_COMPLETED"/>
</intent-filter>
</receiver>
<service android:name=".Services.MyService"/>

Service with START_STICKY in retrun onStartCommand() will start again automatically you dont need to start it again in onDestroy()
#Override
public void onDestroy() {
// startService(new Intent(this, AppLifeService.class));
super.onDestroy();
}

#Sohail Zahid Answer tells you a way to repeatedly start a service again and again when stopped. But in order to keep a service alive like playing a song in a background.
The best Approach I found is
startForeground(int, Notification)
where int value must be unique for every notification
You'll need to supply a Notification to the method which is displayed in the Notifications Bar in the Ongoing section. In this way the app will keep alive in background without any interuption.

Related

Save last reading position

I created an app that reads books to the user.
The user needs to be able to continue reading
from the same position as he was in a previous app session.
How do i do something like that, if a process kill can occur anytime?
you can create here a service class in your app like this and create an api with your backend too :-
Service Class OnClearFromRecentService.class:-
public class OnClearFromRecentService extends Service {
#Override
public IBinder onBind(Intent intent) {
return null;
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
return START_NOT_STICKY;
}
#Override
public void onDestroy() {
super.onDestroy();
}
#Override
public void onTaskRemoved(Intent rootIntent) {
callApi();
stopSelf();
}
public void callApi(){
//set your api here
}
}
and set this service class in your manifeast :-
<service
android:name=".halper.OnClearFromRecentService"
android:stopWithTask="false" />
and start this service when your video is play :-
OnClearFromRecentService onClearFromRecentService = new OnClearFromRecentService();
or stop your service where your you need to stop service like this:-
onClearFromRecentService.onTaskRemoved(new Intent(LandingScreen.this, OnClearFromRecentService.class));

Android: Run code when application is permanently closed

So I have code that I want called when my application is closed. Not just when it is sent to the background or the surface is destroyed. How do I do this? Is there a method that I can override in a SurfaceView or Activity class?
New Edit - current BackgroundService class:
public class BackgroundService extends Service {
private String savedString;
public void onCreate() {
System.out.println("Service created");
super.onCreate();
}
public int onStartCommand(Intent intent, int flags, int startId) {
System.out.println("start command: ");
savedString = intent.getStringExtra("myString);
return super.onStartCommand(intent, flags, startId);
}
public IBinder onBind(Intent intent) {
return null;
}
public void onTaskRemoved(Intent rootIntent) {
System.out.println("the saved string was: " + savedString);
super.onTaskRemoved(rootIntent);
}
public void onDestroy() {
System.out.println("destroyed service");
super.onDestroy();
}
}
Where I then have this in my other class:
Intent serviceIntent = new Intent(activity.getApplicationContext(), BackgroundService.class);
serviceIntent.putExtra("myString", "this is my saved string");
activity.startService(serviceIntent);
you need to add a background service
public class BackgroundServices extends Service
{
#Override
public void onCreate() {
Toast.makeText(this, "start", Toast.LENGTH_SHORT).show();
super.onCreate();
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
}
#Nullable
#Override
public IBinder onBind(Intent intent) {
return null;
}
#Override
public void onDestroy() {
super.onDestroy();
}
}
then in your activity. where you want to trigger this service
use
startService(new Intent(getBaseContext(), BackgroundServices.class));
in your case it will be call on onDestory function of that activity
Yes when the process is terminated
That is not possible in general. Nothing in your app is called when the process is terminated.
For example when you open the running apps screen, and swipe away the app to stop it from running
That is a task removal. It may result in your process being terminated, and there are many ways in which your process can be terminated that has nothing to do with task removal.
To detect task removal, override onTaskRemoved() in a Service.

Android : Check if app is closed

I have an alarm broadcast receiver where I want to check if my app is completely closed, which means app is neither running in foreground nor background.
Can anyone tells me how can I check this ?
You can create a service and overwrite the onTaskRemoved() method
From the Documentation
the user has removed a task means swiping the app out from the task
list. Stopping the Service from the phone's settings does not trigger
Service.onTaskRemoved().
Code:
public class AppStopped extends Service {
#Override
public IBinder onBind(Intent intent) {
return null;
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
Log.d("Service", "Service Started");
return START_NOT_STICKY;
}
#Override
public void onDestroy() {
super.onDestroy();
Log.d("Service", "Service Destroyed");
}
#Override
public void onTaskRemoved(Intent rootIntent) {
Log.e("Service", "END");
Toast.makeText(getApplicationContext(), "App Stopped", Toast.LENGTH_SHORT).show();
//Code here
stopSelf();
}
}
In Manifest:
<service android:name="com.example.AppStopped"
android:stopWithTask="false" />
Start the service in your activity like:
startService(new Intent(getBaseContext(), AppStopped.class));
In your Application class:
public class MyApplication extends Application {
#Override
public void onTerminate() {
super.onTerminate();
// your app is closed
}
}

Quick Settings Toggle in Android N

I'm trying to add a quick settings toggle to my app in Android N. The quick tile shows up, but it doesn't do anything when clicked. I can see the visible feedback when touched, so I know that it is recognizing the click, but it doesn't do anything when clicked.
Here's my service code:
public class QuickSettingTileService extends TileService {
public QuickSettingTileService()
{
}
#Override
public IBinder onBind(Intent intent)
{
return null;
}
#Override
public int onStartCommand(Intent intent, int flags, int startID)
{
//some setup code is here
return START_STICKY;
}
#Override
public void onClick()
{
Context context = getApplicationContext();
Toast.makeText(context, "Quick Setting Clicked", Toast.LENGTH_SHORT).show();
//Toggle code is here
}
}
My manifest has the code almost directly copied from the documentation. Only slight modifications have been made:
<service
android:name=".QuickSettingTileService"
android:label="#string/app_name"
android:icon="#drawable/quick_toggle_off"
android:permission="android.permission.BIND_QUICK_SETTINGS_TILE">
<intent-filter>
<action android:name="android.service.quicksettings.action.QS_TILE" />
</intent-filter>
</service>
The service is started upon opening the app:
Intent serviceIntent = new Intent(this, QuickSettingTileService.class);
startService(serviceIntent);
Just remove these lines from your QuickSettingTileService class
#Override
public IBinder onBind(Intent intent)
{
return null;
}
#Override
public int onStartCommand(Intent intent, int flags, int startID)
{
//some setup code is here
return START_STICKY;
}
There is no need to override onBind() or onStartCommand() on a TileService.
Also, you don't need to explicitly start this service. The permission and intent-filter in the manifest will make sure Android OS will start your service when your tile is added to the Notification bar.

Service is NOT running always even after I have used START_STICKY

Issues
Service is NOT running always even after I have used START_STICKY.
Sometimes I dont get any Toast Action for Outgoing call, is that mean service stops after some time ?
My Requirment
Application shows a Toast whenever user makes a outgoing call from the phone. For this I am using a BroadcastReceiver to tap the call action and a service (to run Receiver always). once I start this activity, it starts showing toast when a outgoing call get initiated ..but not Always.
Below is the complete code -
MainActivity.class
public class MainActivity extends Activity
{
CallNotifierService m_service;
boolean isBound = false;
private ServiceConnection m_serviceConnection = new ServiceConnection()
{
#Override
public void onServiceConnected(ComponentName className, IBinder service)
{
m_service = ((CallNotifierService.MyBinder)service).getService();
Toast.makeText(MainActivity.this, "Service Connected", Toast.LENGTH_LONG).show();
isBound = true;
Intent intent = new Intent(MainActivity.this, CallNotifierService.class);
startService(intent);
}
#Override
public void onServiceDisconnected(ComponentName className)
{
m_service = null;
isBound = false;
}
};
#Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Intent intent = new Intent(this, CallNotifierService.class);
bindService(intent, m_serviceConnection, Context.BIND_AUTO_CREATE);
}
.
.
.
}
CallNotifierService.class
public class CallNotifierService extends Service
{
private final IBinder myBinder = new MyBinder();
private static final String ACTION_OUTGOING_CALL = "android.intent.action.NEW_OUTGOING_CALL";
private CallBr br_call;
#Override
public IBinder onBind(Intent arg0)
{
return myBinder;
}
#Override
public void onDestroy()
{
Log.d("service", "destroy");
this.unregisterReceiver(this.br_call);
Toast.makeText(CallNotifierService.this, "Receiver Un-Registered", Toast.LENGTH_LONG).show();
super.onDestroy();
}
#Override
public int onStartCommand(Intent intent, int flags, int startId)
{
final IntentFilter filter = new IntentFilter();
filter.addAction(ACTION_OUTGOING_CALL);
this.br_call = new CallBr();
this.registerReceiver(this.br_call, filter);
Toast.makeText(CallNotifierService.this, "onStartCommand Called", Toast.LENGTH_LONG).show();
return START_STICKY;
}
public class MyBinder extends Binder
{
CallNotifierService getService()
{
return CallNotifierService.this;
}
}
public class CallBr extends BroadcastReceiver
{
public CallBr() {}
#Override
public void onReceive(Context context, Intent intent)
{
Toast.makeText(context, "Action:"+intent.getAction(), Toast.LENGTH_LONG).show();
}
}
}
You are getting the wrong approach here, by mixing a simple idea (that would work if done correctly) with more complicated ideas (that cannot work).
Keep in mind: services are not "always running" components, even when using START_STICKY.
The Android system will not hesitate to kill your service if it needs memory somewhere else. START_STICKY only means that the Android system will re-start your service when it can, calling onStartCommand as specified in the documentation.
If you need a service to really stick around, then you must use a foreground service. But it will have consequences on the UI (annoying notification icon always showing), and battery life, and you do not need this here.
Now here is the magic trick: your app does not need to be running for your BroadcastReceiver to work. All you need to do is to register it in your AndroidManifest.xml with the correct intent-filter:
<receiver android:name=".broadcastreceivers.CallBroadcastReceiver">
<intent-filter>
<action android:name="android.intent.action.NEW_OUTGOING_CALL"/>
</intent-filter>
</receiver>
(also make sure your app has the required permissions, namely PROCESS_OUTGOING_CALLS).
Then all you need in code is:
public class CallBroadcastReceiver extends BroadcastReceiver
{
#Override
public void onReceive(Context context, Intent intent)
{
Toast.makeText(context, "Action: " + intent.getAction(), Toast.LENGTH_LONG).show();
}
}
No activity (except to ask for the PROCESS_OUTGOING_CALLS permission on Android 6+), no service, nothing. Simple and battery-efficient !
The service does get re-created, not not re-started.
If you override the onCreate and do a Log.d or a Toast, you will see that it gets called after your app is destroyed.
So the trick to keep it running after it is recreated is to do your code on the onCreate method and use the onStartCommand just to return START_STICKY.

Categories

Resources