Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Music service killed even when startForground

is it possible to prevent Service(startForground) from being killed by os? I use it to play audio but it's killed when I use another app which requires more resources(Angry birds go) for a while. In logs I see app process being killed by ActivityManager. I replicated that also with some other audio apps. Only app which is not killed is Play Music app. It was replicated on samsung s3 android 4.3.

like image 206
Martin Vandzura Avatar asked Aug 28 '14 15:08

Martin Vandzura


2 Answers

Is it possible to prevent Service(startForground) from being killed by os?

No. It's Android who decides which process has to be stopped when. The only way is to make it "less attractive for being stopped" by reducing amount of memory it consumes.

Save memory. Put the service into its own very small process. So that android os can kill the main process to reclaim memory and your service can keep running. Maintain a tiny service code by passing in setting and preferences with the intent used to start the service.

Note: tiny service must be a foreground service, meaning it has to show an icon in status bar.

manifest for seperate process

        <service
        android:name="com.gosylvester.bestrides.ServiceLocationRecorder"
         android:process=":bestRidesService" >
    </service>
</application>

pass in settings with the intent used to start the service. Simply restart the service to change the settings.

@Override
public int onStartCommand(Intent intent, int flags, int startId) {
    boolean isTrackerMarker = SettingMarker.TRACKER_MARKER_DEFAULT;
    if (intent != null) {
        // intent is processing = b
        isMiles = intent.getBooleanExtra(
                SettingApplication.APPLICATION_MILE,
                SettingApplication.APPLICATION_MILE_DEFAULT);
        isRecordAccuracy = intent.getBooleanExtra(
                SettingRecord.RECORD_ACCURACY,
                SettingRecord.RECORD_ACCURACY_DEFAULT);
        locationInterval = intent.getLongExtra(SettingRecord.RECORD_MIlLIS,
                SettingRecord.RECORD_PRESET_MEDIUM_MILLIS);
        startMillis = intent.getLongExtra(BUNDLE_START_MILLIS, 0);
        distance = intent.getDoubleExtra(
                ServiceLocationRecorder.BUNDLE_TRACKED_DISTANCE, 0);
        recordDistance = (float) intent.getIntExtra(
                SettingRecord.RECORD_DISTANCE,
                SettingRecord.RECORD_PRESET_MEDIUM_DISTANCE);
        boolean newIsRecording = intent.getBooleanExtra(
                SettingRecord.RECORDING, isRecording);

        isTrackerMarker = intent.getBooleanExtra(
                SettingMarker.TRACKER_MARKER,
                SettingMarker.TRACKER_MARKER_DEFAULT);
        startRecording(newIsRecording);
    }
like image 140
danny117 Avatar answered Sep 26 '22 19:09

danny117


Did you tried to request focus and control gain and lost of it? I think this app management is far from our control, but at least you can do something when this happens.

At some point of your app cycle, try something like this:

audioManager.requestAudioFocus(new OnAudioFocusChangeListener() {

        @Override
        public void onAudioFocusChange(int focusChange) {
            switch (focusChange) {
                case AudioManager.AUDIOFOCUS_GAIN:
                    // you have the focus, you can start or restarting playing
                    break;
                case AudioManager.AUDIOFOCUS_LOSS:
                case AudioManager.AUDIOFOCUS_LOSS_TRANSIENT:
                    // you lost the focus, you should pause or stop playing
                    break;
                case AudioManager.AUDIOFOCUS_LOSS_TRANSIENT_CAN_DUCK:
                    // you lost the focus, but your app can continue playing in "duck" mode
                    break;
                 default:
            }

        }
    }, AudioManager.STREAM_MUSIC, AudioManager.AUDIOFOCUS_GAIN);
like image 45
PFROLIM Avatar answered Sep 22 '22 19:09

PFROLIM