2014-12-12 3 views
6

Я пытаюсь использовать новый API Face Face на эмуляторе износа, и когда я расширяю CanvasWatchFaceService , методы onTimeTick никогда не запускались, поэтому часы никогда не обновлялись.Android Wear WatchFace API onTimeTick не запускается

Я использую образец аналогового и попытаться удалить вторую руку (просто отключить таймер на данный момент):

/* 
* Copyright (C) 2014 The Android Open Source Project 
* 
* Licensed under the Apache License, Version 2.0 (the "License"); 
* you may not use this file except in compliance with the License. 
* You may obtain a copy of the License at 
* 
*  http://www.apache.org/licenses/LICENSE-2.0 
* 
* Unless required by applicable law or agreed to in writing, software 
* distributed under the License is distributed on an "AS IS" BASIS, 
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
* See the License for the specific language governing permissions and 
* limitations under the License. 
*/ 

package com.example.android.wearable.watchface; 

import android.content.BroadcastReceiver; 
import android.content.Context; 
import android.content.Intent; 
import android.content.IntentFilter; 
import android.content.res.Resources; 
import android.graphics.Bitmap; 
import android.graphics.Canvas; 
import android.graphics.Paint; 
import android.graphics.Rect; 
import android.graphics.drawable.BitmapDrawable; 
import android.graphics.drawable.Drawable; 
import android.os.Bundle; 
import android.os.Handler; 
import android.os.Message; 
import android.support.wearable.watchface.CanvasWatchFaceService; 
import android.support.wearable.watchface.WatchFaceService; 
import android.support.wearable.watchface.WatchFaceStyle; 
import android.text.format.Time; 
import android.util.Log; 
import android.view.SurfaceHolder; 

import java.util.TimeZone; 
import java.util.concurrent.TimeUnit; 

/** 
* Sample analog watch face with a ticking second hand. In ambient mode, the second hand isn't 
* shown. On devices with low-bit ambient mode, the hands are drawn without anti-aliasing in ambient 
* mode. The watch face is drawn with less contrast in mute mode. 
* 
* {@link SweepWatchFaceService} is similar but has a sweep second hand. 
*/ 
public class AnalogWatchFaceService extends CanvasWatchFaceService { 
    private static final String TAG = "AnalogWatchFaceService"; 

    /** 
    * Update rate in milliseconds for interactive mode. We update once a second to advance the 
    * second hand. 
    */ 
    private static final long INTERACTIVE_UPDATE_RATE_MS = TimeUnit.SECONDS.toMillis(1); 

    @Override 
    public Engine onCreateEngine() { 
     return new Engine(); 
    } 

    private class Engine extends CanvasWatchFaceService.Engine { 
     static final int MSG_UPDATE_TIME = 0; 

     Paint mHourPaint; 
     Paint mMinutePaint; 
     Paint mSecondPaint; 
     Paint mTickPaint; 
     boolean mMute; 
     Time mTime; 

     /** 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: 
         if (Log.isLoggable(TAG, Log.VERBOSE)) { 
          Log.v(TAG, "updating time"); 
         } 
         invalidate(); 
         if (shouldTimerBeRunning()) { 
          long timeMs = System.currentTimeMillis(); 
          long delayMs = INTERACTIVE_UPDATE_RATE_MS 
            - (timeMs % INTERACTIVE_UPDATE_RATE_MS); 
          mUpdateTimeHandler.sendEmptyMessageDelayed(MSG_UPDATE_TIME, delayMs); 
         } 
         break; 
       } 
      } 
     }; 

     final BroadcastReceiver mTimeZoneReceiver = new BroadcastReceiver() { 
      @Override 
      public void onReceive(Context context, Intent intent) { 
       mTime.clear(intent.getStringExtra("time-zone")); 
       mTime.setToNow(); 
      } 
     }; 
     boolean mRegisteredTimeZoneReceiver = false; 

     /** 
     * Whether the display supports fewer bits for each color in ambient mode. When true, we 
     * disable anti-aliasing in ambient mode. 
     */ 
     boolean mLowBitAmbient; 

     Bitmap mBackgroundBitmap; 
     Bitmap mBackgroundScaledBitmap; 

