android4.2 添加永不休眠选项

本文详细解析了Android系统中屏幕休眠时间设置的实现方式,包括配置文件arrays.xml中的时间选项与对应毫秒值,以及如何根据不同语言进行国际化处理,并介绍了主界面显示异常时的代码修复方法。
设置 > 显示 > 休眠

a. 
res/values/arrays.xml
    <string-array name="screen_timeout_entries">

        <item>15 seconds</item>

        <item>30 seconds</item>

        <item>1 minute</item>

        <item>2 minutes</item>

        <item>5 minutes</item>

        <item>10 minutes</item>

        <item>30 minutes</item>

        <item>Never </item>

    </string-array>

<!-- AnsonCode 2012.7.4

+ <item>Never </item>

-->

    <!-- Do not translate. -->

    <string-array name="screen_timeout_values" translatable="false">

        <!-- Do not translate. -->

        <item>15000</item>

        <!-- Do not translate. -->

        <item>30000</item>

        <!-- Do not translate. -->

        <item>60000</item>

        <!-- Do not translate. -->

        <item>120000</item>

        <!-- Do not translate. -->

        <item>300000</item>

        <!-- Do not translate. -->

        <item>600000</item>

        <!-- Do not translate. -->

        <item>1800000</item>

        <item>-1</item>

    </string-array>

<!-- AnsonCode

-1 的值在表示永不休眠。
+ <item>-1</item>

-->


b. 
在其它有定义<string-array name="screen_timeout_entries">
的地方添加一行,用于显示不同语言文字的内容,这是为了解决在不同语言时,如果没有定义,会出现异常退出的情况。大概有50个arrays.xml文件需要修改。
如:res/values-zh-rCN/arrays.xml中(此路径中绿色表示国家语言)
  <string-array name="screen_timeout_entries">

    <item msgid="3342301044271143016">"15 秒"</item>

    <item msgid="8881760709354815449">"30 秒"</item>

    <item msgid="7589406073232279088">"1 分钟"</item>

    <item msgid="7001195990902244174">"2 分钟"</item>

    <item msgid="7489864775127957179">"5 分钟"</item>

    <item msgid="2314124409517439288">"10 分钟"</item>

    <item msgid="6864027152847611413">"30 分钟"</item>

    <item msgid="6864027952847611413">"从不"</item>

  </string-array>


c.
在作出以上修改后,主界面的显示会不正常,需要在代码中加以下处理:
找到如下方法:
private void updateTimeoutPreferenceDescription(long currentTimeout) {

        ListPreference preference = mScreenTimeoutPreference;

        String summary;

        if (currentTimeout < -1) {

        //if (currentTimeout < 0) { AnsonCode2012.7.4

            // Unsupported value

            summary = "";

        } else {

            final CharSequence[] entries = preference.getEntries();

            final CharSequence[] values = preference.getEntryValues();

            int best = 0;

            for (int i = 0; i < values.length; i++) {

                long timeout = Long.parseLong(values[i].toString());

                if (currentTimeout == timeout) {

                    best = i;

                    break;////AnsonCode2012.7.4

                }

            }

            summary = preference.getContext().getString(R.string.screen_timeout_summary,

                    entries[best]);

            if(currentTimeout < 0)summary = entries[best].toString();//AnsonCode2012.7.4

        }

        preference.setSummary(summary);

    }


//注意与原来代码的区别:
//1) 修改 0 改为-1, 为保证,在界面中,显示的文字不为空。
//2)将 >=改为 ==是作一个准确判断,找到所设定的值便返回,退出循环;
//3)不加此句内容,在界面上会显示: 无操作 从不 后, 加了以后则显示: 从不

