屏幕关闭时Android Wear手表的面部震动 [英] Android Wear Watch Face Vibrate With Screen Off

查看:250
本文介绍了屏幕关闭时Android Wear手表的面部震动的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个Android Wear表盘,我试图使其在一个小时内振动。除手表屏幕关闭的情况外,此功能均有效。根据日志语句,处理程序方法每分钟调用一次,而chime方法则按小时调用。如果我使用Moto 360通过蓝牙进行调试,那么即使屏幕关闭也可以使用。如果我安装了发行版APK,则只有在屏幕打开时它才会振动。如果屏幕在一小时前关闭,它将不会振动,直到屏幕重新打开为止。我试过在没有运气的情况下获得唤醒锁。我想如果我在onCreate中获得唤醒锁并在onDestroy中释放它,可能会起作用,但我不想这样做以节省电池电量。另一个有趣的花絮是,我有另一个功能,当可穿戴数据api中的某些数据发生更改时,该功能会振动,并且该功能可以在屏幕关闭的情况下工作。也许WearableListenerService可以将手表唤醒足够长的时间,以免发生振动。我的逻辑有问题吗,或者这是某些Android Wear设备的限制吗?

I have an Android Wear watch face that I'm trying to have vibrate the watch on the hour. It is working except in cases where the watch screen is off. According to the log statements, the handler method is called every minute and the chime method is called on the hour. If I'm debugging over bluetooth with the Moto 360, it works even with the screen off. If I install a release apk, it only vibrates if the screen is on. If the screen is off at the top of the hour, it wont vibrate until the screen comes back on. I have tried acquiring a wake lock before the vibrate with no luck. I'm thinking it may work if I acquire a wake lock in the onCreate and release it in the onDestroy but I would rather not do that to preserve battery. Another interesting tidbit is that I have another function that vibrates when certain data changes in the wearable data api and that is working with the screen off. Maybe the WearableListenerService wakes the watch up long enough for the vibrate to occur. Is there something wrong with my logic or is this a limitation of certain Android Wear devices?

时间更改处理程序:

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中注销该接收器

Update The solution that worked was to create an AlarmManager and register it with a broadcast receiver in the watch face onCreate then unregister the receiver in 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();
}


推荐答案

当手表进入环境模式,它将进入深度睡眠状态。结果,用 Handler 无法运行。因此,您应该使用 AlarmManager 。有关如何实现此操作的详细信息,请参考更频繁地更新 部分/wearables/apps/always-on.html#UpdateContent rel = nofollow>此页面介绍了Android Wear的始终在线功能。

When the watch goes into ambient mode, it goes into a deep sleep. As a result, code written with Handler will not run. As a result, you should use AlarmManager. For details on how to implement this, you should refer to the "Update more frequently" section on this page about the always-on functionality of Android Wear.

关于蓝牙调试模式,我怀疑它可以工作,因为手表从未进入深度睡眠状态。

With regards to Bluetooth debug mode, I suspect that it works because the watch never goes into deep sleep. The same happens when I develop apps while the watch is docked.

最后,至于唤醒频率,我认为您的功能还不错,因为它每小时仅触发一次。对于其他阅读此内容的人,请避免每分钟超过一次唤醒手表,因为这会严重影响电池寿命。在上传到Play商店之前,请务必先测试一下表盘的电池续航时间。

Lastly, as for the wake up frequency, I think your functionality is fine as it only fires once an hour. For others reading this, please refrain from waking the watch up more than once a minute as this will severely impact battery life. Always test your watch face for battery life before uploading to the Play Store.

这篇关于屏幕关闭时Android Wear手表的面部震动的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