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));// }// }