Android 7.0&8.0 Quick Settings 添加一个新项

来源:互联网 发布:民警优化环境心得体会 编辑:程序博客网 时间:2024/05/16 14:45

这里主要介绍怎么在QS中添加一个新的项,新选项的主要功能就是修改Settings数据库。我是在AOSP8.0模拟器上测试的。

1.在config.xml中添加新选项
frameworks\base\packages\SystemUI\res\values\config.xml
这里的2个地方都用添加,我们这里添加了一个test,一个是默认的QS要显示的选项,一个是点击了编辑后,所以的选项。QS是可以编辑的,选项的位置,个数都是可以拖动的。

    <!-- The default tiles to display in QuickSettings -->    <string name="quick_settings_tiles_default" translatable="false">        wifi,cell,battery,dnd,flashlight,rotation,bt,airplane,test    </string>    <!-- Tiles native to System UI. Order should match "quick_settings_tiles_default" -->    <string name="quick_settings_tiles_stock" translatable="false">        wifi,cell,battery,dnd,flashlight,rotation,bt,airplane,test,location,hotspot,inversion,saver,work,cast,night    </string>

2.新建一个自己的Tile
我是模仿AirPlaneTile的。在构造函数中添加对settings数据库的监听,每次下拉QS都会去刷新下状态。handleClick() 是点击事件,我们这里点击后就去设置下settings数据库的值,然后通知QS刷新下状态。getMetricsCategory()一定要添加一个返回字段,否则当你把QS全部下滑(下滑2此)会crash。MetricsEvent在frameworks\base\proto\src\metrics_constants.proto中定义的字段,编译完成后会在这生成out\target\common\obj\JAVA_LIBRARIES\framework-protos_intermediates\src\proto\src\com\android\internal\logging\MetricsProto.java(不要修改这个文件,编译后会自动修改,把你添加的字段自动加上)。如果编译失败,会提示你删除一些东西什么的,直接把out\target\common\obj目录全部删除再编译,或者clean后build。添加完成后记得在引用的地方要导入com.android.internal.logging.MetricsProto.MetricsEvent;

package com.android.systemui.qs.tiles;import com.android.systemui.R;import com.android.systemui.qs.GlobalSetting;import com.android.systemui.qs.QSTile;import com.android.systemui.qs.QSTile.BooleanState;import com.android.systemui.qs.QSTile.ResourceIcon;import com.android.internal.logging.MetricsProto.MetricsEvent;import android.content.Intent;import android.provider.Settings.Global;import android.util.Log;import android.widget.Switch;public class TestTile extends QSTile<QSTile.BooleanState> {    private final GlobalSetting mSetting;    public TestTile(Host host) {        super(host);        // TODO Auto-generated constructor stub        mSetting = new GlobalSetting(mContext, mHandler, Global.GAME_MODE) {            @Override            protected void handleValueChanged(int value) {                handleRefreshState(value);            }        };    }    @Override    public BooleanState newTileState() {        // TODO Auto-generated method stub        return new BooleanState();    }    @Override    protected void handleClick() {        // TODO Auto-generated method stub        Log.i("a", "click test   "+mState.value);        int value=mSetting.getValue();        if(value==0) {             mSetting.setValue(1);        }else {             mSetting.setValue(0);        }        //handleRefreshState(value);        mSetting.onChange(true);    }    @Override    protected void handleUpdateState(BooleanState state, Object arg) {        // TODO Auto-generated method stub        Log.i("a", "qs change   ");        final int value = arg instanceof Integer ? (Integer)arg : mSetting.getValue();        final boolean airplaneMode = value != 0;        state.value = airplaneMode;        state.label = mContext.getString(R.string.quick_settings_test_label);        if (airplaneMode) {            state.icon = ResourceIcon.get(R.drawable.ic_qs_bluetooth_on);        } else {            state.icon = ResourceIcon.get(R.drawable.ic_qs_bluetooth_off);        }        state.contentDescription = state.label;        state.minimalAccessibilityClassName = state.expandedAccessibilityClassName                = Switch.class.getName();    }    @Override    public int getMetricsCategory() {        // TODO Auto-generated method stub        //return MetricsEvent.QS_TEST;return MetricsEvent.QS_TEST;    }    @Override    public Intent getLongClickIntent() {        // TODO Auto-generated method stub        return null;    }    @Override    protected void setListening(boolean listening) {        // TODO Auto-generated method stub    }    @Override    public CharSequence getTileLabel() {        // TODO Auto-generated method stub        return mContext.getString(R.string.quick_settings_test_label);    }    @Override    protected String composeChangeAnnouncement() {        if (mState.value) {            return mContext.getString(R.string.accessibility_quick_settings_test_changed_on);        } else {            return mContext.getString(R.string.accessibility_quick_settings_test_changed_off);        }    }}

3.引用自己的Tile
frameworks\base\packages\SystemUI\src\com\android\systemui\statusbar\phone\QSTileHost.java会加载所有的Tile,我们只需要把我们自定义的TestTile添加进去就可以了。

    public 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("cell")) return new CellularTile(this);        else if (tileSpec.equals("dnd")) return new DndTile(this);        else if (tileSpec.equals("inversion")) return new ColorInversionTile(this);        else if (tileSpec.equals("airplane")) return new AirplaneModeTile(this);        else if (tileSpec.equals("work")) return new WorkModeTile(this);        else if (tileSpec.equals("rotation")) return new RotationLockTile(this);        else if (tileSpec.equals("flashlight")) return new FlashlightTile(this);        else if (tileSpec.equals("location")) return new LocationTile(this);        else if (tileSpec.equals("cast")) return new CastTile(this);        else if (tileSpec.equals("hotspot")) return new HotspotTile(this);        else if (tileSpec.equals("user")) return new UserTile(this);        else if (tileSpec.equals("battery")) return new BatteryTile(this);        else if (tileSpec.equals("saver")) return new DataSaverTile(this);        else if (tileSpec.equals("night")) return new NightDisplayTile(this);        else if (tileSpec.equals("nfc")) return new NfcTile(this);        else if (tileSpec.equals("test")) return new TestTile(this);        // Intent tiles.        else if (tileSpec.startsWith(IntentTile.PREFIX)) return IntentTile.create(this,tileSpec);        else if (tileSpec.startsWith(CustomTile.PREFIX)) return CustomTile.create(this,tileSpec);        else {            Log.w(TAG, "Bad tile spec: " + tileSpec);            return null;        }    }

至此,自定义的QS已经添加好了。