androidking
androidking

Reputation: 207

make service unkilled even when app clossed

I m working pedometer app and i have one service class which extends service class .

   public class StepService extends Service {
    private static final String TAG =  "name.bagi.levente.pedometer.StepService";
private SharedPreferences mSettings;
private PedometerSettings mPedometerSettings;
private SharedPreferences mState;
private SharedPreferences.Editor mStateEditor;
private Utils mUtils;
private SensorManager mSensorManager;
private Sensor mSensor;
private StepDetector mStepDetector;
// private StepBuzzer mStepBuzzer; // used for debugging
private StepDisplayer mStepDisplayer;
private PaceNotifier mPaceNotifier;
private DistanceNotifier mDistanceNotifier;
private SpeedNotifier mSpeedNotifier;
private CaloriesNotifier mCaloriesNotifier;
private SpeakingTimer mSpeakingTimer;

private PowerManager.WakeLock wakeLock;
private NotificationManager mNM;

private int mSteps;
private int mPace;
private float mDistance;
private float mSpeed;
private float mCalories;

/**
 * Class for clients to access.  Because we know this service always
 * runs in the same process as its clients, we don't need to deal with
 * IPC.
 */
public class StepBinder extends Binder {
    StepService getService() {
        return StepService.this;
    }
}

@Override
public void onCreate() {
  //  Log.i(TAG, "[SERVICE] onCreate");
    super.onCreate();

    mNM = (NotificationManager)getSystemService(NOTIFICATION_SERVICE);
    showNotification();

    // Load settings
    mSettings = PreferenceManager.getDefaultSharedPreferences(this);
    mPedometerSettings = new PedometerSettings(mSettings);
    mState = getSharedPreferences("state", 0);

    mUtils = Utils.getInstance();
    mUtils.setService(this);
    mUtils.initTTS();

    acquireWakeLock();

    // Start detecting
    mStepDetector = new StepDetector();
    mSensorManager = (SensorManager) getSystemService(SENSOR_SERVICE);
    registerDetector();

    // Register our receiver for the ACTION_SCREEN_OFF action. This will make our receiver
    // code be called whenever the phone enters standby mode.
    IntentFilter filter = new IntentFilter(Intent.ACTION_SCREEN_OFF);
    registerReceiver(mReceiver, filter);

    mStepDisplayer = new StepDisplayer(mPedometerSettings, mUtils);
    mStepDisplayer.setSteps(mSteps = mState.getInt("steps", 0));
    mStepDisplayer.addListener(mStepListener);
    mStepDetector.addStepListener(mStepDisplayer);

    mPaceNotifier     = new PaceNotifier(mPedometerSettings, mUtils);
    mPaceNotifier.setPace(mPace = mState.getInt("pace", 0));
    mPaceNotifier.addListener(mPaceListener);
    mStepDetector.addStepListener(mPaceNotifier);

    mDistanceNotifier = new DistanceNotifier(mDistanceListener, mPedometerSettings, mUtils);
    mDistanceNotifier.setDistance(mDistance = mState.getFloat("distance", 0));
    mStepDetector.addStepListener(mDistanceNotifier);

    mSpeedNotifier    = new SpeedNotifier(mSpeedListener,    mPedometerSettings, mUtils);
    mSpeedNotifier.setSpeed(mSpeed = mState.getFloat("speed", 0));
    mPaceNotifier.addListener(mSpeedNotifier);

    mCaloriesNotifier = new CaloriesNotifier(mCaloriesListener, mPedometerSettings, mUtils);
    mCaloriesNotifier.setCalories(mCalories = mState.getFloat("calories", 0));
    mStepDetector.addStepListener(mCaloriesNotifier);

    mSpeakingTimer = new SpeakingTimer(mPedometerSettings, mUtils);
    mSpeakingTimer.addListener(mStepDisplayer);
    mSpeakingTimer.addListener(mPaceNotifier);
    mSpeakingTimer.addListener(mDistanceNotifier);
    mSpeakingTimer.addListener(mSpeedNotifier);
    mSpeakingTimer.addListener(mCaloriesNotifier);
    mStepDetector.addStepListener(mSpeakingTimer);

    // Used when debugging:
    // mStepBuzzer = new StepBuzzer(this);
    // mStepDetector.addStepListener(mStepBuzzer);

    // Start voice
    reloadSettings();

    // Tell the user we started.
    Toast.makeText(this, getText(R.string.started), Toast.LENGTH_SHORT).show();
}

@Override
public void onStart(Intent intent, int startId) {
   // Log.i(TAG, "[SERVICE] onStart");
    super.onStart(intent, startId);
}

@Override
public void onDestroy() {
  //  Log.i(TAG, "[SERVICE] onDestroy");
    mUtils.shutdownTTS();

    // Unregister our receiver.
    unregisterReceiver(mReceiver);
    unregisterDetector();

    mStateEditor = mState.edit();
    mStateEditor.putInt("steps", mSteps);
    mStateEditor.putInt("pace", mPace);
    mStateEditor.putFloat("distance", mDistance);
    mStateEditor.putFloat("speed", mSpeed);
    mStateEditor.putFloat("calories", mCalories);
    mStateEditor.commit();

    mNM.cancel(R.string.app_name);

    wakeLock.release();

    super.onDestroy();

    // Stop detecting
    mSensorManager.unregisterListener(mStepDetector);

    // Tell the user we stopped.
    Toast.makeText(this, getText(R.string.stopped), Toast.LENGTH_SHORT).show();
}

private void registerDetector() {
    mSensor = mSensorManager.getDefaultSensor(
        Sensor.TYPE_ACCELEROMETER /*| 
        Sensor.TYPE_MAGNETIC_FIELD | 
        Sensor.TYPE_ORIENTATION*/);
    mSensorManager.registerListener(mStepDetector,
        mSensor,
        SensorManager.SENSOR_DELAY_FASTEST);
}

private void unregisterDetector() {
    mSensorManager.unregisterListener(mStepDetector);
}

@Override
public IBinder onBind(Intent intent) {
 //   Log.i(TAG, "[SERVICE] onBind");
    return mBinder;
}

/**
 * Receives messages from activity.
 */
private final IBinder mBinder = new StepBinder();

public interface ICallback {
    public void stepsChanged(int value);
    public void paceChanged(int value);
    public void distanceChanged(float value);
    public void speedChanged(float value);
    public void caloriesChanged(float value);
}

private ICallback mCallback;

public void registerCallback(ICallback cb) {
    mCallback = cb;
    //mStepDisplayer.passValue();
    //mPaceListener.passValue();
}

private int mDesiredPace;
private float mDesiredSpeed;

/**
 * Called by activity to pass the desired pace value, 
 * whenever it is modified by the user.
 * @param desiredPace
 */
public void setDesiredPace(int desiredPace) {
    mDesiredPace = desiredPace;
    if (mPaceNotifier != null) {
        mPaceNotifier.setDesiredPace(mDesiredPace);
    }
}
/**
 * Called by activity to pass the desired speed value, 
 * whenever it is modified by the user.
 * @param desiredSpeed
 */
public void setDesiredSpeed(float desiredSpeed) {
    mDesiredSpeed = desiredSpeed;
    if (mSpeedNotifier != null) {
        mSpeedNotifier.setDesiredSpeed(mDesiredSpeed);
    }
}

public void reloadSettings() {
    mSettings = PreferenceManager.getDefaultSharedPreferences(this);

    if (mStepDetector != null) { 
        mStepDetector.setSensitivity(
                Float.valueOf(mSettings.getString("sensitivity", "10"))
        );
    }

    if (mStepDisplayer    != null) mStepDisplayer.reloadSettings();
    if (mPaceNotifier     != null) mPaceNotifier.reloadSettings();
    if (mDistanceNotifier != null) mDistanceNotifier.reloadSettings();
    if (mSpeedNotifier    != null) mSpeedNotifier.reloadSettings();
    if (mCaloriesNotifier != null) mCaloriesNotifier.reloadSettings();
    if (mSpeakingTimer    != null) mSpeakingTimer.reloadSettings();
}

public void resetValues() {
    mStepDisplayer.setSteps(0);
    mPaceNotifier.setPace(0);
    mDistanceNotifier.setDistance(0);
    mSpeedNotifier.setSpeed(0);
    mCaloriesNotifier.setCalories(0);
}

/**
 * Forwards pace values from PaceNotifier to the activity. 
 */
private StepDisplayer.Listener mStepListener = new StepDisplayer.Listener() {
    public void stepsChanged(int value) {
        mSteps = value;
        passValue();
    }
    public void passValue() {
        if (mCallback != null) {
            mCallback.stepsChanged(mSteps);
        }
    }
};
/**
 * Forwards pace values from PaceNotifier to the activity. 
 */
private PaceNotifier.Listener mPaceListener = new PaceNotifier.Listener() {
    public void paceChanged(int value) {
        mPace = value;
        passValue();
    }
    public void passValue() {
        if (mCallback != null) {
            mCallback.paceChanged(mPace);
        }
    }
};
/**
 * Forwards distance values from DistanceNotifier to the activity. 
 */
private DistanceNotifier.Listener mDistanceListener = new DistanceNotifier.Listener() {
    public void valueChanged(float value) {
        mDistance = value;
        passValue();
    }
    public void passValue() {
        if (mCallback != null) {
            mCallback.distanceChanged(mDistance);
        }
    }
};
/**
 * Forwards speed values from SpeedNotifier to the activity. 
 */
private SpeedNotifier.Listener mSpeedListener = new SpeedNotifier.Listener() {
    public void valueChanged(float value) {
        mSpeed = value;
        passValue();
    }
    public void passValue() {
        if (mCallback != null) {
            mCallback.speedChanged(mSpeed);
        }
    }
};
/**
 * Forwards calories values from CaloriesNotifier to the activity. 
 */
private CaloriesNotifier.Listener mCaloriesListener = new CaloriesNotifier.Listener() {
    public void valueChanged(float value) {
        mCalories = value;
        passValue();
    }
    public void passValue() {
        if (mCallback != null) {
            mCallback.caloriesChanged(mCalories);
        }
    }
};

/**
 * Show a notification while this service is running.
 */
private void showNotification() {
    CharSequence text = getText(R.string.app_name);
    Notification notification = new Notification(R.drawable.ic_notification, null,
            System.currentTimeMillis());
    notification.flags = Notification.FLAG_NO_CLEAR | Notification.FLAG_ONGOING_EVENT;
    Intent pedometerIntent = new Intent();
    pedometerIntent.setComponent(new ComponentName(this, Pedometer.class));
    pedometerIntent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
    PendingIntent contentIntent = PendingIntent.getActivity(this, 0,
            pedometerIntent, 0);
   /* notification.setLatestEventInfo(this, text,
            getText(R.string.notification_subtitle), contentIntent);

    mNM.notify(R.string.app_name, notification);*/
}


// BroadcastReceiver for handling ACTION_SCREEN_OFF.
private BroadcastReceiver mReceiver = new BroadcastReceiver() {
    @Override
    public void onReceive(Context context, Intent intent) {
        // Check action just to be on the safe side.
        if (intent.getAction().equals(Intent.ACTION_SCREEN_OFF)) {
            // Unregisters the listener and registers it again.
            StepService.this.unregisterDetector();
            StepService.this.registerDetector();
            if (mPedometerSettings.wakeAggressively()) {
                wakeLock.release();
                acquireWakeLock();
            }
        }
    }
};

private void acquireWakeLock() {
    PowerManager pm = (PowerManager) getSystemService(Context.POWER_SERVICE);
    int wakeFlags;
    if (mPedometerSettings.wakeAggressively()) {
        wakeFlags = PowerManager.SCREEN_DIM_WAKE_LOCK | PowerManager.ACQUIRE_CAUSES_WAKEUP;
    }
    else if (mPedometerSettings.keepScreenOn()) {
        wakeFlags = PowerManager.SCREEN_DIM_WAKE_LOCK;
    }
    else {
        wakeFlags = PowerManager.PARTIAL_WAKE_LOCK;
    }
    wakeLock = pm.newWakeLock(wakeFlags, TAG);
    wakeLock.acquire();
}

}

ho to make this service live even when app killed also I have to count footstep even when app killed. I m calling service like this.

   startService(new Intent(Pedometer.this,
                StepService.class));

Upvotes: 0

Views: 333

Answers (1)

Niks
Niks

Reputation: 510

    @Override
    public void onTaskRemoved(Intent rootIntent)
    {
        super.onTaskRemoved(rootIntent);
        startStepService();
    }

    private void startStepService()
    {
        startService(new Intent(this,StepService.class));
    }

Upvotes: 2

Related Questions