    package com.sheep.jiuyan.samllsheep.service;

    import android.annotation.TargetApi;
    import android.app.Activity;
    import android.app.Service;
    import android.content.Context;
    import android.content.Intent;
    import android.graphics.Bitmap;
    import android.graphics.BitmapFactory;
    import android.graphics.PixelFormat;
    import android.hardware.display.DisplayManager;
    import android.hardware.display.VirtualDisplay;
    import android.media.Image;
    import android.media.ImageReader;
    import android.media.projection.MediaProjection;
    import android.media.projection.MediaProjectionManager;
    import android.os.Build;
    import android.os.Handler;
    import android.os.IBinder;
    import android.os.Message;
    import android.os.SystemClock;
    import android.util.DisplayMetrics;
    import android.view.Display;
    import android.view.GestureDetector;
    import android.view.Gravity;
    import android.view.MotionEvent;
    import android.view.View;
    import android.view.WindowManager;
    import android.widget.ImageView;

    import com.sheep.gamegroup.absBase.AbsObserver;
    import com.sheep.gamegroup.util.DataUtil;
    import com.sheep.gamegroup.util.GlobalScreenShot;
    import com.sheep.gamegroup.util.LogUtil;
    import com.sheep.gamegroup.view.activity.MiddleScreenShotAct;
    import com.sheep.jiuyan.samllsheep.R;
    import com.sheep.jiuyan.samllsheep.SheepApp;
    import com.sheep.jiuyan.samllsheep.utils.G;

    import java.io.File;
    import java.io.FileNotFoundException;
    import java.io.FileOutputStream;
    import java.io.IOException;
    import java.nio.ByteBuffer;

    import io.reactivex.Observable;
    import io.reactivex.android.schedulers.AndroidSchedulers;
    import io.reactivex.functions.Function;
    import io.reactivex.schedulers.Schedulers;


/**
 * Created by realicing on 2018/5/8.
 * realicing@sina.com
 */
@TargetApi(Build.VERSION_CODES.LOLLIPOP)
public class FloatShotScreenService extends Service {

    //不与Activity进行绑定.
    @Override
    public IBinder onBind(Intent intent) {
        return null;
    }
    private static FloatShotScreenService instance;

    public static FloatShotScreenService getInstance() {
        return instance;
    }

