如何根据白天或夜晚更改背景图片 android

how to change a background image depending on whether it is day or night android

我想知道如何在我的 android 应用程序中根据白天或晚上更改背景图片。

独立打开应用程序,只取决于是晚上还是白天。

谢谢!

有两种方法可以做到这一点

  1. 使用手机上可用的光传感器。

  2. 使用手机时间。

    Calendar c = Calendar.getInstance();
    int timeOfDay = c.get(Calendar.HOUR_OF_DAY);
    
    if(timeOfDay >= 0 && timeOfDay < 12){
        Toast.makeText(this, "Good Morning", Toast.LENGTH_SHORT).show();        
    }else if(timeOfDay >= 12 && timeOfDay < 16){
        Toast.makeText(this, "Good Afternoon", Toast.LENGTH_SHORT).show();
    }else if(timeOfDay >= 16 && timeOfDay < 21){
        Toast.makeText(this, "Good Evening", Toast.LENGTH_SHORT).show();
    }else if(timeOfDay >= 21 && timeOfDay < 24){
        Toast.makeText(this, "Good Night", Toast.LENGTH_SHORT).show();
    }
    

尝试用 AM/PM 获取您 Android 的当前时间,

Calendar now = Calendar.getInstance();
int a = now.get(Calendar.AM_PM);
if(a == Calendar.AM)
   System.out.println("AM"+now.get(Calendar.HOUR));

现在再次检查时间以设置白天和黑夜,例如,如果 8:00 下午是晚上,如果 10:00 上午是白天。

当您的应用程序打开时,然后调用以下函数:

Calendar c = Calendar.getInstance();
int timeOfDay = c.get(Calendar.HOUR_OF_DAY);

if(timeOfDay >= 0 && timeOfDay < 12){
   view.setBackground(R.mipmap.img1);     
}else if(timeOfDay >= 12 && timeOfDay < 16){
   view.setBackground(R.mipmap.img2);  
}else if(timeOfDay >= 16 && timeOfDay < 21){
    view.setBackground(R.mipmap.img3);  
}else if(timeOfDay >= 21 && timeOfDay < 24){
    view.setBackground(R.mipmap.img4);  
}

如果你想改变闪屏背景那么你需要把上面的代码片段放在应用程序 class

public class ApplicationController 扩展应用程序 {

@Override
public void onCreate() {
    super.onCreate();
Calendar c = Calendar.getInstance();
    int timeOfDay = c.get(Calendar.HOUR_OF_DAY);

    if(timeOfDay >= 0 && timeOfDay < 12){
    Global.drawable = getResources().getDrawable(R.mipmap.img1)
    }else if(timeOfDay >= 12 && timeOfDay < 16){
        Global.drawable = getResources().getDrawable(R.mipmap.img2)
    }else if(timeOfDay >= 16 && timeOfDay < 21){
            Global.drawable = getResources().getDrawable(R.mipmap.img3)
    }else if(timeOfDay >= 21 && timeOfDay < 24){
            Global.drawable = getResources().getDrawable(R.mipmap.img4)
    }

   }

}

使用Global.drawable作为闪屏背景。 清单:

  <application
        android:name=".ApplicationController"

当前时间并不能真正告诉您是晚上还是白天,因为在世界上不同的地方(取决于 north/south 您的情况)您将在不同的时间进入夜晚。 不仅如此,一年四季,日落和日出的时间每天都在变化。

您需要做的是首先获取设备的位置(或至少是它的估计值),然后进行一些计算。

Google 最近发布 (here) 它的代码可用但已弃用(因为性能不佳)。它实际上用于与您写的相同的目的:根据现在是否是晚上设置 dark/light 主题。

用法:

private void updateUi(Location location) {
    if (location != null) {
        TwilightCalculator twilightCalculator = TwilightCalculator.getInstance();
        twilightCalculator.calculateTwilight(System.currentTimeMillis(), location.getLatitude(), location.getLongitude());
        boolean isDay = twilightCalculator.state == TwilightCalculator.DAY;
        locationTv.setText("Latitude : " + location.getLatitude() + "\nLongitude : " + location.getLongitude() + "\nIsDay?" + isDay);
    }
}

代码

AndroidX:https://android.googlesource.com/platform/frameworks/support/+/androidx-master-dev/appcompat/src/main/java/androidx/appcompat/app/TwilightCalculator.java

