在Android设备上,状态栏是用户界面的重要组成部分。它包含了各种系统图标,如电池、信号强度、时间等。有时候,我们可能希望屏蔽某个特定的图标,使其在状态栏中不显示。本文将详细介绍如何通过修改代码来实现这一目标。
首先,我们需要创建一个自定义的 Android 应用程序,并在其中修改 SystemUI 的源代码。以下是一些关键步骤,供你参考:
首先,在 Android 开发环境中创建一个新的 Android 项目。你可以使用 Android Studio 或其他适合的开发工具。
在项目结构中导入 SystemUI 的源代码。SystemUI 是 Android 系统的一部分,它负责管理状态栏和其他系统UI元素。
在 SystemUI 源代码中,你需要找到负责状态栏图标布局的文件。该文件通常位于 frameworks/base/packages/SystemUI/res/layout
目录下,名为 status_bar.xml
或类似的名称。
在状态栏图标布局文件中,查找要屏蔽的图标。这些图标通常以
元素的形式存在,并且每个图标都有一个唯一的标识符。
找到要屏蔽的图标后,你可以通过修改其可见性来使其不显示。在 Java 代码中,你可以使用 setVisibility()
方法来实现。以下是一些示例代码:
在Android的系统中, 状态栏的lcon管理控制是由StatusBarlconController.java 来负责的,所以我们可以阅读其源码,查找解决方案。类代码路径:
frameworks/base/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarIconController.java
重点关注 getIconHideList
注释解释 /** Reads the default hide list from config value unless hideListStr is provided. */
“除非提供了hideListStr,否则从配置值中读取默认的隐藏列表。”
static ArraySet
.....
String[] hideList = hideListStr == null
? context.getResources().getStringArray(R.array.config_statusBarIconsToExclude)
: hideListStr.split(",");
...
config_statusBarIconsToExclude默认配置
/*
* Copyright (C) 2017 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.systemui.statusbar.phone;
import static com.android.systemui.statusbar.phone.StatusBarIconHolder.TYPE_ICON;
import static com.android.systemui.statusbar.phone.StatusBarIconHolder.TYPE_MOBILE;
import static com.android.systemui.statusbar.phone.StatusBarIconHolder.TYPE_WIFI;
import android.annotation.Nullable;
import android.content.Context;
import android.os.Bundle;
import android.text.TextUtils;
import android.util.ArraySet;
import android.view.Gravity;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.LinearLayout.LayoutParams;
import androidx.annotation.VisibleForTesting;
import com.android.internal.statusbar.StatusBarIcon;
import com.android.systemui.Dependency;
import com.android.systemui.R;
import com.android.systemui.demomode.DemoModeCommandReceiver;
import com.android.systemui.plugins.DarkIconDispatcher;
import com.android.systemui.plugins.DarkIconDispatcher.DarkReceiver;
import com.android.systemui.statusbar.FeatureFlags;
import com.android.systemui.statusbar.StatusBarIconView;
import com.android.systemui.statusbar.StatusBarMobileView;
import com.android.systemui.statusbar.StatusBarWifiView;
import com.android.systemui.statusbar.StatusIconDisplayable;
import com.android.systemui.statusbar.phone.StatusBarSignalPolicy.CallIndicatorIconState;
import com.android.systemui.statusbar.phone.StatusBarSignalPolicy.MobileIconState;
import com.android.systemui.statusbar.phone.StatusBarSignalPolicy.WifiIconState;
import java.util.ArrayList;
import java.util.List;
public interface StatusBarIconController {
/**
* When an icon is added with TAG_PRIMARY, it will be treated as the primary icon
* in that slot and not added as a sub slot.
*/
int TAG_PRIMARY = 0;
/** */
void addIconGroup(IconManager iconManager);
/** */
void removeIconGroup(IconManager iconManager);
/** */
void setExternalIcon(String slot);
/** */
void setIcon(String slot, int resourceId, CharSequence contentDescription);
/** */
void setIcon(String slot, StatusBarIcon icon);
/** */
void setSignalIcon(String slot, WifiIconState state);
/** */
void setMobileIcons(String slot, List states);
/**
* Display the no calling & SMS icons.
*/
void setCallStrengthIcons(String slot, List states);
/**
* Display the no calling & SMS icons.
*/
void setNoCallingIcons(String slot, List states);
public void setIconVisibility(String slot, boolean b);
/**
* Sets the live region mode for the icon
* @see android.view.View#setAccessibilityLiveRegion(int)
* @param slot Icon slot to set region for
* @param accessibilityLiveRegion live region mode for the icon
*/
void setIconAccessibilityLiveRegion(String slot, int accessibilityLiveRegion);
/**
* If you don't know what to pass for `tag`, either remove all icons for slot, or use
* TAG_PRIMARY to refer to the first icon at a given slot.
*/
void removeIcon(String slot, int tag);
/** */
void removeAllIconsForSlot(String slot);
// TODO: See if we can rename this tunable name.
String ICON_HIDE_LIST = "icon_blacklist";
/** Reads the default hide list from config value unless hideListStr is provided. */
static ArraySet getIconHideList(Context context, String hideListStr) {
ArraySet ret = new ArraySet<>();
String[] hideList = hideListStr == null
? context.getResources().getStringArray(R.array.config_statusBarIconsToExclude)
: hideListStr.split(",");
for (String slot : hideList) {
if (!TextUtils.isEmpty(slot)) {
ret.add(slot);
}
}
return ret;
}
/**
* Version of ViewGroup that observes state from the DarkIconDispatcher.
*/
class DarkIconManager extends IconManager {
private final DarkIconDispatcher mDarkIconDispatcher;
private int mIconHPadding;
public DarkIconManager(LinearLayout linearLayout, FeatureFlags featureFlags) {
super(linearLayout, featureFlags);
mIconHPadding = mContext.getResources().getDimensionPixelSize(
R.dimen.status_bar_icon_padding);
mDarkIconDispatcher = Dependency.get(DarkIconDispatcher.class);
}
@Override
protected void onIconAdded(int index, String slot, boolean blocked,
StatusBarIconHolder holder) {
StatusIconDisplayable view = addHolder(index, slot, blocked, holder);
mDarkIconDispatcher.addDarkReceiver((DarkReceiver) view);
}
@Override
protected LayoutParams onCreateLayoutParams() {
LinearLayout.LayoutParams lp = new LinearLayout.LayoutParams(
ViewGroup.LayoutParams.WRAP_CONTENT, mIconSize);
lp.setMargins(mIconHPadding, 0, mIconHPadding, 0);
return lp;
}
@Override
protected void destroy() {
for (int i = 0; i < mGroup.getChildCount(); i++) {
mDarkIconDispatcher.removeDarkReceiver((DarkReceiver) mGroup.getChildAt(i));
}
mGroup.removeAllViews();
}
@Override
protected void onRemoveIcon(int viewIndex) {
mDarkIconDispatcher.removeDarkReceiver((DarkReceiver) mGroup.getChildAt(viewIndex));
super.onRemoveIcon(viewIndex);
}
@Override
public void onSetIcon(int viewIndex, StatusBarIcon icon) {
super.onSetIcon(viewIndex, icon);
mDarkIconDispatcher.applyDark((DarkReceiver) mGroup.getChildAt(viewIndex));
}
@Override
protected DemoStatusIcons createDemoStatusIcons() {
DemoStatusIcons icons = super.createDemoStatusIcons();
mDarkIconDispatcher.addDarkReceiver(icons);
return icons;
}
@Override
protected void exitDemoMode() {
mDarkIconDispatcher.removeDarkReceiver(mDemoStatusIcons);
super.exitDemoMode();
}
}
文件路径
frameworks/base/packages/SystemUI/res/xml/tuner_prefs.xml
新增com.android.systemui.tuner.StatusBarSwitch类似的代码