    @Override
    public void onCreate() {
        super.onCreate();
        instance = this;
        createFloatView();
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        removeMessages();
        if (floatView != null) {
            try {
                if(isAdded)
                    windowManager.removeViewImmediate(floatView);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        stopVirtual();

        tearDownMediaProjection();
    }

    public static final int OPERATION_SHOW = 100;
    public static final int OPERATION_HIDE = 101;
    public static final int SCREEN_SHOT = 1;//截图回调
    public static final int SET_SHOW_OR_HIDE = 2;//设置显示或不显示

    private static final int HANDLE_CHECK_ACTIVITY = 200;

    private boolean isAdded = false; // 是否已增加悬浮窗
    private WindowManager windowManager;
    private WindowManager.LayoutParams params;
    private View floatView;


    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        if (intent != null) {
            int type = intent.getIntExtra("type", 0);
            switch (type) {
                case SCREEN_SHOT:
                    performClick();
                    break;
                case SET_SHOW_OR_HIDE:
                    if (intent.getBooleanExtra("isShow", true)) {
                        mHandler.sendEmptyMessageDelayed(OPERATION_SHOW, 1000L);
                    } else {
                        removeMessages();
                        mHandler.sendEmptyMessage(OPERATION_HIDE);
                    }
                    break;
                default:
                    break;
            }
        }
        return super.onStartCommand(intent, flags, startId);
    }

    private void removeMessages() {
        mHandler.removeMessages(OPERATION_HIDE);
        mHandler.removeMessages(OPERATION_SHOW);
    }

    private Handler mHandler = new TwHandler(this);

    static class TwHandler extends Handler {
        TwHandler(FloatShotScreenService service) {
            this.service = service;
        }

        FloatShotScreenService service;

        @Override
        public void handleMessage(Message msg) {
            switch (msg.what) {
                case OPERATION_SHOW:
                    if (!service.isAdded) {
                        try {
//                            service.floatView.setAlpha(1.0f);
//                            windowManager.updateViewLayout(service.floatView, params);
                            service.resetParams();
                            service.windowManager.addView(service.floatView, service.params);
                        } catch (Exception e) {
                            e.printStackTrace();
                        }
                        service.isAdded = true;
                    }
                    break;
                case OPERATION_HIDE:
                case HANDLE_CHECK_ACTIVITY:
                    if (service.isAdded) {
                        try {
//                            service.floatView.setAlpha(0.0f);
//                            windowManager.updateViewLayout(service.floatView, params);
                            service.windowManager.removeViewImmediate(service.floatView);
                        } catch (Exception e) {
                            e.printStackTrace();
                        }
                        service.isAdded = false;
                    }
                    break;
            }
        }
    }


    /**
     * 创建悬浮窗
     */
    private void createFloatView() {
        //获取浮动窗口视图所在布局.
        ImageView imageView = new ImageView(getApplicationContext());
        imageView.setImageBitmap(BitmapFactory.decodeResource(getResources(), R.mipmap.jietu));
        floatView = imageView;

        windowManager = (WindowManager) getApplicationContext().getSystemService(Context.WINDOW_SERVICE);
        params = new WindowManager.LayoutParams();

        // 设置window type
//        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O){//6.0
//            params.type = WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY;
//        }else {
//            params.type =  WindowManager.LayoutParams.TYPE_SYSTEM_ALERT;
//        }
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
            //  大于等于 24 即为 7.0 及以上执行内容
//            Log.e("qx", "7.0");
            params.type = WindowManager.LayoutParams.TYPE_PHONE; // 7.1
        } else {
            //  低于 24 即为 7.0 以下执行内容
            params.type = WindowManager.LayoutParams.TYPE_TOAST;   // 4.4
//            Log.e("qx", "4.4");

        }
        /*
         * 如果设置为params.type = WindowManager.LayoutParams.TYPE_PHONE; 那么优先级会降低一些,
         * 即拉下通知栏不可见
         */

        params.format = PixelFormat.RGBA_8888; // 设置图片格式，效果为背景透明

        // 设置Window flag
        params.flags = WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL
                | WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE;
        // 设置悬浮窗的Touch监听
        floatView.setOnTouchListener(new View.OnTouchListener() {
            GestureDetector mGestureDetector = new GestureDetector(getApplicationContext(), new FloatGestureTouchListener());
            @Override
            public boolean onTouch(View v, MotionEvent event) {
                if(event == null)
                    v.performClick();
                return mGestureDetector.onTouchEvent(event);
            }
        });

//        resetParams();
//
//        try {
//            windowManager.addView(floatView, params);
//            isAdded = true;
//        } catch (Exception e) {
//            e.printStackTrace();
//        }
    }

    private void resetParams() {
        Display display = windowManager.getDefaultDisplay();
        DisplayMetrics metric = new DisplayMetrics();
        display.getMetrics(metric);
        // 设置悬浮窗的长得宽
        params.width = SheepApp.getInstance().getResources().getDimensionPixelSize(R.dimen.content_padding_30);
        params.height = WindowManager.LayoutParams.WRAP_CONTENT;
        params.gravity = Gravity.START | Gravity.TOP;
        params.x = metric.widthPixels;
        params.y = SheepApp.getInstance().getResources().getDimensionPixelSize(R.dimen.content_padding_100);
    }

    private void performClick() {
        //获取当前正在运行的程序的包名
        //不判断是否是正在进行的任务上截图，只在上传截图的地方获取指定包名的截图
        packageNameInForeground = ListenerShotService.getPackageNameInForeground(getApplicationContext());
        // 设置点击悬浮窗的响应
        startScreenShot();
    }
    private String packageNameInForeground;

