zoukankan      html  css  js  c++  java
  • Android悬浮窗拖动

    此代码只能应用于 版本号19以上的手机

    悬浮窗的关键是 :WindowManager  以下列出了 button ,Imageview,SurfaceView(视频) 三种悬浮窗 

    要想悬浮窗不影响到其他应用的使用 需要将 WindowManager 的 LayoutParams flag  参数设置成以下的模式

    // 设置LayoutParam
                mLayoutParams = new WindowManager.LayoutParams();
                if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
                    mLayoutParams.type = WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY;
                } else {
                    mLayoutParams.type = WindowManager.LayoutParams.TYPE_PHONE;
                }
                mLayoutParams.flags = mLayoutParams.FLAG_NOT_TOUCH_MODAL | mLayoutParams.FLAG_NOT_FOCUSABLE | mLayoutParams.FLAG_FULLSCREEN
                        | mLayoutParams.FLAG_LAYOUT_IN_SCREEN;
    

    设置权限

    <uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW"/>

    检查是否设置了权限,因为可以再其他应用之上使用 所以需要通过服务来控制悬浮窗

    @RequiresApi(api = Build.VERSION_CODES.M)
        public void startFloatingService(View view) {
            if(!Settings.canDrawOverlays(this)){
                Toast.makeText(this, "当前无权限,请授权", Toast.LENGTH_SHORT).show();
                startActivityForResult(new Intent(Settings.ACTION_MANAGE_OVERLAY_PERMISSION, Uri.parse("package:"+getPackageName())),0);
            } else {
                startService(new Intent(FloatActivity.this, FloatServices.class));
            }
        }

    具体代码如下   Activity

    package com.example.android.recycleautocarousel;
    
    import android.content.Intent;
    import android.net.Uri;
    import android.os.Build;
    import android.os.Bundle;
    import android.provider.Settings;
    import android.support.annotation.RequiresApi;
    import android.support.v7.app.AppCompatActivity;
    import android.view.View;
    import android.widget.Toast;
    
    import com.example.android.recycleautocarousel.services.FloatServices;
    
    public class FloatActivity extends AppCompatActivity {
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_float);
        }
    
        @RequiresApi(api = Build.VERSION_CODES.M)
        public void startFloatingService(View view) {
            if(!Settings.canDrawOverlays(this)){
                Toast.makeText(this, "当前无权限,请授权", Toast.LENGTH_SHORT).show();
                startActivityForResult(new Intent(Settings.ACTION_MANAGE_OVERLAY_PERMISSION, Uri.parse("package:"+getPackageName())),0);
            } else {
                startService(new Intent(FloatActivity.this, FloatServices.class));
            }
        }
    
        @RequiresApi(api = Build.VERSION_CODES.M)
        @Override
        protected void onActivityResult(int requestCode, int resultCode, Intent data) {
            if (requestCode == 0) {
                if (!Settings.canDrawOverlays(this)) {
                    Toast.makeText(this, "授权失败", Toast.LENGTH_SHORT).show();
                } else {
                    Toast.makeText(this, "授权成功", Toast.LENGTH_SHORT).show();
                    startService(new Intent(FloatActivity.this, FloatServices.class));
                }
            }
        }
    
    
    }

    Service

    package com.example.android.recycleautocarousel.services;
    
    import android.app.Service;
    import android.content.Intent;
    import android.graphics.Color;
    import android.graphics.PixelFormat;
    import android.media.AudioManager;
    import android.media.MediaPlayer;
    import android.net.Uri;
    import android.os.Build;
    import android.os.IBinder;
    import android.provider.Settings;
    import android.view.LayoutInflater;
    import android.view.MotionEvent;
    import android.view.SurfaceHolder;
    import android.view.SurfaceView;
    import android.view.View;
    import android.view.WindowManager;
    import android.widget.Button;
    import android.widget.ImageView;
    import android.widget.Toast;
    
    import com.example.android.recycleautocarousel.R;
    
    import java.io.IOException;
    
    /**
     * Created by android on 2018/6/22.
     */
    
    public class FloatServices extends Service {
    
        private Button mButton;
        private WindowManager mWindowManager;
        private WindowManager.LayoutParams mLayoutParams;
    
        @Override
        public IBinder onBind(Intent intent) {
            return null;
        }
    
        @Override
        public int onStartCommand(Intent intent, int flags, int startId) {
            showFloatingWindow();
    
            return super.onStartCommand(intent, flags, startId);
        }
    
    
    
    
        private  class FloatingOnTouchListener implements View.OnTouchListener{
            private int x;
            private int y;
    
            @Override
            public boolean onTouch(View v, MotionEvent event) {
               switch (event.getAction()) {
                    case MotionEvent.ACTION_DOWN:
                        x = (int) event.getRawX();
                        y = (int) event.getRawY();
                        break;
                    case MotionEvent.ACTION_MOVE:
                        int nowX = (int) event.getRawX();
                        int nowY = (int) event.getRawY();
                        int movedX = nowX - x;
                        int movedY = nowY - y;
                        x = nowX;
                        y = nowY;
                        mLayoutParams.x = mLayoutParams.x + movedX;
                        mLayoutParams.y = mLayoutParams.y + movedY;
    
                        // 更新悬浮窗控件布局
                        mWindowManager.updateViewLayout(v, mLayoutParams);
                        break;
                    default:
                        break;
                }
                return false;
            }
        }
    
    
    
    
    
    
        /**
         * 悬浮窗口 视屏
         */
        private void showFloatingWindow() {
            if (Settings.canDrawOverlays(this)) {
    
                mWindowManager = (WindowManager) getSystemService(WINDOW_SERVICE);
                LayoutInflater layoutInflater = LayoutInflater.from(this);
                View displayView = layoutInflater.inflate(R.layout.image_display, null);
                displayView.setOnTouchListener(new  FloatingOnTouchListener());
    
                // 获取WindowManager服务
                final MediaPlayer mediaPlayer = new MediaPlayer();
                mediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
                SurfaceView surfaceView = displayView.findViewById(R.id.video_display_surfaceview);
                final SurfaceHolder surfaceHolder = surfaceView.getHolder();
    
    
    
                surfaceHolder.addCallback(new SurfaceHolder.Callback() {
                      @Override
                      public void surfaceCreated(SurfaceHolder holder) {
                          mediaPlayer.setDisplay(surfaceHolder);
                      }
    
                    @Override
                    public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
    
                    }
    
                    @Override
                    public void surfaceDestroyed(SurfaceHolder holder) {
    
                    }
    
                });
                mediaPlayer.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
                    @Override
                    public void onPrepared(MediaPlayer mp) {
                        mediaPlayer.start();
                    }
                });
    
    
                try {
                    mediaPlayer.setDataSource(this, Uri.parse("https://raw.githubusercontent.com/dongzhong/ImageAndVideoStore/master/Bruno%20Mars%20-%20Treasure.mp4"));
                    mediaPlayer.prepareAsync();
                }
                catch (IOException e) {
                    Toast.makeText(this, "无法打开视频源", Toast.LENGTH_LONG).show();
                }
    
    
                // 设置LayoutParam
                mLayoutParams = new WindowManager.LayoutParams();
                if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
                    mLayoutParams.type = WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY;
                } else {
                    mLayoutParams.type = WindowManager.LayoutParams.TYPE_PHONE;
                }
                // flag参数必须设置 不然有悬浮窗 但其他应用也无法使用
                mLayoutParams.flags = mLayoutParams.FLAG_NOT_TOUCH_MODAL | mLayoutParams.FLAG_NOT_FOCUSABLE | mLayoutParams.FLAG_FULLSCREEN
                        | mLayoutParams.FLAG_LAYOUT_IN_SCREEN;
                mLayoutParams.format = PixelFormat.RGBA_8888;
                mLayoutParams.width = 300;
                mLayoutParams.height = 300;
                mLayoutParams.x = 300;
                mLayoutParams.y = 300;
    
                // 将悬浮窗控件添加到WindowManager
                mWindowManager.addView(displayView, mLayoutParams);
            }
        }
    
    
    
        /**
         * 悬浮窗口Imageview
         */
        private void showFloatingWindow2() {
            if (Settings.canDrawOverlays(this)) {
                // 获取WindowManager服务
                mWindowManager = (WindowManager) getSystemService(WINDOW_SERVICE);
    
                LayoutInflater layoutInflater = LayoutInflater.from(this);
                View displayView = layoutInflater.inflate(R.layout.image_display, null);
                displayView.setOnTouchListener(new  FloatingOnTouchListener());
    
                ImageView imageView = displayView.findViewById(R.id.image_display_imageview);
                imageView.setImageResource(R.drawable.item1);
    
    
    
                // 设置LayoutParam
                mLayoutParams = new WindowManager.LayoutParams();
                if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
                    mLayoutParams.type = WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY;
                } else {
                    mLayoutParams.type = WindowManager.LayoutParams.TYPE_PHONE;
                }
                // flag参数必须设置 不然有悬浮窗 但其他应用也无法使用
                mLayoutParams.flags = mLayoutParams.FLAG_NOT_TOUCH_MODAL | mLayoutParams.FLAG_NOT_FOCUSABLE | mLayoutParams.FLAG_FULLSCREEN
                        | mLayoutParams.FLAG_LAYOUT_IN_SCREEN;
                mLayoutParams.format = PixelFormat.RGBA_8888;
                mLayoutParams.width = 100;
                mLayoutParams.height = 100;
                mLayoutParams.x = 300;
                mLayoutParams.y = 300;
    
                // 将悬浮窗控件添加到WindowManager
                mWindowManager.addView(displayView, mLayoutParams);
            }
        }
    
        /**
         * 悬浮窗口button
         */
        private void showFloatingWindow1() {
            if (Settings.canDrawOverlays(this)) {
                // 获取WindowManager服务
                mWindowManager = (WindowManager) getSystemService(WINDOW_SERVICE);
    
                // 新建悬浮窗控件
                mButton = new Button(getApplicationContext());
                mButton.setText("Floating Window");
                mButton.setBackgroundColor(Color.BLUE);
    
                // 设置LayoutParam
                mLayoutParams = new WindowManager.LayoutParams();
                if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
                    mLayoutParams.type = WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY;
                } else {
                    mLayoutParams.type = WindowManager.LayoutParams.TYPE_PHONE;
                }
                // flag参数必须设置 不然有悬浮窗 但其他应用也无法使用
                mLayoutParams.flags = mLayoutParams.FLAG_NOT_TOUCH_MODAL | mLayoutParams.FLAG_NOT_FOCUSABLE | mLayoutParams.FLAG_FULLSCREEN
                        | mLayoutParams.FLAG_LAYOUT_IN_SCREEN;
                mLayoutParams.format = PixelFormat.RGBA_8888;
                mLayoutParams.width = 500;
                mLayoutParams.height = 100;
                mLayoutParams.x = 300;
                mLayoutParams.y = 300;
    
                // 将悬浮窗控件添加到WindowManager
                mWindowManager.addView(mButton, mLayoutParams);
            }
        }
    }

    activity_float.xml

    <?xml version="1.0" encoding="utf-8"?>
    <RelativeLayout
        xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:tools="http://schemas.android.com/tools"
        android:id="@+id/activity_float"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:paddingBottom="@dimen/activity_vertical_margin"
        android:paddingLeft="@dimen/activity_horizontal_margin"
        android:paddingRight="@dimen/activity_horizontal_margin"
        android:paddingTop="@dimen/activity_vertical_margin"
        tools:context="com.example.android.recycleautocarousel.FloatActivity"
        >
    
        <Button
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="nihao "
            android:onClick="startFloatingService"
            />
    
    
    </RelativeLayout>

    image_display.xml

    <?xml version="1.0" encoding="utf-8"?>
    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
                  android:orientation="vertical"
                  android:layout_width="wrap_content"
                  android:layout_height="wrap_content">
    
        <ImageView
            android:visibility="gone"
            android:id="@+id/image_display_imageview"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            />
    
        <SurfaceView
            android:id="@+id/video_display_surfaceview"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            />
    
    
    </LinearLayout>

     打完收工

  • 相关阅读:
    rsyslog 只读取变化的日志
    Invalid component element. Instead of passing a string like 'div', pass React.createElement('div')
    Java 并发之 CountDownLatch、CyclicBarrier 和 Semaphore
    JUC (Java Util Concurrency) 基础内容概述
    浅析Java中CountDownLatch用法
    java 多线程 CountDownLatch用法
    基于Netty的“请求-响应”同步通信机制实现
    响应头location 页面跳转
    8.1 Optimization Overview
    论人不地道,我只佩服TT——北漂18年(68)
  • 原文地址:https://www.cnblogs.com/LKit/p/9214439.html
Copyright © 2011-2022 走看看