2

我有一个 Android Wear 表盘,我正试图让手表整点振动。除非手表屏幕关闭,否则它可以正常工作。根据日志语句,handler 方法每分钟调用一次,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();
    }
}

每小时钟声()

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);
    }
};

onDestroy()

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

    super.onDestroy();
}
4

2 回答 2

2

在我的项目中,我使用带有 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();
    }
}
于 2016-12-17T15:40:12.450 回答
2

当手表进入环境模式时,它会进入深度睡眠。结果,用编写的代码Handler将无法运行。因此,您应该使用AlarmManager. 有关如何实现此功能的详细信息,您应该参阅此页面上有关 Android Wear 的永远在线功能的“更频繁地更新”部分。

关于蓝牙调试模式,我怀疑它可以工作,因为手表永远不会进入深度睡眠。当我在手表停靠时开发应用程序时也会发生同样的情况。

最后,至于唤醒频率,我认为您的功能很好,因为它每小时只触发一次。对于阅读本文的其他人,请不要每分钟唤醒手表超过一次,因为这会严重影响电池寿命。在上传到 Play 商店之前,请务必测试表盘的电池寿命。

于 2015-12-23T10:36:50.663 回答