     @Override 
     public void onCreate(SurfaceHolder holder) { 
      if (Log.isLoggable(TAG, Log.DEBUG)) { 
       Log.d(TAG, "onCreate"); 
      } 
      super.onCreate(holder); 

      setWatchFaceStyle(new WatchFaceStyle.Builder(AnalogWatchFaceService.this) 
        .setCardPeekMode(WatchFaceStyle.PEEK_MODE_SHORT) 
        .setBackgroundVisibility(WatchFaceStyle.BACKGROUND_VISIBILITY_INTERRUPTIVE) 
        .setShowSystemUiTime(false) 
        .build()); 

      Resources resources = AnalogWatchFaceService.this.getResources(); 
      Drawable backgroundDrawable = resources.getDrawable(R.drawable.bg); 
      mBackgroundBitmap = ((BitmapDrawable) backgroundDrawable).getBitmap(); 

      mHourPaint = new Paint(); 
      mHourPaint.setARGB(255, 200, 200, 200); 
      mHourPaint.setStrokeWidth(5.f); 
      mHourPaint.setAntiAlias(true); 
      mHourPaint.setStrokeCap(Paint.Cap.ROUND); 

      mMinutePaint = new Paint(); 
      mMinutePaint.setARGB(255, 200, 200, 200); 
      mMinutePaint.setStrokeWidth(3.f); 
      mMinutePaint.setAntiAlias(true); 
      mMinutePaint.setStrokeCap(Paint.Cap.ROUND); 

      mSecondPaint = new Paint(); 
      mSecondPaint.setARGB(255, 255, 0, 0); 
      mSecondPaint.setStrokeWidth(2.f); 
      mSecondPaint.setAntiAlias(true); 
      mSecondPaint.setStrokeCap(Paint.Cap.ROUND); 

      mTickPaint = new Paint(); 
      mTickPaint.setARGB(100, 255, 255, 255); 
      mTickPaint.setStrokeWidth(2.f); 
      mTickPaint.setAntiAlias(true); 

      mTime = new Time(); 
     } 

     @Override 
     public void onDestroy() { 
      mUpdateTimeHandler.removeMessages(MSG_UPDATE_TIME); 
      super.onDestroy(); 
     } 

     @Override 
     public void onPropertiesChanged(Bundle properties) { 
      super.onPropertiesChanged(properties); 
      mLowBitAmbient = properties.getBoolean(PROPERTY_LOW_BIT_AMBIENT, false); 
      if (Log.isLoggable(TAG, Log.DEBUG)) { 
       Log.d(TAG, "onPropertiesChanged: low-bit ambient = " + mLowBitAmbient); 
      } 
     } 

     @Override 
     public void onTimeTick() { 
      super.onTimeTick(); 
      if (Log.isLoggable(TAG, Log.DEBUG)) { 
       Log.d(TAG, "onTimeTick: ambient = " + isInAmbientMode()); 
      } 
      invalidate(); 
     } 

     @Override 
     public void onAmbientModeChanged(boolean inAmbientMode) { 
      super.onAmbientModeChanged(inAmbientMode); 
      if (Log.isLoggable(TAG, Log.DEBUG)) { 
       Log.d(TAG, "onAmbientModeChanged: " + inAmbientMode); 
      } 
      if (mLowBitAmbient) { 
       boolean antiAlias = !inAmbientMode; 
       mHourPaint.setAntiAlias(antiAlias); 
       mMinutePaint.setAntiAlias(antiAlias); 
       mSecondPaint.setAntiAlias(antiAlias); 
       mTickPaint.setAntiAlias(antiAlias); 
      } 
      invalidate(); 

      // Whether the timer should be running depends on whether we're in ambient mode (as well 
      // as whether we're visible), so we may need to start or stop the timer. 
      updateTimer(); 
     } 

     @Override 
     public void onInterruptionFilterChanged(int interruptionFilter) { 
      super.onInterruptionFilterChanged(interruptionFilter); 
      boolean inMuteMode = (interruptionFilter == WatchFaceService.INTERRUPTION_FILTER_NONE); 
      if (mMute != inMuteMode) { 
       mMute = inMuteMode; 
       mHourPaint.setAlpha(inMuteMode ? 100 : 255); 
       mMinutePaint.setAlpha(inMuteMode ? 100 : 255); 
       mSecondPaint.setAlpha(inMuteMode ? 80 : 255); 
       invalidate(); 
      } 
     } 

