由于最近小蔡的手机音量键坏了,调节音量有点麻烦,突发奇想,想自己实现一个快捷键来调节音量,总结出一般本章,分享给大家。
首先 按钮要想实现悬浮在任何界面,那么必须是要写在服务里面的,使用定时器,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;@Overridepublic void onCreate() {super.onCreate();Log.i(TAG, "onCreate");screenHeight = ScreenParam.getInstance().height;//自己写的工具类用来获取屏幕宽高。screenWidth = ScreenParam.getInstance().width;createFloatView();myCountDownTimer = new MyCountDownTimer(2500, 1000); //设置计时2.5smyCountDownTimer.start();}@SuppressWarnings("static-access")@SuppressLint("InflateParams")private void createFloatView() {wmParams = new WindowManager.LayoutParams();// 通过getApplication获取的是WindowManagerImpl.CompatModeWrappermWindowManager = (WindowManager) getApplication().getSystemService(getApplication().WINDOW_SERVICE);// 设置window typewmParams.type = LayoutParams.TYPE_PHONE;// 设置图片格式,效果为背景透明wmParams.format = PixelFormat.RGBA_8888;// 设置浮动窗口不可聚焦(实现操作除浮动窗口外的其他可见窗口的操作)wmParams.flags = LayoutParams.FLAG_NOT_FOCUSABLE;// 调整悬浮窗显示的停靠位置为右侧底部wmParams.gravity = Gravity.RIGHT | Gravity.BOTTOM;// 以屏幕左上角为原点,设置x、y初始值,相对于gravitywmParams.x = 0;wmParams.y = 150;// 设置悬浮窗口长宽数据wmParams.width = WindowManager.LayoutParams.WRAP_CONTENT;wmParams.height = WindowManager.LayoutParams.WRAP_CONTENT;LayoutInflater inflater = LayoutInflater.from(getApplication());// 获取浮动窗口视图所在布局mFloatLayout = (LinearLayout) inflater.inflate(R.layout.alert_window_menu, null);// 添加mFloatLayoutmWindowManager.addView(mFloatLayout, wmParams);// 浮动窗口按钮mFloatView = (ImageButton) mFloatLayout.findViewById(R.id.alert_window_imagebtn);mFloatLayout.measure(View.MeasureSpec.makeMeasureSpec(0,View.MeasureSpec.UNSPECIFIED), View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED));// 设置监听浮动窗口的触摸移动mFloatView.setOnTouchListener(new OnTouchListener() {boolean isClick;private int leftDistance;private float rawX;private float rawY;@SuppressLint("ClickableViewAccessibility")@Overridepublic boolean onTouch(View v, MotionEvent event) {switch (event.getAction()) {case MotionEvent.ACTION_DOWN:mFloatLayout.setAlpha(1.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.updateViewLayout(mFloatLayout, wmParams);rawX = event.getRawX();rawY = event.getRawY();break;case MotionEvent.ACTION_UP:myCountDownTimer.start();重新开始计时if(wmParams.x>leftDistance){wmParams.x = screenWidth-mFloatView.getMeasuredWidth() / 2;}else{wmParams.x = 0;}mWindowManager.updateViewLayout(mFloatLayout, wmParams);break;}return false;}});mFloatView.setOnClickListener(new OnClickListener() {@Overridepublic void onClick(View v) {AudioManager audioManager = (AudioManager) getSystemService(Service.AUDIO_SERVICE);audioManager.setStreamVolume(AudioManager.STREAM_MUSIC,audioManager.getStreamVolume(AudioManager.STREAM_MUSIC), AudioManager.FLAG_SHOW_UI);
// Toast.makeText(FloatViewService.this, "hello!",
// Toast.LENGTH_SHORT).show();}});}@Overridepublic void onDestroy() {super.onDestroy();if (mFloatLayout != null) {// 移除悬浮窗口mWindowManager.removeView(mFloatLayout);}}@Overridepublic IBinder onBind(Intent intent) {return null;}public class MyCountDownTimer extends CountDownTimer {public MyCountDownTimer(long millisInFuture, long countDownInterval) {super(millisInFuture, countDownInterval);}@Overridepublic void onTick(long millisUntilFinished) {}@Overridepublic void onFinish() {mFloatLayout.setAlpha(0.4f);}}}
然后再Activity里启动服务就好了
protected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);ScreenParam.getInstance().init(this);}@Overrideprotected void onStart() {// TODO Auto-generated method stubIntent intent = new Intent(MainActivity.this, FloatViewService.class); //启动FloatViewService startService(intent); super.onStart();}
如果不想显示Activity界面的话,可以在配置这个属性就ok了
android:theme="@android:style/Theme.NoDisplay"
就是这么简单!