1

Ich versuche, einen AlarmManager hinzuzufügen, um ein Zifferblatt in Intervallen von einer halben Minute zu aktualisieren. Dies ist für eine ternäre Uhr. Dies ist meine erste Programmierung mit Java oder Android Studio.Wo kann der Alarmmanager zum Aktualisieren einer Uhr im Umgebungsmodus deklariert werden?

Ich folge eine Führung bei https://developer.android.com/training/wearables/apps/always-on.html

Der Führer sagt „erklärt die Alarmmanager und die anstehende Absicht in der onCreate() -Methode Ihre Aktivität“

Soll ich

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

oder

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

oder soll ich anfangen eine neue Methode oder an anderer Stelle deklarieren?

Derzeit verwende ich

private class Engine extends CanvasWatchFaceService.Engine { 
    final Handler mUpdateTimeHandler = new EngineHandler(this); 

für die meisten meiner Initialisierung.

Dies ist mein Code ohne den Alarmmanager. Das Problem ist, dass es während einer halben Minute aktualisiert werden muss, da die Zeit als ausgeglichenes ternäres auf die nächste Minute eingestellt sein sollte.

public class ternary extends CanvasWatchFaceService { 
private static final Typeface NORMAL_TYPEFACE = 
     Typeface.create(Typeface.SANS_SERIF, Typeface.NORMAL); 

private static final int MSG_UPDATE_TIME = 0; 

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

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

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

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

private class Engine extends CanvasWatchFaceService.Engine { 
    final Handler mUpdateTimeHandler = new EngineHandler(this); 
    boolean mRegisteredTimeZoneReceiver = false; 
    Paint mBackgroundPaint; 
    Paint mTextPaint; 
    boolean mAmbient; 
    Time mTime; 
    final BroadcastReceiver mTimeZoneReceiver = new BroadcastReceiver() { 
     @Override 
     public void onReceive(Context context, Intent intent) { 
      mTime.clear(intent.getStringExtra("time-zone")); 
      mTime.setToNow(); 
     } 
    }; 
    int mTapCount; 

    float mXOffset; 
    float mYOffset; 

    // adjust text size 
    float textRatio = (float)1; // 2/3; 

    // make adjusted offset for hours 
    float hrsIndent; 
    float hrsIndentAdjust = textRatio * 55; 

    // vertical offset for multiple lines 
    float ySpacer = textRatio * 65; 

    // first run. 
    boolean yesFirstRun = true; 
    // flag for seconds 
    boolean yesSecs; 
    // prior state of yesSecs 
    boolean wasSecs = true; 
    // flag for conservation mode (no seconds in ambient) 
    boolean yesConcerve = false; 
    // flag for allowing seconds 
    boolean allowSecs = true; 
    // for execution control 
    boolean openGate = false; 

    // counter for next draw 
    int c = 0; 
    // counter for time loops 
    int k; 
    boolean drawNow = true; 
    // strings for draw 
    String hrs = ""; 
    String mns = ""; 
    String sks = ""; 
    // register for milliseconds 
    long millis = 0; 
    // float for calculating trits from time. 
    float tim = 0; 
    // ints for minute and hour offsets. 
    int minInt = 0; 
    int hourInt = 0; 

    // lists for time to trit for loop conversions. 
    int [] trits3 = {9, 3, 1}; 
    int [] trits4 = {27, 9, 3, 1}; 

    // absolute count for trouble shooting 
    // long x = 0; 

    /** 
    * 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(ternary.this) 
       .setCardPeekMode(WatchFaceStyle.PEEK_MODE_VARIABLE) 
       .setBackgroundVisibility(WatchFaceStyle.BACKGROUND_VISIBILITY_INTERRUPTIVE) 
       .setShowSystemUiTime(false) 
       .setAcceptsTapEvents(true) 
       .build()); 
     Resources resources = ternary.this.getResources(); 

     // shift y offset up 
     mYOffset = -30 + resources.getDimension(R.dimen.digital_y_offset); 

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

     mTextPaint = new Paint(); 
     mTextPaint = createTextPaint(resources.getColor(R.color.digital_text)); 

     mTime = new Time(); 
    } 

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

    private Paint createTextPaint(int textColor) { 
     Paint paint = new Paint(); 
     paint.setColor(textColor); 
     paint.setTypeface(NORMAL_TYPEFACE); 
     paint.setAntiAlias(true); 
     return paint; 
    } 

    @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); 
     ternary.this.registerReceiver(mTimeZoneReceiver, filter); 
    } 

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

    @Override 
    public void onApplyWindowInsets(WindowInsets insets) { 
     super.onApplyWindowInsets(insets); 

     // Load resources that have alternate values for round watches. 
     Resources resources = ternary.this.getResources(); 
     boolean isRound = insets.isRound(); 

     // shift offset 75 to the right 
     mXOffset = 75 + resources.getDimension(isRound 
       ? R.dimen.digital_x_offset_round : R.dimen.digital_x_offset); 
     float textSize = resources.getDimension(isRound 
       ? R.dimen.digital_text_size_round : R.dimen.digital_text_size); 

     // adjust hrs Indent to MXOffset 
     hrsIndent = hrsIndentAdjust + mXOffset; 

     // adjust size to textRatio 
     mTextPaint.setTextSize(textSize * textRatio); 
    } 

    @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) { 
       mTextPaint.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(); 
    } 

    /** 
    * Captures tap event (and tap type) and toggles the background color if the user finishes 
    * a tap. 
    */ 
    @Override 
    public void onTapCommand(int tapType, int x, int y, long eventTime) { 
     Resources resources = ternary.this.getResources(); 
     switch (tapType) { 
      case TAP_TYPE_TOUCH: 
       // The user has started touching the screen. 
       break; 
      case TAP_TYPE_TOUCH_CANCEL: 
       // The user has started a different gesture or otherwise cancelled the tap. 
       break; 
      case TAP_TYPE_TAP: 
       // The user has completed the tap gesture. 
       mTapCount++; 
       mBackgroundPaint.setColor(resources.getColor(mTapCount % 2 == 0 ? 
         R.color.background : R.color.background2)); 
       break; 
     } 
     invalidate(); 
    } 

