前言

定时开机需要底层 RTC 时钟支持,本文只针对 MTK 平台,其它平台不一定能适用请慎重参考文末链接

定时开关机的原理其实和闹钟是一样的,只不过是个特殊的闹钟而已,由于之前 MTK 6.0 的系统中自带就有定时开关机的功能(在设置中嵌入菜单),

8.1 中我们也将在设置界面中嵌入此功能。

代码

直接 copy 6.0 中的 SchedulePowerOnOff 源码,如果你没有可下载我提供的,将 app 源码放置到 *vendor\mediatek\proprietary\packages\apps* 路径下

修改一 在 AndroidManifest.xml 中增加 Settings 配置(下载的源码中已经修改过)

 <activity android:name="com.mediatek.schpwronoff.AlarmClock"android:label="@string/schedule_power_on_off_settings_title"android:configChanges="orientation|keyboardHidden|keyboard|navigation"><intent-filter><action android:name="android.intent.action.MAIN" /><action android:name="com.android.settings.SCHEDULE_POWER_ON_OFF_SETTING" /><category android:name="android.intent.category.DEFAULT" /></intent-filter><!--add for settings show quick into --><intent-filter android:priority="5"><action android:name="com.android.settings.action.EXTRA_SETTINGS" /></intent-filter><meta-dataandroid:name="com.android.settings.category"android:value="com.android.settings.category.ia.homepage" /><meta-dataandroid:name="com.android.settings.icon"android:resource="@drawable/ic_settings_schpwronoff" /><!-- end --></activity>

修改二 在 MtkAlarmManagerService 中添加 SchedulePowerOnOff 的包名

vendor\mediatek\proprietary\frameworks\base\services\core\java\com\mediatek\server\MtkAlarmManagerService.java

