хронометр не работает - PullRequest
       9

хронометр не работает

0 голосов
/ 10 сентября 2018

Я пытаюсь запустить хронометр внутри Service. Но я не могу его запустить. Я нажимаю кнопку в Activity, и это событие передается в Service. Если кнопка нажата, тогда запускается Chronometer, но проблема в setOnChronometerTickListener вызывается только один раз и останавливается. Где я делаю ошибку? Вот мой Service и Activity класс:

Класс обслуживания:

public class TimerService extends Service {


    NotificationManager notificationManager;
    NotificationCompat.Builder mBuilder;
    Callbacks activity;
    private final IBinder mBinder = new LocalBinder();
    private Chronometer chronometer;
    SharedPreferences sharedPreferences;
    private int state = 0; //0 means stop state,1 means play, 2 means pause
    private boolean running = false;
    private long pauseOffSet = -1;

    @Subscribe(threadMode = ThreadMode.MAIN)
    public void onMessageEvent(MessageEvent event) {
        if (event.message) {
            if (!running) {
                if (pauseOffSet != -1) {
                    pauseOffSet = sharedPreferences.getLong("milli", -1);
                }
                chronometer.setBase(SystemClock.elapsedRealtime() - pauseOffSet);
                chronometer.start();
                state = 1;
                pauseOffSet = 0;
                running = true;
            }
        } else {
            if (running) {
                chronometer.stop();
                pauseOffSet = SystemClock.elapsedRealtime() - chronometer.getBase();
                state = 2;
                running = false;
            }
        }
    }

    @Override
    public void onCreate() {
        super.onCreate();
        EventBus.getDefault().register(this);
    }

    @Override
    public void onDestroy() {
        EventBus.getDefault().unregister(this);
        super.onDestroy();
    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {

        sharedPreferences = getSharedPreferences("myprefs", MODE_PRIVATE);
        chronometer = new Chronometer(this);
        state = sharedPreferences.getInt("state", 0);

        chronometer.setOnChronometerTickListener(new Chronometer.OnChronometerTickListener() {
            @Override
            public void onChronometerTick(Chronometer chronometer) {
                Log.e("TimerService","timer");
                pauseOffSet = SystemClock.elapsedRealtime() - chronometer.getBase();
                if (pauseOffSet >= 79200000) {
                    chronometer.setBase(SystemClock.elapsedRealtime());
                    chronometer.stop();
                    running = false;
//                    progressBar.setProgress(0);
                } else {
                    chronometer.setText(setFormat(pauseOffSet));
//                    int convertTime = (int) pauseOffSet;
//                    progressBar.setProgress(convertTime);
                }
                if (activity != null) {
                    activity.updateClient(pauseOffSet);
                }
            }
        });
        if (state == 1) { // its in play mode
            running = true;
            chronometer.setBase(SystemClock.elapsedRealtime() - sharedPreferences.getLong("milli", 0));
            chronometer.start();
        } else if (state == 2) { //its in pause mode
            running = false;
            pauseOffSet = sharedPreferences.getLong("milli", -1);
            long time = SystemClock.elapsedRealtime() - pauseOffSet;
            chronometer.setBase(time);
            int convertTime = (int) pauseOffSet;
//            progressBar.setProgress(convertTime);
        } else {
            running = false;
        }

        //Do what you need in onStartCommand when service has been started
        return START_NOT_STICKY;
    }

    @Override
    public IBinder onBind(Intent intent) {
        return mBinder;
    }

    //returns the instance of the service
    public class LocalBinder extends Binder {
        public TimerService getServiceInstance() {
            return TimerService.this;
        }
    }

    //Here Activity register to the service as Callbacks client
    public void registerClient(Activity activity) {
        this.activity = (Callbacks) activity;
    }


    //callbacks interface for communication with service clients!
    public interface Callbacks {
        public void updateClient(long data);
    }

    String setFormat(long time) {
        int h = (int) (time / 3600000);
        int m = (int) (time - h * 3600000) / 60000;
        int s = (int) (time - h * 3600000 - m * 60000) / 1000;
        String hh = h < 10 ? "0" + h : h + "";
        String mm = m < 10 ? "0" + m : m + "";
        String ss = s < 10 ? "0" + s : s + "";
        return hh + ":" + mm + ":" + ss;
    }
}

Это мой класс занятий:

public class MainActivity extends AppCompatActivity implements View.OnClickListener, TimerService.Callbacks {

