Vikas singh
Vikas singh

Reputation: 3879

service automatically stops after several minutes

I'm creating a service which should work when the activity is in background as well as when the whole application is destroyed.

I'm calling location coordinates in the service at every 1 minute interval.

However, when I try to do so, the service shuts down automatically just after 12-15 minutes.

I want the service to work endlessly until and unless it is destroyed by the completion of activity on user interaction.

My service class is as follows:

public class SensorService extends Service {
    public int counter=0; 
    public static final int NINTY_SECONDS = 90000; 
    public static Boolean isRunning = false;
    public LocationManager mLocationManager;
    public Get_Coordinates mLocationListener;
    public GetSharedPreference sharedPreference;
    @Override
    public void onCreate() {
        mLocationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
        mLocationListener = new Get_Coordinates(getApplicationContext());
        sharedPreference = new GetSharedPreference(getApplicationContext());
        startTimer();
        super.onCreate();
    }
    public SensorService(Context applicationContext) {
        super();
        Log.i("HERE", "here I am!");
    }

    public SensorService() {
    }
    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        super.onStartCommand(intent, flags, startId);
        return START_STICKY;
    }
    @Override
    public void onDestroy() {
        super.onDestroy();
        Log.i("EXIT", "ondestroy!");
        Intent broadcastIntent = new Intent("com.android.startBgService");
        broadcastIntent.putExtra("abc","abcd");
        sendBroadcast(broadcastIntent);
        stoptimertask();
    }

    private Timer timer;
    private TimerTask timerTask;
    long oldTime=0;
    public void startTimer() {
        //set a new Timer
        timer = new Timer();

        //initialize the TimerTask's job
        initializeTimerTask();

        //schedule the timer, to wake up every 1 second
        timer.schedule(timerTask, NINTY_SECONDS, NINTY_SECONDS); //
    }

    /**
     * it sets the timer to print the counter every x seconds
     */
    public void initializeTimerTask() {
        timerTask = new TimerTask() {
            public void run() {
               // Log.i("in Etro Sendor", "in timer ++++  "+ (counter++));
                if (Check_Internet_Con.isConnectingToInternet(getApplicationContext())) {

                    if (!isRunning) {
                        startListening();
                    }
                    try {
                        if (sharedPreference.getActiveUserId() > 0) {
                            mLocationListener.getLocation();
                            mLocationListener.insertCoordinatesInSqlite();
                        }
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
            }
        };
    }

    /**
     * not needed
     */
    public void stoptimertask() {
        //stop the timer, if it's not already null
        if (timer != null) {
            timer.cancel();
            timer = null;
        }
    }

    @Nullable
    @Override
    public IBinder onBind(Intent intent) {
        return null;
    }
    public void startListening() {
        if (ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED
                || ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) == PackageManager.PERMISSION_GRANTED) {
            if (mLocationManager.getAllProviders().contains(LocationManager.NETWORK_PROVIDER))
                mLocationManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 0, 0, mLocationListener, Looper.getMainLooper());

            if (mLocationManager.getAllProviders().contains(LocationManager.GPS_PROVIDER))
                mLocationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0, mLocationListener,Looper.getMainLooper());
        }
        isRunning = true;
    }
}

Here is my manifest

<service
           android:name="com.lunetta.etro.e_tro.SensorService"
           android:enabled="true"></service>
       <service
           android:name="com.lunetta.etro.e_tro.SecondService"
           android:enabled="true" >
       </service>

       <receiver
           android:name=".SensorRestarterBroadcastReceiver"
           android:enabled="true"
           android:exported="true"
           android:label="RestartServiceWhenStopped">
           <intent-filter>
               <action android:name="com.android.startBgService" />
               <action android:name="android.intent.action.BOOT_COMPLETED" />
           </intent-filter>
       </receiver>

And Here is SensorRestarterBroadcastReceiver class

public class SensorRestarterBroadcastReceiver extends BroadcastReceiver {
    @Override
    public void onReceive(Context context, Intent intent) {
        Log.i(SensorRestarterBroadcastReceiver.class.getSimpleName(), "Service Stops! Oooooooooooooppppssssss!!!!");
        context.startService(new Intent(context, SensorService.class));
        
    }
}

Upvotes: 3

Views: 3485

Answers (2)

Niraj Sanghani
Niraj Sanghani

Reputation: 1493

Yes it will stop working, check out the new Docs put up by Google, It has changed completely how location works for battery performance, and yes it having a big deal effect on performance i have changed my completely for the very specific task. Also stop using other repos that do claim that they work are wrong

Check the new updated docs by google

https://developer.android.com/training/building-location.html

The best way I implemented your same requirement is and is live in over about 60k devices and working flawlessly is With depending on Version of Android API using JobService with 23 and higher and lower with Background service. Have use LocationProvider API and Location provider Client API accordingly.

with personal experience i will say this The old style of code use to drain the device battery in few hours, now my code is hardly making a dent, its consuming only like 15 percent overnight overall usage. thats a big change in consumption.

Upvotes: 1

JustinDanielson
JustinDanielson

Reputation: 3185

https://developer.android.com/guide/components/bound-services.html

"A bound service typically lives only while it serves another application component and does not run in the background indefinitely."

To make it run indefinitely, you need to bind the service to a UI component that exists indefinitely. You can use an Android Notification. This is a foreground service.

https://developer.android.com/guide/components/services.html#Foreground

Upvotes: 2

Related Questions