由于最近小蔡的手机音量键坏了,调节音量有点麻烦,突发奇想,想自己实现一个快捷键来调节音量。在忘上参考了一些代码,总结出一般本章,分享给大家。
首先 按钮要想实现悬浮在任何界面,那么必须是要写在服务里面的,使用定时器,2.5s不触摸后,背景变淡
清单文件中加权限
<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" />
public class FloatViewService extends Service { private static final String TAG = "FloatViewService"; // 定义浮动窗口布局 private LinearLayout mFloatLayout; private WindowManager.LayoutParams wmParams; // 创建浮动窗口设置布局参数的对象 private WindowManager mWindowManager; private ImageButton mFloatView; private int screenHeight; private int screenWidth; private MyCountDownTimer myCountDownTimer; @Override public void onCreate) { super.onCreate); Log.iTAG, "onCreate"); screenHeight = ScreenParam.getInstance).height;//自己写的工具类用来获取屏幕宽高。 screenWidth = ScreenParam.getInstance).width; createFloatView); myCountDownTimer = new MyCountDownTimer2500, 1000); //设置计时2.5s myCountDownTimer.start); } @SuppressWarnings"static-access") @SuppressLint"InflateParams") private void createFloatView) { wmParams = new WindowManager.LayoutParams); // 通过getApplication获取的是WindowManagerImpl.CompatModeWrapper mWindowManager = WindowManager) getApplication).getSystemService getApplication).WINDOW_SERVICE); // 设置window type wmParams.type = LayoutParams.TYPE_PHONE; // 设置图片格式,效果为背景透明 wmParams.format = PixelFormat.RGBA_8888; // 设置浮动窗口不可聚焦(实现操作除浮动窗口外的其他可见窗口的操作) wmParams.flags = LayoutParams.FLAG_NOT_FOCUSABLE; // 调整悬浮窗显示的停靠位置为右侧底部 wmParams.gravity = Gravity.RIGHT | Gravity.BOTTOM; // 以屏幕左上角为原点,设置x、y初始值,相对于gravity wmParams.x = 0; wmParams.y = 150; // 设置悬浮窗口长宽数据 wmParams.width = WindowManager.LayoutParams.WRAP_CONTENT; wmParams.height = WindowManager.LayoutParams.WRAP_CONTENT; LayoutInflater inflater = LayoutInflater.fromgetApplication)); // 获取浮动窗口视图所在布局 mFloatLayout = LinearLayout) inflater.inflate R.layout.alert_window_menu, null); // 添加mFloatLayout mWindowManager.addViewmFloatLayout, wmParams); // 浮动窗口按钮 mFloatView = ImageButton) mFloatLayout .findViewByIdR.id.alert_window_imagebtn); mFloatLayout.measureView.MeasureSpec.makeMeasureSpec0, View.MeasureSpec.UNSPECIFIED), View.MeasureSpec .makeMeasureSpec0, View.MeasureSpec.UNSPECIFIED)); // 设置监听浮动窗口的触摸移动 mFloatView.setOnTouchListenernew OnTouchListener) { boolean isClick; private int leftDistance; private float rawX; private float rawY; @SuppressLint"ClickableViewAccessibility") @Override public boolean onTouchView v, MotionEvent event) { switch event.getAction)) { case MotionEvent.ACTION_DOWN: mFloatLayout.setAlpha1.0f); myCountDownTimer.cancel);取消计时 rawX = event.getRawX); rawY = event.getRawY); break; case MotionEvent.ACTION_MOVE: // getRawX是触摸位置相对于屏幕的坐标,getX是相对于按钮的坐标 int distanceX = int) event.getRawX)-rawX); int distanceY = int) event.getRawY)-rawY); leftDistance = int) event.getRawX) + mFloatView.getMeasuredWidth) / 2; wmParams.x = wmParams.x-distanceX; wmParams.y = wmParams.y-distanceY; // 刷新 mWindowManager.updateViewLayoutmFloatLayout, wmParams); rawX = event.getRawX); rawY = event.getRawY); break; case MotionEvent.ACTION_UP: myCountDownTimer.start);重新开始计时 ifwmParams.x>leftDistance){ wmParams.x = screenWidth-mFloatView.getMeasuredWidth) / 2; }else{ wmParams.x = 0; } mWindowManager.updateViewLayoutmFloatLayout, wmParams); break; } return false; } }); mFloatView.setOnClickListenernew OnClickListener) { @Override public void onClickView v) { AudioManager audioManager = AudioManager) getSystemServiceService.AUDIO_SERVICE); audioManager.setStreamVolumeAudioManager.STREAM_MUSIC, audioManager.getStreamVolumeAudioManager.STREAM_MUSIC), AudioManager.FLAG_SHOW_UI); // Toast.makeTextFloatViewService.this, "hello!", // Toast.LENGTH_SHORT).show); } }); } @Override public void onDestroy) { super.onDestroy); if mFloatLayout != null) { // 移除悬浮窗口 mWindowManager.removeViewmFloatLayout); } } @Override public IBinder onBindIntent intent) { return null; } public class MyCountDownTimer extends CountDownTimer { public MyCountDownTimerlong millisInFuture, long countDownInterval) { supermillisInFuture, countDownInterval); } @Override public void onTicklong millisUntilFinished) { } @Override public void onFinish) { mFloatLayout.setAlpha0.4f); } } }
然后再Activity里启动服务就好了
protected void onCreateBundle savedInstanceState) { super.onCreatesavedInstanceState); setContentViewR.layout.activity_main); ScreenParam.getInstance).initthis); } @Override protected void onStart) { // TODO Auto-generated method stub Intent intent = new IntentMainActivity.this, FloatViewService.class); //启动FloatViewService startServiceintent); super.onStart); }
如果不想显示Activity界面的话,可以在配置这个属性就ok了
android:theme="@android:style/Theme.NoDisplay"
就是这么简单!