RK3576 Android15 设置中新增定时开关机功能

问题背景

        项目需要在系统设置中增加定时开关机功能

设计思路

  1. 定时关机只需要调用系统关机接口,而定时开机需要硬件RTC支持。
  2. 参考日期和时间设置选项,按照手机的设计逻辑,决定在辅助功能条目中增加“定时开关机”开关。
  3. 定时开关机包括“开机时间”、“关机时间”、“周期”三个功能。
  4. 系统重启后需要重新设置重复时间。

代码实现

  • 通过SettingsProvider属性来控制功能开关

frameworks/base/core/java/android/provider/Settings.java

diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java
index f494376b9989..c978641857f3 100644
--- a/core/java/android/provider/Settings.java
+++ b/core/java/android/provider/Settings.java
@@ -5812,6 +5812,20 @@ public final class Settings {
         public static final String HIDE_ROTATION_LOCK_TOGGLE_FOR_ACCESSIBILITY =
                 "hide_rotation_lock_toggle_for_accessibility";
 
+        /**
+         * power scheduler off state.
+         *
+         * @hide
+         */
+        public static final String POWER_SCHEDULER_STATE = "power_scheduler_state";
+
         /**
          * Whether the phone vibrates when it is ringing due to an incoming call. This will
          * be used by Phone and Setting apps; it shouldn't affect other apps.
  • 赋予关机广播权限

frameworks/base/core/res/AndroidManifest.xml

diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml
index d35c66ed719e..e900fda2a3f0 100644
--- a/core/res/AndroidManifest.xml
+++ b/core/res/AndroidManifest.xml
@@ -844,6 +844,7 @@
     <protected-broadcast android:name="android.intent.action.MAIN_USER_LOCKSCREEN_KNOWLEDGE_FACTOR_CHANGED" />
     <protected-broadcast android:name="com.android.uwb.uwbcountrycode.GEOCODE_RETRY" />
     <protected-broadcast android:name="android.telephony.action.ACTION_SATELLITE_SUBSCRIBER_ID_LIST_CHANGED" />
+    <protected-broadcast android:name="android.intent.action.ACTION_REQUEST_SHUTDOWN" />
 
     <!-- ====================================================================== -->
     <!--                          RUNTIME PERMISSIONS                           -->
-- 
  • 赋予设置关机权限

如果这里不给权限,会导致卡开机动画,无法进入Launcher

frameworks/base/data/etc/com.android.settings.xml 

diff --git a/data/etc/com.android.settings.xml b/data/etc/com.android.settings.xml
index 99911de09b7d..72dab4da8730 100644
--- a/data/etc/com.android.settings.xml
+++ b/data/etc/com.android.settings.xml
@@ -70,5 +70,6 @@
         <permission name="android.permission.SATELLITE_COMMUNICATION" />
         <permission name="android.permission.READ_SYSTEM_GRAMMATICAL_GENDER" />
         <permission name="android.permission.SET_BIOMETRIC_DIALOG_ADVANCED" />
+        <permission name="android.permission.SHUTDOWN"/>
     </privapp-permissions>
 </permissions>
  • 设置->辅助功能中增加“定时开关机”条目
diff --git a/res/xml/accessibility_settings.xml b/res/xml/accessibility_settings.xml
index 18e645591ff..b72e25566d0 100644
--- a/res/xml/accessibility_settings.xml
+++ b/res/xml/accessibility_settings.xml
@@ -251,6 +251,13 @@
             android:title="@string/tts_settings_title"
             settings:controller="com.android.settings.language.TtsPreferenceController"/>
 
+        <Preference
+            android:fragment="com.android.settings.scheduledpower.ScheduledPowerSettings"
+            android:key="accessibility_schedule_power_settings_preference"
+            android:persistent="false"
+            android:title="@string/schedule_power_settings_title"
+            settings:controller="com.android.settings.scheduledpower.ScheduledPowerPreferenceController"/>
+
     </PreferenceCategory>
 
 </PreferenceScreen>
  • Preference显示开关
diff --git a/res/values/config.xml b/res/values/config.xml
index 68d0d18ac95..b5c5b073516 100644
--- a/res/values/config.xml
+++ b/res/values/config.xml
@@ -453,6 +453,9 @@
     <!-- Whether tts_settings_summary should be shown or not. -->
     <bool name="config_show_tts_settings_summary">true</bool>
 
+    <!-- Whether scheduled_power_settings_summary should be shown or not. -->
+    <bool name="config_show_scheduled_power_settings_summary">true</bool>
+
     <!-- Whether pointer_speed should be shown or not. -->
     <bool name="config_show_pointer_speed">true</bool>
  • 新增Preference布局文件

 res/xml/accessibility_scheduled_power_prefs.xml

<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright (C) 2008 The Android Open Source Project

     Licensed under the Apache License, Version 2.0 (the "License");
     you may not use this file except in compliance with the License.
     You may obtain a copy of the License at

          http://www.apache.org/licenses/LICENSE-2.0

     Unless required by applicable law or agreed to in writing, software
     distributed under the License is distributed on an "AS IS" BASIS,
     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     See the License for the specific language governing permissions and
     limitations under the License.
-->

<PreferenceScreen
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:settings="http://schemas.android.com/apk/res-auto"
    android:title="@string/schedule_power_settings_title"
    settings:keywords="@string/keywords_schedule_power_settings">

    <com.android.settingslib.RestrictedSwitchPreference
        android:key="schedule_power_settings"
        android:title="@string/schedule_power_settings_title"
        settings:controller="com.android.settings.scheduledpower.ScheduledPowerSwitchController" />

    <com.android.settingslib.RestrictedPreference
        android:key="power_on"
        android:title="@string/power_on_time"
        android:summary="@string/summary_placeholder"
        settings:controller="com.android.settings.scheduledpower.PowerOnTimeController" />

    <com.android.settingslib.RestrictedPreference
        android:key="power_off"
        android:title="@string/power_off_time"
        android:summary="@string/summary_placeholder"
        settings:controller="com.android.settings.scheduledpower.PowerOffTimeController" />

    <Preference
        android:key="selected_days"
        android:title="@string/scheduled_repeat"
        android:summary="@string/summary_placeholder"
        settings:controller="com.android.settings.scheduledpower.RepeatSettingsController" />

</PreferenceScreen>
  •  在SettingsActivity中注册定时开关机的Activity
diff --git a/src/com/android/settings/Settings.java b/src/com/android/settings/Settings.java
index bfdd506ede1..bc75485f522 100644
--- a/src/com/android/settings/Settings.java
+++ b/src/com/android/settings/Settings.java
@@ -530,4 +530,9 @@ public class Settings extends SettingsActivity {
      */
     public static class HdmiSettingsActivity extends SettingsActivity {}
     //----------------------------------------
+
+    /**
+     * Activity for ScheduledPowerSettings
+     */
+    public static class ScheduledPowerSettingsActivity extends SettingsActivity { /* empty */ }
 }
