Android下拉状态栏快捷开关的添加

最近基于工作需要,在Android5.0上研究了一下系统下拉状态栏的知识,并参考了“LYJ的IT生活”的http://blog.csdn.net/lyjit/article/details/51579067文章,在学习了他的做法之后,现在总结一下自己的实际应用:


添加自己的快捷开关


此处以添加静音快捷开关为例,首先,打开这个文件frameworks/base/packages/SystemUI/res/values/config.xml,搜索“quick_settings_tiles_default”找到该处内容,如我的代码是

<!– The default tiles to display in QuickSettings –>

<string name=”quick_settings_tiles_default” translatable=”false”>

wifi,bt,inversion,cell,airplane,rotation,flashlight,location,cast,hotspot

</string>

这是自适应的布局,这些快捷按键的定义都在这里,如要添加或替换,在这里修改即可。这里我添加了静音开关mute,代码如下:

<!– The default tiles to display in QuickSettings –>

<string name=”quick_settings_tiles_default” translatable=”false”>

wifi,bt,inversion,cell,airplane,rotation,flashlight,location,cast,hotspot,mute

</string>

其次,打开frameworks/base/packages/SystemUI/src/com/android/systemui/statusbar/phone/QSTileHost.java文件,找到private QSTile<?> createTile(String tileSpec) 函数,并添加mute相关代码,如下所示:

private QSTile<?> createTile(String tileSpec) {

if (tileSpec.equals(“wifi”)) return new WifiTile(this);

else if (tileSpec.equals(“bt”)) return new BluetoothTile(this);

else if (tileSpec.equals(“mute”)) return new MuteTile(this);

……

}

这里主要是获取到预定义好的各个快捷图标的QSTile。

下面是新建MuteTile这个文件,在frameworks/base/packages/SystemUI/src/com/Android/systemui/qs/tiles
这个路径下面就是你定义的开关实现功能的地方,这里新添加的mute在原有的快捷开关里面是没有的,所以要在这里新添加一个文件MuteTile.java,该文件代码如下:


package com.android.systemui.qs.tiles;

import android.media.AudioManager;
import android.provider.Settings;
import android.provider.Settings.Global;

import com.android.systemui.R;
import com.android.systemui.qs.GlobalSetting;
import com.android.systemui.qs.QSTile;

public class MuteTile extends QSTile<QSTile.BooleanState> {

private boolean mListening;
private AudioManager mAudioManager;
private final GlobalSetting mSetting;

public MuteTile(Host host) {
super(host);
// TODO Auto-generated constructor stub
mAudioManager = (AudioManager)mContext.getSystemService(mContext.AUDIO_SERVICE);
mSetting = new GlobalSetting(mContext, mHandler, Settings.System.MODE_RINGER_STREAMS_AFFECTED) {
            @Override
            protected void handleValueChanged(int value) {
                handleRefreshState(value);
            }
        };
}

public void setListening(boolean listening) {
// TODO Auto-generated method stub
if (mListening == listening) return;
        mListening = listening;
        mSetting.setListening(listening);
}

@Override
protected BooleanState newTileState() {
// TODO Auto-generated method stub
return new BooleanState();
}

@Override
protected void handleClick() {
// TODO Auto-generated method stub
setMute();
}

@Override
protected void handleUpdateState(
BooleanState state, Object arg) {
// TODO Auto-generated method stub
//int mode = mSetting.getValue();
state.visible = true;
state.value = true;
state.label = mContext.getString(R.string.quick_settings_mute_label);
if (mAudioManager.getStreamVolume(AudioManager.STREAM_RING) != 0) {
state.icon = ResourceIcon.get(R.drawable.ic_qs_mute_off);
state.contentDescription =  mContext.getString(R.string.accessibility_quick_settings_mute_off);
} else {
state.icon = ResourceIcon.get(R.drawable.ic_qs_mute_on);
state.contentDescription =  mContext.getString(R.string.accessibility_quick_settings_mute_on);
}
        
}

private void setMute() {
if (mAudioManager.getStreamVolume(AudioManager.STREAM_RING) != 0) {
mAudioManager.setStreamMute(AudioManager.STREAM_RING, true);
} else {
mAudioManager.setStreamMute(AudioManager.STREAM_RING, false);
}
mSetting.setValue(mAudioManager.getStreamVolume(AudioManager.STREAM_RING));
}
}


其中mSetting的定义很关键,GlobalSetting里的参数要结合自己的具体实际来写,不然点击图标是不会刷新界面的,另外,setMute()函数须放在handleClick中,不能放在handleUpdateState中,因为handleUpdateState是负责刷新界面的,会一直都在程序的刷新监听中,放在里面有可能会导致图标不断变化。


最后,mSetting.setValue(mAudioManager.getStreamVolume(AudioManager.STREAM_RING));这一句是刷新页面的关键,因为我们程序里面通过GlobalSetting定义了相关的监听ContentObserver ,每次点击图标后都是通过设置这个value的方式通知ContentObserver 刷新界面的。

    原文作者:疾风-Bevis
    原文地址: https://blog.csdn.net/love000520/article/details/52190595
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