
package sc.tool.screenshot;

import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.PixelFormat;
import android.hardware.display.DisplayManager;
import android.media.Image;
import android.media.ImageReader;
import android.media.projection.MediaProjection;
import android.media.projection.MediaProjectionManager;
import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
import android.util.DisplayMetrics;
import android.view.WindowManager;
import android.widget.Toast;


/* 请在AndroidManifest.xml中添加存储权限和Activity声明
 * 
 <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
 <activity
 android:name="sc.tool.screenshot.ScreenActivity"
 android:configChanges="orientation|keyboardHidden|screenSize"
 android:theme="@android:style/Theme.Translucent.NoTitleBar.Fullscreen"
 android:launchMode="singleTop" />

 */

/** 封装MediaProjectionManager，方便获取屏幕操作 用法： 
 * 1、初始化请求允许获取屏幕 ScreenActivity.Init(context); 
 * 2、获取屏幕图像 ScreenActivity.GetScreen_pic() 或 直接保存截屏 ScreenActivity.GetScreen(); 
 * 拓展调用接口：ScreenActivity.GetScreen(final long DellayMillionSecond, final int times) 
 * 
 * 原理：
 * 1、通过MediaProjectionManager请求获取屏幕投影，在用户允许时获取屏幕投影，将屏幕投影到虚拟显示器（虚拟显示器创建时与ImageReader绑定） 
 * 2、通过ImageReader读取投影屏幕 
 */
public class ScreenActivity extends Activity
{
	private static Context context_S = null;
	
	/** 截屏初始化（请求用户允许获取屏幕） */
	public static void Init(Context context)
	{
		if (isInit) return;
		context_S = context;
		
		if (context != null)
		{
			Intent intent = new Intent(context, ScreenActivity.class);
			// intent.setAction("intent.action.sc.ScreenShot");
			context.startActivity(intent);
		}
	}
	
	private static ScreenCallBack call;
	
	/** 截屏初始化（请求用户允许获取屏幕），在允许时执行回调 */
	public static void Init(Context context, ScreenCallBack initCall)
	{
		call = initCall;
		Init(context);
	}
	
	/** 标记是否初始化成功 */
	private static boolean isInit = false;
	private static MediaProjection Projection;
	private static ImageReader ImageR;
	
	private MediaProjectionManager PrManager;	// 屏幕投影管理器
	public static final int requestCode_Projection = 6556;
	
	private int W;
	private int H;
	private int D;
	
	// 初始载入屏幕尺寸、分辨率信息
	private void LoadScreenInfo()
	{
		WindowManager mWindowManager = (WindowManager) getSystemService(Context.WINDOW_SERVICE);
		
		DisplayMetrics metrics = new DisplayMetrics();
		mWindowManager.getDefaultDisplay().getMetrics(metrics);
		
		D = metrics.densityDpi;
		W = metrics.widthPixels;
		H = metrics.heightPixels;
	}
	
	@Override
	protected void onCreate(Bundle savedInstanceState)
	{
		super.onCreate(savedInstanceState);
		// setContentView(R.layout.activity_main);
		
		try
		{
			LoadScreenInfo();
			
			PrManager = (MediaProjectionManager) getSystemService(Context.MEDIA_PROJECTION_SERVICE);	// 获取Manager
			startActivityForResult(PrManager.createScreenCaptureIntent(), requestCode_Projection);	// 请求获取屏幕显示
			
			// Toast.makeText(this, "onCreate -> 已执行", Toast.LENGTH_SHORT).show();
		}
		catch (Exception ex)
		{
			ex.printStackTrace();
		}
	}
	
	@Override
	protected void onActivityResult(int requestCode, int resultCode, Intent data)
	{
		super.onActivityResult(requestCode, resultCode, data);
		
		if (requestCode == requestCode_Projection)
		{
			// Toast.makeText(this, "onActivityResult -> 已执行0", Toast.LENGTH_SHORT).show();
			
			if (resultCode == RESULT_OK && data != null)
			{
				Projection = PrManager.getMediaProjection(Activity.RESULT_OK, data);	// 允许获取屏幕时，获取投影
				
				// 根据屏幕尺寸创建ImageReader，用于读取投影屏幕
				// ImageR = ImageReader.newInstance(W, H, PixelFormat.RGB_888, 1); // 格式若不是PixelFormat.RGB_888，在获取截屏时会报错给出类型: The producer output buffer format
				// 0x03
				ImageR = ImageReader.newInstance(W, H, PixelFormat.RGBA_8888, 1);
				
				// 将屏幕投影到虚拟显示器（虚拟显示器创建时与ImageReader绑定）
				Projection.createVirtualDisplay("screen-mirror", W, H, D, DisplayManager.VIRTUAL_DISPLAY_FLAG_AUTO_MIRROR, ImageR.getSurface(), null, null);
				
				isInit = true;
				if (call != null) call.Success();	// 执行回调逻辑
					
				// Toast.makeText(this, "onActivityResult -> 已执行1", Toast.LENGTH_SHORT).show();
			}
		}
		
		// Toast.makeText(this, "onActivityResult -> 已执行2 : " + resultCode, Toast.LENGTH_SHORT).show();
		
		// Toast.makeText(this, "onActivityResult -> 已执行2", Toast.LENGTH_SHORT).show();
		this.finish();						// 权限请求后关闭当前Activity
	}
	
	/** 获取实时显示的屏幕图像 */
	public static Bitmap GetScreen_pic()
	{
		Bitmap pic = null;
		if (isInit)
		{
			try
			{
				Image image = ImageR.acquireLatestImage();	// 通过ImageReader从屏幕投影中读取最新的图像
				pic = ScreenTool.ToBitmap(image);			// 转化为Bitmap
				
				// boolean isNull = (image == null);
				// Toast.makeText(context_S, "startScreenShot -> " + (isNull ? "null" : "非空"), Toast.LENGTH_SHORT).show();
				
			}
			catch (Exception ex)
			{
				ex.printStackTrace();
				// Toast.makeText(this, "startScreenShot -> \n" + ex.toString(), Toast.LENGTH_SHORT).show();
			}
		}
		// else Init(context_S); // 若未初始化，则自动初始化请求允许获取屏幕
		
		return pic;
	}
	
	/** 获取实时显示的屏幕图像，自动保存 */
	public static boolean GetScreen()
	{
		Bitmap pic = GetScreen_pic();
		return ScreenTool.SaveScreen(pic);
		// return ScreenTool.SaveScreen(context_S, pic);
	}
	
	private static int count = 5;
	
	/** 截屏（延时毫秒、截屏次数） */
	public static void GetScreen(final long DellayMillionSecond, final int times)
	{
		count = times;
		final Handler mainHandler = new Handler(Looper.getMainLooper());
		Runnable r = new Runnable()
		{
			@Override
			public void run()
			{
				if (count > 0)
				{
					// Toast.makeText(context_S, "GetScreen" + count, Toast.LENGTH_SHORT).show();
					count--;
					ScreenActivity.GetScreen();
					mainHandler.postDelayed(this, DellayMillionSecond);
				}
				else mainHandler.removeCallbacks(this);
			}
		};
		
		if (count > 0) mainHandler.postDelayed(r, DellayMillionSecond);
	}
	
	/** 屏幕投影请求回调 */
	public static abstract class ScreenCallBack
	{
		/** 屏幕投影请求成功 */
		public abstract void Success();
	}
	
}
