service automatically stops after several minutes

六月ゝ 毕业季﹏ 提交于 2019-11-30 16:00:45

问题


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));
        
    }
}

回答1:


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.




回答2:


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



来源:https://stackoverflow.com/questions/47090007/service-automatically-stops-after-several-minutes

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!