     @Override 
     public void onDraw(Canvas canvas, Rect bounds) { 
      mTime.setToNow(); 



      int width = bounds.width(); 
      int height = bounds.height(); 

      // Draw the background, scaled to fit. 
      if (mBackgroundScaledBitmap == null 
        || mBackgroundScaledBitmap.getWidth() != width 
        || mBackgroundScaledBitmap.getHeight() != height) { 
       mBackgroundScaledBitmap = Bitmap.createScaledBitmap(mBackgroundBitmap, 
         width, height, true /* filter */); 
      } 
      canvas.drawBitmap(mBackgroundScaledBitmap, 0, 0, null); 

      // Find the center. Ignore the window insets so that, on round watches with a 
      // "chin", the watch face is centered on the entire screen, not just the usable 
      // portion. 
      float centerX = width/2f; 
      float centerY = height/2f; 

      // Draw the ticks. 
      float innerTickRadius = centerX - 10; 
      float outerTickRadius = centerX; 
      for (int tickIndex = 0; tickIndex < 12; tickIndex++) { 
       float tickRot = (float) (tickIndex * Math.PI * 2/12); 
       float innerX = (float) Math.sin(tickRot) * innerTickRadius; 
       float innerY = (float) -Math.cos(tickRot) * innerTickRadius; 
       float outerX = (float) Math.sin(tickRot) * outerTickRadius; 
       float outerY = (float) -Math.cos(tickRot) * outerTickRadius; 
       canvas.drawLine(centerX + innerX, centerY + innerY, 
         centerX + outerX, centerY + outerY, mTickPaint); 
      } 

      float secRot = mTime.second/30f * (float) Math.PI; 
      int minutes = mTime.minute; 
      float minRot = minutes/30f * (float) Math.PI; 
      float hrRot = ((mTime.hour + (minutes/60f))/6f) * (float) Math.PI; 

      float secLength = centerX - 20; 
      float minLength = centerX - 40; 
      float hrLength = centerX - 80; 

      if (!isInAmbientMode()) { 
       float secX = (float) Math.sin(secRot) * secLength; 
       float secY = (float) -Math.cos(secRot) * secLength; 
       canvas.drawLine(centerX, centerY, centerX + secX, centerY + secY, mSecondPaint); 
      } 

      float minX = (float) Math.sin(minRot) * minLength; 
      float minY = (float) -Math.cos(minRot) * minLength; 
      canvas.drawLine(centerX, centerY, centerX + minX, centerY + minY, mMinutePaint); 

      float hrX = (float) Math.sin(hrRot) * hrLength; 
      float hrY = (float) -Math.cos(hrRot) * hrLength; 
      canvas.drawLine(centerX, centerY, centerX + hrX, centerY + hrY, mHourPaint); 
     } 

     @Override 
     public void onVisibilityChanged(boolean visible) { 
      super.onVisibilityChanged(visible); 
      if (Log.isLoggable(TAG, Log.DEBUG)) { 
       Log.d(TAG, "onVisibilityChanged: " + visible); 
      } 

      if (visible) { 
       registerReceiver(); 

       // Update time zone in case it changed while we weren't visible. 
       mTime.clear(TimeZone.getDefault().getID()); 
       mTime.setToNow(); 
      } else { 
       unregisterReceiver(); 
      } 

      // Whether the timer should be running depends on whether we're visible (as well as 
      // whether we're in ambient mode), so we may need to start or stop the timer. 
      updateTimer(); 
     } 

     private void registerReceiver() { 
      if (mRegisteredTimeZoneReceiver) { 
       return; 
      } 
      mRegisteredTimeZoneReceiver = true; 
      IntentFilter filter = new IntentFilter(Intent.ACTION_TIMEZONE_CHANGED); 
      AnalogWatchFaceService.this.registerReceiver(mTimeZoneReceiver, filter); 
     } 

     private void unregisterReceiver() { 
      if (!mRegisteredTimeZoneReceiver) { 
       return; 
      } 
      mRegisteredTimeZoneReceiver = false; 
      AnalogWatchFaceService.this.unregisterReceiver(mTimeZoneReceiver); 
     } 

     /** 
     * Starts the {@link #mUpdateTimeHandler} timer if it should be running and isn't currently 
     * or stops it if it shouldn't be running but currently is. 
     */ 
     private void updateTimer() { 
      if (Log.isLoggable(TAG, Log.DEBUG)) { 
       Log.d(TAG, "updateTimer"); 
      } 
      mUpdateTimeHandler.removeMessages(MSG_UPDATE_TIME); 
      if (shouldTimerBeRunning()) { 
       mUpdateTimeHandler.sendEmptyMessage(MSG_UPDATE_TIME); 
      } 
     } 

     /** 
     * Returns whether the {@link #mUpdateTimeHandler} timer should be running. The timer should 
     * only run when we're visible and in interactive mode. 
     */ 
     private boolean shouldTimerBeRunning() { 
      return isVisible() && !isInAmbientMode() && false; 
     } 

    } 
} 

ответ

8

onTimeTick будет доставлен Вам в режиме окружающей среды. Посмотрите на обращения WatchFaceService:

 Called periodically in ambient mode to update the time shown by the watch face. This 
    method is called at least once per minute. 

В интерактивном режиме вам нужно реализовать свой собственный механизм.

+0

Спасибо! Я скучаю по этому! – jaumard

+2

Спасибо - это может быть намного более ясным в документах. В документе «Чертеж смотреть лица» он просто говорит: «Система вызывает метод Engine.onTimeTick() каждую минуту». Нет никакого упоминания, что это происходит только в окружающем режиме. – String

+4

Мы исправим его в следующем выпуске и сделаем его более надежным. – gruszczy

Смежные вопросы