Hi i'm trying to make an app which can be run in background and does not go to PAUSE mode.
I have read about services and tried to do that,but dint actually get how to use Service to do so.
Please help me out with services or any other way to to run an application in background.
To create a application to run in the background of other current activities, one needs to create a Service. The Service can run indefinitely (unbounded) or can run at the lifespan of the calling activity(bounded).
Please note that a Service has a different lifecycle than activities therefore have different methods. But to begin a service in the application a call to startService() which envokes the service onCreate() method and onStart() beginning running the service.
https://thenewcircle.com/s/post/60/servicesdemo_using_android_services
Source
http://thenewcircle.com/static/tutorials/ServicesDemo.zip
Music File
http://thenewcircle.com/static/tutorials/braincandy.m4a
service class extends Service{
//service methods
#Override
public void onCreate() {
Toast.makeText(this, "My Service Created", Toast.LENGTH_LONG).show();
Log.d(TAG, "onCreate");
player = MediaPlayer.create(this, R.raw.braincandy);
player.setLooping(false); // Set looping
}
#Override
public void onDestroy() {
Toast.makeText(this, "My Service Stopped", Toast.LENGTH_LONG).show();
Log.d(TAG, "onDestroy");
player.stop();
}
#Override
public void onStart(Intent intent, int startid) {
Toast.makeText(this, "My Service Started", Toast.LENGTH_LONG).show();
Log.d(TAG, "onStart");
player.start();
}
}
It works perfect, i have tested this also.
http://developer.android.com/reference/android/app/Service.html
Android: How to periodically send location to a server
keep application running in background
Pls let me know if still ur facing any problem :)
Try something like below.
The following code start new activity.
Intent intent = new Intent(MainActivity.this, AppService.class);
startService(intent);
// This function is used to hide your app
hideApp(getApplicationContext().getPackageName());
System.out.println("Inside of main");
}
private void hideApp(String appPackage) {
ComponentName componentName = new ComponentName(appPackage, appPackage
+ ".MainActivity");
getPackageManager().setComponentEnabledSetting(componentName,
PackageManager.COMPONENT_ENABLED_STATE_DISABLED,
PackageManager.DONT_KILL_APP);
}
So basically do your task whatever you want to do in AppService class
and in manifest file declare service class as a service not as an activity so it should be like this
<service android:name=".AppService" >
</service>
Related
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.
I am starting and stopping a service from an activity calling startSertice()/stopService() (when user select/deselect a check box and service is not bounded). Every thing is working fine even though the activity that starts the service is closed. In "Running apps" I'm able to see 1 processes, 1 service running. But when I kill the application, using Task manager kind of application, the process is getting killed and service is not working though the running apps showing 0 processes, 1 service. How to make the service working in such situations? I observed the same in some other security applications like Avast with 0 processes, 1 service, while service working properly. Please help me out on this.
Following is the activity on click method
#Override
public void onClick(View arg0) {
boolean value = checkBox.isChecked();
if(value){
// start the service
startService(new Intent(this, MyService.class));
Toast.makeText(this, "Background service started", Toast.LENGTH_SHORT).show();
} else {
stopService(new Intent(this, MyService.class));
Toast.makeText(this, "Background service stopped", Toast.LENGTH_SHORT).show();
}
}
Following is the service class:
public class MyService extends Service{
#Override
public IBinder onBind(Intent arg0) {
// TODO Auto-generated method stub
return null;
}
#Override
public void onCreate(){
super.onCreate();
Log.d("######Service","Service created successfully");
}
#Override
public int onStartCommand(Intent intent, int flags, int stardId){
Log.d("######Service","Service started successfully");
IntentFilter powerButtonIntentFilter = new IntentFilter();
powerButtonIntentFilter.addAction("android.intent.action.SCREEN_ON");
this.registerReceiver(pbReceiver, powerButtonIntentFilter);
Log.d("#######","Power button register registered");
return START_STICKY;
}
#Override
public void onDestroy(){
Log.d("######Service","Service destroyed successfully");
this.unregisterReceiver(pbReceiver);
Log.d("#######","Power button register un-registered");
super.onDestroy();
}
}
Everything is working fine in ideal case. SCREEN ON action is being listened by the broadcast receiver properly even when the activity that starts the service is closed. I am able to see the app running in settings. But when I force kill the process using Task Manager kind of applications, processes is getting killed and in running apps I am able to see 0 process, 1 service running. Though the service is running after force killing the app from Task manager, broadcast receiver is not listening to the SCREEN ON action. Please help me out on this.
Thanks, JK
I am starting a service from my main Android activity as follows:
final Context context = base.getApplicationContext();
final Intent intent = new Intent(context, MyService.class);
startService(intent);
When I close the activity page by swiping it out from the recent apps list, the service stops running and restarts after some time. I can't use persistent services with notifications because of my app requirements. How can I make the service NOT restart or shutdown and just keep on running on app exit?
I'm in the same situation, so far I learned when the app is closed the service get closed also because they are in a one thread, so the service should be on another thread in order fot it not to be closed, look into that and look into keeping the service alive with alarm manager here an example http://www.vogella.com/articles/AndroidServices/article.html this way your service won't be shown in notification.
lastly, after all the research I've done I'm coming to realize that the best choice for a long running service is startForeground(), because it is made for that and the system actually deals with your service well.
make you service like this in your Mainifest
<service
android:name=".sys.service.youservice"
android:exported="true"
android:process=":ServiceProcess" />
then your service will run on other process named ServiceProcess
if you want make your service never die :
onStartCommand() return START_STICKY
onDestroy() -> startself
create a Deamon service
jin -> create a Native Deamon process, you can find some open-source projects on github
startForeground() , there is a way to startForeground without Notification ,google it
Services are quite complicated sometimes.
When you start a service from an activity (or your process), the service is essentially on the same process.
quoting from the developer notes
Most confusion about the Service class actually revolves around what it is not:
A Service is not a separate process. The Service object itself does not imply it is running in its own process; unless otherwise specified, it runs in the same process as the application it is part of.
A Service is not a thread. It is not a means itself to do work off of the main thread (to avoid Application Not Responding errors).
So, what this means is, if the user swipes the app away from the recent tasks it will delete your process(this includes all your activities etc).
Now, lets take three scenarios.
First where the service does not have a foreground notification.
In this case your process is killed along with your service.
Second where the service has a foreground notification
In this case the service is not killed and neither is the process
Third scenario
If the service does not have a foreground notification, it can still keep running if the app is closed. We can do this by making the service run in a different process.
(However, I've heard some people say that it may not work. left to you to try it out yourself)
you can create a service in a separate process by including the below attribute
in your manifest.
android:process=":yourService"
or
android:process="yourService" process name must begin with lower case.
quoting from developer notes
If the name assigned to this attribute begins with a colon (':'), a new process, private to the application, is created when it's needed and the service runs in that process. If the process name begins with a lowercase character, the service will run in a global process of that name, provided that it has permission to do so. This allows components in different applications to share a process, reducing resource usage.
this is what I have gathered, if anyone is an expert, please do correct me if I'm wrong :)
This may help you. I may be mistaken but it seems to me that this is related with returning START_STICKY in your onStartCommand() method. You can avoid the service from being called again by returning START_NOT_STICKY instead.
The Main problem is in unable to start the service when app closed, android OS(In Some OS) will kill the service for Resource Optimization, If you are not able to restart the service then call a alarm manger to start the receiver like this,Here is the entire code, This code will keep alive ur service.
Manifest is,
<service
android:name=".BackgroundService"
android:description="#string/app_name"
android:enabled="true"
android:label="Notification" />
<receiver android:name="AlarmReceiver">
<intent-filter>
<action android:name="REFRESH_THIS" />
</intent-filter>
</receiver>
IN Main Activty start alarm manger in this way,
String alarm = Context.ALARM_SERVICE;
AlarmManager am = (AlarmManager) getSystemService(alarm);
Intent intent = new Intent("REFRESH_THIS");
PendingIntent pi = PendingIntent.getBroadcast(this, 123456789, intent, 0);
int type = AlarmManager.RTC_WAKEUP;
long interval = 1000 * 50;
am.setInexactRepeating(type, System.currentTimeMillis(), interval, pi);
this will call reciver and reciver is,
public class AlarmReceiver extends BroadcastReceiver {
Context context;
#Override
public void onReceive(Context context, Intent intent) {
this.context = context;
System.out.println("Alarma Reciver Called");
if (isMyServiceRunning(this.context, BackgroundService.class)) {
System.out.println("alredy running no need to start again");
} else {
Intent background = new Intent(context, BackgroundService.class);
context.startService(background);
}
}
public static boolean isMyServiceRunning(Context context, Class<?> serviceClass) {
ActivityManager activityManager = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
List<ActivityManager.RunningServiceInfo> services = activityManager.getRunningServices(Integer.MAX_VALUE);
if (services != null) {
for (int i = 0; i < services.size(); i++) {
if ((serviceClass.getName()).equals(services.get(i).service.getClassName()) && services.get(i).pid != 0) {
return true;
}
}
}
return false;
}
}
And this Alaram reciver calls once when android app is opened and when app is closed.SO the service is like this,
public class BackgroundService extends Service {
private String LOG_TAG = null;
#Override
public void onCreate() {
super.onCreate();
LOG_TAG = "app_name";
Log.i(LOG_TAG, "service created");
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
Log.i(LOG_TAG, "In onStartCommand");
//ur actual code
return START_STICKY;
}
#Override
public IBinder onBind(Intent intent) {
// Wont be called as service is not bound
Log.i(LOG_TAG, "In onBind");
return null;
}
#TargetApi(Build.VERSION_CODES.ICE_CREAM_SANDWICH)
#Override
public void onTaskRemoved(Intent rootIntent) {
super.onTaskRemoved(rootIntent);
Log.i(LOG_TAG, "In onTaskRemoved");
}
#Override
public void onDestroy() {
super.onDestroy();
Log.i(LOG_TAG, "In onDestroyed");
}
}
From Android O, you cant use the services for the long running background operations due to this, https://developer.android.com/about/versions/oreo/background . Jobservice will be the better option with Jobscheduler implementation.
try this, it will keep the service running in the background.
BackServices.class
public class BackServices extends Service{
#Override
public IBinder onBind(Intent arg0) {
// TODO Auto-generated method stub
return null;
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
// Let it continue running until it is stopped.
Toast.makeText(this, "Service Started", Toast.LENGTH_LONG).show();
return START_STICKY;
}
#Override
public void onDestroy() {
super.onDestroy();
Toast.makeText(this, "Service Destroyed", Toast.LENGTH_LONG).show();
}
}
in your MainActivity onCreate drop this line of code
startService(new Intent(getBaseContext(), BackServices.class));
Now the service will stay running in background.
Using the same process for the service and the activity and START_STICKY or START_REDELIVER_INTENT in the service is the only way to be able to restart the service when the application restarts, which happens when the user closes the application for example, but also when the system decides to close it for optimisations reasons. You CAN NOT have a service that will run permanently without any interruption. This is by design, smartphones are not made to run continuous processes for long period of time. This is due to the fact that battery life is the highest priority. You need to design your service so it handles being stopped at any point.
You must add this code in your Service class so that it handles the case when your process is being killed
#Override
public void onTaskRemoved(Intent rootIntent) {
Intent restartServiceIntent = new Intent(getApplicationContext(), this.getClass());
restartServiceIntent.setPackage(getPackageName());
PendingIntent restartServicePendingIntent = PendingIntent.getService(getApplicationContext(), 1, restartServiceIntent, PendingIntent.FLAG_ONE_SHOT);
AlarmManager alarmService = (AlarmManager) getApplicationContext().getSystemService(Context.ALARM_SERVICE);
alarmService.set(
AlarmManager.ELAPSED_REALTIME,
SystemClock.elapsedRealtime() + 1000,
restartServicePendingIntent);
super.onTaskRemoved(rootIntent);
}
Why not use an IntentService?
IntentService opens a new Thread apart from the main Thread and works there, that way closing the app wont effect it
Be advised that IntentService runs the onHandleIntent() and when its done the service closes, see if it fits your needs.
http://developer.android.com/reference/android/app/IntentService.html
Best solution is to use the sync Adapter in android to start the service. Create a Sync Adapter and call start service their.. inside onPerformSync method. to create sync Account please refer this link https://developer.android.com/training/sync-adapters/index.html
Why SyncAdapter? Ans: Because earlier you used to start the service using your App context. so whenever your app process get killed (When u remove it from task manager or OS kill it because of lack of resources ) at that time your service will also be removed. SyncAdapter will not work in application thread.. so if u call inside it.. service will no longer be removed.. unless u write code to remove it.
<service android:name=".Service2"
android:process="#string/app_name"
android:exported="true"
android:isolatedProcess="true"
/>
Declare this in your manifest. Give a custom name to your process and make that process isolated and exported .
Running an intent service will be easier. Service in creating a thread in the application but it's still in the application.
Just override onDestroy method in your first visible activity like after splash you have home page and while redirecting from splash to home page you have already finish splash. so put on destroy in home page. and stop service in that method.
Please take a look at my simple three-methods Service class that streams audio and play it directly.
public class StreamService extends Service {
private static final String TAG = "MyService";
String url;
MediaPlayer mp;
#Override
public void onCreate() {
Toast.makeText(this, "My Service Created", Toast.LENGTH_LONG).show();
Log.d(TAG, "onCreate");
mp = new MediaPlayer();
mp.setAudioStreamType(AudioManager.STREAM_MUSIC);
}
#Override
public void onDestroy() {
Toast.makeText(this, "My Service Stopped", Toast.LENGTH_LONG).show();
Log.d(TAG, "onDestroy");
mp.stop();
}
#Override
public int onStartCommand(Intent intent, int flags, int startid) {
Toast.makeText(this, "My Service Started", Toast.LENGTH_LONG).show();
Log.d(TAG, "onStart");
url = intent.getExtras().getString("url");
try {
mp.setDataSource(url);
mp.prepare();
mp.start();
} catch(Exception e){}
return START_STICKY;
}
}
In my activity, I have two buttons to play/stop the media file:
The playButton execute this:
Intent i = new Intent(this, StreamService.class);
i.putExtra("my_mp3_url_string");
startService(i);
The stopButton execute this:
stopService(new Intent(this, StreamService.class));
Now, I have some questions:
how I can implement the pauseButton? I want to pause the media running in the Service
Does my way of playing/stopping the media/Service correct ? Is there any better way?
How I can (periodically) update my Activity's UI from my Service? do I need to add something?
I would recommend not using the lifetime of the Service as a way to start and stop playback. Using that approach will mean that every time you want to start a new stream, the code will be slowed down even more by having to bring up a new Service. You can save some time by just having the same Service play everything. Though that doesn't mean it should remain running all the time.
To accomplish that (and to be able to pause), you'll need to bind to the Service after it is started. With the bound Service, you'll be able to make calls to it - such as pause, play, stop, etc.
Here are some links that should help you with what you're looking for:
Using a Service with MediaPlayer
Binding to a Service
I currently have a Service that runs fine when I start it but when I try to stop it using the stopService method its onDestroy method doesn't get called.
Here is the code I use to try to stop the Service
stop_Scan_Button = (Button)findViewById(R.id.stopScanButton);
stop_Scan_Button.setOnClickListener(new View.OnClickListener(){
public void onClick(View v){
Log.d("DEBUGSERVICE", "Stop Button pressed");
Intent service = new Intent(CiceroEngine. CICERO_SERVICE);
releaseBind();
Log.d("Stop_Scan_Button", "Service: " + service.toString());
stopService(service);
Log.d("Stop_Scan_Button", "Service should stop! ");
}
});
Am I right in thinking that when stopService is used it calls the onDestroy method of the Service? When I press my stop scan button the onDestroy() method in my Service is not called.
Is there anything else I am missing that I should put in to stop the service?
EDIT: to add onServiceConnected() gets called when stopService is run instead of onServiceDisconnected(), why would that be happening?
EDIT:To add more info regards Binding
I call bindService in the onCreate() method and I then have the releaseBind() method unbind the Service.
Here is the code for that method:
public void releaseBind(){
unbindService(this);
}
So I presume that the unbinding is not my problem?
I am going to guess that your having a method call for releaseBind() means that you previously called bindService() on this service and that releaseBind() is calling unbindService(). If my guess is incorrect, please ignore this answer.
A service will shut down after all bindService() calls have had their corresponding unbindService() calls. If there are no bound clients, then the service will also need stopService() if and only if somebody called startService() on the service.
So, there are a few possibilities here:
You still have bound clients (e.g., other activities), in which case you cannot stop the service until they unbind
Since both unbindService() and stopService() are asynchronous, something might be going haywire with the timing, in which case you may get better luck if you call stopService() from your ServiceConnection's onServiceDisconnected() method
Also, bear in mind that the exact timing of the service being destroyed is up to Android and may not be immediate. So, for example, if you are relying upon onDestroy() to cause your service to stop some work that is being done, consider using another trigger for that (e.g., activity calling a stopDoingStuff() method through the service binder interface).
Are all your bindings closed?
A service can be used in two
ways. The two modes are not
entirely
separate. You can bind to a service
that was started with startService().
For example, a background music
service could be started by calling
startService() with an Intent object
that identifies the music to play.
Only later, possibly when the user
wants to exercise some control over
the player or get information about
the current song, would an activity
establish a connection to the service
by calling bindService(). In cases
like this, stopService() will not
actually stop the service until the
last binding is closed
.
hai guys sorry for the late answer but as far as i know i have successfull stop the service in this code: you may check a link here.
public void onClick(View src) {
switch (src.getId()) {
case R.id.buttonStart:
Log.d(TAG, "onClick: starting srvice");
startService(new Intent(this, MyService.class));
break;
case R.id.buttonStop:
Log.d(TAG, "onClick: stopping srvice");
stopService(new Intent(this, MyService.class));
break;
}
}
and in services class:
public class MyService extends Service {
private static final String TAG = "MyService";
#Override
public IBinder onBind(Intent intent) {
return null;
}
#Override
public void onCreate() {
Toast.makeText(this, "My Service Created", Toast.LENGTH_LONG).show();
Log.d(TAG, "onCreate");
}
#Override
public void onDestroy() {
Toast.makeText(this, "My Service Stopped", Toast.LENGTH_LONG).show();
Log.d(TAG, "onDestroy");
}
#Override
public void onStart(Intent intent, int startid) {
Toast.makeText(this, "My Service Started", Toast.LENGTH_LONG).show();
Log.d(TAG, "onStart");
}
}