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

本文详细介绍如何在Android系统中自定义快速设置(QS)项,并通过修改Settings数据库实现新功能。以AOSP 8.0为例,从配置XML到创建自定义Tile及引用,全程解析。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

这里主要介绍怎么在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已经添加好了。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值