/*
 * Copyright (C) 2015 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 androidx.appcompat.app;
import android.text.format.DateUtils;
/**
 * Imported from frameworks/base/services/core/java/com/android/server/TwilightCalculator.java
 *
 * <p>Calculates the sunrise and sunsets times for a given location.</p>
 */
class TwilightCalculator {
    private static TwilightCalculator sInstance;
    static TwilightCalculator getInstance() {
        if (sInstance == null) {
            sInstance = new TwilightCalculator();
        }
        return sInstance;
    }
    /** Value of {@link #state} if it is currently day */
    public static final int DAY = 0;
    /** Value of {@link #state} if it is currently night */
    public static final int NIGHT = 1;
    private static final float DEGREES_TO_RADIANS = (float) (Math.PI / 180.0f);
    // element for calculating solar transit.
    private static final float J0 = 0.0009f;
    // correction for civil twilight
    @SuppressWarnings("FloatingPointLiteralPrecision")
    private static final float ALTIDUTE_CORRECTION_CIVIL_TWILIGHT = -0.104719755f;
    // coefficients for calculating Equation of Center.
    private static final float C1 = 0.0334196f;
    private static final float C2 = 0.000349066f;
    private static final float C3 = 0.000005236f;
    @SuppressWarnings("FloatingPointLiteralPrecision")
    private static final float OBLIQUITY = 0.40927971f;
    // Java time on Jan 1, 2000 12:00 UTC.
    private static final long UTC_2000 = 946728000000L;
    /**
     * Time of sunset (civil twilight) in milliseconds or -1 in the case the day
     * or night never ends.
     */
    public long sunset;
    /**
     * Time of sunrise (civil twilight) in milliseconds or -1 in the case the
     * day or night never ends.
     */
    public long sunrise;
    /**
     * Current state
     */
    public int state;
    /**
     * calculates the civil twilight bases on time and geo-coordinates.
     *
     * @param time time in milliseconds.
     * @param latitude latitude in degrees.
     * @param longitude latitude in degrees.
     */
    @SuppressWarnings("FloatingPointLiteralPrecision")
    public void calculateTwilight(long time, double latitude, double longitude) {
        final float daysSince2000 = (float) (time - UTC_2000) / DateUtils.DAY_IN_MILLIS;
        // mean anomaly
        final float meanAnomaly = 6.240059968f + daysSince2000 * 0.01720197f;
        // true anomaly
        final double trueAnomaly = meanAnomaly + C1 * Math.sin(meanAnomaly) + C2
                * Math.sin(2 * meanAnomaly) + C3 * Math.sin(3 * meanAnomaly);
        // ecliptic longitude
        final double solarLng = trueAnomaly + 1.796593063d + Math.PI;
        // solar transit in days since 2000
        final double arcLongitude = -longitude / 360;
        float n = Math.round(daysSince2000 - J0 - arcLongitude);
        double solarTransitJ2000 = n + J0 + arcLongitude + 0.0053d * Math.sin(meanAnomaly)
                + -0.0069d * Math.sin(2 * solarLng);
        // declination of sun
        double solarDec = Math.asin(Math.sin(solarLng) * Math.sin(OBLIQUITY));
        final double latRad = latitude * DEGREES_TO_RADIANS;
        double cosHourAngle = (Math.sin(ALTIDUTE_CORRECTION_CIVIL_TWILIGHT) - Math.sin(latRad)
                * Math.sin(solarDec)) / (Math.cos(latRad) * Math.cos(solarDec));
        // The day or night never ends for the given date and location, if this value is out of
        // range.
        if (cosHourAngle >= 1) {
            state = NIGHT;
            sunset = -1;
            sunrise = -1;
            return;
        } else if (cosHourAngle <= -1) {
            state = DAY;
            sunset = -1;
            sunrise = -1;
            return;
        }
        float hourAngle = (float) (Math.acos(cosHourAngle) / (2 * Math.PI));
        sunset = Math.round((solarTransitJ2000 + hourAngle) * DateUtils.DAY_IN_MILLIS) + UTC_2000;
        sunrise = Math.round((solarTransitJ2000 - hourAngle) * DateUtils.DAY_IN_MILLIS) + UTC_2000;
        if (sunrise < time && sunset > time) {
            state = DAY;
        } else {
            state = NIGHT;
        }
    }
}

平台:

https://android.googlesource.com/platform/frameworks/base/+/refs/heads/master/services/core/java/com/android/server/twilight/TwilightService.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.server.twilight;
import android.annotation.NonNull;
import android.app.AlarmManager;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.icu.impl.CalendarAstronomer;
import android.icu.util.Calendar;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
import android.os.Message;
import android.util.ArrayMap;
import android.util.Slog;
import com.android.internal.annotations.GuardedBy;
import com.android.server.SystemService;
import java.util.Objects;
/**
 * Figures out whether it's twilight time based on the user's location.
 * <p>
 * Used by the UI mode manager and other components to adjust night mode
 * effects based on sunrise and sunset.
 */
public final class TwilightService extends SystemService
        implements AlarmManager.OnAlarmListener, Handler.Callback, LocationListener {
    private static final String TAG = "TwilightService";
    private static final boolean DEBUG = false;
    private static final int MSG_START_LISTENING = 1;
    private static final int MSG_STOP_LISTENING = 2;
    @GuardedBy("mListeners")
    private final ArrayMap<TwilightListener, Handler> mListeners = new ArrayMap<>();
    private final Handler mHandler;
    protected AlarmManager mAlarmManager;
    private LocationManager mLocationManager;
    private boolean mBootCompleted;
    private boolean mHasListeners;
    private BroadcastReceiver mTimeChangedReceiver;
    protected Location mLastLocation;
    @GuardedBy("mListeners")
    protected TwilightState mLastTwilightState;
    public TwilightService(Context context) {
        super(context);
        mHandler = new Handler(Looper.getMainLooper(), this);
    }
    @Override
    public void onStart() {
        publishLocalService(TwilightManager.class, new TwilightManager() {
            @Override
            public void registerListener(@NonNull TwilightListener listener,
                    @NonNull Handler handler) {
                synchronized (mListeners) {
                    final boolean wasEmpty = mListeners.isEmpty();
                    mListeners.put(listener, handler);
                    if (wasEmpty && !mListeners.isEmpty()) {
                        mHandler.sendEmptyMessage(MSG_START_LISTENING);
                    }
                }
            }
            @Override
            public void unregisterListener(@NonNull TwilightListener listener) {
                synchronized (mListeners) {
                    final boolean wasEmpty = mListeners.isEmpty();
                    mListeners.remove(listener);
                    if (!wasEmpty && mListeners.isEmpty()) {
                        mHandler.sendEmptyMessage(MSG_STOP_LISTENING);
                    }
                }
            }
            @Override
            public TwilightState getLastTwilightState() {
                synchronized (mListeners) {
                    return mLastTwilightState;
                }
            }
        });
    }
    @Override
    public void onBootPhase(int phase) {
        if (phase == PHASE_BOOT_COMPLETED) {
            final Context c = getContext();
            mAlarmManager = (AlarmManager) c.getSystemService(Context.ALARM_SERVICE);
            mLocationManager = (LocationManager) c.getSystemService(Context.LOCATION_SERVICE);
            mBootCompleted = true;
            if (mHasListeners) {
                startListening();
            }
        }
    }
    @Override
    public boolean handleMessage(Message msg) {
        switch (msg.what) {
            case MSG_START_LISTENING:
                if (!mHasListeners) {
                    mHasListeners = true;
                    if (mBootCompleted) {
                        startListening();
                    }
                }
                return true;
            case MSG_STOP_LISTENING:
                if (mHasListeners) {
                    mHasListeners = false;
                    if (mBootCompleted) {
                        stopListening();
                    }
                }
                return true;
        }
        return false;
    }
    private void startListening() {
        Slog.d(TAG, "startListening");
        // Start listening for location updates (default: low power, max 1h, min 10m).
        mLocationManager.requestLocationUpdates(
                null /* default */, this, Looper.getMainLooper());
        // Request the device's location immediately if a previous location isn't available.
        if (mLocationManager.getLastLocation() == null) {
            if (mLocationManager.isProviderEnabled(LocationManager.NETWORK_PROVIDER)) {
                mLocationManager.requestSingleUpdate(
                        LocationManager.NETWORK_PROVIDER, this, Looper.getMainLooper());
            } else if (mLocationManager.isProviderEnabled(LocationManager.GPS_PROVIDER)) {
                mLocationManager.requestSingleUpdate(
                        LocationManager.GPS_PROVIDER, this, Looper.getMainLooper());
            }
        }
        // Update whenever the system clock is changed.
        if (mTimeChangedReceiver == null) {
            mTimeChangedReceiver = new BroadcastReceiver() {
                @Override
                public void onReceive(Context context, Intent intent) {
                    Slog.d(TAG, "onReceive: " + intent);
                    updateTwilightState();
                }
            };
            final IntentFilter intentFilter = new IntentFilter(Intent.ACTION_TIME_CHANGED);
            intentFilter.addAction(Intent.ACTION_TIMEZONE_CHANGED);
            getContext().registerReceiver(mTimeChangedReceiver, intentFilter);
        }
        // Force an update now that we have listeners registered.
        updateTwilightState();
    }
    private void stopListening() {
        Slog.d(TAG, "stopListening");
        if (mTimeChangedReceiver != null) {
            getContext().unregisterReceiver(mTimeChangedReceiver);
            mTimeChangedReceiver = null;
        }
        if (mLastTwilightState != null) {
            mAlarmManager.cancel(this);
        }
        mLocationManager.removeUpdates(this);
        mLastLocation = null;
    }
    private void updateTwilightState() {
        // Calculate the twilight state based on the current time and location.
        final long currentTimeMillis = System.currentTimeMillis();
        final Location location = mLastLocation != null ? mLastLocation
                : mLocationManager.getLastLocation();
        final TwilightState state = calculateTwilightState(location, currentTimeMillis);
        if (DEBUG) {
            Slog.d(TAG, "updateTwilightState: " + state);
        }
        // Notify listeners if the state has changed.
        synchronized (mListeners) {
            if (!Objects.equals(mLastTwilightState, state)) {
                mLastTwilightState = state;
                for (int i = mListeners.size() - 1; i >= 0; --i) {
                    final TwilightListener listener = mListeners.keyAt(i);
                    final Handler handler = mListeners.valueAt(i);
                    handler.post(new Runnable() {
                        @Override
                        public void run() {
                            listener.onTwilightStateChanged(state);
                        }
                    });
                }
            }
        }
        // Schedule an alarm to update the state at the next sunrise or sunset.
        if (state != null) {
            final long triggerAtMillis = state.isNight()
                    ? state.sunriseTimeMillis() : state.sunsetTimeMillis();
            mAlarmManager.setExact(AlarmManager.RTC, triggerAtMillis, TAG, this, mHandler);
        }
    }
    @Override
    public void onAlarm() {
        Slog.d(TAG, "onAlarm");
        updateTwilightState();
    }
    @Override
    public void onLocationChanged(Location location) {
        // Location providers may erroneously return (0.0, 0.0) when they fail to determine the
        // device's location. These location updates can be safely ignored since the chance of a
        // user actually being at these coordinates is quite low.
        if (location != null
                && !(location.getLongitude() == 0.0 && location.getLatitude() == 0.0)) {
            Slog.d(TAG, "onLocationChanged:"
                    + " provider=" + location.getProvider()
                    + " accuracy=" + location.getAccuracy()
                    + " time=" + location.getTime());
            mLastLocation = location;
            updateTwilightState();
        }
    }
    @Override
    public void onStatusChanged(String provider, int status, Bundle extras) {
    }
    @Override
    public void onProviderEnabled(String provider) {
    }
    @Override
    public void onProviderDisabled(String provider) {
    }
    /**
     * Calculates the twilight state for a specific location and time.
     *
     * @param location the location to use
     * @param timeMillis the reference time to use
     * @return the calculated {@link TwilightState}, or {@code null} if location is {@code null}
     */
    private static TwilightState calculateTwilightState(Location location, long timeMillis) {
        if (location == null) {
            return null;
        }
        final CalendarAstronomer ca = new CalendarAstronomer(
                location.getLongitude(), location.getLatitude());
        final Calendar noon = Calendar.getInstance();
        noon.setTimeInMillis(timeMillis);
        noon.set(Calendar.HOUR_OF_DAY, 12);
        noon.set(Calendar.MINUTE, 0);
        noon.set(Calendar.SECOND, 0);
        noon.set(Calendar.MILLISECOND, 0);
        ca.setTime(noon.getTimeInMillis());
        long sunriseTimeMillis = ca.getSunRiseSet(true /* rise */);
        long sunsetTimeMillis = ca.getSunRiseSet(false /* rise */);
        if (sunsetTimeMillis < timeMillis) {
            noon.add(Calendar.DATE, 1);
            ca.setTime(noon.getTimeInMillis());
            sunriseTimeMillis = ca.getSunRiseSet(true /* rise */);
        } else if (sunriseTimeMillis > timeMillis) {
            noon.add(Calendar.DATE, -1);
            ca.setTime(noon.getTimeInMillis());
            sunsetTimeMillis = ca.getSunRiseSet(false /* rise */);
        }
        return new TwilightState(sunriseTimeMillis, sunsetTimeMillis);
    }
}