/***For PowerOffalarm feature, this function is used for AlarmManagerService* to set the latest alarm registered*/
private void resetPoweroffAlarm(Alarm alarm) {String setPackageName = alarm.operation.getTargetPackage();long latestTime = alarm.when;// Only DeskClock is allowed to set this alarmif (mNativeData != 0 && mNativeData != -1) {if (setPackageName.equals("com.android.deskclock")|| setPackageName.equals("com.mediatek.schpwronoff")) {//add SchedulePowerOnOff package name/// M: Extra Logging @{if (DEBUG_ALARM_CLOCK) {Slog.i(TAG, "mBootPackage = " + setPackageName + " set Prop 2");}///@}SystemProperties.set("persist.sys.bootpackage", "2");set(mNativeData, PRE_SCHEDULE_POWER_OFF_ALARM,latestTime / 1000, (latestTime % 1000) * 1000 * 1000);SystemProperties.set("sys.power_off_alarm", Long.toString(latestTime / 1000));.......}

这样就 ok 了,需要注意的是在 8.1 上设置定时开机时间必须大于 120s,否则不会自动开机,据说是新版本的问题,6.0 是没有问题的,无时间限制。

6.0 的 MTK 开关机分析可参考 Android MTK auto power on & off And DeskClock app

开关机简单分析

用户通过 SetAlarm.java PreferenceActivity 来选择开关机时间,最终点击保存调用 saveAlarm()

SchedulePowerOnOff\src\com\mediatek\schpwronoff\SetAlarm.java

private void saveAlarm() {final String alert = Alarms.ALARM_ALERT_SILENT;mEnabled |= mRepeatPref.mIsPressedPositive;Alarms.setAlarm(this, mId, mEnabled, mHour, mMinutes, mRepeatPref.getDaysOfWeek(), true, "", alert);if (mEnabled) {popAlarmSetToast(this.getApplicationContext(), mHour, mMinutes, mRepeatPref.getDaysOfWeek(), mId);}}

注意里面的 mId 字段,为 1 表示定时开机,为 2 表示定时关机,通过 setAlarm 来设置"闹钟"

SchedulePowerOnOff\src\com\mediatek\schpwronoff\Alarms.java

public static void setAlarm(Context context, int id, boolean enabled, int hour, int minutes,Alarm.DaysOfWeek daysOfWeek, boolean vibrate, String message, String alert) {final int initSize = 8;ContentValues values = new ContentValues(initSize);ContentResolver resolver = context.getContentResolver();// Set the alarm_time value if this alarm does not repeat. This will be// used later to disable expired alarms.long time = 0;if (!daysOfWeek.isRepeatSet()) {time = calculateAlarm(hour, minutes, daysOfWeek).getTimeInMillis();}Log.d("@M_" + TAG, "**  setAlarm * idx " + id + " hour " + hour + " minutes " + minutes+ " enabled " + enabled + " time " + time);values.put(Alarm.Columns.ENABLED, enabled ? 1 : 0);values.put(Alarm.Columns.HOUR, hour);values.put(Alarm.Columns.MINUTES, minutes);values.put(Alarm.Columns.ALARM_TIME, time);values.put(Alarm.Columns.DAYS_OF_WEEK, daysOfWeek.getCoded());values.put(Alarm.Columns.VIBRATE, vibrate);values.put(Alarm.Columns.MESSAGE, message);values.put(Alarm.Columns.ALERT, alert);resolver.update(ContentUris.withAppendedId(Alarm.Columns.CONTENT_URI, id), values, null,null);if (id == 1) {// power onsetNextAlertPowerOn(context);} else if (id == 2) {// power offsetNextAlertPowerOff(context);}}private static void enableAlert(Context context, final Alarm alarm, final long atTimeInMillis) {if (alarm == null) {return;}AlarmManager am = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);Log.d("@M_" + TAG, "** setAlert id " + alarm.mId + " atTime " + atTimeInMillis);Intent intent = new Intent(context, com.mediatek.schpwronoff.SchPwrOffReceiver.class);Parcel out = Parcel.obtain();alarm.writeToParcel(out, 0);out.setDataPosition(0);intent.putExtra(ALARM_RAW_DATA, out.marshall());PendingIntent sender = PendingIntent.getBroadcast(context, 0, intent,PendingIntent.FLAG_CANCEL_CURRENT);am.setExact(AlarmManager.RTC_WAKEUP, atTimeInMillis, sender);Calendar c = Calendar.getInstance();c.setTime(new java.util.Date(atTimeInMillis));Log.d("@M_" + TAG, "Alarms.enableAlertPowerOff(): setAlert id " + alarm.mId + " atTime "+ c.getTime());}

setNextAlertPowerOff 中通过调用 enableAlert(),设置一个 RTC_WAKEUP 时钟,当到设置的关机时间时,SchPwrOffReceiver 广播会被触发,弹出一个 30s 的倒计时提醒用户,点击取消则取消本次定时关机操作,点击确定则立即执行关机操作,关机操作通过隐藏 action ACTION_REQUEST_SHUTDOWN

SchedulePowerOnOff\src\com\mediatek\schpwronoff\ShutdownActivity.java

private void fireShutDown() {Intent intent = new Intent(Intent.ACTION_REQUEST_SHUTDOWN);intent.putExtra(Intent.EXTRA_KEY_CONFIRM, false);intent.setFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);startActivity(intent);}

再回到定时开机操作 enableAlertPowerOn 中

private static void enableAlertPowerOn(Context context, final Alarm alarm,final long atTimeInMillis) {Log.d("@M_" + TAG, "** setAlert id " + alarm.mId + " atTime " + atTimeInMillis);AlarmManager am = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);Intent intent = new Intent(context, com.mediatek.schpwronoff.SchPwrOnReceiver.class);Parcel out = Parcel.obtain();alarm.writeToParcel(out, 0);out.setDataPosition(0);intent.putExtra(ALARM_RAW_DATA, out.marshall());PendingIntent sender = PendingIntent.getBroadcast(context, 0, intent,PendingIntent.FLAG_CANCEL_CURRENT);am.setExact(7, atTimeInMillis, sender);Calendar c = Calendar.getInstance();c.setTime(new java.util.Date(atTimeInMillis));Log.d("@M_" + TAG, "Alarms.enableAlertPowerOn(): setAlert id " + alarm.mId + " atTime "+ c.getTime());}

可以看到此处的 setExact 类型变成了 7, 之前的定时关机是** AlarmManager.RTC_WAKEUP**,这个 7 有点来头

frameworks\base\core\java\android\app\AlarmManager.java

/*** Alarm time in {@link System#currentTimeMillis System.currentTimeMillis()}* (wall clock time in UTC), which will wake up the device when* it goes off.*/public static final int RTC_WAKEUP = 0;..../*** M: This alarm type is used to set an alarm that would be triggered if device* is in powerOff state. It is set to trigger POWER_OFF_ALARM_BUFFER_TIME ms earlier* than the actual alarm time so that phone is in wakeup state when actual alarm* triggers*//** @hide */public static final int PRE_SCHEDULE_POWER_OFF_ALARM = 7;.....

对应到 MtkAlarmManagerService 中增加要设置的包名,再往下就是 C 中的设置,可参考 Android自动开关机实现

