高通平台 android 12 定时开关机

关机

AlarmManager取消了RTC_POWEROFF_WAKEUP 不支持通过AlarmManager设置关机唤醒设备。
只有AlarmManager.RTC_WAKEUP 可用

关机实现

    /**
     * 设备关机. <br/>
     * 需要系统APP:android:sharedUserId="android.uid.system" <br/>
     * 需要权限:uses-permission android:name="android.permission.SHUTDOWN" <br/>
     */
    public void setPowerOFF(Long time) {
        Log.d("Request","powe off intent time:"+time);
        Intent intent = new Intent(ACTION_REQUEST_SHUTDOWN);
        //是否显示关机提示dialog,true显示false不显示直接关机
        intent.putExtra(EXTRA_KEY_CONFIRM, false);
        intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);

        //获取闹钟的id,给定时设置一个随机id,这样可以设置多个定时器,否则会被覆盖掉
        int alarmId = getIntRandom();
        long intervalMillis = 24 * 3600 * 1000;
        Log.d("Request","powe off alarmId:"+alarmId);
        PendingIntent pi = PendingIntent.getActivity(mContext, alarmId, intent,  PendingIntent.FLAG_IMMUTABLE);
        AlarmManager manager = (AlarmManager)mContext.getSystemService(ALARM_SERVICE);

        //设置重复定时,intervalMillis重复定时的间隔时间。根据自己的需求来设置定时
        //manager.setRepeating(AlarmManager.RTC_WAKEUP, time, intervalMillis, pi);

        //设置一次定时,根据自己的需求来设置定时
       manager.set(AlarmManager.RTC_WAKEUP, time, pi);

    }

开机实现

高通平台提供了PoweroffAlarm 功能 通过调用此系统组件来实现开机

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
	android:shareUserId="android.uid.system">
	<uses-permission android:name="org.codeaurora.permission.POWER_OFF_ALARM">

在app端发送广播

    public void setPowerON(Long time) {
        
        //发送广播
        Intent powerOnIntent = new Intent(ACTION_SET_POWEROFF_ALARM);
        powerOnIntent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
        powerOnIntent.setPackage(POWER_OFF_ALARM_PACKAGE);
        powerOnIntent.putExtra(TIME, time);
        mContext.sendBroadcast(powerOnIntent);
    }
   

具体实现有如下分析

高通提供的关机闹钟实现

	//PowerOffAlarmUtils.java
	public static long setAlarmToRtc(long alarmTime){

		long currentTime = System.currentTimeMillis();
		long alarmInRtc = getAlarmFromRtc();
		long rtcTime = getRtcTime();
		// calculate the alarm to rtc
		long timeDelta = alarmTime - currentTime - MS_IN_ONE_MIN;
		if(timeDelta <= 0){
			Log.d(TAG, "setAlarmToRtc failed: alarm time is in one miunute");
			return FAILURE;
		}
		long alarmTimeToRtc = timeDelta/SEC_TO_MS + rtcTime;
		try{
			IAlarm mProxy = IAlarm.getService(true);
			int ret = mProxy.setAlarm(alarmTimeToRtc);
			if(ret == SUCCESS){
				return alarmTimeToRtc;
			}else{
				return FAILURE;
			}
		}catch{
			return FAILURE;
		}
	}

IAlarm

Return<int32_t> Alarm::setAlarm(int64_t time){
	int fd, rc;
	struct tm alarm_tm;
	struct rtc_wkalrm rtc_alarm;
	time_t alarm_secs = 0;

	ALOGD("alarm hal setAlarm time");
	// #define DEFAULT_RTC_DEV_PATH = "dev/rtc0"
	fd = open(DEFAULT_RTC_DEV_PATH, O_RDONLY);
	if(fd < 0){
		ALOGE("Open rtc dev failed when set alarm!");
		return fd;
	}
	alarm_secs = time;
	gmtime_r(&alarm_secs, &alarm_tm);

	rtc_alarm.time.tm_sec = alarm_tm.tm_sec
	rtc_alarm.time.tm_min = alarm_tm.tm_min
	rtc_alarm.time.tm_hour = alarm_tm.tm_hour
	rtc_alarm.time.tm_mday = alarm_tm.tm_mday
	rtc_alarm.time.tm_mon = alarm_tm.tm_mon
	rtc_alarm.time.tm_year = alarm_tm.tm_year
	rtc_alarm.time.tm_wday = alarm_tm.tm_wday
	rtc_alarm.time.tm_yday = alarm_tm.tm_yday
	rtc_alarm.time.tm_isdst = alarm_tm.tm_isdst

	rtc_alarm.enabled = 1;
	// 设置定时时间
	rc = ioctl(fd, RTC_WKALM_SET, &rtc_alarm);
	close(fd);

	if(rc < 0){
		ALOGE("Set alarm to rtc failed!");
		return rc;
	}

	return 0;
}

总结

高通平台 实现此功能 就是发送广播
一个开机广播
一个关机广播
处理好对应的权限 根据Android版本与log日志 排除bug即可

BR

Logo

为开发者提供学习成长、分享交流、生态实践、资源工具等服务,帮助开发者快速成长。

更多推荐