正在更新 Android 在显示屏打开之前佩戴表盘
Updating Android Wear watchface BEFORE display turns on
我制作的表盘在加载到我的 phone、选择和在我的 MOTO 360 上 运行 时工作正常,但我遇到问题的地方是屏幕关闭,我触摸屏幕,它出现了,但手(位图)在正确的时间旋转。看起来当屏幕关闭时它不再更新。我正在使用一个计时器例程,如果 isVisible() 和 !isInAmbientMode 从 30ms 交互时仅更改为 1 秒更新并触发 invalidate()。
注意:我尝试在所有这些例程中添加 invalidate() 但它没有帮助。
相关代码如下:
// 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();
}
当环境模式处于活动状态时,系统会尝试尽可能多地保存电池并使设备进入深度睡眠,在此期间,处理程序不会 运行。在大多数情况下,对于表盘,当它处于深度睡眠状态时,您不需要每分钟更新一次以上的表盘,因此您可以使用 WatchFaceService.Engine.onTimeTick() 在该状态下每分钟收到一次通知(或当时区更改或日期更改等时),请参阅文档了解详细信息。不推荐任何更频繁的操作,但可以使用 AlarmManager 来实现。
我找到了解决此问题的方法,因此我不必使用警报。我覆盖 onVisiblityChanged 并放置一个布尔标志。在 onDraw 中,我只是将 canvas 涂成黑色。这样当设备被唤醒时,它是黑色的,直到下一轮 onDraw 屏幕已经处于活动状态时。看起来效果不错!
@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);
}
...
}
我制作的表盘在加载到我的 phone、选择和在我的 MOTO 360 上 运行 时工作正常,但我遇到问题的地方是屏幕关闭,我触摸屏幕,它出现了,但手(位图)在正确的时间旋转。看起来当屏幕关闭时它不再更新。我正在使用一个计时器例程,如果 isVisible() 和 !isInAmbientMode 从 30ms 交互时仅更改为 1 秒更新并触发 invalidate()。
注意:我尝试在所有这些例程中添加 invalidate() 但它没有帮助。
相关代码如下:
// 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();
}
当环境模式处于活动状态时,系统会尝试尽可能多地保存电池并使设备进入深度睡眠,在此期间,处理程序不会 运行。在大多数情况下,对于表盘,当它处于深度睡眠状态时,您不需要每分钟更新一次以上的表盘,因此您可以使用 WatchFaceService.Engine.onTimeTick() 在该状态下每分钟收到一次通知(或当时区更改或日期更改等时),请参阅文档了解详细信息。不推荐任何更频繁的操作,但可以使用 AlarmManager 来实现。
我找到了解决此问题的方法,因此我不必使用警报。我覆盖 onVisiblityChanged 并放置一个布尔标志。在 onDraw 中,我只是将 canvas 涂成黑色。这样当设备被唤醒时,它是黑色的,直到下一轮 onDraw 屏幕已经处于活动状态时。看起来效果不错!
@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);
}
...
}