Android AlarmManagerService-设置系统时间无效的问题

现象


使用系统接口设置时间生效,查看rtc也设置成功。但是重启后时间为首次开机的时间.

分析


多次测试后发现,设置时间在第一次开机时系统显示的时间之后,重启后时间设置生效;设置在之前,则会还原成第一次系统开机时显示的时间。

所以怀疑时,系统在开机的时候做了时间有效检测.查看AlarmManagerService.java后发现系统会用当前时间和编译固件的时间做对比,如果早于编译时间则使用编译时间为当前时间。

frameworks/base/apex/jobscheduler/service/java/com/android/server/alarm/AlarmManagerService.java

@Override
    public void onStart() {
        mInjector.init();
        mMetricsHelper = new MetricsHelper(getContext(), mLock);

        mListenerDeathRecipient = new IBinder.DeathRecipient() {
            @Override
            public void binderDied() {
            }

            @Override
            public void binderDied(IBinder who) {
                final IAlarmListener listener = IAlarmListener.Stub.asInterface(who);
                removeImpl(null, listener);
            }
        };

        synchronized (mLock) {
            mHandler = new AlarmHandler();
            mConstants = new Constants();

            mAlarmStore = mConstants.LAZY_BATCHING ? new LazyAlarmStore()
                    : new BatchingAlarmStore();
            mAlarmStore.setAlarmClockRemovalListener(mAlarmClockUpdater);

            mAppWakeupHistory = new AppWakeupHistory(Constants.DEFAULT_APP_STANDBY_WINDOW);
            mAllowWhileIdleHistory = new AppWakeupHistory(INTERVAL_HOUR);
            mAllowWhileIdleCompatHistory = new AppWakeupHistory(INTERVAL_HOUR);

            mNextWakeup = mNextNonWakeup = 0;

            // We have to set current TimeZone info to kernel
            // because kernel doesn't keep this after reboot
            setTimeZoneImpl(SystemProperties.get(TIMEZONE_PROPERTY));

            // Ensure that we're booting with a halfway sensible current time.  Use the
            // most recent of Build.TIME, the root file system's timestamp, and the
            // value of the ro.build.date.utc system property (which is in seconds).
            final long systemBuildTime = Long.max(
                    1000L * SystemProperties.getLong("ro.build.date.utc", -1L),
                    Long.max(Environment.getRootDirectory().lastModified(), Build.TIME));
            if (mInjector.getCurrentTimeMillis() < systemBuildTime) {
                Slog.i(TAG, "Current time only " + mInjector.getCurrentTimeMillis()
                        + ", advancing to build time " + systemBuildTime);
                mInjector.setKernelTime(systemBuildTime);
            }

            mPackageManagerInternal = LocalServices.getService(PackageManagerInternal.class);
        ...
        ...
    }

解决办法

屏蔽此处的时间检验即可或者向客户说明情况

    if (mInjector.getCurrentTimeMillis() < systemBuildTime) {
                Slog.i(TAG, "Current time only " + mInjector.getCurrentTimeMillis()
                        + ", advancing to build time " + systemBuildTime);
                mInjector.setKernelTime(systemBuildTime);
            }

你可能感兴趣的:(FAQ,android)