diff --git a/src/com/android/settings/core/gateway/SettingsGateway.java b/src/com/android/settings/core/gateway/SettingsGateway.java
index 0e48201d2fe..d860eadf4d8 100644
--- a/src/com/android/settings/core/gateway/SettingsGateway.java
+++ b/src/com/android/settings/core/gateway/SettingsGateway.java
@@ -182,6 +182,7 @@ import com.android.settings.privatespace.delete.PrivateSpaceDeletionProgressFrag
 import com.android.settings.privatespace.onelock.PrivateSpaceBiometricSettings;
 import com.android.settings.regionalpreferences.RegionalPreferencesEntriesFragment;
 import com.android.settings.safetycenter.MoreSecurityPrivacyFragment;
+import com.android.settings.scheduledpower.ScheduledPowerSettings;
 import com.android.settings.security.LockscreenDashboardFragment;
 import com.android.settings.security.MemtagPage;
 import com.android.settings.security.SecurityAdvancedSettings;
@@ -412,7 +413,8 @@ public class SettingsGateway {
             AccessibilityHearingAidsFragment.class.getName(),
             HearingDevicePairingFragment.class.getName(),
             ZenModesListFragment.class.getName(),
-            ZenModeFragment.class.getName()
+            ZenModeFragment.class.getName(),
+            ScheduledPowerSettings.class.getName()
     };
 
     public static final String[] SETTINGS_FOR_RESTRICTED = {
@@ -464,5 +466,6 @@ public class SettingsGateway {
             UserBackupSettingsActivity.class.getName(),
             Settings.MemtagPageActivity.class.getName(),
             Settings.NavigationModeSettingsActivity.class.getName(),
+            Settings.ScheduledPowerSettingsActivity.class.getName(),
     };
 }
  • AndroidManifest.xml中增加声明