//在4.2上稍微有些不同, 主要是修改了对时间值的判断。
    private static final int DEFAULT_SCREEN_OFF_TIMEOUT = 15 * 1000;
    private static final int MINIMUM_SCREEN_OFF_TIMEOUT = 10 * 1000;
    private int getScreenOffTimeoutLocked() {
        int timeout = mScreenOffTimeoutSetting;
        if (isMaximumScreenOffTimeoutFromDeviceAdminEnforcedLocked()) {
            timeout = Math.min(timeout, mMaximumScreenOffTimeoutFromDeviceAdmin);
        }
        if (mUserActivityTimeoutOverrideFromWindowManager >= 0) {
            timeout = (int)Math.min(timeout, mUserActivityTimeoutOverrideFromWindowManager);
        }
        return Math.max(timeout, MINIMUM_SCREEN_OFF_TIMEOUT);
    }


 /**
     * Updates the value of mUserActivitySummary to summarize the user requested
     * state of the system such as whether the screen should be bright or dim.
     * Note that user activity is ignored when the system is asleep.
     *
     * This function must have no other side-effects.
     */
    private void updateUserActivitySummaryLocked(long now, int dirty) {
        // Update the status of the user activity timeout timer.
        if ((dirty & (DIRTY_USER_ACTIVITY | DIRTY_WAKEFULNESS | DIRTY_SETTINGS)) != 0) {
            mHandler.removeMessages(MSG_USER_ACTIVITY_TIMEOUT);

            long nextTimeout = 0;
            if (mWakefulness != WAKEFULNESS_ASLEEP) {
                final int screenOffTimeout = getScreenOffTimeoutLocked();
                final int screenDimDuration = getScreenDimDurationLocked(screenOffTimeout);

                mUserActivitySummary = 0;
                if (mLastUserActivityTime >= mLastWakeTime) {
                    nextTimeout = mLastUserActivityTime
                            + screenOffTimeout - screenDimDuration;
                    if (now < nextTimeout) {
                        mUserActivitySummary |= USER_ACTIVITY_SCREEN_BRIGHT;
                    } else {
                        nextTimeout = mLastUserActivityTime + screenOffTimeout;
                        if (now < nextTimeout) {
                            mUserActivitySummary |= USER_ACTIVITY_SCREEN_DIM;
                        }
                    }
                }
                if (mUserActivitySummary == 0
                        && mLastUserActivityTimeNoChangeLights >= mLastWakeTime) {
                    nextTimeout = mLastUserActivityTimeNoChangeLights + screenOffTimeout;
                    if (now < nextTimeout
                            && mDisplayPowerRequest.screenState
                                    != DisplayPowerRequest.SCREEN_STATE_OFF) {
                        mUserActivitySummary = mDisplayPowerRequest.screenState
                                == DisplayPowerRequest.SCREEN_STATE_BRIGHT ?
                                USER_ACTIVITY_SCREEN_BRIGHT : USER_ACTIVITY_SCREEN_DIM;
                    }
                }
                if (mUserActivitySummary != 0) {
                    Message msg = mHandler.obtainMessage(MSG_USER_ACTIVITY_TIMEOUT);
                    msg.setAsynchronous(true);
                    ///mHandler.sendMessageAtTime(msg, nextTimeout);
					if(mScreenOffTimeoutSetting > 0)mHandler.sendMessageAtTime(msg, nextTimeout);//添加了一行判断, 如果值为-1则不发送广播
                }
            } else {
                mUserActivitySummary = 0;
            }

            if (DEBUG_SPEW) {
                Slog.d(TAG, "updateUserActivitySummaryLocked: mWakefulness="
                        + wakefulnessToString(mWakefulness)
                        + ", mUserActivitySummary=0x" + Integer.toHexString(mUserActivitySummary)
                        + ", nextTimeout=" + TimeUtils.formatUptime(nextTimeout));
            }
        }
    }

 

 

 

 

 