Android8.1 MTK平台 增加定时开关机功能相关推荐

  1. Android P 9.0 MTK平台 增加以太网静态IP功能

    前言 朋友们,最近又开始搞 Android P了,同样的以太网静态 IP 是少不了的功能,今天我们就开始来整一下.之前弄6.0 和 8.1 的都 ok 了. 没想到 9.0 改动还是略微有点大的.来来 ...

  2. Android 8.1 第三方apk通过数据库调用系统定时开关机功能

    由于客户需要我们提供API给到他们实现定时开关机功能 做的是展锐的方案,简单看下原厂如何实现该功能 1.展锐创建了一个sqlite数据库用来存放定时开关机相关数据 vendor\sprd\platfo ...

  3. Android8.1 MTK平台 增加三指截屏(仿IOS左下角显示缩略图点击放大显示)

    效果图 修改后动画如下 系统原动画如下 三指截屏 PhoneWindowManager 同级目录下的 SystemGesturesPointerEventListener.java 主要负责处理界面的 ...

  4. Android10.0(Q) MTK平台增加以太网静态IP功能

    前言 朋友们,网卡功能真的是太太太太常用了,这次我又带着 10.0 的以太网静态IP功能来了,相比 9.0 而言, framework 没啥大变化,可以直接对比移植.Settings 部分也没啥大变化 ...

  5. 定时开关机实现原理-Android4.4/6.0

    原址 一.寄存器介绍--RTCSA & RTCSAR 1.RTC是Real Time Clock的简称,它在硬件电路上单独供电,当系统关机时,CPU和其他外部硬件设备全部掉电,但是RTC仍然继 ...

  6. 定时开关机-Android4.4/6.0

    一.寄存器介绍--RTCSA & RTCSAR 1.RTC是Real Time Clock的简称,是一个时钟芯片.它在硬件电路上单独供电,当系统关机时,CPU和其他外部硬件设备全部掉电,但是R ...

  7. 计划任务唤醒计算机,亲测利用windows 10任务计划实现计算机定时开关机(休眠唤醒)...

    利用任务计划实现计算机定时开关机 休眠唤醒 计算机如果具有定时开关机功能 是一件很吸引人的事情 但是一般的电脑要实现开 关机功能 需要有硬件的支持 所幸的是 在没有硬件支持的情况下 我们可以利用 wi ...

  8. 魅蓝e android无限重启,魅蓝E手机怎么设置定时开关机 魅蓝E定时开关机设置图文教程...

    上手魅蓝E手机之后,整体感觉还不错,尤其是外观工艺良好,日常使用流畅度很高.此外,小编还发现魅蓝E有一个比较赞的功能,支持定时开关机,这是目前iPhone都没有的功能.话不多说,本文主要分享一下魅蓝E ...

  9. 高通平台 android 12 定时开关机

    高通平台 android 12 定时开关机 关机 关机实现 开机实现 总结 关机 AlarmManager取消了RTC_POWEROFF_WAKEUP 不支持通过AlarmManager设置关机唤醒设 ...

  10. 安卓定时开关机的实现

    关于安卓定时开关机,在网上很难找到真正的答案,在这里我引用了其他论坛的解决办法,自己也补充了些.望各位有需要的小伙伴们借鉴. 相对于自动开机来说,自动关机可以在应用层通过设置alarm来实现.而自动开 ...

最新文章

  1. 命令行查看电脑WIFI密码
  2. Redis的一些“锁”事
  3. ajxs跨域 php_php设置header头允许ajax跨域请求
  4. linux odbc连接数据库失败,在Linux中使用RODBC连接到SQL Server时出错
  5. 存储对手机性能的影响
  6. 对象存储 OSS > 开发指南 > 存储类型 > 存储类型介绍
  7. 83-MACD 移动平均汇总/分离指标.(2015.7.3)
  8. 英文论文中“such as, for example, e.g., i.e., etc., et al. ”的用法分析 (转)
  9. k8s学习: 部署动态 pvc(nfs-subdir-external-provisioner)
  10. arduino学习笔记-库函数解析_LiquidCrystal_i2c使用说明以及lcd1602的驱动
  11. eclipse安装Subclipse(svn数据源)
  12. 计算机ppt里怎么应用背景图,如何在电脑ppt软件中添加背景图片
  13. 【将金令】炒白银,切忌!切忌!
  14. Linux 流量监控
  15. 怎样刻录系统启动光盘
  16. div和div之间画横线_HTML在两个div标签中间画一条竖线的方法
  17. uniapp 安卓保活插件 Ba-KeepAlive
  18. 微信小程序之Js修改元素样式
  19. CSDN博文大赛赛况简报
  20. LaTex期刊模板下载与使用

热门文章

  1. 计算机键盘中英文,电脑键盘中英文切换键
  2. 删除脚注分割线(word左下角的横线)
  3. C++关键字(static/register/atuo/extern/volatile/const)释疑
  4. java导出excel设置行高列宽_Java 设置Excel自适应行高或列宽
  5. 页面监听-iframe子父页面信息传递与监听
  6. 关于将图片转成base64的方法
  7. 调试STM32f401过程出现的问题
  8. 8.1 向量及其线性运算
  9. c语言单片机仿真keil,如何在keil中仿真stm32单片机
  10. css设置logo图片大小,修改ecshop网站logo图片尺寸大小