Ambient/Blackscreen 的频繁可穿戴振动
Frequent Wearable Vibrations with Ambient/Blackscreen
我正在尝试为模拟您的心跳的智能手表编写一个应用程序,因此它需要能够以 1 秒到大约 0.5-0.3 秒的时间间隔振动,持续时间为 75 毫秒。
当应用程序进入环境模式或开始进入全黑屏时,也需要这样做。我不关心功耗或其他什么,它应该能够 运行 大约 20-30 分钟,没有别的。
在我开发的moto360上,微光模式会变成全黑屏,如果你不把手表放在一定的位置,一进入黑屏,振动就会停止,所以我需要一个也适用于黑屏的解决方案,除非有办法停止手表,进入黑屏,我不知道。
当只处理 onEnterAmbient 等事件时,手表停止振动,当您由于进入黑屏而没有将其保持在正确的角度时,并且振动并不总是一致的,因为必须调用vibrator.vibrate() 方法在 entering/updating 等上再次出现,因此它通常会导致振动模式出现小的不一致,应该避免这种情况。所以我认为使用环境模式的方法是行不通的。
这是之前的代码:
[...]
private long[] vibrationPattern_StandardPulse = {0, 75, 1000};
private long[] vibrationPattern_AcceleratedPulse = {0, 75, 600};
[...]
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
setAmbientEnabled();
mContainerView = (BoxInsetLayout) findViewById(R.id.container);
vibrator = (Vibrator) getSystemService(VIBRATOR_SERVICE);
[...]
@Override
public void onEnterAmbient(Bundle ambientDetails) {
super.onEnterAmbient(ambientDetails);
keepVibrating();
}
@Override
public void onUpdateAmbient() {
super.onUpdateAmbient();
keepVibrating();
}
@Override
public void onExitAmbient() {
super.onExitAmbient();
keepVibrating();
[...]
public void keepVibrating() {
if (standardPulse) {
vibrator.vibrate(vibrationPattern_StandardPulse, 0);
} else {
vibrator.vibrate(vibrationPattern_AcceleratedPulse, 0);
}
}
[...]
所以我用 alarmmanager 再次尝试,(坚持这个 link:https://developer.android.com/training/wearables/apps/always-on.html#UpdateContent)以便在黑屏时也能发送振动,但事实证明, alarmmanager 不能设置这么小的间隔?无论是在黑屏、正常还是环境模式下,它每 5 秒左右振动一次,应该是 1 秒或更短...
代码:
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
setAmbientEnabled();
mAmbientStateAlarmManager =
(AlarmManager) getSystemService(Context.ALARM_SERVICE);
Intent ambientStateIntent =
new Intent(getApplicationContext(), MainActivity.class);
mAmbientStatePendingIntent = PendingIntent.getActivity(
getApplicationContext(),
0,
ambientStateIntent,
PendingIntent.FLAG_UPDATE_CURRENT);
mContainerView = (BoxInsetLayout) findViewById(R.id.container);
//mClockView = (TextView) findViewById(R.id.clock);
vibrator = (Vibrator) getSystemService(VIBRATOR_SERVICE);
[...]}
@Override
public void onNewIntent(Intent intent) {
super.onNewIntent(intent);
setIntent(intent);
refreshDisplayAndSetNextUpdate();
}
private long AMBIENT_INTERVAL_MS = 0;
private void refreshDisplayAndSetNextUpdate() {
if (standardPulse) {
AMBIENT_INTERVAL_MS = 1000;
} else {
AMBIENT_INTERVAL_MS = 600;
}
if (isAmbient()) {
// Implement data retrieval and update the screen for ambient mode
vibrator.vibrate(75);
} else {
// Implement data retrieval and update the screen for interactive mode
vibrator.vibrate(75);
}
long timeMs = System.currentTimeMillis();
// Schedule a new alarm
if (isAmbient()) {
// Calculate the next trigger time
long triggerTimeMs = timeMs + AMBIENT_INTERVAL_MS;
mAmbientStateAlarmManager.setExact(
AlarmManager.RTC_WAKEUP,
triggerTimeMs,
mAmbientStatePendingIntent);
} else {
// Calculate the next trigger time for interactive mode
long triggerTimeMs = timeMs + AMBIENT_INTERVAL_MS;
mAmbientStateAlarmManager.setExact(
AlarmManager.RTC_WAKEUP,
triggerTimeMs,
mAmbientStatePendingIntent);
}
}
RefreshUpdateAndSetNextAlarm 然后也在 onEnterAmbient 事件等中被调用,但没有按预期工作。有没有办法在智能手表上做这些事情,尤其是在 Moto 360 上?
也许如果我通过 messageAPI 从智能手机不断发送消息并将它们设置为紧急?
解决方案是使用 CPU 唤醒锁:
PowerManager powerManager = (PowerManager) getSystemService(POWER_SERVICE);
PowerManager.WakeLock wakeLock = powerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK,
"MyWakelockTag");
wakeLock.acquire();
并且屏幕保持在标志上:
getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
我正在尝试为模拟您的心跳的智能手表编写一个应用程序,因此它需要能够以 1 秒到大约 0.5-0.3 秒的时间间隔振动,持续时间为 75 毫秒。
当应用程序进入环境模式或开始进入全黑屏时,也需要这样做。我不关心功耗或其他什么,它应该能够 运行 大约 20-30 分钟,没有别的。
在我开发的moto360上,微光模式会变成全黑屏,如果你不把手表放在一定的位置,一进入黑屏,振动就会停止,所以我需要一个也适用于黑屏的解决方案,除非有办法停止手表,进入黑屏,我不知道。
当只处理 onEnterAmbient 等事件时,手表停止振动,当您由于进入黑屏而没有将其保持在正确的角度时,并且振动并不总是一致的,因为必须调用vibrator.vibrate() 方法在 entering/updating 等上再次出现,因此它通常会导致振动模式出现小的不一致,应该避免这种情况。所以我认为使用环境模式的方法是行不通的。
这是之前的代码:
[...]
private long[] vibrationPattern_StandardPulse = {0, 75, 1000};
private long[] vibrationPattern_AcceleratedPulse = {0, 75, 600};
[...]
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
setAmbientEnabled();
mContainerView = (BoxInsetLayout) findViewById(R.id.container);
vibrator = (Vibrator) getSystemService(VIBRATOR_SERVICE);
[...]
@Override
public void onEnterAmbient(Bundle ambientDetails) {
super.onEnterAmbient(ambientDetails);
keepVibrating();
}
@Override
public void onUpdateAmbient() {
super.onUpdateAmbient();
keepVibrating();
}
@Override
public void onExitAmbient() {
super.onExitAmbient();
keepVibrating();
[...]
public void keepVibrating() {
if (standardPulse) {
vibrator.vibrate(vibrationPattern_StandardPulse, 0);
} else {
vibrator.vibrate(vibrationPattern_AcceleratedPulse, 0);
}
}
[...]
所以我用 alarmmanager 再次尝试,(坚持这个 link:https://developer.android.com/training/wearables/apps/always-on.html#UpdateContent)以便在黑屏时也能发送振动,但事实证明, alarmmanager 不能设置这么小的间隔?无论是在黑屏、正常还是环境模式下,它每 5 秒左右振动一次,应该是 1 秒或更短...
代码:
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
setAmbientEnabled();
mAmbientStateAlarmManager =
(AlarmManager) getSystemService(Context.ALARM_SERVICE);
Intent ambientStateIntent =
new Intent(getApplicationContext(), MainActivity.class);
mAmbientStatePendingIntent = PendingIntent.getActivity(
getApplicationContext(),
0,
ambientStateIntent,
PendingIntent.FLAG_UPDATE_CURRENT);
mContainerView = (BoxInsetLayout) findViewById(R.id.container);
//mClockView = (TextView) findViewById(R.id.clock);
vibrator = (Vibrator) getSystemService(VIBRATOR_SERVICE);
[...]}
@Override
public void onNewIntent(Intent intent) {
super.onNewIntent(intent);
setIntent(intent);
refreshDisplayAndSetNextUpdate();
}
private long AMBIENT_INTERVAL_MS = 0;
private void refreshDisplayAndSetNextUpdate() {
if (standardPulse) {
AMBIENT_INTERVAL_MS = 1000;
} else {
AMBIENT_INTERVAL_MS = 600;
}
if (isAmbient()) {
// Implement data retrieval and update the screen for ambient mode
vibrator.vibrate(75);
} else {
// Implement data retrieval and update the screen for interactive mode
vibrator.vibrate(75);
}
long timeMs = System.currentTimeMillis();
// Schedule a new alarm
if (isAmbient()) {
// Calculate the next trigger time
long triggerTimeMs = timeMs + AMBIENT_INTERVAL_MS;
mAmbientStateAlarmManager.setExact(
AlarmManager.RTC_WAKEUP,
triggerTimeMs,
mAmbientStatePendingIntent);
} else {
// Calculate the next trigger time for interactive mode
long triggerTimeMs = timeMs + AMBIENT_INTERVAL_MS;
mAmbientStateAlarmManager.setExact(
AlarmManager.RTC_WAKEUP,
triggerTimeMs,
mAmbientStatePendingIntent);
}
}
RefreshUpdateAndSetNextAlarm 然后也在 onEnterAmbient 事件等中被调用,但没有按预期工作。有没有办法在智能手表上做这些事情,尤其是在 Moto 360 上?
也许如果我通过 messageAPI 从智能手机不断发送消息并将它们设置为紧急?
解决方案是使用 CPU 唤醒锁:
PowerManager powerManager = (PowerManager) getSystemService(POWER_SERVICE);
PowerManager.WakeLock wakeLock = powerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK,
"MyWakelockTag");
wakeLock.acquire();
并且屏幕保持在标志上:
getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);