    private static final String TAG = MainActivity.class.getSimpleName();
    Chronometer tvTextView;
    Button btnStart, btnStop;
    private int state = 0; //0 means stop state,1 means play, 2 means pause

    SharedPreferences sharedPreferences;
    private boolean running = false;
    private long pauseOffSet = -1;

    ProgressBar progressBar;

    Intent serviceIntent;
    TimerService myService;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        tvTextView = findViewById(R.id.textview);
        progressBar = findViewById(R.id.puzzleProgressBar);

        btnStart = findViewById(R.id.button1);
        btnStop = findViewById(R.id.button2);
        btnStart.setOnClickListener(this);
        btnStop.setOnClickListener(this);

        serviceIntent = new Intent(this, TimerService.class);

        sharedPreferences = getSharedPreferences("myprefs", MODE_PRIVATE);
        state = sharedPreferences.getInt("state", 0);

        tvTextView.setOnChronometerTickListener(new Chronometer.OnChronometerTickListener() {
            @Override
            public void onChronometerTick(Chronometer chronometer) {
                long time = SystemClock.elapsedRealtime() - chronometer.getBase();
                pauseOffSet = time;
                Log.e(TAG, "pauseOffSet " + pauseOffSet);
                if (time >= 79200000) {
                    tvTextView.setBase(SystemClock.elapsedRealtime());
                    tvTextView.stop();
                    running = false;
                    progressBar.setProgress(0);
                } else {
                    chronometer.setText(setFormat(time));
                    int convertTime = (int) time;
                    progressBar.setProgress(convertTime);
                }
            }
        });

        startService(serviceIntent); //Starting the service
        bindService(serviceIntent, serviceConnection, Context.BIND_AUTO_CREATE); //Binding to the service!

    }

    private ServiceConnection serviceConnection = new ServiceConnection() {
        @Override
        public void onServiceConnected(ComponentName name, IBinder service) {
            TimerService.LocalBinder binder = (TimerService.LocalBinder) service;
            myService = binder.getServiceInstance();
            myService.registerClient(MainActivity.this);
            Log.e(TAG, "service connected");
        }

        @Override
        public void onServiceDisconnected(ComponentName name) {
            Log.e(TAG, "service disconnected");
        }
    };

    public void onClick(View v) {
        if (btnStart == v) {
            EventBus.getDefault().post(new MessageEvent(true));

        } else if (btnStop == v) {
            EventBus.getDefault().post(new MessageEvent(false));
        }
    }

    @Override
    protected void onStop() {
        super.onStop();
        sharedPreferences.edit().putLong("milli", pauseOffSet).commit();
        sharedPreferences.edit().putInt("state", state).commit();
    }

    String setFormat(long time) {
        int h = (int) (time / 3600000);
        int m = (int) (time - h * 3600000) / 60000;
        int s = (int) (time - h * 3600000 - m * 60000) / 1000;
        String hh = h < 10 ? "0" + h : h + "";
        String mm = m < 10 ? "0" + m : m + "";
        String ss = s < 10 ? "0" + s : s + "";
        return hh + ":" + mm + ":" + ss;
    }

    @Override
    public void updateClient(long data) {
        Log.d(TAG, "Data from service" + data);
    }
}

1 Ответ

0 голосов
/ 10 сентября 2018

Chronometer - это View, то есть элемент пользовательского интерфейса.Вы никогда не добавляете свой хронометр в любой макет, я думаю, поэтому он никогда не обновляется.

Вы можете попробовать использовать комбинацию CountDownTimer или Handler / Runnable.

http://developer.android.com/reference/android/os/CountDownTimer.html http://developer.android.com/reference/android/os/Handler.html

Вот пример использования Handler / Runnable, я даже добавил метод stopTimer() для хорошей меры:

private Handler timerHandler;
private Runnable timerRunnable;

// ...

@Override
public void onCreate() {
    super.onCreate();
    Log.d(LOG_TAG, "TimerService created");
    timerHandler = new Handler();
    timerRunnable = new Runnable() {
        @Override
        public void run() {
            Log.d(LOG_TAG, "TICK"); 
            timerHandler.postDelayed(timerRunnable, 1000);
        }
    };
}

public void startTimer() {
    Log.d(LOG_TAG, "Timer started");
    timerHandler.post(timerRunnable);
}

public void stopTimer() {
    Log.d(LOG_TAG, "Timer stopped");
    timerHandler.removeCallbacks(timerRunnable);
}
...