2015-06-05 3 views
1

Я посмотрел несколько мест, в том числе здесь, и ответы, которые я нашел, не помогли. Я также просмотрел код шаблона, который я использую, и не видел, где я ошибся, поэтому мне жаль, если это кажется плохим вопросом. Но я делаю сторожевое лицо, и я пытаюсь расширить его от моего Engine, WeatherWatchFaceEngine. Но когда я это делаю, я получаю ошибку, которая находится в названии этого вопроса. Что я сделал не так?Нет конструктора по умолчанию, доступного в com.marlonjones.nimbus.WeatherWatchFaceService.WeatherWatchFaceEngine

Это код циферблата:

public class NimbusSplashAnalog extends WeatherWatchFaceService { 
/** 
* 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); 

/** 
* Handler message id for updating the time periodically in interactive mode. 
*/ 
private static final int MSG_UPDATE_TIME = 0; 

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

private class Engine extends WeatherWatchFaceEngine { 
    Paint mBackgroundPaint; 
    Paint mHandPaint; 
    boolean mAmbient; 
    Time mTime; 

    final Handler mUpdateTimeHandler = new EngineHandler(this); 

    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; 

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

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

     Resources resources = NimbusSplashAnalog.this.getResources(); 

     mBackgroundPaint = new Paint(); 
     mBackgroundPaint.setColor(resources.getColor(R.color.analog_background)); 

     mHandPaint = new Paint(); 
     mHandPaint.setColor(resources.getColor(R.color.analog_hands)); 
     mHandPaint.setStrokeWidth(resources.getDimension(R.dimen.analog_hand_stroke)); 
     mHandPaint.setAntiAlias(true); 
     mHandPaint.setStrokeCap(Paint.Cap.ROUND); 

     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); 
    } 

    @Override 
    public void onTimeTick() { 
     super.onTimeTick(); 
     invalidate(); 
    } 

    @Override 
    public void onAmbientModeChanged(boolean inAmbientMode) { 
     super.onAmbientModeChanged(inAmbientMode); 
     if (mAmbient != inAmbientMode) { 
      mAmbient = inAmbientMode; 
      if (mLowBitAmbient) { 
       mHandPaint.setAntiAlias(!inAmbientMode); 
      } 
      invalidate(); 
     } 

     // 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(); 
    } 

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

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

     // Draw the background. 
     canvas.drawRect(0, 0, canvas.getWidth(), canvas.getHeight(), mBackgroundPaint); 

     // 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; 

     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 (!mAmbient) { 
      float secX = (float) Math.sin(secRot) * secLength; 
      float secY = (float) -Math.cos(secRot) * secLength; 
      canvas.drawLine(centerX, centerY, centerX + secX, centerY + secY, mHandPaint); 
     } 

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

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


    @Override 
    public void onVisibilityChanged(boolean visible) { 
     super.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); 
     NimbusSplashAnalog.this.registerReceiver(mTimeZoneReceiver, filter); 
    } 

    private void unregisterReceiver() { 
     if (!mRegisteredTimeZoneReceiver) { 
      return; 
     } 
     mRegisteredTimeZoneReceiver = false; 
     NimbusSplashAnalog.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() { 
     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(); 
    } 

    /** 
    * Handle updating the time periodically in interactive mode. 
    */ 
    private void handleUpdateTimeMessage() { 
     invalidate(); 
     if (shouldTimerBeRunning()) { 
      long timeMs = System.currentTimeMillis(); 
      long delayMs = INTERACTIVE_UPDATE_RATE_MS 
        - (timeMs % INTERACTIVE_UPDATE_RATE_MS); 
      mUpdateTimeHandler.sendEmptyMessageDelayed(MSG_UPDATE_TIME, delayMs); 
     } 
    } 
} 

private static class EngineHandler extends Handler { 
    private final WeakReference<NimbusSplashAnalog.Engine> mWeakReference; 

    public EngineHandler(NimbusSplashAnalog.Engine reference) { 
     mWeakReference = new WeakReference<>(reference); 
    } 

    @Override 
    public void handleMessage(Message msg) { 
     NimbusSplashAnalog.Engine engine = mWeakReference.get(); 
     if (engine != null) { 
      switch (msg.what) { 
       case MSG_UPDATE_TIME: 
        engine.handleUpdateTimeMessage(); 
        break; 
      } 
     } 
    } 
} 

}

Это код двигателя/услуг, что я простирающийся от:

public abstract class WeatherWatchFaceService extends CanvasWatchFaceService { 
public class WeatherWatchFaceEngine extends CanvasWatchFaceService.Engine 
     implements 
     GoogleApiClient.ConnectionCallbacks, 
     GoogleApiClient.OnConnectionFailedListener, 
     DataApi.DataListener, NodeApi.NodeListener { 

    protected static final int MSG_UPDATE_TIME = 0; 
    protected long UPDATE_RATE_MS; 
    protected static final long WEATHER_INFO_TIME_OUT = DateUtils.HOUR_IN_MILLIS * 6; 
    protected final BroadcastReceiver mTimeZoneReceiver = new BroadcastReceiver() { 
     @Override 
     public void onReceive(Context context, Intent intent) { 
      //Time zone changed 
      mWeatherInfoReceivedTime = 0; 
      mTime.clear(intent.getStringExtra("time-zone")); 
      mTime.setToNow(); 
     } 
    }; 
    /** 
    * Handler to update the time periodically in interactive mode. 
    */ 
    protected final Handler mUpdateTimeHandler = new Handler() { 
     @Override 
     public void handleMessage(Message message) { 
      switch (message.what) { 
       case MSG_UPDATE_TIME: 
        invalidate(); 

        if (shouldUpdateTimerBeRunning()) { 
         long timeMs = System.currentTimeMillis(); 
         long delayMs = UPDATE_RATE_MS - (timeMs % UPDATE_RATE_MS); 
         mUpdateTimeHandler.sendEmptyMessageDelayed(MSG_UPDATE_TIME, delayMs); 
         requireWeatherInfo(); 
        } 
        break; 
      } 
     } 
    }; 
    protected int mTheme = 3; 
    protected int mTimeUnit = ConverterUtil.TIME_UNIT_12; 
    protected AssetManager mAsserts; 
    protected Bitmap mWeatherConditionDrawable; 
    protected GoogleApiClient mGoogleApiClient; 
    protected Paint mBackgroundPaint; 
    protected Paint mDatePaint; 
    protected Paint mDateSuffixPaint; 
    protected Paint mDebugInfoPaint; 
    protected Paint mTemperatureBorderPaint; 
    protected Paint mTemperaturePaint; 
    protected Paint mTemperatureSuffixPaint; 
    protected Paint mTimePaint; 
    protected Resources mResources; 
    protected String mWeatherCondition; 
    protected String mWeatherConditionResourceName; 
    protected Time mSunriseTime; 
    protected Time mSunsetTime; 
    protected Time mTime; 
    protected boolean isRound; 
    protected boolean mLowBitAmbient; 
    protected boolean mRegisteredService = false; 

    protected int mBackgroundColor; 
    protected int mBackgroundDefaultColor; 
    protected int mRequireInterval; 
    protected int mTemperature = Integer.MAX_VALUE; 
    protected int mTemperatureScale; 
    protected long mWeatherInfoReceivedTime; 
    protected long mWeatherInfoRequiredTime; 
    private String mName; 

    public WeatherWatchFaceEngine(String name) { 
     mName = name; 
     mGoogleApiClient = new GoogleApiClient.Builder(WeatherWatchFaceService.this) 
       .addConnectionCallbacks(this) 
       .addOnConnectionFailedListener(this) 
       .addApi(Wearable.API) 
       .build(); 
    } 

    @Override 
    public void onConnected(Bundle bundle) { 
     log("Connected: " + bundle); 
     getConfig(); 

     Wearable.NodeApi.addListener(mGoogleApiClient, this); 
     Wearable.DataApi.addListener(mGoogleApiClient, this); 
     requireWeatherInfo(); 
    } 

    @Override 
    public void onConnectionSuspended(int i) { 
     log("ConnectionSuspended: " + i); 
    } 

    @Override 
    public void onDataChanged(DataEventBuffer dataEvents) { 
     for (int i = 0; i < dataEvents.getCount(); i++) { 
      DataEvent event = dataEvents.get(i); 
      DataMap dataMap = DataMap.fromByteArray(event.getDataItem().getData()); 
      log("onDataChanged: " + dataMap); 

      fetchConfig(dataMap); 
     } 
    } 

    @Override 
    public void onPeerConnected(Node node) { 
     log("PeerConnected: " + node); 
     requireWeatherInfo(); 
    } 

    @Override 
    public void onPeerDisconnected(Node node) { 
     log("PeerDisconnected: " + node); 
    } 

    @Override 
    public void onConnectionFailed(ConnectionResult connectionResult) { 
     log("ConnectionFailed: " + connectionResult); 

    } 


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

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

     mResources = WeatherWatchFaceService.this.getResources(); 
     mAsserts = WeatherWatchFaceService.this.getAssets(); 

     mDebugInfoPaint = new Paint(); 
     mDebugInfoPaint.setColor(Color.parseColor("White")); 
     mDebugInfoPaint.setTextSize(20); 
     mDebugInfoPaint.setAntiAlias(true); 

     mTime = new Time(); 
     mSunriseTime = new Time(); 
     mSunsetTime = new Time(); 

     mRequireInterval = mResources.getInteger(R.integer.weather_default_require_interval); 
     mWeatherInfoRequiredTime = System.currentTimeMillis() - (DateUtils.SECOND_IN_MILLIS * 58); 
     mGoogleApiClient.connect(); 
    } 

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

