android 增加定时开关机

news/2024/10/22 17:33:59/

定时关机

增加一个系统服务,定时关机相关接口

	private void setPowerOff(Intent intent) {boolean enable = intent.getBooleanExtra(VAL_POWEROFF,false);Intent inten;if(enable) {inten = new Intent(Intent.ACTION_REQUEST_SHUTDOWN);inten.putExtra(Intent.EXTRA_KEY_CONFIRM,false);inten.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);mContext.startActivity(inten);} else {inten = new Intent(Intent.ACTION_REBOOT);inten.putExtra("nowait", 1);inten.putExtra("interval", 1);inten.putExtra("window", 0);mContext.sendBroadcast(inten);}}

定时关机app启动调用如下

    public void setTimePowerOff(long time) {Log.d(TAG,"time:" + time);AlarmManager am = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);Intent intent = new Intent(ACTION);intent.putExtra(CMD_KEY,CMD_ID_POWEROFF);intent.putExtra(VAL_POWEROFF,true);//这里这个intent最后广播会调用上面的系统服务setPowerOffPendingIntent pendingIntent = PendingIntent.getBroadcast(context, 0,intent, PendingIntent.FLAG_CANCEL_CURRENT);am.set(AlarmManager.RTC_WAKEUP, time, pendingIntent);}
      long time =  System.currentTimeMillis() + 10 * 1000;//10秒后关机setTimePowerOff(time);

定时关机,实际基本没什么困难。

定时开机

设备外接的rtc芯片为pcf8563,要实现硬件开机,硬件上需要将pcf8563的INT脚接到POWER KEY上,具体硬件具体接法,实际流程是达到设置的时间后pcf8563会将INT脚接低,此时INT接接在POWER KEY上就相当于常按开机键进行开机,开机启动后在清除pcf8563的状态使INT脚变高.
只是提供给特定软件使用,所以增加的不是系统接口,直接使用JNI进行设置定时开机
pcf8563驱动修改