<think> 我们参考用户提供的引用资料,用户的需求是在Android 13系统中设置永不休眠(即屏幕常亮)。根据引用资料,我们可以总结出几种方法: 1. **应用层解决方案**:在应用中使用WakeLock或者设置窗口标志(FLAG_KEEP_SCREEN_ON)来保持屏幕常亮。但用户提到之前设置的永不休眠权限变成了30秒,所以可能需要更系统级的设置。 2. **修改系统设置**(需要系统权限或root): - 引用[2]提到在MTK平台的Android 12-13上,通过修改SettingsProvider和PowerManagerService的代码实现永不休眠。 - 引用[3]提到两种方法:一种是通过修改`settings_global.xml`中的`sleep_timeout`为最大值(但可能因平台而异),另一种是设置一个足够大的值(如Integer.MAX_VALUE)。 3. **ADB指令**:引用[1]提到使用ADB指令,这可能是无需修改系统源码的方法,但需要具体指令。 由于用户明确要求Android 13系统设置永不休眠,且用户提到“本人不涉及系统层面”,所以可能更倾向于非编译系统的方法(如ADB或应用层设置)。但用户之前的应用层设置失效,因此我们提供多种方案: **方案1:应用层设置(推荐)** 在Activity中设置窗口标志,这样当应用在前台时屏幕保持常亮。这种方法不需要系统权限。 ```java // 在Activity的onCreate方法中添加 getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON); ``` 或者,在布局XML中,在根视图添加属性: ```xml android:keepScreenOn="true" ``` 注意:这种方法只在应用运行期间有效,退出应用或进入后台后失效。 **方案2:修改系统设置(需要ADB或系统权限)** 通过ADB修改系统设置,将屏幕超时设置为最大值(可能实现永不休眠): ```shell adb shell settings put system screen_off_timeout 2147483647 ``` 这里2147483647是Integer.MAX_VALUE(最大值),理论上约为24天,但实际可能受系统限制。在有些系统上,设置为-1可能表示永不休眠,但需测试。 另外,也可以尝试修改全局设置(需要系统权限): ```shell adb shell settings put global stay_on_while_plugged_in 3 ``` 这个设置表示在充电时保持屏幕常亮(3代表AC、USB、Wireless三种充电方式都保持)。但注意,拔掉充电器后可能失效。 **方案3:修改系统源码(需要系统开发权限)** 如引用[2]所述,修改PowerManagerService.java,找到设置休眠时间的地方,将默认休眠时间改为永久。例如,在`PowerManagerService`中,设置屏幕超时时间为一个很大的值(如Integer.MAX_VALUE)或者修改相关逻辑。 具体修改点可能如下(仅供参考,需根据实际代码调整): ```java // 在PowerManagerService.java中,找到设置超时的地方,例如: mScreenOffTimeoutSetting = Integer.MAX_VALUE; ``` 同时,需要修改设置中的选项添加永不休眠”的选项,并确保在设置中选择该选项时传递最大值。 **方案4:使用设备管理员权限(DevicePolicyManager)** 如果设备是工作场景,可以使用DevicePolicyManager的setMaximumTimeToLock方法设置一个很大的超时时间,但这需要设备管理员权限。 ```java ComponentName adminComponent = new ComponentName(context, DeviceAdminReceiver.class); DevicePolicyManager dpm = (DevicePolicyManager) context.getSystemService(Context.DEVICE_POLICY_SERVICE); dpm.setMaximumTimeToLock(adminComponent, Integer.MAX_VALUE); ``` 然后,还需要设置锁屏超时(可能还需要设置屏幕超时): ```java dpm.setMaximumScreenTimeout(adminComponent, Integer.MAX_VALUE); ``` 注意:此方法需要用户激活设备管理员,并且可能不适用于所有设备。 **总结建议**: - 如果只是应用需要,使用方案1(FLAG_KEEP_SCREEN_ON)是最简单且安全的。 - 如果希望整个系统永不休眠(且设备已root或可刷机),可以尝试方案2的ADB命令(设置一个很大的超时值)或者方案3(修改系统源码)。 - 如果设备用于企业场景,方案4可能适用。 请根据实际设备情况和权限选择合适的方案。 §§相关问题§§ 1.Android应用层如何保持屏幕常亮而不影响系统其他部分? 2. 使用ADB设置屏幕永不休眠的具体步骤是什么? 3. 如何通过修改Android系统源码实现永不休眠功能? 4. 设备管理员权限在屏幕常亮设置中有什么作用? </think> 在Android 13系统中设置永不休眠(屏幕常亮)有以下几种方法,根据系统权限层级由浅入深排列: ### 一、应用层实现(无需root) 1. **窗口标志法** 在Activity的`onCreate()`中添加代码: ```java getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON); ``` 或直接在XML布局中设置: ```xml android:keepScreenOn="true" ``` > ✅ 优点:无需特殊权限 > ❌ 限制:仅当前Activity在前台时生效[^1] 2. **WakeLock API** ```java PowerManager pm = (PowerManager) getSystemService(POWER_SERVICE); PowerManager.WakeLock wakeLock = pm.newWakeLock( PowerManager.SCREEN_BRIGHT_WAKE_LOCK, "MyApp:WakeLockTag"); wakeLock.acquire(); ``` > ⚠️ 需添加权限:`<uses-permission android:name="android.permission.WAKE_LOCK"/>` --- ### 二、系统设置修改(需ADB/root) 1. **ADB命令修改超时** ```bash adb shell settings put system screen_off_timeout 2147483647 # 设置为最大值 ``` > 📌 数值说明:`2147483647` = `Integer.MAX_VALUE`(约24.8天)[^3] 2. **修改全局配置文件** 修改`/data/system/users/0/settings_global.xml`: ```xml <setting name="screen_off_timeout" value="2147483647" /> ``` --- ### 三、系统源码级修改(需编译权限) 适用于设备制造商或ROM开发者: 1. **修改默认息屏设置** 编辑`/vendor/mediatek/proprietary/packages/apps/SettingsProvider/res/values/defaults.xml`: ```xml <integer name="def_screen_off_timeout">2147483647</integer> ``` 2. **修改电源管理服务** 在`PowerManagerService.java`中强制设置超时值: ```java // frameworks/base/services/core/java/com/android/server/power/PowerManagerService.java mScreenOffTimeoutSetting = Integer.MAX_VALUE; // 永不休眠 ``` 3. **添加永不休眠选项** 在系统设置菜单中增加选项(修改`arrays.xml`): ```xml <!-- /vendor/mediatek/proprietary/packages/apps/MtkSettings/res/values/arrays.xml --> <string-array name="screen_timeout_entries"> <item>永不</item> </string-array> <integer-array name="screen_timeout_values"> <item>2147483647</item> </integer-array> ``` > 🔧 系统级修改需重新编译ROM并刷机[^2] --- ### ⚠️ 注意事项 1. 永不休眠会显著增加功耗并可能导致烧屏 2. 应用层方案在应用退出后失效 3. 系统级修改需要设备解锁Bootloader 4. Android 13对后台唤醒限制更严格,需测试兼容性 建议优先尝试应用层方案,如需全局生效且设备已root,可使用ADB命令方案。系统开发者应采用源码级修改实现标准化支持[^3]。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符  | 博主筛选后可见
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值