    @Override 
    public void onInterruptionFilterChanged(int interruptionFilter) { 
     super.onInterruptionFilterChanged(interruptionFilter); 

     log("onInterruptionFilterChanged: " + interruptionFilter); 
    } 

    @Override 
    public void onPropertiesChanged(Bundle properties) { 
     super.onPropertiesChanged(properties); 
     mLowBitAmbient = properties.getBoolean(WatchFaceService.PROPERTY_LOW_BIT_AMBIENT, false); 

     log("onPropertiesChanged: LowBitAmbient=" + mLowBitAmbient); 
    } 

    @Override 
    public void onTimeTick() { 
     super.onTimeTick(); 
     log("TimeTick"); 
     invalidate(); 
     requireWeatherInfo(); 
    } 

    @Override 
    public void onVisibilityChanged(boolean visible) { 
     super.onVisibilityChanged(visible); 
     log("onVisibilityChanged: " + visible); 

     if (visible) { 
      mGoogleApiClient.connect(); 
      registerTimeZoneService(); 

      // Update time zone in case it changed while we weren't visible. 
      mTime.clear(TimeZone.getDefault().getID()); 
      mTime.setToNow(); 
     } else { 
      if (mGoogleApiClient != null && mGoogleApiClient.isConnected()) { 
       Wearable.DataApi.removeListener(mGoogleApiClient, this); 
       Wearable.NodeApi.removeListener(mGoogleApiClient, this); 
       mGoogleApiClient.disconnect(); 
      } 

      unregisterTimeZoneService(); 
     } 

     // 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(); 
    } 

    protected Paint createTextPaint(int color, Typeface typeface) { 
     Paint paint = new Paint(); 
     paint.setColor(color); 
     if (typeface != null) 
      paint.setTypeface(typeface); 
     paint.setAntiAlias(true); 
     return paint; 
    } 

    protected boolean shouldUpdateTimerBeRunning() { 
     return isVisible() && !isInAmbientMode(); 
    } 

    protected void fetchConfig(DataMap config) { 
     if (config.containsKey(Consts.KEY_WEATHER_UPDATE_TIME)) { 
      mWeatherInfoReceivedTime = config.getLong(Consts.KEY_WEATHER_UPDATE_TIME); 
     } 

     if (config.containsKey(Consts.KEY_WEATHER_CONDITION)) { 
      String cond = config.getString(Consts.KEY_WEATHER_CONDITION); 
      if (TextUtils.isEmpty(cond)) { 
       mWeatherCondition = null; 
      } else { 
       mWeatherCondition = cond; 
      } 
     } 

     if (config.containsKey(Consts.KEY_WEATHER_TEMPERATURE)) { 
      mTemperature = config.getInt(Consts.KEY_WEATHER_TEMPERATURE); 
      if (mTemperatureScale != ConverterUtil.FAHRENHEIT) { 
       mTemperature = ConverterUtil.convertFahrenheitToCelsius(mTemperature); 
      } 
     } 

     if (config.containsKey(Consts.KEY_WEATHER_SUNRISE)) { 
      mSunriseTime.set(config.getLong(Consts.KEY_WEATHER_SUNRISE) * 1000); 
      log("SunriseTime: " + mSunriseTime); 
     } 

     if (config.containsKey(Consts.KEY_WEATHER_SUNSET)) { 
      mSunsetTime.set(config.getLong(Consts.KEY_WEATHER_SUNSET) * 1000); 
      log("SunsetTime: " + mSunsetTime); 
     } 

     if (config.containsKey(Consts.KEY_CONFIG_TEMPERATURE_SCALE)) { 
      int scale = config.getInt(Consts.KEY_CONFIG_TEMPERATURE_SCALE); 

      if (scale != mTemperatureScale) { 
       if (scale == ConverterUtil.FAHRENHEIT) { 
        mTemperature = ConverterUtil.convertCelsiusToFahrenheit(mTemperature); 
       } else { 
        mTemperature = ConverterUtil.convertFahrenheitToCelsius(mTemperature); 
       } 
      } 

      mTemperatureScale = scale; 
     } 

     if (config.containsKey(Consts.KEY_CONFIG_THEME)) { 
      mTheme = config.getInt(Consts.KEY_CONFIG_THEME); 
     } 

     if (config.containsKey(Consts.KEY_CONFIG_TIME_UNIT)) { 
      mTimeUnit = config.getInt(Consts.KEY_CONFIG_TIME_UNIT); 
     } 

     if (config.containsKey(Consts.KEY_CONFIG_REQUIRE_INTERVAL)) { 
      mRequireInterval = config.getInt(Consts.KEY_CONFIG_REQUIRE_INTERVAL); 
     } 

     invalidate(); 
    } 

