2015-12-21 97 views
1

我有一个Android Wear手表表盘,我试图在一小时内振动手表。除了手表屏幕关闭的情况外,它正在工作。根据日志语句,每分钟调用一次处理程序方法,并在每小时调用一次钟声方法。如果我使用Moto 360通过蓝牙进行调试,即使屏幕关闭,它也可以工作。如果我安装了发行版apk,它只会在屏幕打开时振动。如果屏幕在小时的顶部关闭,则不会振动,直到屏幕重新打开。我试图在没有运气的振动之前获得唤醒锁。我认为这可能会工作,如果我在onCreate获得一个唤醒锁,并在onDestroy中释放它,但我宁愿不这样做来保存电池。另一个有趣的事情是,当可穿戴数据api中的某些数据发生变化并且屏幕处于关闭状态时,我还有另一个功能会发生振动。也许WearableListenerService将手表唤醒足够长的时间,以便发生振动。我的逻辑有问题吗?或者这是某些Android Wear设备的限制?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并与在手表表面的广播接收机中注册它的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); 
    } 
}; 

onDestr Oy()

@Override 
public void onDestroy() { 
    mChimeAlarmManager.cancel(mChimePendingIntent); 

    super.onDestroy(); 
} 
+0

做时,它应该在环境模式剔每小时振动你会得到什么记录? –

+0

环境模式与否,我得到我所期望的所有日志语句。最重要的是,我得到了“振动”日志,因此它能够获得振动器的实例并识别出手表具有振动器,但除非屏幕打开或正在调试,否则振动器不会振动。 –

+0

因此,如果您正在调试,它会在环境模式下振动,对不对?如果你只在调试时遇到问题(这是需要查看日志的权限?) –

回答

1

当手表进入环境模式时,它进入深度睡眠状态。因此,使用Handler编写的代码将不会运行。因此,您应该使用AlarmManager。有关如何执行此操作的详细信息,请参阅“更新频率更高”关于this page about the always-on functionality of Android Wear的部分。

关于蓝牙调试模式,我怀疑它是有效的,因为手表永远不会进入深度睡眠。当手表停靠时开发应用程序时也会发生同样的情况。最后,至于唤醒频率,我认为你的功能很好,因为它每小时只发射一次。对于阅读此内容的其他人,请避免每分钟超过一次以上唤醒手表,否则会严重影响电池寿命。在上传到Play商店之前,请始终测试您的手表表面的电池寿命。

+0

使用AlarmManger工作!我添加了上面的更新解决方案。 –

1

在我的项目中我使用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(); 
    } 
}