Search code examples
android-layoutandroid-intentandroid-inflate

Repeat an action inside of a service


  1. From MainActivity I'm passing an intent to startService. That service is successfully started.

  2. On that service, there is a small rectangle of text ("hello, world") that is originally initialized in an XML layout. In the service code reproduced below, I'm first changing that textView01 text to instead be a string that expresses the date and time. That too is successful (i.e., the user never sees "hello, world" onscreen as the service is started, only the date and time string).

  3. In the same code immediately below that, I update that date and time delayed by 3 seconds. Successful (I'm look at the string change in real time onscreen).

My problem: I can't get it to keep repeating that update. I've tried every loop and delay and wait and sleep and everything else that I've researched and can think of, all to no avail. It currently just stops after having updated--once--after 3 seconds.

Thank you for any help that you can provide.

package com.example.myapplication;

import android.app.Service;
import android.content.Intent;
import android.os.IBinder;
import android.graphics.PixelFormat;
import android.view.LayoutInflater;
import android.view.WindowManager;
import android.view.MotionEvent;
import android.view.View;
import android.widget.TextView;
import java.text.SimpleDateFormat;
import java.util.Date;
import android.os.Handler;

public class FloatingWidgetShowService extends Service{
    WindowManager windowManager;
    View floatingView, collapsedView, expandedView;
    WindowManager.LayoutParams params ;

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

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

        floatingView = LayoutInflater.from(this).inflate(R.layout.floating_widget_layout, null);
        TextView innerView = floatingView.findViewById(R.id.textView01);
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy.MM.dd G 'at' HH:mm:ss z");

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

        windowManager = (WindowManager) getSystemService(WINDOW_SERVICE);
        windowManager.addView(floatingView, params);
        expandedView = floatingView.findViewById(R.id.Layout_Expended);
        collapsedView = floatingView.findViewById(R.id.Layout_Collapsed);
        floatingView.findViewById(R.id.Widget_Close_Icon).setOnClickListener(new View.OnClickListener() {
                    @Override
                    public void onClick(View view) {
                        stopSelf();
                    }
        });

        String currentDateandTime = sdf.format(new Date());
        innerView.setText(currentDateandTime);

        final Handler handler = new Handler();
        handler.postDelayed(new Runnable() {
            @Override
            public void run() {
                String currentDateandTime = sdf.format(new Date());
                innerView.setText(currentDateandTime);
            }
        }, 3000);

        expandedView.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View view) {
                    collapsedView.setVisibility(View.VISIBLE);
                    expandedView.setVisibility(View.GONE);
                }
        });

        floatingView.findViewById(R.id.MainParentRelativeLayout).setOnTouchListener(new View.OnTouchListener() {
            int X_Axis, Y_Axis;
            float TouchX, TouchY;

            @Override
            public boolean onTouch(View v, MotionEvent event) {
                switch (event.getAction()) {
                    case MotionEvent.ACTION_DOWN:
                        X_Axis = params.x;
                        Y_Axis = params.y;
                        TouchX = event.getRawX();
                        TouchY = event.getRawY();
                        return true;
                    case MotionEvent.ACTION_UP:
                        collapsedView.setVisibility(View.GONE);
                        expandedView.setVisibility(View.VISIBLE);
                        return true;
                    case MotionEvent.ACTION_MOVE:
                        params.x = X_Axis + (int) (event.getRawX() - TouchX);
                        params.y = Y_Axis + (int) (event.getRawY() - TouchY);
                        windowManager.updateViewLayout(floatingView, params);
                        return true;
                }
                return false;
            }
        });
    }

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

Solution

  • Just repost your update to the Handler, like this:

    handler.postDelayed(new Runnable() {
            @Override
            public void run() {
                String currentDateandTime = sdf.format(new Date());
                innerView.setText(currentDateandTime);
                // Now post the update to run again in 3 seconds
                handler.postDelayed(this, 3000);
            }
        }, 3000);