關於設置狀態欄字體顏色,判斷MIUI、flyme系統的一些總結

此博客結合之前一篇博客沉浸式狀態欄使用,當我把ActionBar設置爲白色時,狀態欄背景也是白色,而系統狀態欄的字體顏色默認就是白色,這樣就看不見狀態欄上的內容了,所以我們的需求就是改變狀態欄字體顏色。

通過了解,Android從6.0開始才提供修改狀態欄字體顏色的API,而小米在Android4.4和魅族在Flyme 4提供了自家的修改方法,我們知道MIUI7對應Android4.4、Flyme4對應Android5.0。所以就要判斷手機系統是否爲MIUI基於Android4.4-Android6.0之間,如果是就要使用MIUI自家的方法,如果手機系統爲Flyme基於Android5.0-6.0就要使用Flyme自家的方法。
所以在判斷系統版本時找到了大概以下幾種方式:
一、判斷MIUI
1、通過Properties根據MIUI的key來讀取屬性,實測在小米mix2運行時,在load的時候出現了異常FileNotFoundException,不可行
此方式還有一種單例寫法,自定義一個BuildProperties。

private static boolean isMiUI() {
        try {
            final Properties properties = new Properties();
            // 這裏讀文件有異常 FileNotFoundException
            properties.load(new FileInputStream(new File(Environment.getRootDirectory(), "build.prop")));
            String uiCode = properties.getProperty("ro.miui.ui.version.code", null);
            if (uiCode != null) {
                return true;
            } else {
                return false;
            }
        } catch (final Exception e) {
            return false;
        }
    }

二、判斷Flyme
1、通過反射,此方法在魅族16s上運行在getMethod異常,不可行

public static boolean isFlyme() {
        try {
            final Method method = Build.class.getMethod("hasSmartBar");
            return method != null;
        } catch (final Exception e) {
            return false;
        }
    }

2、通過Build.DISPLAY比對,此方法對判斷Flyme系統可行

private static boolean isFlymeV4OrAbove() {
        String displayId = Build.DISPLAY;
        if (!TextUtils.isEmpty(displayId) && displayId.contains("Flyme")) {
            String[] displayIdArray = displayId.split(" ");
            for (String temp : displayIdArray) {
                //版本號4以上,形如4.x.
                if (temp.matches("^[4-9]\\.(\\d+\\.)+\\S*")) {
                    return true;
                }
            }
        }
        return false;
    }

我用了5部手機做了測試:

在這裏插入圖片描述
從測試結果看魅族的Build.DISPLAY是系統版本號,上面方法2確實可行。從以上結果來看MIUI沒辦法判斷,但是我們觀察上圖發現Build.BRAND是每個手機的品牌名,我們結合Build.VERSION.SDK_INT好像能做到一些事情。

於是我就測試通過VERSION_CODE配合BRAND應該能解決以上問題。
1、當VERSION_CODE大於23(Android6.0),使用原生API設置狀態欄字體顏色;
2、否則,當VERSION_CODE大於19(Android4.4),如果是MIUI就使用小米的方法;
當VERSION_CODE大於21(Android5.0),如果是Flyme就使用魅族的方法。

據統計,經過查看用戶分佈(2018-02-23)Android 6.0之下佔33.27%,小米用戶6.69%,魅族用戶1.08%。所以就Android5.0-Android6.0判斷一下系統,確定使用魅族的方法還是小米的方法,高於Android6.0的都用原生方法,就解決了設置狀態欄字體顏色的問題。

package com.txhl.testapp.utils;

import android.app.Activity;
import android.content.Context;
import android.graphics.Color;
import android.os.Build;
import android.view.View;
import android.view.Window;
import android.view.WindowManager;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;

/**
 * Created by chen.yingjie on 2019/5/29
 * description
 */
public class OsUtil {

    private static final String FLYME = "meizu";
    private static final String MIUI = "Xiaomi";

    public static void setStatusBarDarkMode(Activity activity, boolean isDark) {
        // android 6.0以上用原生方法
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
            Window window = activity.getWindow();
            //設置狀態欄底色白色
            window.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS);
            window.clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
            window.setStatusBarColor(Color.TRANSPARENT);
            if (isDark) {
                // 設置狀態欄字體黑色
                window.getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN);
            } else {
                // 設置狀態欄字體白色
                window.getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_STABLE | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN);
            }
        } else {
            // android 5.0 -- android 6.0
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
                if (isMiUI()) {
                    setMIUIStatusBarMode(activity, isDark);
                } else if (isFlyme()) {
                    setFlymeStatusBarMode(activity, isDark);
                }
            }
        }
    }

    /**
     * 小米修改狀態欄字體顏色
     *
     * MIUI 7 == android 4.4
     *
     * @param activity
     * @param dark
     * @return
     */
    private static boolean setMIUIStatusBarMode(Activity activity, boolean dark) {
        boolean result = false;
        Window window = activity.getWindow();
        if (window != null) {
            Class clazz = window.getClass();
            try {
                int darkModeFlag = 0;
                Class layoutParams = Class.forName("android.view.MiuiWindowManager$LayoutParams");
                Field field = layoutParams.getField("EXTRA_FLAG_STATUS_BAR_DARK_MODE");
                darkModeFlag = field.getInt(layoutParams);
                Method extraFlagField = clazz.getMethod("setExtraFlags", int.class, int.class);
                if (dark) {
                    extraFlagField.invoke(window, darkModeFlag, darkModeFlag);//狀態欄透明且黑色字體
                } else {
                    extraFlagField.invoke(window, 0, darkModeFlag);//清除黑色字體
                }
                result = true;
            } catch (Exception e) {

            }
        }
        return result;
    }

    /**
     * 魅族修改狀態欄字體顏色
     *
     * flyme 4.0 == android 5.0
     *
     * @param activity
     * @param dark
     * @return
     */
    private static boolean setFlymeStatusBarMode(Activity activity, boolean dark) {
        boolean result = false;
        if (activity != null) {
            try {
                WindowManager.LayoutParams lp = activity.getWindow().getAttributes();
                Field darkFlag = WindowManager.LayoutParams.class
                        .getDeclaredField("MEIZU_FLAG_DARK_STATUS_BAR_ICON");
                Field meizuFlags = WindowManager.LayoutParams.class
                        .getDeclaredField("meizuFlags");
                darkFlag.setAccessible(true);
                meizuFlags.setAccessible(true);
                int bit = darkFlag.getInt(null);
                int value = meizuFlags.getInt(lp);
                if (dark) {
                    value |= bit;
                } else {
                    value &= ~bit;
                }
                meizuFlags.setInt(lp, value);
                activity.getWindow().setAttributes(lp);
                result = true;
            } catch (Exception e) {
            }
        }
        return result;
    }

    private static boolean isFlyme() {
        return getBrand().equals(FLYME);
    }

    /**
     * 小米手機,包括紅米
     * @return
     */
    private static boolean isMiUI() {
        return getBrand().equals(MIUI);
    }

    /**
     * 手機品牌
     * 小米:Xiaomi    魅族:meizu    榮耀:HONOR
     * @return
     */
    private static String getBrand() {
        return Build.BRAND;
    }
}

由於網上找個各種博客都不能滿足需求,所以我使用了這個不官方的方式來解決,如果有bug還請大家提出。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章