Android截图方案使用MediaProjection截图
文章目录
1.简介
MediaProjection 是google官方的屏幕截屏/录屏方式,
通过MediaProjectionManager管理有具体类型的MediaProjection建立屏幕捕获对话来实现截屏或者录屏。也就是说其实是靠MediaProjection来实现截屏或录屏的。
所有代码都在Github-Tinder
/**
* Manages the retrieval of certain types of {@link MediaProjection} tokens.
*
* <p><ol>An example flow of starting a media projection will be:
* <li>Declare a foreground service with the type {@code mediaProjection} in
* the {@code AndroidManifest.xml}.
* </li>
* <li>Create an intent by calling {@link MediaProjectionManager#createScreenCaptureIntent()}
* and pass this intent to {@link Activity#startActivityForResult(Intent, int)}.
* </li>
* <li>On getting {@link Activity#onActivityResult(int, int, Intent)},
* start the foreground service with the type
* {@link android.content.pm.ServiceInfo#FOREGROUND_SERVICE_TYPE_MEDIA_PROJECTION}.
* </li>
* <li>Retrieve the media projection token by calling
* {@link MediaProjectionManager#getMediaProjection(int, Intent)} with the result code and
* intent from the {@link Activity#onActivityResult(int, int, Intent)} above.
* </li>
* <li>Start the screen capture session for media projection by calling
* {@link MediaProjection#createVirtualDisplay(String, int, int, int, int, Surface,
* android.hardware.display.VirtualDisplay.Callback, Handler)}.
* </li>
* </ol>
*/
类注解就说的很明白,使用MediaProjectionManager
实现截屏仅需5步:
- 声明一个
foregroundServiceType
包含mediaProjection
类型的service - 通过 MediaProjectionManager.createScreenCaptureIntent() 获取intent,然后调用
Activity.tartActivityForResult(Intent, int)
- 在收到
Activity.onActivityResult(int, int, Intent)
回调后,启动Service,并传递foregroundServiceType
为ServiceInfo#FOREGROUND_SERVICE_TYPE_MEDIA_PROJECTION
- 在
Activity.onActivityResult(int, int, Intent)
中调用MediaProjectionManager.getMediaProjection(int, Intent)
获取MediaProjection
- 调用
MediaProjection#createVirtualDisplay(String, int, int, int, int, Surface,android.hardware.display.VirtualDisplay.Callback, Handler)
开始捕获屏幕
2.具体使用
接下来,正式按照上述步骤介绍如何实现截屏
2.1 声明Service
Service代码
class TinderService : Service() {
override fun onBind(intent: Intent?): IBinder? {
return null
}
override fun onCreate() {
super.onCreate()
Log.i(TAG, "onCreate: ")
//前台化通知
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
val channelId = "001"
val channelName = "screenshot"
val channel =
NotificationChannel(channelId, channelName, NotificationManager.IMPORTANCE_NONE)
channel.lightColor = Color.BLUE
channel.lockscreenVisibility = Notification.VISIBILITY_PRIVATE
val manager = getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager?
if (manager != null) {
val activityIntent: Intent = Intent(
this,
MainActivity::class.java
)
activityIntent.setAction("stop")
val contentIntent = PendingIntent.getActivity(
this,
0,
activityIntent,
PendingIntent.FLAG_MUTABLE
)
manager.createNotificationChannel(channel)
val notification: Notification =
Notification.Bu