i'm trying to make a very simple service that plays an audio file by putting a button that its onClick() -> starts the service which in turn plays the sound.
but when i destroy the activity the song stops ( i can't tell Service state)[that i put a toast in onDestroy method in Service class , and it didn't come out.]
Any One Can HELP ?!!
AndroidManifest
<service android:name=".ExampleService"
android:enabled="true"
android:exported="true"
></service>
ExampleService.java
public class ExampleService extends Service {
MediaPlayer mpService;
private final static String TAG="ExampleService";
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
mpService.start();
return START_STICKY;
}
#Override
public void onCreate() {
super.onCreate();
mpService=MediaPlayer.create(this,R.raw.lwyashko);
Toast.makeText(this,"*** STARTED *** ",Toast.LENGTH_SHORT).show();
}
#Override
public void onStart(Intent intent, int startId) {
super.onStart(intent, startId);
}
#Override
public void onDestroy() {
Log.d(TAG,"onDestroy was Called ");
Toast.makeText(this,"Service Destroyed",Toast.LENGTH_SHORT).show();
}
#Nullable
#Override
public IBinder onBind(Intent intent) {
return null;
}
}
MainActivity.java
playService.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
i=new Intent(getApplication(),ExampleService.class);
startService(i);
}
});
As of API 26, only foreground services will usually be allowed to run without an Activity still active. You make a service a foreground one by calling startForeground() within the service. You will need to create and provide a notification in the call. Here's the relevant documentation page.
Normally, after the service is started by startService, the service will not be destroyed after the activity is closed. However, if the user manually cleans up the task, the entire APP process will be closed and the Service will stop.
Related
I'm building an android service for audio playback (it's a flutter app using native code for playback), but when launching the service it doesn't seem to run onCreate() and `onStartCommand()'.
I've tested it with putting some print or log statements in those functions, but they never run. I've also made sure to add the service into the AndroidManifest.xml
Here is how I launch the service:
public class MainActivity extends FlutterActivity implements MethodCallHandler {
public void onMethodCall(MethodCall call, Result result) {
switch (call.method) {
[...]
case "startService":
Intent serviceIntent = new Intent(getFlutterView().getContext(), AudioService.class);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
this.startForegroundService(serviceIntent);
} else {
this.startService(serviceIntent);
}
break;
[...]
}
}
FlutterActivity is a class that extends Activity
Here is the service class:
public class AudioService extends Service {
public MediaPlayer audioPlayer;
#Override
public IBinder onBind(Intent intent) {
return null;
}
#Override
public void onCreate() {
super.onCreate();
Log.i("Audio", "onCreate()");
}
#Nullable
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
super.onStartCommand(intent, flags, startId);
Log.i("Audio", "Starting service...");
// create notification
Intent notificationIntent = new Intent(this, MainActivity.class);
PendingIntent pendingIntent = PendingIntent.getActivity(
this,
0,
notificationIntent,
0
);
Notification audioNotification = new NotificationCompat.Builder(this, CHANNEL_ID)
.setContentTitle("Foreground service is running")
.setContentText("This notification does nothing")
.setSmallIcon(R.drawable.app_icon)
.setContentIntent(pendingIntent)
.build();
startForeground(1, audioNotification);
audioPlayer = new MediaPlayer();
Log.i("Audio", "Service started successfuly");
return START_STICKY;
}
#Override
public void onDestroy() {
super.onDestroy();
// destroy the player
stopAudio();
}
[...]
}
And the service declaration in AndroidManifest:
<service
android:name=".AudioService"
android:process="net.tailosive.app.AudioService"
android:enabled="true"
android:exported="true"/>
I don't see what I'm doing wrong here.
A thing worth mentioning is that the installed package name is net.tailosive.app, but the the package name included in java files, directories and manifest is com.example.tailosive. Could this be an issue?
I highly recommend reading this topic : Context.startForegroundService() did not then call Service.startForeground()
From my experience (Working on the same scenario), you will face lots of unexpected bugs on different devices and different SDK versions by starting a Foreground Service using startForegroundService command. Just use the old startService method and you'll be fine.
Also what's the purpose of using START_STICKY while it's a Foreground Service and it's guaranteed to be running as long as the ongoing notification displays?
I want to listen the power key event in the service.
How can in do that ?
Currently I am working with an app, where I need to listen the power button for some events, from a service which is running in a background, even when the app is killed or stopped.
Somehow I can manage to get it.
But when I kill/stop the app, the service is getting stopped.
How can i overcome this ?
Currently the code i am using this :
Service Class:
public class SampleService extends Service
{
SettingContentObserver mSettingsContentObserver;
AudioManager mAudioManager;
private ComponentName mRemoteControlResponder;
private Intent intent;
#Override
public int onStartCommand(Intent intent, int flags, int startId)
{
Log.v("StartServiceAtBoot", "StartAtBootService -- onStartCommand()");
// We want this service to continue running until it is explicitly
// stopped, so return sticky.
return START_STICKY;
}
#Override
public void onStart(Intent intent, int startId) {
boolean screenOn = intent.getBooleanExtra("screen_state", false);
if (!screenOn) {
Toast.makeText(getApplicationContext(), "On", Toast.LENGTH_SHORT).show();
} else {
Toast.makeText(getApplicationContext(), "Off", Toast.LENGTH_SHORT).show();
}
}
public void onCreate()
{
mSettingsContentObserver = new SettingContentObserver(this,new Handler());
getApplicationContext().getContentResolver().registerContentObserver
(android.provider.Settings.System.CONTENT_URI, true, mSettingsContentObserver );
mAudioManager = (AudioManager) getSystemService(Context.AUDIO_SERVICE);
mRemoteControlResponder = new ComponentName(getPackageName(),
StartAtBootServiceReceiver.class.getName());
IntentFilter filter = new IntentFilter(Intent.ACTION_SCREEN_ON);
filter.addAction(Intent.ACTION_SCREEN_OFF);
BroadcastReceiver mReceiver = new StartAtBootServiceReceiver();
registerReceiver(mReceiver, filter);
}
#Override
public IBinder onBind(Intent intent) {
// TODO Auto-generated method stub
return null;
}
public void onDestroy()
{
getApplicationContext().getContentResolver().unregisterContentObserver(mSettingsContentObserver);
}
}
BroadcastReceiver Class:
public class StartAtBootServiceReceiver extends BroadcastReceiver
{
static boolean wasScreenOn;
private boolean screenOff;
public void onReceive(Context context, Intent intent)
{
if(intent.getAction().equals(Intent.ACTION_SCREEN_OFF))
{
wasScreenOn = false;
Toast.makeText(context, "Power Off", Toast.LENGTH_SHORT).show();
}
else if(intent.getAction().equals(Intent.ACTION_SCREEN_ON))
{
wasScreenOn = true;
}
Intent i = new Intent(context, SampleService.class);
i.putExtra("screen_state", screenOff);
i.setAction("com.example.antitheft.SampleService");
context.startService(i);
//
if (intent.getAction().equals(Intent.ACTION_BOOT_COMPLETED)) {
Intent i1 = new Intent();
i1.setAction("com.example.sampleonkeylistener.MainActivity");
context.startService(i1);
}
}
}
given above is the sample code and i have created AndroidManifest.xml files also with user's permission but i cannot get the app continue service if it is killed or stopped.
Thanks in Advance.
#Override
public void onDestroy() {
super.onDestroy();
startService(new Intent(this, SampleService.class));
}
This is one way to ensure that service will never stop even user want to destroy it.
This is one Just ONE of ways to achieve what you are trying to achieve.
Secondly, you can try and run service in "foreground" by using startForeground().
Also, make sure that in you return "START_STICKY" (which you are doing in the sample code that you shared and I trust that you are also doing in App's code too :) ) in Services's onStartCommand().
This will ensure that If this service's process is killed while it is started (after returning from onStartCommand(Intent, int, int)), then leave it in the started state but don't retain this delivered intent. Later the system will try to re-create the service.
And you may find some additional pointers/hints to make sure your service is not stopped at below link.
How can we prevent a Service from being killed by OS?
Just pick and choose the approach that best suits YOUR Need/implementation.
I have a service that I am trying to run constantly as long as the user has it on. The problem is the service uses a ton of memory; I'm guessing because it notifies the users and displays images constantly. So I put the bulk of my code in another activity. The service just calls the activity.
The issue is that I'm trying to use the return Start_Sticky to restart the service when it needs to. It takes about 2 hours before it uses up enough memory to need to restart. When it does restart it doesn't do the onStartCommand am I missing something?
public class AUTOAlarmService extends Service {
#Override
public void onCreate() {
}
#Override
public IBinder onBind(Intent intent) {
return null;
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
Intent DI = new Intent(getBaseContext(), AUTOSERVICES.class);
DI.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
getApplication().startActivity(DI);
return START_STICKY;
}
#Override
public boolean onUnbind(Intent intent) {
return super.onUnbind(intent);
}
}
I think you should reconsider some work done because your service is taking too much resources and that shouldnt be happening any way. There are many applications with a lot of services but non have problem of restarting the device for that matter.
However if you want to restart a service you have to stop and then start the service again.
stopService(new Intent(this, YourService.class));
startService(new Intent(this, YourService.class));
Hope it helps.
I created a service and want to run this service always until my phone restarts or force closed. The service should run in background.
Sample code of created service and start services:
Start the service:
Intent service = new Intent(getApplicationContext(), MyService.class);
getApplicationContext().startService(service);
The service:
public class MyService extends Service {
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
// TODO do something useful
HFLAG = true;
//smsHandler.sendEmptyMessageDelayed(DISPLAY_DATA, 1000);
return Service.START_NOT_STICKY;
}
#Override
public IBinder onBind(Intent intent) {
// TODO for communication return IBinder implementation
return null;
}
}
Manifest declaration:
<service
android:name=".MyService"
android:icon="#drawable/ic_launcher"
android:label="#string/app_name" >
</service>
Is it possible to run this service always as when the application pauses and anything else.
After some time my application goes pause and the services also go pause or stop.
So how can I run this service in background and always.
"Is it possible to run this service always as when the application pause and anything else?"
Yes.
In the service onStartCommand method return START_STICKY.
public int onStartCommand(Intent intent, int flags, int startId) {
return START_STICKY;
}
Start the service in the background using startService(MyService) so that it always stays active regardless of the number of bound clients.
Intent intent = new Intent(this, PowerMeterService.class);
startService(intent);
Create the binder.
public class MyBinder extends Binder {
public MyService getService() {
return MyService.this;
}
}
Define a service connection.
private ServiceConnection m_serviceConnection = new ServiceConnection() {
public void onServiceConnected(ComponentName className, IBinder service) {
m_service = ((MyService.MyBinder)service).getService();
}
public void onServiceDisconnected(ComponentName className) {
m_service = null;
}
};
Bind to the service using bindService.
Intent intent = new Intent(this, MyService.class);
bindService(intent, m_serviceConnection, BIND_AUTO_CREATE);
For your service you may want a notification to launch the appropriate activity once it has been closed.
private void addNotification() {
// create the notification
Notification.Builder m_notificationBuilder = new Notification.Builder(this)
.setContentTitle(getText(R.string.service_name))
.setContentText(getResources().getText(R.string.service_status_monitor))
.setSmallIcon(R.drawable.notification_small_icon);
// create the pending intent and add to the notification
Intent intent = new Intent(this, MyService.class);
PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, intent, 0);
m_notificationBuilder.setContentIntent(pendingIntent);
// send the notification
m_notificationManager.notify(NOTIFICATION_ID, m_notificationBuilder.build());
}
You need to modify the manifest to launch the activity in single top mode.
android:launchMode="singleTop"
Note that if the system needs the resources and your service is not very active it may be killed. If this is unacceptable bring the service to the foreground using startForeground.
startForeground(NOTIFICATION_ID, m_notificationBuilder.build());
In order to start a service in its own process, you must specify the following in the xml declaration.
<service
android:name="WordService"
android:process=":my_process"
android:icon="#drawable/icon"
android:label="#string/service_name"
>
</service>
Here you can find a good tutorial that was really useful to me
http://www.vogella.com/articles/AndroidServices/article.html
Hope this helps
If you already have a service and want it to work all the time, you need to add 2 things:
in the service itself:
public int onStartCommand(Intent intent, int flags, int startId) {
return START_STICKY;
}
In the manifest:
android:launchMode="singleTop"
No need to add bind unless you need it in the service.
A simple solution is to restart the service when the system stops it.
I found this very simple implementation of this method:
How to make android service unstoppable
You can implement startForeground for the service and even if it dies you can restart it by using START_STICKY on startCommand(). Not sure though this is the right implementation.
I found a simple and clear way of keeping the Service running always.
This guy has explained it so clearly and have used a good algorithm. His approach is to send a Broadcast when the service is about to get killed and then use it to restart the service.
You should check it out: http://fabcirablog.weebly.com/blog/creating-a-never-ending-background-service-in-android
You don't require broadcast receiver. If one would take some pain copy one of the api(serviceconnection) from above example by Stephen Donecker and paste it in google you would get this, https://www.concretepage.com/android/android-local-bound-service-example-with-binder-and-serviceconnection
Add this in manifest.
<service
android:name=".YourServiceName"
android:enabled="true"
android:exported="false" />
Add a service class.
public class YourServiceName extends Service {
#Override
public void onCreate() {
super.onCreate();
// Timer task makes your service will repeat after every 20 Sec.
TimerTask doAsynchronousTask = new TimerTask() {
#Override
public void run() {
handler.post(new Runnable() {
public void run() {
// Add your code here.
}
});
}
};
//Starts after 20 sec and will repeat on every 20 sec of time interval.
timer.schedule(doAsynchronousTask, 20000,20000); // 20 sec timer
(enter your own time)
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
// TODO do something useful
return START_STICKY;
}
}
I had overcome this issue, and my sample code is as follows.
Add the below line in your Main Activity, here BackGroundClass is the service class.You can create this class in New -> JavaClass (In this class, add the process (tasks) in which you needs to occur at background). For Convenience, first denote them with notification ringtone as background process.
startService(new Intent(this, BackGroundClass .class));
In the BackGroundClass, just include my codings and you may see the result.
import android.app.Service;
import android.content.Intent;
import android.media.MediaPlayer;
import android.os.IBinder;
import android.provider.Settings;
import android.support.annotation.Nullable;
import android.widget.Toast;
public class BackgroundService extends Service {
private MediaPlayer player;
#Nullable
#Override
public IBinder onBind(Intent intent) {
return null;
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
player = MediaPlayer.create(this,Settings.System.DEFAULT_RINGTONE_URI);
player.setLooping(true);
player.start();
return START_STICKY;
}
#Override
public void onDestroy() {
super.onDestroy();
player.stop();
}
}
And in AndroidManifest.xml, try to add this.
<service android:name=".BackgroundService"/>
Run the program, just open the application, you may find the notification alert at the background. Even, you may exit the application but still you might have hear the ringtone alert unless and until if you switched off the application or Uninstall the application. This denotes that the notification alert is at the background process. Like this you may add some process for background.
Kind Attention: Please, Don't verify with TOAST as it will run only once even though it was at background process.
Hope it will helps...!!
I am creating a game app and I have a few activities for the different screens. I have a service I am using to play music through out the activities. A really simple service, I have the title screen with image buttons to turn it on and off. Now I am getting a unexpected close and this error message from eclipse:
[2011-05-19 19:50:04 - ddms]null
java.lang.NullPointerException
at com.android.ddmlib.Client.sendAndConsume(Client.java:571)
at com.android.ddmlib.HandleHello.sendHELO(HandleHello.java:142)
at com.android.ddmlib.HandleHello.sendHelloCommands(HandleHello.java:65)
at com.android.ddmlib.Client.getJdwpPacket(Client.java:670)
at com.android.ddmlib.MonitorThread.processClientActivity(MonitorThread.java:317)
at com.android.ddmlib.MonitorThread.run(MonitorThread.java:263)
EDIT: Code For Service
public class BGMusic extends Service {
MediaPlayer player;
#Override
public IBinder onBind(Intent arg0) {
// TODO Auto-generated method stub
return null;
}
#Override
public void onCreate() {
super.onCreate();
player = MediaPlayer.create(this, R.raw.still_wana);
}
public void onStart(Intent intent, int startId) {
super.onCreate();
player.start();
}
#Override
public void onDestroy() {
super.onDestroy();
player.stop();
}
}
EDIT: Console Android Msg
Starting activity com.android.hitmanassault.HitmanTitle on device emulator-5554
ActivityManager: DDM dispatch reg wait timeout
ActivityManager: Can't dispatch DDM chunk 52454151: no handler defined
ActivityManager: Starting: Intent { act=android.intent.action.MAIN cat=[android.intent.category.LAUNCHER] cmp=com.android.hitmanassault/.HitmanTitle }
java.lang.NullPointerException
at com.android.ddmlib.Client.sendAndConsume(Client.java:571)
You have a null pointer problem at line 571 of Client.java.
Probably caused by passing a parameter that can't be null as null. Maybe this for example:
R.raw.still_wana
You are calling the wrong super method in onStart():
public void onStart(Intent intent, int startId) {
super.onCreate();
It should be:
public void onStart(Intent intent, int startId) {
super.onStart(intent, startId);