Android8.1 下拉状态栏添加铃声静音快捷键简单记录
1.修改quick_settings_tiles_default
<!-- The default tiles to display in QuickSettings -->
<string name="quick_settings_tiles_default" translatable="false">
wifi,bt,dnd,battery,cell,airplane
</string>
由于如果直接在airplane后加ring会导致显示不全ring无法显示在一次下拉中(只能在下拉一次后再次下拉的时候才能显示,如果要强改可能需要改布局文件造成更多的修改),并且dnd(免打扰功能)没有需求,所以直接把dnd换成ring。
<!-- The default tiles to display in QuickSettings -->
<string name="quick_settings_tiles_default" translatable="false">
wifi,bt,ring,battery,cell,airplane
</string>
2.metrics_constants.proto中添加 QS_RING = 1145;
//frameworks\base\proto\src\metrics_constants.proto
// logged when we cancel an app transition.
APP_TRANSITION_CANCELLED = 1144;
QS_RING = 1145;
// ---- End O-MR1 Constants, all O-MR1 constants go above this line ----
// Add new aosp constants above this line.
// END OF AOSP CONSTANTS
}
}
3.新建RingTile ,修改QSFactoryImpl。
在createTile中添加else if (tileSpec.equals("ring")) {return new RingTile(mHost);}
public class QSFactoryImpl implements QSFactory {
.............
public QSTile createTile(String tileSpec) {
/// M: Add extra tiles in quicksetting @{
Context context = mHost.getContext();
IQuickSettingsPlugin quickSettingsPlugin = OpSystemUICustomizationFactoryBase
.getOpFactory(context).makeQuickSettings(context);
/// @}
if (tileSpec.equals("wifi")) return new WifiTile(mHost);
else if (tileSpec.equals("bt")) return new BluetoothTile(mHost);
else if (tileSpec.equals("cell")) return new CellularTile(mHost);
.............
else if (tileSpec.equals("ring")) {
return new RingTile(mHost);
}
.............
}
}
新建RingTile。
package com.android.systemui.qs.tiles;
import com.android.systemui.qs.GlobalSetting;
import com.android.systemui.qs.QSHost;
import com.android.systemui.qs.tileimpl.QSTileImpl;
import com.android.systemui.plugins.qs.QSTile.BooleanState;
import com.android.systemui.R;
import android.service.quicksettings.Tile;
import android.content.Intent;
import android.media.AudioManager;
import android.provider.Settings;
import com.android.internal.logging.MetricsLogger;
import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
public class RingTile extends QSTileImpl<BooleanState> {
private boolean mListening;
private AudioManager mAudioManager;
private final GlobalSetting mGlobalSetting;
private boolean isRingerModeSilent;
public RingTile(QSHost host) {
super(host);
mAudioManager = (AudioManager) mContext.getSystemService(mContext.AUDIO_SERVICE);
mGlobalSetting = new GlobalSetting(mContext, mHandler, Settings.System.MODE_RINGER_STREAMS_AFFECTED) {
@Override
protected void handleValueChanged(int value) {
handleRefreshState(value);
}
};
}
@Override
public int getMetricsCategory() {
return MetricsEvent.QS_RING;
}
@Override
public CharSequence getTileLabel() {
return mContext.getString(R.string.quick_settings_ringer_silent);
}
@Override
public BooleanState newTileState() {
return new BooleanState();
}
@Override
public void handleSetListening(boolean listening) {
if (mListening == listening) return;
mListening = listening;
mGlobalSetting.setListening(mListening);
}
//长按快捷图标跳转对应设置
@Override
public Intent getLongClickIntent() {
return new Intent(Settings.ACTION_SOUND_SETTINGS);
}
@Override
protected void handleClick() {
if (mAudioManager.getRingerMode()!= AudioManager.RINGER_MODE_SILENT) {
mAudioManager.setRingerMode(AudioManager.RINGER_MODE_SILENT);
} else {
mAudioManager.setRingerMode(AudioManager.RINGER_MODE_NORMAL);
}
refreshState();
}
@Override
protected void handleUpdateState(BooleanState state, Object arg) {
state.label = mContext.getString(R.string.quick_settings_ringer_silent);
if (mAudioManager.getRingerMode() == AudioManager.RINGER_MODE_SILENT) {
state.icon = ResourceIcon.get(R.drawable.ic_qs_ringer_silent);
state.state = Tile.STATE_ACTIVE;
} else {
state.icon = ResourceIcon.get(R.drawable.ic_qs_ringer_audible);
state.state = Tile.STATE_INACTIVE;
}
}
}
定义Silent的string。
//vendor\mediatek\proprietary\packages\apps\SystemUI\res\values\strings.xml
<string name="quick_settings_ringer_silent">Silent</string>
state.state这个属性,跟图标的最终显示颜色有关。system ui中的下拉栏中的图标基本是svg图片,fillColor属性为 #FFFFFFFF,但是最终显示却不是白色,是因为setTint,动态修改了颜色。
//vendor\mediatek\proprietary\packages\apps\SystemUI\src\com\android\systemui\qs\tileimpl\QSIconViewImpl.java
protected void setIcon(ImageView iv, QSTile.State state) {
updateIcon(iv, state);
if (state.disabledByPolicy) {
iv.setColorFilter(getContext().getColor(R.color.qs_tile_disabled_color));
} else {
iv.clearColorFilter();
}
if (state.state != mState) {
int color = getColor(state.state);
mState = state.state;
if (iv.isShown() && mTint != 0) {
animateGrayScale(mTint, color, iv);
mTint = color;
} else {
if (iv instanceof AlphaControlledSlashImageView) {
((AlphaControlledSlashImageView)iv)
.setFinalImageTintList(ColorStateList.valueOf(color));
} else {
setTint(iv, color);
}
mTint = color;
}
}
}
参考链接:
android(cm11)状态栏源代码分析(一)
SystemUI之Qs Tile加载流程
android 7.0 system UI之快速启动栏的分析(一)
Android 8.1 SystemUI下拉状态栏修改
Android下拉状态栏快捷开关的添加
Android 状态栏下拉列表添加自定义item开关
Android 9.0 SystemUI 下拉状态栏快捷开关
Android N SystemUI-状态栏
SystemUI 状态栏 system icon 和 notification icon 的修改
AndroidN SystemUI新增小图标
Android 8.0 SystemUI下拉状态栏快捷开关
Android实现手机静音
Android中 跳转到系统设置界面方法总结