Задать вопрос

Как релизовать запуск/остановку сервиса при сворачивании/разворачивании Activity?

Есть активити, в котором постоянно производятся расчеты. Необходимо, чтобы при сворачивании приложения, эти расчеты продолжались.
Подскажите пожалуйста, как реализовать запуск сервиса и передачу в него параметров для расчетов при сворачивании Activity, и остановку сервиса и получение из него данных при разворачивании Activity?

Прикладываю полный листинг того, что наваял.
MainActivity
package com.example.service;

import android.app.ActivityManager;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.ServiceConnection;
import android.content.SharedPreferences;
import android.os.Bundle;
import android.os.IBinder;
import android.support.design.widget.FloatingActionButton;
import android.support.design.widget.Snackbar;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.Toolbar;
import android.util.Log;
import android.view.View;
import android.view.Menu;
import android.view.MenuItem;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;


public class MainActivity extends AppCompatActivity implements View.OnClickListener {

    public String LOG_TAG = "llog";
    Button btn1, btn2, btnexit;
    TextView rezultat;
    private Intent serviceintent;
    private SharedPreferences sPref;
    private ServiceConnection sConn;
    private KVService kvService;
    boolean bound = false, exit = false;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        Log.d(LOG_TAG, "onCreate");
        setContentView(R.layout.activity_main);
        Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
        setSupportActionBar(toolbar);

        FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.fab);
        fab.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                Snackbar.make(view, "Replace with your own action", Snackbar.LENGTH_LONG)
                        .setAction("Action", null).show();
            }
        });

        btn1 = (Button)findViewById(R.id.btn1);
        btn2 = (Button)findViewById(R.id.btn2);
        btnexit = (Button)findViewById(R.id.btnEXIT);
        rezultat = (TextView)findViewById(R.id.rezultat);

        btn1.setOnClickListener(this);
        btn2.setOnClickListener(this);
        btnexit.setOnClickListener(this);

        serviceintent = new Intent(this, KVService.class);
        sPref = getSharedPreferences("Rally", Context.MODE_PRIVATE);
        startService(serviceintent);
        sConn = new ServiceConnection() {
            public void onServiceConnected(ComponentName name, IBinder binder) {
                Log.d(LOG_TAG, "KVFragment onServiceConnected");
                kvService = ((KVService.MyBinder) binder).getService();
                bound = true;
            }

            public void onServiceDisconnected(ComponentName name) {
                Log.d(LOG_TAG, "KVFragment onServiceDisconnected");
                rezultat.setText(sPref.getString("KV_Pdistance", ""));
                bound = false;
            }
        };
    }

    @Override
    protected void onResume() {
        Log.d(LOG_TAG, "KVFragment onResume");
        if (bound){
            Log.d(LOG_TAG, "Останавливем сервис");
            //stopService(serviceintent);
            unbindService(sConn);
        };
        //unbindService(sConn);
        super.onResume();
    }

    @Override
    protected void onPause() {
        Log.d(LOG_TAG, "KVFragment onPause");
        super.onPause();
    }

    @Override
    protected void onStop() {
        Log.d(LOG_TAG, "KVFragment onStop");
        if (!exit & !bound) {
            SharedPreferences.Editor ed = sPref.edit();
            ed.putString("KV_Pdistance", "1");
            ed.putString("FakeSpeed", "120.0");
            ed.putString("koef", "1");
            ed.apply();
            Log.d(LOG_TAG, "Вызываем bindservice");
            bindService(serviceintent, sConn, 0);
        }
        super.onStop();
    }

    @Override
    protected void onDestroy() {
        Log.d(LOG_TAG, "KVFragment onDestroy");
        super.onDestroy();
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        getMenuInflater().inflate(R.menu.menu_main, menu);
        return true;
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        int id = item.getItemId();

        if (id == R.id.action_settings) {
            return true;
        }
        return super.onOptionsItemSelected(item);
    }

    @Override
    public void onClick(View v) {
        switch (v.getId()) {
            case R.id.btn1:
                break;
            case R.id.btn2:
                break;
            case R.id.btnEXIT:
                exit =true;
                stopService(serviceintent);
                finish();
                break;
        }
    }

    private boolean isMyServiceRunning(Class<?> serviceClass) {
        ActivityManager manager = (ActivityManager) getSystemService(Context.ACTIVITY_SERVICE);
        for (ActivityManager.RunningServiceInfo service : manager.getRunningServices(Integer.MAX_VALUE)) {
            if (serviceClass.getName().equals(service.service.getClassName())) {
                return true;
            }
        }
        return false;
    }
}


