Android实现手机截屏并保存截图功能
在Android开发中,实现手机截屏并保存截图的功能是一个常见的需求,本文将详细介绍如何使用Android SDK来实现这一功能,包括获取屏幕截图、保存截图到本地存储以及处理相关权限等。
一、准备工作
添加权限
需要在AndroidManifest.xml
文件中添加读取和写入外部存储的权限:
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
检查和请求权限
从Android 6.0(API级别23)开始,需要在运行时动态请求这些权限,以下是一个简单的示例代码来检查和请求权限:
private static final int PERMISSION_REQUEST_CODE = 1; public boolean hasStoragePermission() { String[] permissions = { Manifest.permission.READ_EXTERNAL_STORAGE, Manifest.permission.WRITE_EXTERNAL_STORAGE }; for (String permission : permissions) { if (ContextCompat.checkSelfPermission(this, permission) != PackageManager.PERMISSION_GRANTED) { return false; } } return true; } public void requestStoragePermission() { ActivityCompat.requestPermissions(this, new String[]{ Manifest.permission.READ_EXTERNAL_STORAGE, Manifest.permission.WRITE_EXTERNAL_STORAGE }, PERMISSION_REQUEST_CODE); }
在onCreate
方法中调用hasStoragePermission()
方法来检查权限,如果没有权限则调用requestStoragePermission()
方法请求权限:
@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); if (!hasStoragePermission()) { requestStoragePermission(); } else { takeScreenshot(); } } @Override public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) { super.onRequestPermissionsResult(requestCode, grantResults); if (requestCode == PERMISSION_REQUEST_CODE) { if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) { takeScreenshot(); } else { Toast.makeText(this, "需要存储权限", Toast.LENGTH_SHORT).show(); } } }
二、获取屏幕截图
1. 使用MediaProjection API
从Android 5.0(API级别21)开始,可以使用MediaProjection
API来捕获屏幕内容,以下步骤展示了如何使用这个API:
1.1 启动屏幕捕获
需要启动一个活动来请求屏幕捕获权限:
Intent intent = new Intent(MediaProjectionManager.ACTION_SCREEN_CAPTURE); startActivityForResult(intent, SCREEN_CAPTURE_PERMISSION_CODE);
1.2 处理结果
在onActivityResult
方法中处理用户的选择:
@Override protected void onActivityResult(int requestCode, resultCode, packageName, Intent data) { super.onActivityResult(requestCode, resultCode, packageName, data); if (requestCode == SCREEN_CAPTURE_PERMISSION_CODE) { if (resultCode == RESULT_OK && data != null) { imageReader = ImageReader.newInstance(displayWidth, displayHeight, PixelFormat.RGBA_8888, null); mediaProjection = (MediaProjection) getIntent().getExtras().get("data"); mediaProjection.createVirtualDisplay("screencap", displayWidth, displayHeight, displayDensity, surface, null, null); } else { Toast.makeText(this, "用户拒绝屏幕捕获权限", Toast.LENGTH_SHORT).show(); } } }
1.3 创建虚拟显示并捕获帧数据
创建一个Surface
对象并将其传递给createVirtualDisplay
方法:
ImageReader.OnImageAvailableListener imageListener = new ImageReader.OnImageAvailableListener() { @Override public void onImageAvailable(ImageReader reader) { Image image = null; try { image = reader.acquireLatestImage(); if (image != null) { // 将图像转换为Bitmap并保存到本地存储 Image.Plane[] planes = image.getPlanes(); ByteBuffer buffer = planes[0].getBuffer(); byte[] bytes = new byte[buffer.remaining()]; buffer.get(bytes); Bitmap bitmap = BitmapFactory.decodeByteArray(bytes, 0, bytes.length); saveBitmap(bitmap); image.close(); } } finally { if (image != null) { image.close(); } } } };
三、保存截图到本地存储
创建文件并写入数据
使用Bitmap
对象的compress
方法将其保存为文件:
private void saveBitmap(Bitmap bitmap) { FileOutputStream out = null; try { File file = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES), "screenshot_" + System.currentTimeMillis() + ".png"); out = new FileOutputStream(file); bitmap.compress(Bitmap.CompressFormat.PNG, 100, out); Toast.makeText(this, "截图已保存:" + file.getAbsolutePath(), Toast.LENGTH_SHORT).show(); } catch (IOException e) { e.printStackTrace(); } finally { try { if (out != null) { out.close(); } } catch (IOException e) { e.printStackTrace(); } } }
四、处理不同屏幕方向和分辨率
为了确保截图能够适应不同的屏幕方向和分辨率,可以在启动屏幕捕获之前获取设备的显示参数:
WindowManager windowManager = (WindowManager) getSystemService(WINDOW_SERVICE); Display display = windowManager.getDefaultDisplay(); Point size = new Point(); display.getSize(size); int displayWidth = size.x; int displayHeight = size.y; int displayDensity = display.getDensityDpi();
五、完整示例代码
以下是一个完整的示例代码,展示了如何实现上述功能:
public class MainActivity extends AppCompatActivity { private static final int SCREEN_CAPTURE_PERMISSION_CODE = 2; private MediaProjection mediaProjection; null; private ImageReader imageReader = null; private Surface surface = null; private int displayWidth; private int displayHeight; private int displayDensity; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); if (!hasStoragePermission()) { requestStoragePermission(); } else { takeScreenshot(); } } private boolean hasStoragePermission() { String[] permissions = {Manifest.permission.READ_EXTERNAL_STORAGE, Manifest.permission.WRITE_EXTERNAL_STORAGE}; for (String permission : permissions) { if (ContextCompat.checkSelfPermission(this, permission) != PackageManager.PERMISSION_GRANTED) { return false; } } return true; } private void requestStoragePermission() { ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.READ_EXTERNAL_STORAGE, Manifest.permission.WRITE_EXTERNAL_STORAGE}, SCREEN_CAPTURE_PERMISSION_CODE); } @Override public void onRequestPermissionsResult(int requestCode, grantResults) { super.onRequestPermissionsResult(requestCode, grantResults); if (requestCode == SCREEN_CAPTURE_PERMISSION_CODE) { if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) { takeScreenshot(); } else { Toast.makeText(this, "需要存储权限", Toast.LENGTH_SHORT).show(); } } } private void takeScreenshot() { WindowManager windowManager = (WindowManager) getSystemService(WINDOW_SERVICE); Display display = windowManager.getDefaultDisplay(); Point size = new Point(); display.getSize(size); displayWidth = size.x; displayHeight = size.y; displayDensity = display.getDensityDpi(); Intent intent = new Intent(MediaProjectionManager.ACTION_SCREEN_CAPTURE); startActivityForResult(intent, SCREEN_CAPTURE_PERMISSION_CODE); } @Override protected void onActivityResult(int requestCode, resultCode, packageName, Intent data) { super.onActivityResult(requestCode, resultCode, packageName, data); if (requestCode == SCREEN_CAPTURE_PERMISSION_CODE) { if (resultCode == RESULT_OK && data != null) { imageReader = ImageReader.newInstance(displayWidth, displayHeight, PixelFormat.RGBA_8888, null); mediaProjection = (MediaProjection) getIntent().getExtras().get("data"); mediaProjection.createVirtualDisplay("screencap", displayWidth, displayHeight, displayDensity, surface, null, null); } else { Toast.makeText(this, "用户拒绝屏幕捕获权限", Toast.LENGTH_SHORT).show(); } } } }
小伙伴们,上文介绍了“android实现手机截屏并保存截图功能”的内容,你了解清楚吗?希望对你有所帮助,任何问题可以给我留言,让我们下期再见吧。