    protected void getConfig() { 
     log("Start getting Config"); 
     Wearable.NodeApi.getLocalNode(mGoogleApiClient).setResultCallback(new ResultCallback<NodeApi.GetLocalNodeResult>() { 
      @Override 
      public void onResult(NodeApi.GetLocalNodeResult getLocalNodeResult) { 
       Uri uri = new Uri.Builder() 
         .scheme("wear") 
         .path(Consts.PATH_CONFIG + mName) 
         .authority(getLocalNodeResult.getNode().getId()) 
         .build(); 

       getConfig(uri); 

       uri = new Uri.Builder() 
         .scheme("wear") 
         .path(Consts.PATH_WEATHER_INFO) 
         .authority(getLocalNodeResult.getNode().getId()) 
         .build(); 

       getConfig(uri); 
      } 
     }); 
    } 

    protected void getConfig(Uri uri) { 

     Wearable.DataApi.getDataItem(mGoogleApiClient, uri) 
       .setResultCallback(
         new ResultCallback<DataApi.DataItemResult>() { 
          @Override 
          public void onResult(DataApi.DataItemResult dataItemResult) { 
           log("Finish Config: " + dataItemResult.getStatus()); 
           if (dataItemResult.getStatus().isSuccess() && dataItemResult.getDataItem() != null) { 
            fetchConfig(DataMapItem.fromDataItem(dataItemResult.getDataItem()).getDataMap()); 
           } 
          } 
         } 
       ); 
    } 

    protected void log(String message) { 
     Log.d(WeatherWatchFaceService.this.getClass().getSimpleName(), message); 
    } 

    protected void registerTimeZoneService() { 
     //TimeZone 
     if (mRegisteredService) { 
      return; 
     } 

     mRegisteredService = true; 

     // TimeZone 
     IntentFilter filter = new IntentFilter(Intent.ACTION_TIMEZONE_CHANGED); 
     WeatherWatchFaceService.this.registerReceiver(mTimeZoneReceiver, filter); 
    } 

    protected void requireWeatherInfo() { 
     if (!mGoogleApiClient.isConnected()) 
      return; 

     long timeMs = System.currentTimeMillis(); 

     // The weather info is still up to date. 
     if ((timeMs - mWeatherInfoReceivedTime) <= mRequireInterval) 
      return; 

     // Try once in a min. 
     if ((timeMs - mWeatherInfoRequiredTime) <= DateUtils.MINUTE_IN_MILLIS) 
      return; 

     mWeatherInfoRequiredTime = timeMs; 
     Wearable.MessageApi.sendMessage(mGoogleApiClient, "", Consts.PATH_WEATHER_REQUIRE, null) 
       .setResultCallback(new ResultCallback<MessageApi.SendMessageResult>() { 
        @Override 
        public void onResult(MessageApi.SendMessageResult sendMessageResult) { 
         log("SendRequireMessage:" + sendMessageResult.getStatus()); 
        } 
       }); 
    } 

    protected void unregisterTimeZoneService() { 
     if (!mRegisteredService) { 
      return; 
     } 
     mRegisteredService = false; 

     //TimeZone 
     WeatherWatchFaceService.this.unregisterReceiver(mTimeZoneReceiver); 
    } 

    protected void updateTimer() { 
     mUpdateTimeHandler.removeMessages(MSG_UPDATE_TIME); 
     if (shouldUpdateTimerBeRunning()) { 
      mUpdateTimeHandler.sendEmptyMessage(MSG_UPDATE_TIME); 
     } 
    } 
} 

}

Любая помощь была бы высоко оценена :) (Это также мое первое в реальном времени изготовление часов fa ce, поэтому, пожалуйста, простите меня)

+0

Есть ли что-нибудь еще мне нужно добавить к этому? Или просто введите код точно так же, как и у вас? (Не могу поместить его прямо сейчас, так как я не рядом с моим ПК, но я прокомментирую, если он будет работать) – MJonesDev

ответ

0

Конструктор по умолчанию принимает нулевые аргументы. У вас есть только конструктор с одним аргументом в WeatherWatchFaceEngine.

Добавить нулевой аргумент конструктора к WeatherWatchFaceEngine, чей signiture будет public WeatherWatchFaceEngine(){...}

+0

Реализация зависит от того, что вам нужно делать. – akodiakson

+0

Просто FYI: когда конструкторы не объявлены, подразумевается конструктор по умолчанию. – akodiakson

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