'Service stops running after a while on the real device ( > 40 minutes ) works on emulator

Friends,

I created an android background service that is called every 2 minutes. When its called it starts listening for locationUpdates for GPS and NETWORK for 40 seconds. Extracting useful information( lat, long, accuracy, provider ... ) And sent the data to a server.

When I run the application on the emulator it works fine. ( Well I don't get real GPS information, just the default values of all the variables, but I know my service is called every two minutes and sends the data to the server )

So when i run the application on a real device, its working perfect for something like 40 minutes. Then , I guess , something is closing my service. ( maybe android itself because of memoryconsumpiton or whatever )

Has anybody an idee of how I can track down the bug , or even what could be the bug???

here some of my code:

private Runnable mUpdateTimeTask = new Runnable() {
    public void run() {
        Log.i(ctx.getString(R.string.app_name),
                "HUJIDataCollectionService, mUpdateTimeTask1 start");
        setuplistenerandrequestupdates();
        mHandler.removeCallbacks(mUpdateTimeTask);
    }
};
private Runnable mUpdateTimeTask2 = new Runnable() {
    public void run() {
        Log.i(ctx.getString(R.string.app_name),"HUJIDataCollectionService, mUpdateTimeTask2 start");
        // Send Data to Server here!!
        sendDataToServer();
        // Remove LocationUpdates here!!!
        managerS.removeUpdates(listenerS);
        mHandler.removeCallbacks(mUpdateTimeTask2);
    }
};

private TimerTask startServiceTask = new TimerTask() {
    @Override
    public void run() {
        Log.i(ctx.getString(R.string.app_name),"HUJIDataCollectionService, startServiceTask, run()1");

        // Start Locationupdates here!!!!

        longitude = 0;
        latitude = 0;
        locationprovider = "";
        locationproviderConverted = 0;
        locationAccuracy = 100000;
        // remove old updates from timer tasks
        mHandler.removeCallbacks(mUpdateTimeTask);
        mHandler.removeCallbacks(mUpdateTimeTask2);
        mHandler.postDelayed(mUpdateTimeTask, 1000);
        mHandler.postDelayed(mUpdateTimeTask2,
                conf_LocationUpdatePeriodInSec * 1000);
    }
};

@Override
public void onStart(Intent intent, int startId) {
    super.onStart(intent, startId);

    ShowNotification();

    LoadPreferences();
    startDataCollectionServiceIntervallTimer = new Timer(
            "HUJIDataCollectionServiceStartTimer");

    startDataCollectionServiceIntervallTimer.schedule(startServiceTask,
            1000L, conf_sampleTimeInMin * 60 * 1000L);
    // Starting StopTimer(Thread) to stop listening for location updates
    mHandler = new Handler();
}

private void setuplistenerandrequestupdates() {

    managerS = (LocationManager) ctx
            .getSystemService(Context.LOCATION_SERVICE);
    listenerS = new LocationListener() {

        @Override
        public void onStatusChanged(String arg0, int arg1, Bundle arg2) {}

        @Override
        public void onProviderEnabled(String arg0) {}

        @Override
        public void onProviderDisabled(String arg0) {}

        @Override
        public void onLocationChanged(Location location) {
            // storing data from the latest location update
            float tempLocLongitude = (float) location.getLongitude();
            float tempLocLatitude = (float) location.getLatitude();
            float tempLocAccuracy = location.getAccuracy();
            String tempLocProvider = location.getProvider();

            // if accuracy of new location is better than existing, store
            // accuracy,latitude,longitude and location provider
            if ((tempLocAccuracy < locationAccuracy)
                    && (tempLocAccuracy != 0.0)) {
                // store current latitude
                latitude = tempLocLatitude;
                // store current longitude
                longitude = tempLocLongitude;
                // store current provider
                locationprovider = tempLocProvider;
                // store current accuracy
                locationAccuracy = (int) tempLocAccuracy;
                // converts the String value of locationprovider to the
                // required integer value for the server
                convertLocationProvider();
            }
        }
    };
}

Thanks a lot guys!!!



Solution 1:[1]

Probably Android is killing off your service for living too long and consuming too much resources along the way.

If you believe that the user will highly value your app -- as your app is written, their battery life will be only a couple of hours if they keep your app running -- use startForeground() to indicate to Android that your service is part of the foreground user experience.

Personally, I suggest that you reconsider how your app works, such that you do not consume nearly so much power. For example, check for locations every hour, using AlarmManager and something akin to my LocationPoller. This not only will reduce how frequently and how long you keep GPS on, but it gets your service out of memory in between polls.

Solution 2:[2]

You should also use:

@Override
public int onStartCommand(Intent intent, int flags, int startId) {
    // TODO Your code here or in onStart as you did...

    return START_STICKY;        
}

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 CommonsWare
Solution 2 Domeniko Divjak