Answer the question
In order to leave comments, you need to log in
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);
}
}
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);
}
}
<?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>
Answer the question
In order to leave comments, you need to log in
Didn't find what you were looking for?
Ask your questionAsk a Question
731 491 924 answers to any question