I
I
IamFromUSSR2019-01-22 23:38:55
Java
IamFromUSSR, 2019-01-22 23:38:55

Timer on top of all windows in Android?

We need a timer that will hang on top of all windows. Press it once to start/pause, double press to reset.
There were no problems with the timer itself. On top of all windows, made using WindowManager.
But I got a problem. I'm running an activity with a reset button and a clock face on top of all windows, but I can't figure out how to make them work.
Separately, the class that performs the functions of the timer - works without problems, but I do not know how to attach it to an activity that is on top of all windows.
This is how I did it on top of all windows

public class FloatButtonService extends Service {

    @Override
    public IBinder onBind(Intent intent) {
        return null;
    }
    private WindowManager windowManager;
    private View rootView;



    @Override
    public void onCreate() {
        super.onCreate();

        windowManager = (WindowManager) getSystemService(WINDOW_SERVICE);

        int layout_parms;

        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O)
        {
            layout_parms = WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY;
        }
        else {
            layout_parms = WindowManager.LayoutParams.TYPE_PHONE;
        }

        final WindowManager.LayoutParams params = new WindowManager.LayoutParams(
                WindowManager.LayoutParams.WRAP_CONTENT,
                WindowManager.LayoutParams.WRAP_CONTENT,
                layout_parms,
                WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE,
                PixelFormat.TRANSLUCENT );

        params.gravity = Gravity.TOP | Gravity.LEFT;
        params.x = 0;
        params.y = 100;

        rootView = (RelativeLayout) LayoutInflater.from(this).inflate(R.layout.activity_timer, null);


        windowManager.addView(rootView, params);

        Button mButtonStartPause = rootView.findViewById(R.id.button_start_pause);
        mButtonStartPause.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {

                Intent intent = new Intent(FloatButtonService.this, timer.class);
                intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);


            }
        });


        rootView.setOnTouchListener(new View.OnTouchListener() {
            private int initialX;
            private int initialY;
            private float initialTouchX;
            private float initialTouchY;
            private boolean shouldClick;

            @Override
            public boolean onTouch(View v, MotionEvent event) {
                switch (event.getAction()) {
                    case MotionEvent.ACTION_DOWN:
                        shouldClick = true;
                        initialX = params.x;
                        initialY = params.y;
                        initialTouchX = event.getRawX();
                        initialTouchY = event.getRawY();
                        return true;
                    case MotionEvent.ACTION_UP:
                        if(shouldClick)
                            return true;
                    case MotionEvent.ACTION_MOVE:
                        shouldClick = false;
                        params.x = initialX
                                + (int) (event.getRawX() - initialTouchX);
                        params.y = initialY
                                + (int) (event.getRawY() - initialTouchY);
                        windowManager.updateViewLayout(rootView, params);
                        return true;
                }
                return false;
            }
        });



    }


    @Override
    public void onDestroy() {
        super.onDestroy();
        if (rootView != null)
            windowManager.removeView(rootView);
    }
}

Here is the timer itself
public class timer extends MainActivity  {


    private static final long DOUBLE_PRESS_INTERVAL = 250; // in millis
    private long lastPressTime;


    private static final long START_TIME_IN_MILLIS = 600000;

    private TextView mTextViewCountDoun;
    private static Button mButtonStartPause;


    private CountDownTimer mCountDownTimer;
    private boolean mTimerRunning;
    private long mTimeLeftInMilles = START_TIME_IN_MILLIS;



    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_timer);



        mTextViewCountDoun = findViewById(R.id.text_view_countdown);

        mButtonStartPause = findViewById(R.id.button_start_pause);


        mButtonStartPause.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                long pressTime = System.currentTimeMillis();

                if (pressTime - lastPressTime <= DOUBLE_PRESS_INTERVAL) {
                    resetTimer();
                }
                else if (mTimerRunning ) {
                    pauseTimer();
                }
                else {
                    startTimer();
                }
                lastPressTime = pressTime;
            }
        });


        updateCountDownText();

    }
    private void startTimer(){
        mCountDownTimer = new CountDownTimer(mTimeLeftInMilles, 1000) {
            @Override
            public void onTick(long millisUntilFinished) {
                mTimeLeftInMilles = millisUntilFinished;
                updateCountDownText();
            }

            @Override
            public void onFinish() {
                mTimerRunning = false;
                mButtonStartPause.setText("RESET");
            }
        }.start();

        mTimerRunning = true;
           mButtonStartPause.setText("PAUSE");
    }

    private void pauseTimer(){
        mCountDownTimer.cancel();
        mTimerRunning = false;
          mButtonStartPause.setText("START");
    }

    private void resetTimer(){
        mTimeLeftInMilles = START_TIME_IN_MILLIS;
        pauseTimer();
        updateCountDownText();
           mButtonStartPause.setText("RESET");
    }

    private void updateCountDownText() {
        int minutes = (int) (mTimeLeftInMilles / 1000) / 60;
        int seconds = (int) (mTimeLeftInMilles / 1000) % 60;

        String timeLeftFormated = String.format(Locale.getDefault(),"%02d:%02d", minutes,seconds);
        mTextViewCountDoun.setText(timeLeftFormated);
    }
}

Timer activity
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="180dp"
    android:layout_height="300dp"
    android:id="@+id/testTest"
    tools:context=".timer"
    tools:showIn="@layout/activity_timer"
    >


    <TextView
        android:id="@+id/text_view_countdown"
        android:layout_width="100dp"
        android:layout_height="30dp"
        android:layout_centerHorizontal="true"
        android:text="00:00"
        android:textColor="@android:color/black"
        android:textSize="25dp"
        />

    <Button
        android:id="@+id/button_start_pause"
        android:layout_width="100dp"
        android:layout_height="100dp"
        android:layout_below="@id/text_view_countdown"
        android:layout_centerHorizontal="true"
        android:text="START"
        android:textSize="10dp"/

</RelativeLayout>

Thanks for future advice

Answer the question

In order to leave comments, you need to log in

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question