package com.falling.inairproandmark;
import android.app.Service;
import android.content.Intent;
import android.media.MediaPlayer;
import android.os.IBinder;
public class BackgroundSoundService extends Service {
private static final String TAG = null;
MediaPlayer player;
public IBinder onBind(Intent arg0) {
return null;
}
#Override
public void onCreate() {
super.onCreate();
player = MediaPlayer.create(this, R.raw.bgmusic);
player.setVolume(100,100);
}
public int onStartCommand(Intent intent, int flags, int startId) {
player.start();
return 1;
}
public void onStart(Intent intent, int startId) {
// TODO
}
public IBinder onUnBind(Intent arg0) {
// TODO Auto-generated method stub
return null;
}
public void onStop() {
}
public void onPause() {
}
#Override
public void onDestroy() {
player.stop();
player.release();
}
#Override
public void onLowMemory() {
}
}
I don't understand coding much...
But what I'm trying to do is play the music thru-out the activities.
Let's say I have 10 activities... I want the music to play while i go through them and when I get a call or exit the application by pressing Home key... Music stops or at least pauses... how do i do that?
Thanks
Wahid
You need to launch separate service (different intent filter in the Manifest for the same serivce) in onStartCommand() you'll check the action of the intent i.e if the action has the same value as the one you specified for intent action in the manifest file and if the action matches the intent filter action name then just stop the service.
Example from one of my projects:
In the manifest file:
<service android:name=".MyPlayerService" android:permission="android.permission.MODIFY_AUDIO_SETTINGS">
<intent-filter >
.... some other filters
<action android:name="com.my.player.EXIT"/>
....
</intent-filter>
</service>
In the onStartCommand():
Here we can see the need of specifying action name, which is used to distinguish numerous actions within the same service.
#Override
public int onStartCommand(Intent intent, int flags, int startId)
{
Log.i("ON START COMMAND", "Huston, we have a lift off!");
if(intent.getAction().equals("com.my.player.EXIT")
{ // means that you have envoked action that will has to stop the service
MyPlayerService.this.stopSelf(); // See the note below
}else if(//some other actions that has to be done on the service)
}
Note:
Note that here you can simply stop the MediaPlayer from playing or pause it using .stop() or .pause(),or just terminate the service as I provided above.
Now back to the activity. Catching Home button is not good idea. But this you can do in the onDestroy() method, where the activity is not in the stack i.e just before it is destroyed. Here you just launch intent that will signal the service to stop working.
Example:
Intent exit = new Intent("com.my.player.EXIT"); //intent filter has to be specified with the action name for the intent
this.startService(exit);
Read more on Android Dev about stopSelf()
If you are trying this approach starting the MediaPlayer good practice will be to make the playing has its own action name in the intent filter, and do the same checking in the onStartCommand()
Related
So I've been trying to build a music player app and despite visiting all pages on stackoverflow I'm still stuck on one issue. The code works fine for the most part, but when I press the back button to close the app the action buttons stop working, even though they work fine when I press the home button. I think the broadcast receiver is getting unregistered when the app is closed even though I don't want it to. Here is the code:
public BroadcastReceiver broadcastReceiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
String action = intent.getExtras().getString("actionname");
Helper.makeToast(context, action);
switch (action) {
case CreateNotification.ACTION_PREVIUOS:
//play previous
case CreateNotification.ACTION_PLAY:
if (isPlaying) {
//pause
} else {
// play
}
break;
case CreateNotification.ACTION_NEXT:
//play next
}
}
};
This is the onresume method on main activity
#Override
protected void onResume() {
super.onResume();
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
registerReceiver(broadcastReceiver, new IntentFilter("TRACKS_TRACKS"));
startService(new Intent(getBaseContext(), OnClearFromRecentService.class));
}
}
This is the Service
public class OnClearFromRecentService extends Service {
#Nullable
#Override
public IBinder onBind(Intent intent) {
return null;
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
return START_STICKY_COMPATIBILITY;
}
#Override
public void onDestroy() {
super.onDestroy();
}
#Override
public void onTaskRemoved(Intent rootIntent) {
stopSelf();
}
}
In the manifest:
<receiver .services.OnClearFromRecentService" />
So my questions are: Is the broadcastreceiver automatically unregistered when I close the app? If so, how do I prevent this? How do I keep the broadcast receiver working when I close the app?
This type of receivers unregister automatically when you close your app. This is right. However you have to unregister from your receiver in onStop(). Because if you don't do this you are going to get LeakIntentMemory error message in your LogCat but your app don't crashes. You can check it from your logcat. I think that if you want to receive something when your app closed, you have to declare your receiver in AndroidManifest with an action name.
<receiver android:name=".YourReceiver" >
<intent-filter>
<action android:name="first.custom.action"> </action>
</intent-filter>
</receiver>
i am trying to write a sample Android service code to test whether , the service stop itself or not after returning START_NOT_STICKY to onStartCommand. But i whenever , i closed my app , the service stop itself , whereas according to the rule START_NOT_STICKY will not allow to stop the service automatically.
MyCode :
ServiceDemo.java
package com.example.servicedemo;
import android.os.Bundle;
import android.app.Activity;
import android.content.Intent;
public class MainActivity extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Intent in = new Intent(this,TrackService.class);
startService(in);
}}
TrackService.java
package com.example.servicedemo;
import android.app.Service;
import android.content.Intent;
import android.os.IBinder;
public class TrackService 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)
{
return START_NOT_STICKY;
}
#Override
public boolean onUnbind(Intent intent)
{
return super.onUnbind(intent);
}}
this my above code , whenever i close my app , the app service stops itself , please help me out , how can i restrict my service to stop or restart itself.
close my app means , pressing home and from slide menu swipe up app to close completely
That means that you are terminating your background process. At that point, your service is gone, and since you are returning START_NOT_STICKY, it will not automatically restart.
In other words, what is happening is perfectly normal.
Close with swipe won't kill this code.
It's a service that runs in the foreground so android treats it as if it is on the screen. It runs in a seperate process so the main process can be killed. It shows a custom notification to the user when its running so its completely ligit and it is written.
Note Eclipse ADK Users only put the service in a different process when your done debugging it.
manifest
<service
android:name="com.gosylvester.bestrides.ServiceLocationRecorder"
android:process=":myService" >
</service>
</application>
MyService class
private boolean isRecording = false;
public int onStartCommand(Intent intent, int flags, int startId) {
boolean isTrackerMarker = SettingMarker.TRACKER_MARKER_DEFAULT;
if (intent != null) {
isRecording = intent.getBooleanExtra("isrecording", isRecording);
startRecording(isRecording);
}
//if isRecording keep the service running else let os know service can be killed
if (isRecording) {
startForeground(R.id.action_record, getMyCustomNotification());
return Service.START_STICKY;
} else {
stopForeground(true);
return Service.START_NOT_STICKY;
}
}
The service does get re-created, just not re-started.
If you override the onCreate and do a Log.d or a Toast, you will see that onCreate gets called after your activity and app is destroyed and even the service onDestroy is called.
So the trick to keep it running after it is re-created is to put your code on the onCreate method and use the onStartCommand just to return START_STICKY.
Note: onCreate is called before onStartCommand, so your code will run both when it is started by startService and from the system self re-creation.
I am implementing in my Android app a splash screen which:
dowloads a sqlite database from a server
loads urls to get JSONs
creates a sqlite database in the device and execute several queries
I am using AsyncTask to do everything, my problem will occur if the user close the app in the middle of the process or turn off the device because the app:
could be creating a database or executing crucial queries in the device
could be downloading the sqlite db from a server
could be running several important process
etc
Definitely, the entire process (3-5 seconds) is important.
So... How could I avoid this? should I use handlers, loaders, on-(pause, stop, destroy) methods in order to get my objective? Can you give me an example?
As mentioned in the comment above, you should use a service as their lifecycle is separate to that of the activity.
Create the service like so:
public class MyService extends Service {
#Override
public IBinder onBind(Intent intent) {
// TODO Auto-generated method stub
return null;
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
// Do everything you need to here, then call stop:
Log.d("DEBUG", "Started...");
stopSelf();
return super.onStartCommand(intent, flags, startId);
}
#Override
public void onDestroy() {
Intent intent = new Intent("com.example.androidexample.SERVICE_STOPPING");
sendBroadcast(intent);
super.onDestroy();
}
}
Then in the activity:
public class MainActivity extends Activity {
private ServiceCompleteReceiver receiver;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
IntentFilter filter;
receiver = new ServiceCompleteReceiver();
filter = new IntentFilter("com.example.androidexample.SERVICE_STOPPING");
startService(new Intent(this, MyService.class));
registerReceiver(receiver, filter);
}
public class ServiceCompleteReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
// Do whatever needs to be done here
unregisterReceiver(receiver);
}
}
}
EDIT :
Don't forget to add it to your manifest as well
<service
android:name="com.example.androidexample.MyService"
android:icon="#drawable/ic_launcher"
android:label="#string/app_name" >
</service>
My Service is running.
WAY 1:I did set stop Service when user pressed back button.
WAY 2:When user exit to home screen(with home key) and press home key then remove the app from list,device get this message:Unfortunately, yourapp has stopped
I know that user should stop service to close non-error app.
Is a way to stop service in WAY2?
MyService:
#Override
public IBinder onBind(Intent intent) {
return null;
}
#Override
public void onStart(Intent intent, int startid) {
Bundle b=intent.getExtras();
name = b.getStringArray("name");
builder = new StringBuilder();
for(String i : name)
{
builder.append(i);
}
player = MediaPlayer.create(this, Uri.parse(Environment.getExternalStorageDirectory().getPath()+ "/Titraj/"+builder+".mp3"));
player.start();
}
#Override
public void onDestroy() {
player.stop();
}
Edit:
The with null in the stacktrace says the Intent is null.
From the documentation:
The Intent supplied to startService(Intent), as given. This may be null if the service is being restarted after its process has gone away, and it had previously returned anything except START_STICKY_COMPATIBILITY.
This is my situation: I have a service running and every time I deploy my app the service disappears from settings>>application>>runningService (therefore, the service is not running) how can I set it so that the service does not disappears?
I have tried to startForeground but it did not worked.
AndroidManifest:
<service
android:name=".service.PhoneCallInOutService"
android:enabled="true"
android:exported="false" >
</service>
This is how I start the service in my Activity:
chkCallsRecord.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
boolean isChecked = chkCallsRecord.isChecked();
updateBackgroundTasks(isChecked);
}
});
The method actually starting the service:
private void updateBackgroundTasks(boolean start) {
Intent serviceIntent = new Intent(getApplicationContext(),PhoneCallInOutService.class);
if (start) {
getApplicationContext().startService(serviceIntent);
} else {
getApplicationContext().stopService(serviceIntent);
}
}
And here is the service:
public class PhoneCallInOutService extends Service {
private TelephonyManager telephonyMgr;
private PhoneCallStateListener pcsListener;
private OutgoingCallReceiver ocReceiver;
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
super.onStartCommand(intent, flags, startId);
// Listener
pcsListener = new PhoneCallStateListener(getApplicationContext(),appDto);
telephonyMgr = (TelephonyManager)getApplicationContext().getSystemService(Context.TELEPHONY_SERVICE);
telephonyMgr.listen(pcsListener, PhoneStateListener.LISTEN_CALL_STATE);
// Receiver
ocReceiver = new OutgoingCallReceiver(getApplication());
IntentFilter intentF = new IntentFilter(Intent.ACTION_NEW_OUTGOING_CALL);
getApplicationContext().registerReceiver(ocReceiver, intentF);
return START_STICKY;
}
#Override
public void onDestroy() {
super.onDestroy();
// Listener
telephonyMgr.listen(pcsListener, PhoneStateListener.LISTEN_NONE);
// Receiver
getApplicationContext().unregisterReceiver(ocReceiver);
}
#Override
public IBinder onBind(Intent arg0) {
return null;
}
}
Thank you very much in advance.
If by deploy you mean you try to launch new build of your app, then this is actually normal and expected behaviour. By deploying new build you replace old code (incl. service code) therefore it have to be killed first to avoid any crashes and other oddities. So your old iteration of app is completely killed. Then new app is installed and most often auto-launched. Your data create by the app usually stay, but it's also normal.
EDIT
For security reasons you are not allowed to re-launch itself after being updated. User has to to this. As for "he/she may assume the service is still there running, which is not true", use notification of type "On Going" to indicate running service