John Smith
John Smith

Reputation: 3615

Updating Android Wear watchface BEFORE display turns on

I have made a watchface that is working fine as far as loading on to my phone, selecting and running on my MOTO 360, BUT where I'm having the problem is when the screen turns off and I touch the screen, it comes on but the hands (bitmaps) whip around to the right time. It looks like when the screen goes off it's no longer updating. I'm using a timer routine that only changes to 1 second updates if isVisible() and !isInAmbientMode from 30ms when interactive and triggers an invalidate().

NOTE: I tried adding invalidate() in all those routines but it didn't help.

Here is the relevant code:

    // handler to update the time once a second in interactive mode
    final Handler mUpdateTimeHandler = new Handler() {
        @Override
        public void handleMessage(Message message) {
            switch (message.what) {
                case MSG_UPDATE_TIME:

                    invalidate();

                    long timeMs = System.currentTimeMillis();

                    if (shouldTimerBeRunning()) {
                        long delayMs = INTERACTIVE_UPDATE_RATE_MS
                                - (timeMs % INTERACTIVE_UPDATE_RATE_MS);
                        mUpdateTimeHandler
                                .sendEmptyMessageDelayed(MSG_UPDATE_TIME, delayMs);
                    } else {

                        long delayMs = NON_INTERACTIVE_UPDATE_RATE_MS
                                - (timeMs % NON_INTERACTIVE_UPDATE_RATE_MS);
                        mUpdateTimeHandler
                                .sendEmptyMessageDelayed(MSG_UPDATE_TIME, delayMs);
                    }
                    break;
            }
        }
    };

    @Override
    public void onAmbientModeChanged(boolean inAmbientMode) {
        super.onAmbientModeChanged(inAmbientMode);

        if (bLowBitAmbient) {
            boolean antiAlias = !inAmbientMode;
            mHrPaint.setAntiAlias(antiAlias);
            mMinPaint.setAntiAlias(antiAlias);
            mSecPaint.setAntiAlias(antiAlias);
            mCapPaint.setAntiAlias(antiAlias);
            mTextPaint.setAntiAlias(antiAlias);
            mTickPaint.setAntiAlias(antiAlias);
        }

        updateTimer();
    }

    // Request to update Timer (only if visible and interactive)
    private void updateTimer() {
        mUpdateTimeHandler.removeMessages(MSG_UPDATE_TIME);
        if (shouldTimerBeRunning()) {
            mUpdateTimeHandler.sendEmptyMessage(MSG_UPDATE_TIME);
        }
    }

    // Timer only runs when visible and interactive.
    private boolean shouldTimerBeRunning() {
        return isVisible() && !isInAmbientMode();
    }

Upvotes: 0

Views: 265

Answers (2)

John Smith
John Smith

Reputation: 3615

I have found a work around for this so I don't have to use an alarm. I Override onVisiblityChanged and place a boolean flag. In onDraw I just paint the canvas black. That way when the device wakes up, it's black until the next round of onDraw when the screen is already alive. Seems to work nicely!

    @Override
    public void onVisibilityChanged(boolean visible) {
        super.onVisibilityChanged(visible);

        // the watch face became visible or invisible
        bDisplayBitmap = visible;

        ...

        invalidate();
    }


    @Override
    public void onDraw(Canvas canvas, Rect bounds) {

        // Draw watch face

        ...

        if(bDisplayBitmap) {

            canvas.drawBitmap(mBackgroundBitmap, 0, 0, null);

        } else {

            canvas.drawPaint(mBackgroundPaint);
        }

        ...
    }

Upvotes: 2

Ali Naddaf
Ali Naddaf

Reputation: 19034

When Ambient mode is active, system tries to preserve the battery as much as possible and sends the device into a deep sleep, during which, handlers don't run. In most cases, for a watch face, you don't need to update the watch face more than once a minute when it is in deep sleep so you can use WatchFaceService.Engine.onTimeTick() to be notified once a minute in that state (or when time zone changes or date has changed, etc), see the docs for details. Anything more frequent is not recommended but can be achieved using AlarmManager.

Upvotes: 0

Related Questions