KVService
package com.example.service;

import android.app.Service;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.SharedPreferences;
import android.os.Binder;
import android.os.IBinder;
import android.util.Log;
import android.view.View;

import java.util.Timer;
import java.util.TimerTask;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class KVService extends Service {
    final String LOG_TAG = "llog";
    Timer myTimer, StartTimer, RealTimer;
    ExecutorService es;
    MyBinder binder = new MyBinder();
    BroadcastReceiver br;
    public Double gpsSpeed = 0.0; //spped
    public final static String GpsSpeed = "0";
    public final static String BROADCAST_ACTION = "KVService";//gpsService
    String NMEA_Speed = "0.0";
    SharedPreferences sPref;
    private double rdist;
    private String fakespped;
    private Double changetime = 10.0;

    public void onCreate() {
        super.onCreate();
        Log.d(LOG_TAG, "KVService onCreate");
        es = Executors.newFixedThreadPool(2);
        sPref = getSharedPreferences("Rally", Context.MODE_PRIVATE);

    }

    public int onStartCommand(Intent intent, int flags, int startId) {
        Log.d(LOG_TAG, "KVService onStartCommand");
        return super.onStartCommand(intent, flags, startId);
    }

    public void onDestroy() {
        super.onDestroy();
        Log.d(LOG_TAG, "KVService onDestroy");
    }

    class RealTime implements Runnable {

        public RealTime(){
        }

        @Override
        public void run() {
            //Log.i(LOG_TAG, "i = " + i++);
            Log.i(LOG_TAG, "Скорость получена от сервиса GPSService = " + gpsSpeed);

                gpsSpeed = Double.valueOf(fakespped);

            rdist += ((gpsSpeed * (changetime / 36000)) / 100) * Double.valueOf(sPref.getString("koef", ""));//Фактически пройденное расстояние

;
        }
    }

    public IBinder onBind(Intent arg0) {
        Log.d(LOG_TAG, "KVService onBind");
        final RealTime realtime = new RealTime();
        rdist = Double.valueOf(sPref.getString("KV_Pdistance", ""));
        fakespped = sPref.getString("FakeSpeed","");
        RealTimer = new Timer();
        RealTimer.schedule(new TimerTask() {
            public void run() {
                es.execute(realtime);
            }
        }, 0, 10); // каждую 1 секунду
        return binder;
    }
    public boolean onUnbind(Intent intent) {
        Log.d(LOG_TAG, "KVService onUnbind");
        RealTimer.cancel();
        SharedPreferences.Editor ed = sPref.edit();
        ed.putString("KV_Pdistance", String.valueOf(rdist));
        ed.apply();
        return super.onUnbind(intent);
    }

    public class MyBinder extends Binder {
        public KVService getService() {
            return KVService.this;
        }
    }
}
  • Вопрос задан
  • 898 просмотров
Подписаться 2 Оценить Комментировать
Ответ пользователя itdroid К ответам на вопрос (2)
@itdroid
В вашем случае, как по мне, лучше всего перенести всю логику расчетов в сервис и использовать его как Bound Service (developer.android.com/intl/ru/guide/components/bou...

Когда пользователь открывает Activity, вы поднимаете сервис (startService) передавая ему исходные данные и сервис начинает делать что-то важное :). Далее, в onStart вашей Activity вы подключаетесь к сервису через bindService и начинаете с ним общаться. Когда пользователь сворачивает приложение, в onStop, вы отписываетесь от сервиса через unbindService. Но сервис продолжает делать что-то важное) Потом когда пользователь вернется в ваше приложение вы подключитесь к сервису и запрашиваете свежие данные.

Если вам необходимо чтобы система не убивала сервис продолжительное время используйте Foreground Service, это повысит приоритет вашего процесса.
Ответ написан