diff --git a/lichee/linux-3.4/drivers/rtc/rtc-pcf8563.c b/lichee/linux-3.4/drivers/rtc/rtc-pcf8563.c
index cd3b4bb..ed4ae78 100755
--- a/lichee/linux-3.4/drivers/rtc/rtc-pcf8563.c
+++ b/lichee/linux-3.4/drivers/rtc/rtc-pcf8563.c
@@ -24,6 +24,9 @@#define PCF8563_REG_ST1		0x00 /* status */#define PCF8563_REG_ST2		0x01
+#define PCF8563_BIT_AIE		(1 << 1)
+#define PCF8563_BIT_AF		(1 << 3)
+#define PCF8563_BITS_ST2_N	(7 << 5)#define PCF8563_REG_SC		0x02 /* datetime */#define PCF8563_REG_MN		0x03
@@ -183,10 +186,130 @@ static int pcf8563_rtc_set_time(struct device *dev, struct rtc_time *tm)return pcf8563_set_datetime(to_i2c_client(dev), tm);}-static int pcf8563_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alrm)
+static int pcf8563_read_block_data(struct i2c_client *client, unsigned char reg,
+				   unsigned char length, unsigned char *buf){
+	struct i2c_msg msgs[] = {
+		{/* setup read ptr */
+			.addr = client->addr,
+			.len = 1,
+			.buf = &reg,
+		},
+		{
+			.addr = client->addr,
+			.flags = I2C_M_RD,
+			.len = length,
+			.buf = buf
+		},
+	};
+
+	if ((i2c_transfer(client->adapter, msgs, 2)) != 2) {
+		dev_err(&client->dev, "%s: read error\n", __func__);
+		return -EIO;
+	}
+
+	return 0;
+}
+
+static int pcf8563_write_block_data(struct i2c_client *client,
+				   unsigned char reg, unsigned char length,
+				   unsigned char *buf)
+{
+	int i, err;
+
+	for (i = 0; i < length; i++) {
+		unsigned char data[2] = { reg + i, buf[i] };
+
+		err = i2c_master_send(client, data, sizeof(data));
+		if (err != sizeof(data)) {
+			dev_err(&client->dev,
+				"%s: err=%d addr=%02x, data=%02x\n",
+				__func__, err, data[0], data[1]);
+			return -EIO;
+		}
+	}
+
+	return 0;
+}
+
+static int pcf8563_set_alarm_mode(struct i2c_client *client, bool on)
+{
+	unsigned char buf;
+	int err;
+
+	err = pcf8563_read_block_data(client, PCF8563_REG_ST2, 1, &buf);
+	if (err < 0)
+		return err;
+
+	if (on)
+		buf |= PCF8563_BIT_AIE;
+	else
+		buf &= ~PCF8563_BIT_AIE;
+
+	buf &= ~(PCF8563_BIT_AF | PCF8563_BITS_ST2_N);
+
+	err = pcf8563_write_block_data(client, PCF8563_REG_ST2, 1, &buf);
+	if (err < 0) {
+		dev_err(&client->dev, "%s: write error\n", __func__);
+		return -EIO;
+	}
+
+	return 0;
+}
+
+static int pcf8563_get_alarm_mode(struct i2c_client *client, unsigned char *en,
+				  unsigned char *pen)
+{
+	unsigned char buf;
+	int err;
+
+	err = pcf8563_read_block_data(client, PCF8563_REG_ST2, 1, &buf);
+	if (err)
+		return err;
+
+	if (en)
+		*en = !!(buf & PCF8563_BIT_AIE);
+	if (pen)
+		*pen = !!(buf & PCF8563_BIT_AF);
+
+	return 0;
+}
+
+static int pcf8563_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *tm)
+{
+	struct i2c_client *client = to_i2c_client(dev);
+	unsigned char buf[4];
+	int err;
+	/* The alarm has no seconds, round up to nearest minute */
+	/*if (tm->time.tm_sec) {
+		time64_t alarm_time = rtc_tm_to_time64(&tm->time);
+
+		alarm_time += 60 - tm->time.tm_sec;
+		rtc_time64_to_tm(alarm_time, &tm->time);
+	}*/
+
+	dev_dbg(dev, "%s, min=%d hour=%d wday=%d mday=%d "
+		"enabled=%d pending=%d\n", __func__,
+		tm->time.tm_min, tm->time.tm_hour, tm->time.tm_wday,
+		tm->time.tm_mday, tm->enabled, tm->pending);
+
+	buf[0] = bin2bcd(tm->time.tm_min);
+	buf[1] = bin2bcd(tm->time.tm_hour);
+	buf[2] = bin2bcd(tm->time.tm_mday);
+	buf[3] = tm->time.tm_wday & 0x07;
+
+	err = pcf8563_write_block_data(client, PCF8563_REG_AMN, 4, buf);
+	if (err)
+		return err;
+
+	return pcf8563_set_alarm_mode(client, 1);}static const struct rtc_class_ops pcf8563_rtc_ops = {
@@ -199,7 +322,7 @@ static int pcf8563_probe(struct i2c_client *client,const struct i2c_device_id *id){struct pcf8563 *pcf8563;
-
+	unsigned char alm_pending;int err = 0;dev_dbg(&client->dev, "%s\n", __func__);
@@ -218,7 +341,16 @@ static int pcf8563_probe(struct i2c_client *client,if (!device_can_wakeup(&client->dev)) { //add by hclydaodevice_init_wakeup(&client->dev, 1);}
-
+
+	err = pcf8563_get_alarm_mode(client, NULL, &alm_pending);//清除状态
+	if (err) {
+		dev_err(&client->dev, "%s: read error\n", __func__);
+		return err;
+	}
+
+	if (alm_pending)
+		pcf8563_set_alarm_mode(client, 0);
+		pcf8563->rtc = rtc_device_register(pcf8563_driver.driver.name,&client->dev, &pcf8563_rtc_ops, THIS_MODULE);

应用层jni

JNIEXPORT jint JNICALL Java_com_gzease_hwc_Hwc_setRtcPowerOn(JNIEnv * env, jclass obj,jlong millis)
{struct timeval tv;int ret;struct tm tm, *gmtime_res;struct rtc_time rtc;int fd;if (millis <= 0 || millis / 1000LL >= INT_MAX) {return -1;}tv.tv_sec = (time_t) (millis / 1000LL);tv.tv_usec = (suseconds_t) ((millis % 1000LL) * 1000LL);//LOGD("Setting time of day to sec=%d\n", (int) tv.tv_sec);gmtime_res = gmtime_r(&tv.tv_sec, &tm);if (!gmtime_res) {LOGE("gmtime_r() failed: %s\n", strerror(errno));return -1;}memset(&rtc, 0, sizeof(rtc));rtc.tm_sec = tm.tm_sec;rtc.tm_min = tm.tm_min;rtc.tm_hour = tm.tm_hour;rtc.tm_mday = tm.tm_mday;rtc.tm_mon = tm.tm_mon;rtc.tm_year = tm.tm_year;rtc.tm_wday = tm.tm_wday;rtc.tm_yday = tm.tm_yday;rtc.tm_isdst = tm.tm_isdst;/*LOGD("setAlarm RTC date/time: %d/%d/%d %02d:%02d:%02d\n",rtc.tm_mday, rtc.tm_mon + 1, rtc.tm_year + 1900,rtc.tm_hour, rtc.tm_min, rtc.tm_sec);*/fd = open("/dev/rtc0", O_RDONLY|O_NONBLOCK);if (fd == -1) {LOGE("setRtc open /dev/rtc0 error");return -1;}ret = ioctl(fd, RTC_ALM_SET, &rtc);if (ret == -1) {LOGE("ioctl RTC_SET_TIME error");close(fd);return -1;}close(fd);return 0;
}

java层调用

tim =  System.currentTimeMillis() + 60 * 1000;//60秒后开机 最小单位为分钟 不能小于60秒
setTimePowerOn(tim);

同时需要修改/dev/rtc0权限,定时开机设置使用ioctl(fd, RTC_ALM_SET, &rtc)这个会调用到pcf8563驱动中的pcf8563_rtc_set_alarm,当定时时间到后系统启动在pcf8563 probe函数会使用pcf8563_set_alarm_mode清除状态将INT接高.
如果是在系统里加接口有点麻烦,这里就直接用jni进行设置.
参考:
https://blog.csdn.net/zy_style/article/details/53228509?utm_source=blogxgwz9

======================================
作者:hclydao
http://blog.csdn.net/hclydao
版权没有,但是转载请保留此段声明

=======================================


http://www.ppmy.cn/news/353841.html

相关文章

Win10系统定时开关机

系统检查 1.1 打开控制面板->搜索 电源&#xff0c;点击更改电源按钮功能&#xff1b; 1.2 点击更改当前不可用设置&#xff0c;取消勾选启用快速启动选项&#xff1b; 1.3 勾选允许预定维护在预定时间唤醒我的计算机。 2 设置定时关机 2.1 重启计算机&#xff0c;连续点…

windows定时开关机方法

一、定时开机&#xff1a; 电脑关机重启&#xff1a;按住Esc F12 键&#xff0c;进入BIO页面&#xff0c;选择OEM,点击第二个RTC Wake Settings , 状态改为Enabled,然后设定开机时间。 3. 按键盘上的F10键保存并退出BIOS,设置完成。 二&#xff0e;定时关机 1.先点“…

Win10如何设置定时开关机休眠唤醒

http://www.yunnanlong.com/c/120624335142022.html 现在大部分人都在使用Win10系统&#xff0c;因为这个是最新的系统&#xff0c;而且功能多 。我们在没有硬件支持的情况下&#xff0c;可以利用Wndows系统自带的任务计划程序和休眠功能&#xff0c;实现计算的定时开关机&…

安卓定时开关机的实现

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

计算机定时开机命令,定时开关机

自动定时开机的实现\主板必须有相应的支持才行,绝大多数都支持自动开机,我们只要在BIOS中进行相应设置即可。按“Delete”键进入BIOS界面。在BIOS设置主界面中选择“Power Management Setup”菜单,进入电源管理窗口。默认情况下,“Automatic Power Up(定时开机,有些机器选…

安卓系统定时开关机

直接上代码 Override protected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);//关机时间int[] timeoff{2019,7,9,15,40};//开机时间int[] timeon{2019,7,9,15,44};Intent intentnew Intent();intent.putExtra("timeoff", timeoff…

Android系统定时开关机

1、系统定时开关机需要系统权限&#xff0c;所以需要apk做系统签名。 2、在AndroidManifest.xml文件的头部的 标记中添加系统权限。 android:sharedUserId“android.uid.system” 注意&#xff1a;设置定时开机后&#xff0c;如果改设置没有到时间&#xff0c;无法更改定时开…

利用fiddler和burp抓取手机流量

为什么这样抓取流量 用“模拟器”“burp”抓取流量虽然好用&#xff0c;但有些限制 1、如果APP做了“虚拟环境检查”&#xff0c;打开APP就直接闪退。 2、如果APP与微信或QQ软件关联的话&#xff0c;“模拟器”不好操作。 3、如果APP获取定位等信息&#xff0c;“模拟器”无法…