• Android源码分析(十三)----SystemUI下拉状态栏如何添加快捷开关


    一:如何添加快捷开关

    源码路径:frameworks/base/packages/SystemUI/res/values/config.xml
    添加headset快捷开关,参考如下修改。

    Index: res/values/config.xml
    ===================================================================
    --- res/values/config.xml	(版本 6870)
    +++ res/values/config.xml	(工作副本)
    @@ -101,7 +101,7 @@
         <!-- The default tiles to display in QuickSettings -->
         <!-- M: add hotknot tile -->
         <string name="quick_settings_tiles_default" translatable="false">
    -        wifi,cell,battery,autobringht,custom(com.bullitt_group.night/nightsight.bullitt_group.com.night.quicksettings.QuickSettingsService),flashlight,dnd,rotation,bt,airplane,hotknot,nfc,location
    +        wifi,cell,battery,autobringht,custom(com.bullitt_group.night/nightsight.bullitt_group.com.night.quicksettings.QuickSettingsService),flashlight,dnd,rotation,bt,airplane,hotknot,nfc,location,headset
         </string>
     
         <!-- Tiles native to System UI. Order should match "quick_settings_tiles_default" -->
    

    Android版本7.1修改方式
    源码路径:frameworks/base/packages/SystemUI/src/com/android/systemui/statusbar/phone/QSTileHost.java
    创建HeadsetTile 对象,实现快捷开关主要功能。

    Index: src/com/android/systemui/statusbar/phone/QSTileHost.java
    ===================================================================
    --- src/com/android/systemui/statusbar/phone/QSTileHost.java	(版本 6870)
    +++ src/com/android/systemui/statusbar/phone/QSTileHost.java	(工作副本)
    @@ -41,6 +41,7 @@
     import com.android.systemui.qs.external.TileLifecycleManager;
     import com.android.systemui.qs.external.TileServices;
     import com.android.systemui.qs.tiles.AirplaneModeTile;
    +import com.android.systemui.qs.tiles.HeadsetTile;
     import com.android.systemui.qs.tiles.BatteryTile;
     import com.android.systemui.qs.tiles.BluetoothTile;
     import com.android.systemui.qs.tiles.CastTile;
    @@ -501,6 +502,7 @@
             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("headset")) return new HeadsetTile(this);
     
             /// M: Add extra tiles in quicksetting @{
             else if (tileSpec.equals("hotknot") && SIMHelper.isMtkHotKnotSupport())
    

    Android8.0修改方式,原理一样,只是代码路径不同,这里不做过多介绍。
    源码路径:frameworks/base/packages/SystemUI/src/com/android/systemui/qs/tileimpl/QSFactoryImpl.java

    public class QSFactoryImpl implements QSFactory {
    
        private static final String TAG = "QSFactory";
        private final QSTileHost mHost;
    
        public QSFactoryImpl(QSTileHost host) {
            mHost = host;
        }   
    
        public QSTile createTile(String tileSpec) {
            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("dnd")) return new DndTile(mHost);
            else if (tileSpec.equals("inversion")) return new ColorInversionTile(mHost);
            else if (tileSpec.equals("airplane")) return new AirplaneModeTile(mHost);
            else if (tileSpec.equals("work")) return new WorkModeTile(mHost);
            else if (tileSpec.equals("rotation")) return new RotationLockTile(mHost);
            else if (tileSpec.equals("flashlight")) return new FlashlightTile(mHost);
            else if (tileSpec.equals("location")) return new LocationTile(mHost);
            else if (tileSpec.equals("cast")) return new CastTile(mHost);
            else if (tileSpec.equals("hotspot")) return new HotspotTile(mHost);
            else if (tileSpec.equals("user")) return new UserTile(mHost);
            else if (tileSpec.equals("battery")) return new BatterySaverTile(mHost);
            else if (tileSpec.equals("saver")) return new DataSaverTile(mHost);
            else if (tileSpec.equals("night")) return new NightDisplayTile(mHost);
            else if (tileSpec.equals("nfc")) return new NfcTile(mHost);
            // Intent tiles.
            else if (tileSpec.startsWith(IntentTile.PREFIX)) return IntentTile.create(mHost, tileSpec);
            else if (tileSpec.startsWith(CustomTile.PREFIX)) return CustomTile.create(mHost, tileSpec);
            else {
                Log.w(TAG, "Bad tile spec: " + tileSpec);
                return null;
            }   
        }  
    
    二:快捷开关功能实现

    这里主要实现,打开开关弹出Notification(不可删除通知),关闭开关才能关闭通知。
    源码路径:frameworks/base/packages/SystemUI/src/com/android/systemui/qs/tiles/HeadsetTile.java

    1. 继承 QSTile<QSTile.BooleanState>
    2. newTileState方法中return new BooleanState()
    3. handleClick方法处理点击事件
    4. handleUpdateState方法更新状态信息
    /*
     * Copyright (c) 2016, 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.qs.tiles;
    
    import android.app.Notification;
    import android.app.NotificationManager;
    import android.app.PendingIntent;
    import android.content.Context;
    import android.content.Intent;
    import android.provider.Settings;
    import android.util.Log;
    import android.widget.Switch;
    
    import com.android.internal.logging.MetricsLogger;
    import com.android.internal.logging.MetricsProto.MetricsEvent;
    import com.android.systemui.R;
    import com.android.systemui.SystemUI;
    import com.android.systemui.qs.QSTile;
    
    
    public class HeadsetTile extends QSTile<QSTile.BooleanState> {
    
        private Notification notification = new Notification();
        private NotificationManager mNotificationManager = (NotificationManager) mContext.getSystemService(Context.NOTIFICATION_SERVICE);
        private boolean headsetState;
    
        public boolean isHeadsetState() {
            return headsetState;
        }
    
        public void setHeadsetState(boolean headsetState) {
            this.headsetState = headsetState;
        }
    
        public HeadsetTile(Host host) {
            super(host);
        }
    
    
        @Override
        public BooleanState newTileState() {
            return new BooleanState();
        }
    
        @Override
        protected void handleClick() {
            //default mState.value is false
            final boolean activated = !mState.value;
            Log.d("jasun", "========activated========" + activated);
            MetricsLogger.action(mContext, getMetricsCategory(), activated);
            if (activated == true) {
                SendNotification("Disable the headphone jack.");
                setHeadsetState(activated);
            } else {
                mNotificationManager.cancel(1);
                setHeadsetState(activated);
            }
            refreshState();
        }
    
    
        @Override
        protected void handleUpdateState(BooleanState state, Object arg) {
            final boolean isActivated = isHeadsetState();
            state.value = isActivated;
            state.label = mContext.getString(R.string.quick_settings_headset_label);
            state.icon = ResourceIcon.get(isActivated ? R.drawable.ic_qs_headset_on
                    : R.drawable.ic_qs_headset_off);
            state.contentDescription = mContext.getString(isActivated
                    ? R.string.quick_settings_headset_summary_on
                    : R.string.quick_settings_headset_summary_off);
            state.minimalAccessibilityClassName = state.expandedAccessibilityClassName
                    = Switch.class.getName();
        }
    
        @Override
        public int getMetricsCategory() {
            return MetricsEvent.QS_headset;
        }
    
        @Override
        public Intent getLongClickIntent() {
            return new Intent(Settings.ACTION_headset_SETTINGS);
        }
    
        @Override
        protected void setListening(boolean listening) {
    
        }
    
        private void sendNotification(String message) {
            Intent intent = new Intent(mContext, SystemUI.class);
            PendingIntent pendingIntent = PendingIntent.getActivity(mContext, 0,
                    intent, 0);
            notification.icon = R.drawable.ic_qs_headset_on;
            notification.tickerText = "HeadSet can not used";
            notification.when = System.currentTimeMillis();
            notification.defaults = Notification.DEFAULT_SOUND
                    | Notification.DEFAULT_VIBRATE;// set default sound
    //        notification.flags = Notification.FLAG_AUTO_CANCEL;// click auto disappeared
            notification.flags = Notification.FLAG_NO_CLEAR;
            notification.setLatestEventInfo(mContext, "Headset can not used", message, pendingIntent);
    
            mNotificationManager.notify(1, notification);
    
        }
    
        @Override
        public CharSequence getTileLabel() {
            return mContext.getString(R.string.quick_settings_headset_label);
        }
    }
    
    

    喜欢源码分析系列可参考其他文章:
    Android源码分析(一)-----如何快速掌握Android编译文件
    Android源码分析(二)-----如何编译修改后的framework资源文件
    Android源码分析(三)-----系统框架设计思想
    Android源码分析(四)-----Android源码编译及刷机步骤
    Android源码分析(五)-----如何从架构师的角度去设计Framework框架

  • 相关阅读:
    类数据源Visual C++对ODBC数据库资源的访问
    变量对话框MFC 关于控件变量的使用
    S3C2440上LCD驱动(FrameBuffer)实例开发讲解(二)
    设备内存缓冲区和 /proc/iomem
    multiplexed pins
    电脑硬件资源有冲突怎么处理?
    redhat open source university 硬件资源
    深入理解linux系统下proc文件系统内容
    S3C2440上LCD驱动(FrameBuffer)实例开发讲解(一)
    Framebuffer文章收集
  • 原文地址:https://www.cnblogs.com/ljx646566715/p/10893950.html
Copyright © 2020-2023  润新知