    private void startScreenShot() {
        Handler handler1 = new Handler();
        handler1.postDelayed(new Runnable() {
            public void run() {
                floatView.setVisibility(View.GONE);
            }
        }, 0);
        handler1.postDelayed(new Runnable() {
            public void run() {
                //start virtual
                startVirtual();
            }
        }, 5);

    }

    private ImageReader createImageReader(DisplayMetrics metric) {
        if(mImageReader == null) {
            mImageReader = ImageReader.newInstance(metric.widthPixels, metric.heightPixels, PixelFormat.RGBA_8888, 1);
        }
        return mImageReader;

    }

    public void startVirtual() {
        if (mResultData == null) {
            floatView.setVisibility(View.VISIBLE);
            Intent intent = new Intent(getApplicationContext(), MiddleScreenShotAct.class);
            intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
            startActivity(intent);
            LogUtil.println("FloatShotScreenService", "没有mResultData");
        } else {
            virtualDisplay();
        }
    }

    public MediaProjection setUpMediaProjection() {
        if(mMediaProjection == null) {
            mMediaProjection = getMediaProjectionManager().getMediaProjection(Activity.RESULT_OK, mResultData);
        }
        return mMediaProjection;
    }

    private MediaProjectionManager getMediaProjectionManager() {

        return (MediaProjectionManager) getSystemService(Context.MEDIA_PROJECTION_SERVICE);
    }

    private void virtualDisplay() {
        Display display = windowManager.getDefaultDisplay();
        DisplayMetrics metric = new DisplayMetrics();
        display.getMetrics(metric);

        mImageReader = createImageReader(metric);
        mVirtualDisplay = setUpMediaProjection().createVirtualDisplay("screen-mirror",
                metric.widthPixels,  metric.heightPixels, metric.densityDpi, DisplayManager.VIRTUAL_DISPLAY_FLAG_AUTO_MIRROR,
                mImageReader.getSurface(), null, null);
        SystemClock.sleep(500);
        Image image = mImageReader.acquireLatestImage();
        if (image == null) {
            floatView.setVisibility(View.VISIBLE);
            G.showToast("请稍候重新截图！");
            LogUtil.println("FloatShotScreenService", "image");
        } else {
            Observable.just(image)
                    .map(new Function<Image, Bitmap>() {
                        @Override
                        public Bitmap apply(Image image) throws Exception {
                            return getBitmapFromImage(image);
                        }
                    })
                    .subscribeOn(Schedulers.io())
                    .observeOn(AndroidSchedulers.mainThread())
                    .subscribe(new AbsObserver<Bitmap>() {
                        @Override
                        public void onNext(Bitmap bitmap) {
                            //预览图片
                            if (bitmap != null) {
                                new GlobalScreenShot(getApplicationContext()).takeScreenshot(bitmap, new GlobalScreenShot.onScreenShotListener() {
                                    @Override
                                    public void onStartShot() {

                                    }

                                    @Override
                                    public void onFinishShot(boolean success) {
                                        G.showToast("截图成功");
                                    }
                                }, true, true);
                            }
                            floatView.setVisibility(View.VISIBLE);
                        }
                    });
        }
    }

    private Bitmap getBitmapFromImage(Image image) {
        int width = image.getWidth();
        int height = image.getHeight();
        final Image.Plane[] planes = image.getPlanes();
        final ByteBuffer buffer = planes[0].getBuffer();
        //每个像素的间距
        int pixelStride = planes[0].getPixelStride();
        //总的间距
        int rowStride = planes[0].getRowStride();
        int rowPadding = rowStride - pixelStride * width;
        Bitmap bitmap = Bitmap.createBitmap(width + rowPadding / pixelStride, height, Bitmap.Config.ARGB_8888);
        bitmap.copyPixelsFromBuffer(buffer);
        bitmap = Bitmap.createBitmap(bitmap, 0, 0, width, height);
        image.close();
        File fileImage = null;
        if (bitmap != null) {
            try {
                fileImage = DataUtil.getScreenShotsFile(packageNameInForeground);
                if (!fileImage.exists()) {
                    fileImage.createNewFile();
                }
                FileOutputStream out = new FileOutputStream(fileImage);
                bitmap.compress(Bitmap.CompressFormat.PNG, 100, out);
                out.flush();
                out.close();
//                Intent media = new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE);
//                Uri contentUri = Uri.fromFile(fileImage);
//                media.setData(contentUri);
//                sendBroadcast(media);
            } catch (FileNotFoundException e) {
                e.printStackTrace();
                fileImage = null;
            } catch (IOException e) {
                e.printStackTrace();
                fileImage = null;
            }
        }

        if (fileImage != null) {
            return bitmap;
        }
        return null;
    }

