Android Vibrator学习记录

由于设备没有马达,有个需求需要修改音量上下键中弹出界面的震动图标。

按音量上下键后,弹出的界面在systemUI 中的VolumeDialogImpl 中。

复制代码
private void initDialog(int lockTaskModeState) {
        mDialog = new CustomDialog(mContext);

        initDimens();

        mConfigurableTexts = new ConfigurableTexts(mContext);
        mHovering = false;
        mShowing = false;
        mWindow = mDialog.getWindow();
        mWindow.requestFeature(Window.FEATURE_NO_TITLE);
        mWindow.setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT));
        mWindow.clearFlags(WindowManager.LayoutParams.FLAG_DIM_BEHIND
                | WindowManager.LayoutParams.FLAG_LAYOUT_INSET_DECOR);
        mWindow.addFlags(WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
                | WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL
                | WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED
                | WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH
                | WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED);
        mWindow.addPrivateFlags(WindowManager.LayoutParams.PRIVATE_FLAG_TRUSTED_OVERLAY);
        mWindow.setType(WindowManager.LayoutParams.TYPE_VOLUME_OVERLAY);
        mWindow.setWindowAnimations(com.android.internal.R.style.Animation_Toast);
        WindowManager.LayoutParams lp = mWindow.getAttributes();
        lp.format = PixelFormat.TRANSLUCENT;
        lp.setTitle(VolumeDialogImpl.class.getSimpleName());
        lp.windowAnimations = -1;
        lp.gravity = mContext.getResources().getInteger(R.integer.volume_dialog_gravity);
        mWindow.setAttributes(lp);
        mWindow.setLayout(WRAP_CONTENT, WRAP_CONTENT);

        mDialog.setContentView(R.layout.volume_dialog);
        mDialogView = mDialog.findViewById(R.id.volume_dialog);

由initDialog 可知,布局文件由volume_dialog.xml 实现。

复制代码
 if (!mShowVibrate) {
            mRingerDrawerVibrate.setVisibility(GONE);
        }

震动图标是否显示由mShowVibrate 控制。

跟代码可知该变量由VibratorHelper.hasVibrator().

复制代码
 public boolean hasVibrator() {
        return mVibrator != null && mVibrator.hasVibrator();
    }

在SystemVIbrator.java 中实现方式为

复制代码
    public boolean hasVibrator() {
        if (mVibratorManager == null) {
            Log.w(TAG, "Failed to check if vibrator exists; no vibrator manager.");
            return false;
        }
        return mVibratorManager.getVibratorIds().length > 0;
    }

最终是获取hal层VibratorIds 数量来判断是否支持震动。

复制代码
// Load vibrator hardware info. The vibrator ids and manager capabilities are loaded only
        // once and assumed unchanged for the lifecycle of this service. Each individual vibrator
        // can still retry loading each individual vibrator hardware spec once more at systemReady.
        mCapabilities = mNativeWrapper.getCapabilities();
        int[] vibratorIds = mNativeWrapper.getVibratorIds();
        if (vibratorIds == null) {
            mVibratorIds = new int[0];
            mVibrators = new SparseArray<>(0);
        } else {
            // Keep original vibrator id order, which might be meaningful.
            mVibratorIds = vibratorIds;
            mVibrators = new SparseArray<>(mVibratorIds.length);
            for (int vibratorId : vibratorIds) {
                VibratorController vibratorController =
                        injector.createVibratorController(vibratorId, listener);
                mVibrators.put(vibratorId, vibratorController);
            }
        }

将这里屏蔽后,fwk就不会再支持震动了。

复制代码
    // int[] vibratorIds = mNativeWrapper.getVibratorIds();
        // if (vibratorIds == null) {
   
            mVibratorIds = new int[0];
            mVibrators = new SparseArray<>(0);
        // } else {
        //     // Keep original vibrator id order, which might be meaningful.
        //     mVibratorIds = vibratorIds;
        //     mVibrators = new SparseArray<>(mVibratorIds.length);
        //     for (int vibratorId : vibratorIds) {
    
        //         mVibrators.put(vibratorId, injector.createVibratorController(vibratorId, listener));
        //     }
        // }
相关推荐
劈星斩月9 分钟前
监督学习算法 之 决策树
学习·算法·决策树
AOwhisky20 分钟前
Python 学习笔记(第五期)——组合数据类型:列表、元组、集合与字典精讲——核心知识点自测与详解
开发语言·笔记·python·学习·云计算
woshihuanglaoshi35 分钟前
数据迁移与版本管理 - Flutter在鸿蒙平台实现数据库升级策略
数据库·学习·flutter·华为·harmonyos·鸿蒙·鸿蒙系统
世人万千丶10 小时前
参数管理_Flutter在鸿蒙平台路由参数最佳实践
学习·flutter·华为·harmonyos·鸿蒙
遇乐的果园13 小时前
前端学习笔记-vue加载渲染优化
前端·笔记·学习
遇乐的果园15 小时前
前端学习笔记-vue状态管理优化
前端·笔记·学习
从零开始的代码生活_15 小时前
C++ 继承详解:访问控制、对象模型、菱形继承与设计取舍
开发语言·c++·后端·学习·算法
可乐奶茶sky16 小时前
AI Agent 学习
人工智能·学习
茯苓gao16 小时前
嵌入式开发笔记:EtherCAT协议从硬件到软件完整配置指南——从零搭建一套EtherCAT通信系统
笔记·嵌入式硬件·学习
RD_daoyi18 小时前
外链权重暴跌至13%,品牌提及反超传统链接——2026年不做Digital PR,你的独立站等于隐形
运维·网络·学习·机器学习·搜索引擎