我有一个Android Wear表盘,我正试图在一小时内振动手表。除了手表屏幕关闭的情况外,它正在工作。根据日志语句,每分钟调用一次处理程序方法,并在小时调用chime方法。如果我使用Moto 360对蓝牙进行调试,即使屏幕关闭也能正常工作。如果我安装了一个版本apk,它只会在屏幕打开时振动。如果屏幕在一小时的顶部关闭,它将不会振动,直到屏幕重新亮起。我试着在振动之前获得一个唤醒锁,没有运气。我认为如果我在onCreate中获取唤醒锁并在onDestroy中释放它可能会有效,但我宁愿不这样做以保留电池。另一个有趣的消息是,我有另一个功能,当可穿戴数据api中的某些数据发生变化并且屏幕关闭时,它会振动。也许WearableListenerService唤醒了足够长的时间以便振动发生。我的逻辑是否有问题,或者这是某些Android Wear设备的限制?
时间变更处理程序:
final Handler mUpdateTimeHandler = new Handler() {
@Override
public void handleMessage(Message message) {
switch (message.what) {
case MSG_UPDATE_TIME:
MyLog.d("Time Tick Message Handler");
doTimeTickStuff();
long timeMs = System.currentTimeMillis();
long delayMs = mInteractiveUpdateRateMs - (timeMs % mInteractiveUpdateRateMs);
mUpdateTimeHandler.sendEmptyMessageDelayed(MSG_UPDATE_TIME, delayMs);
break;
}
}
};
doTimeTickStuff()
private void doTimeTickStuff()
{
MyLog.d("timetickstuff");
try {
mCalendar = Calendar.getInstance();
int currMin = mCalendar.get(Calendar.MINUTE);
if (currMin == 0) {
hourlyChime();
}
}
catch(Exception ex)
{
MyLog.e(ex, "Error occurred in time tick handler");
}
if (mIsVisible) {
invalidate();
}
}
hourlyChime()
private void hourlyChime(){
Vibrator v = (Vibrator) getBaseContext().getSystemService(VIBRATOR_SERVICE);
if (v.hasVibrator()) {
MyLog.d("vibrating");
v.vibrate(1000);
}
else {
MyLog.d("No vibrator");
}
}
更新 有效的解决方案是创建一个AlarmManager并将其注册到watchface onCreate中的广播接收器,然后在onDestroy中取消注册接收器
的onCreate()
@Override
public void onCreate(SurfaceHolder holder) {
super.onCreate(holder);
mChimeAlarmManager =
(AlarmManager) getSystemService(Context.ALARM_SERVICE);
Intent ambientStateIntent = new Intent("packagename.HOURLY_CHIME");
mChimePendingIntent = PendingIntent.getBroadcast(getApplicationContext(),
1234, ambientStateIntent, PendingIntent.FLAG_UPDATE_CURRENT);
WeatherTime.this.registerReceiver(chimeReceiver,
new IntentFilter("packagename.HOURLY_CHIME"));
long alarmMs = getMsTillNextHour() + System.currentTimeMillis();
mChimeAlarmManager.setExact(
AlarmManager.RTC_WAKEUP,
alarmMs,
mChimePendingIntent);
}
广播接收器
private BroadcastReceiver chimeReceiver = new BroadcastReceiver()
{
@Override
public void onReceive(Context context, Intent intent) {
hourlyChime();
mChimeAlarmManager.setExact(
AlarmManager.RTC_WAKEUP,
getMsTillNextHour() + System.currentTimeMillis(),
mChimePendingIntent);
}
};
的onDestroy()
@Override
public void onDestroy() {
mChimeAlarmManager.cancel(mChimePendingIntent);
super.onDestroy();
}
答案 0 :(得分:2)
当手表进入环境模式时,它会进入深度睡眠状态。因此,使用Handler
编写的代码将无法运行。因此,您应该使用AlarmManager
。有关如何实现此问题的详细信息,请参阅this page about the always-on functionality of Android Wear上的 "更频繁更新" 部分。
关于蓝牙调试模式,我怀疑它是否有效,因为手表永远不会进入深度睡眠状态。当手表停靠时我开发应用程序时会发生同样的情况。
最后,关于唤醒频率,我认为你的功能很好,因为它每小时只发射一次。对于阅读此内容的其他人,请不要每分钟超过一次,因为这将严重影响电池寿命。在上传到Play商店之前,请务必测试您的表盘电池寿命。
答案 1 :(得分:2)
在我的项目中我使用Alarm Manager和MyIntentService扩展了IntentService。 在onHandleIntent中唤醒(屏幕上)设备 使用以下:
if (intent.getAction() != null) {
tmp = intent.getAction();
PowerManager powerManager = (PowerManager) getSystemService(POWER_SERVICE);
wakeLock = powerManager.newWakeLock((PowerManager.SCREEN_BRIGHT_WAKE_LOCK | PowerManager.FULL_WAKE_LOCK | PowerManager.ACQUIRE_CAUSES_WAKEUP), TAG);
wakeLock.setReferenceCounted(true);
if(!wakeLock.isHeld()) {
wakeLock.acquire();
}
}