    private MediaProjection mMediaProjection;
    private VirtualDisplay mVirtualDisplay;

    private Intent mResultData = null;

    public void setResultData(Intent mResultData) {
        this.mResultData = mResultData;
    }

    private ImageReader mImageReader;

    private void tearDownMediaProjection() {
        if (mMediaProjection != null) {
            mMediaProjection.stop();
            mMediaProjection = null;
        }
    }

    private void stopVirtual() {
        if (mVirtualDisplay == null) {
            return;
        }
        mVirtualDisplay.release();
        mVirtualDisplay = null;
    }

    private class FloatGestureTouchListener extends GestureDetector.SimpleOnGestureListener {
        int lastX, lastY;
        int paramX, paramY;

        /**
         * onDown():刚刚手指接触到触摸屏的那一刹那，就是触的那一下。
         */
        @Override
        public boolean onDown(MotionEvent event) {
            lastX = (int) event.getRawX();
            lastY = (int) event.getRawY();
            paramX = params.x;
            paramY = params.y;
            return true;
        }

        /**
         * onShowPress():手指按在触摸屏上，它的时间范围：在按下起后，在长按之前
         */
        @Override
        public void onShowPress(MotionEvent e) {

        }

        /**
         * onScroll():手指在屏幕上滑动
         */
        @Override
        public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) {
            int dx = (int) e2.getRawX() - lastX;
            int dy = (int) e2.getRawY() - lastY;
            params.x = paramX + dx;
            params.y = paramY + dy;
            // 更新悬浮窗位置
            windowManager.updateViewLayout(floatView, params);
            return true;
        }

        /**
         * onFling():手指在触摸屏上迅速移动，并松开的动作(滑动的比onScroll快)
         */
        @Override
        public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {
            return false;
        }

        /**
         * onLongPress():手指在屏幕上停留一段时间 后抬起
         */
        @Override
        public void onLongPress(MotionEvent e) {

        }

        /**
         * onSingleTapUp():手指离开view那一瞬间执行
         */
        @Override
        public boolean onSingleTapUp(MotionEvent e) {
            return super.onSingleTapUp(e);
        }

        /**
         * onSingleTapConfirmed() 同上者，但有附加条件，就是Android会确保单击之后短时间内没有再次单击，才会触发该函数。
         * 举个列子，如果监听双击事件：onSingleTapUp()会被触发两次。但是onSingleTapConfirmed()一次都不会被触发。
         * 所以，如果你既想监听单击事件，又想监听双击时间，那么请使用onSingleTapConfirmed()函数。
         */
        @Override
        public boolean onSingleTapConfirmed(MotionEvent e) {
            performClick();
            return true;
        }

        /**
         * 通知DoubleTap手势中的事件，包含down、up和move事件（这里指的是在双击之间发生的事件，例如在同一个地方双击会产生DoubleTap手势，而在DoubleTap手势里面还会发生down和up事件，这两个事件由该函数通知）；双击的第二下Touch down和up都会触发，可用e.getAction()区分
         */
        @Override
        public boolean onDoubleTapEvent(MotionEvent e) {
            return super.onDoubleTapEvent(e);
        }

        /**
         * 在双击的第二下，Touch down时触发
         */
        @Override
        public boolean onDoubleTap(MotionEvent e) {
            return super.onDoubleTap(e);
        }
    }
}