diff --git a/AndroidManifest.xml b/AndroidManifest.xml
index 6bd4f458263..493c8230c29 100644
--- a/AndroidManifest.xml
+++ b/AndroidManifest.xml
@@ -16,6 +16,7 @@
         android:name="com.android.settings.USE_BIOMETRIC_PROVIDER"
         android:protectionLevel="signature|privileged"/>
 
+    <uses-permission android:name="android.permission.SHUTDOWN" />
     <uses-permission android:name="android.permission.REQUEST_NETWORK_SCORES" />
     <uses-permission android:name="android.permission.WRITE_MEDIA_STORAGE" />
     <uses-permission android:name="android.permission.MANAGE_EXTERNAL_STORAGE" />
@@ -5428,6 +5429,43 @@
             </intent-filter>
         </receiver>
 
+        <!-- Scheduled Power -->
+        <activity
+            android:name="Settings$ScheduledPowerSettingsActivity"
+            android:label="@string/schedule_power_settings_title"
+            android:exported="true">
+            <intent-filter android:priority="1">
+                <action android:name="android.settings.SCHEDULED_POWER_SETTINGS" />
+                <category android:name="android.intent.category.BROWSABLE" />
+                <category android:name="android.intent.category.DEFAULT" />
+            </intent-filter>
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <action android:name="android.intent.action.SCHEDULED_POWER_SETTINGS" />
+                <category android:name="android.intent.category.VOICE_LAUNCH" />
+                <category android:name="android.intent.category.DEFAULT" />
+            </intent-filter>
+            <meta-data android:name="com.android.settings.FRAGMENT_CLASS"
+                android:value="com.android.settings.scheduledpower.ScheduledPowerSettings" />
+            <meta-data android:name="com.android.settings.HIGHLIGHT_MENU_KEY"
+                       android:value="@string/menu_key_system"/>
+            <meta-data android:name="com.android.settings.PRIMARY_PROFILE_CONTROLLED"
+                android:value="true" />
+        </activity>
+        <receiver android:name=".scheduledpower.BootReceiver"
+                  android:enabled="true"
+                  android:exported="true"
+                  android:permission="android.permission.RECEIVE_BOOT_COMPLETED">
+            <intent-filter>
+                <action android:name="android.intent.action.BOOT_COMPLETED" />
+            </intent-filter>
+        </receiver>
+
+        <service
+            android:name=".scheduledpower.ShutdownCountdownService"
+            android:permission="android.permission.FOREGROUND_SERVICE"
+            android:foregroundServiceType="systemExempted"
+            android:exported="false"/>
         <!-- This is the longest AndroidManifest.xml ever. -->
     </application>
 </manifest>
  •  增加广播接收器用于监听开机广播重写开机关机时间

src/com/android/settings/scheduledpower/BootReceiver.java

package com.android.settings.scheduledpower;

import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.provider.Settings;

public class BootReceiver extends BroadcastReceiver {

    @Override
    public void onReceive(Context context, Intent intent) {
        if (Intent.ACTION_BOOT_COMPLETED.equals(intent.getAction())) {
            
            // 取消可能存在的关机倒计时
            Intent cancelIntent = new Intent(context, ShutdownCountdownService.class);
            cancelIntent.setAction(ShutdownCountdownService.ACTION_CANCEL_SHUTDOWN);
            context.startService(cancelIntent);

            // 检查开关状态
            boolean isEnabled = Settings.System.getInt(context.getContentResolver(),
                    Settings.System.POWER_SCHEDULER_STATE, 0) == 1;
            
            if (isEnabled) {
                // 重新设置闹钟
                new ScheduledPowerSwitchController(context, "schedule_power_settings").rescheduleAlarms();
            }
        }
    }
}
  •  增加日期工具类,用于计算下一次重启时间

src/com/android/settings/scheduledpower/DataUtils.java

/*
 * Copyright (C) 2016 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.android.settings.scheduledpower;

import android.content.Context;
import android.content.SharedPreferences;
import android.util.Log;

import androidx.preference.PreferenceManager;

import java.util.Calendar;
import java.util.Collections;
import java.util.HashSet;
import java.util.Set;

public class DataUtils {
    private static final String TAG = "DataUtils";
    private static final String PREFS_NAME = "PowerSchedulerPrefs";
    private static final String POWER_ON_HOUR = "power_on_hour";
    private static final String POWER_ON_MINUTE
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值