    @Override 
    public void onDraw(Canvas canvas, Rect bounds) { 
     // Greebo counter 
     // x += 1; 

     // seconds handling 
     wasSecs = yesSecs; 
     yesSecs = allowSecs && !isInAmbientMode(); 
     // for clearing seconds 
     if (!yesSecs && wasSecs) { sks = ""; } 

     // Draw at mid second 
     if (c == 0 && yesSecs) { 
      drawNow = true; 
     } else { 
      c = 0; 
      // mid minute 
      if (mTime.second == 30 || isInAmbientMode()) { 
       drawNow = true; 
      } else { 
       // mid hour 
       if (mTime.second == 0) { 
        if (mTime.minute == 30) { 
         drawNow = true; 
        } else { 
         // mid night 
         if (mTime.minute == 0) { 
          if (mTime.hour == 0) { 
           drawNow = true; 
          } 
         } 
        } 
       } 
      } 
     } 

     if (drawNow) { 
      drawNow = false; 

      mTime.setToNow(); 
      millis = System.currentTimeMillis() % 1000; 

      // mid seconds 
      if (yesSecs) { if (millis > 499) { c = 1; } } 

      tim = (float)((mTime.minute * 60 + mTime.second) * 1000 + millis)/ 3600000; 
      // hours past noon 
      tim += mTime.hour - 12; 

      // find hrs 9s, 3s, 1s. 
      openGate = false; 
      if (yesFirstRun || mTime.minute == 30){ openGate = true; } 
      else { openGate = mTime.second == 0 && mTime.minute == 0 && mTime.hour == 0;} 
      if (openGate) { 
       hrs = ""; 
       hourInt = 0; 
       // i is for item. 
       for (int i : trits3) { 
        if (tim > ((float) i/2)) { 
         tim -= i; 
         hourInt -= i; 
         hrs = hrs + "1"; 
        } else { 
         if (tim < ((float) i/-2)) { 
          tim += i; 
          hourInt += i; 
          hrs = hrs + "¬"; 
         } else { 
          hrs = hrs + "0"; 
         } 
        } 
        // add space 
        if (i > 1) {hrs += " "; } 
       } 
      } else { tim += hourInt; } 

      // minutes 27s, 9s, 3s, 1s 
      openGate = false; 
      if (yesFirstRun || mTime.second == 30 || isInAmbientMode()) {openGate = true; } 
      else { openGate = mTime.second == 0 && (mTime.minute == 30 
        || (mTime.minute == 0 && mTime.hour == 0));} 
      if (openGate) { 
       mns = ""; 
       tim *= 60; 
       minInt = 0; 
       // i is for item. 
       for (int i : trits4) { 
        if (tim > ((float) i/2)) { 
         tim -= i; 
         if (yesSecs) {minInt -= i;} 
         mns = mns + "1"; 
        } else { 
         if (tim < ((float) i/-2)) { 
          tim += i; 
          if (yesSecs) {minInt += i;} 
          mns = mns + "¬"; 
         } else { 
          mns = mns + "0"; 
         } 
        } 
        // add space 
        if (i > 1) {mns += " "; } 
       } 
      } else { if (yesSecs) { tim += minInt; tim *= 60; } } 

      // seconds 27s, 9s, 3s, 1s 
      if (yesSecs) { 
       sks = ""; 
       tim *= 60; 
       for (int i : trits4) { 
        if (tim > ((float) i/2)) { 
         tim -= i; 
         sks = sks + "1"; 
        } else { 
         if (tim < ((float) i/-2)) { 
          tim += i; 
          sks = sks + "¬"; 
         } else { 
          sks = sks + "0"; 
         } 
        } 
        // add space 
        if (i > 1) {sks += " "; } 
       } 
      } 
     } 

     // Draw the background. 
     if (isInAmbientMode()) { 
      canvas.drawColor(Color.BLACK); 
     } else { 
      canvas.drawRect(0, 0, bounds.width(), bounds.height(), mBackgroundPaint); 
     } 

     // draw hours 
     canvas.drawText(hrs, hrsIndent, mYOffset - ySpacer, mTextPaint); 
     // draw minutes 
     canvas.drawText(mns, mXOffset, mYOffset, mTextPaint); 
     // draw or clear seconds 
     if (yesSecs || wasSecs) {canvas.drawText(sks, mXOffset, mYOffset + ySpacer , mTextPaint);} 

     // show count and millis for greebo reduction. 
     // canvas.drawText(String.format("%1$03d,%2$02d,%3$d", x % 1000, millis/10, 0), mXOffset, mYOffset + 100, mTextPaint); 
     //canvas.drawText(String.format("%$02d:%2$02d:%3$02d", mTime.hour, mTime.minute, 
     //  mTime.second), mXOffset, mYOffset + 100, mTextPaint); 

    } 


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

}

Antwort

0

Die "onCreate()" Methode mit zu korrelieren scheint:

public class ternären erweitert CanvasWatchFaceService

Ihre Erklärung sollte wie folgt lauten:

public class ternary extends CanvasWatchFaceService { 
    private AlarmManager mAmbientStateAlarmManager; 
    private PendingIntent mAmbientStatePendingIntent; 

Und sicher sein, android.app.AlarmManager und android.ap zu importieren p.PendingIntent .