Created
September 18, 2016 08:40
-
-
Save nosix/fcf1923f0c7cc42aa8c2ee70ff457b9c to your computer and use it in GitHub Desktop.
Taking a snapshot of the screen for Android (SDK 21) in Kotlin 1.0.3
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package xxx | |
import android.content.Context | |
import android.graphics.Bitmap | |
import android.graphics.PixelFormat | |
import android.hardware.display.DisplayManager | |
import android.hardware.display.VirtualDisplay | |
import android.media.ImageReader | |
import android.media.projection.MediaProjection | |
import android.util.Log | |
class Capture(val context: Context) : ImageReader.OnImageAvailableListener { | |
companion object { | |
private val TAG = Capture::class.qualifiedName | |
} | |
private var display: VirtualDisplay? = null | |
private var onCaptureListener: ((Bitmap) -> Unit)? = null | |
fun run(mediaProjection: MediaProjection, onCaptureListener: (Bitmap) -> Unit) { | |
this.onCaptureListener = onCaptureListener | |
if (display == null) { | |
display = createDisplay(mediaProjection) | |
} | |
} | |
private fun createDisplay(mediaProjection: MediaProjection): VirtualDisplay { | |
context.resources.displayMetrics.run { | |
val maxImages = 2 | |
val reader = ImageReader.newInstance( | |
widthPixels, heightPixels, PixelFormat.RGBA_8888, maxImages) | |
reader.setOnImageAvailableListener(this@Capture, null) | |
val display = mediaProjection.createVirtualDisplay( | |
"Capture Display", widthPixels, heightPixels, densityDpi, | |
DisplayManager.VIRTUAL_DISPLAY_FLAG_AUTO_MIRROR, | |
reader.surface, null, null) | |
Log.d(TAG, "createVirtualDisplay") | |
return display | |
} | |
} | |
override fun onImageAvailable(reader: ImageReader) { | |
if (display != null) { | |
onCaptureListener?.invoke(captureImage(reader)) | |
} | |
} | |
private fun captureImage(reader: ImageReader): Bitmap { | |
Log.d(TAG, "captureImage") | |
val image = reader.acquireLatestImage() | |
context.resources.displayMetrics.run { | |
image.planes[0].run { | |
val bitmap = Bitmap.createBitmap( | |
rowStride / pixelStride, heightPixels, Bitmap.Config.ARGB_8888) | |
bitmap.copyPixelsFromBuffer(buffer) | |
image.close() | |
return bitmap | |
} | |
} | |
} | |
fun stop() { | |
display?.release() | |
display = null | |
onCaptureListener = null | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package xxx | |
import android.app.Activity | |
import android.app.Service | |
import android.content.Intent | |
import android.media.projection.MediaProjection | |
import android.media.projection.MediaProjectionManager | |
import android.os.Bundle | |
import android.widget.Toast | |
class CaptureActivity : Activity() { | |
companion object { | |
private const val REQUEST_CAPTURE = 1 | |
var projection: MediaProjection? = null | |
} | |
private lateinit var mediaProjectionManager: MediaProjectionManager | |
override fun onCreate(savedInstanceState: Bundle?) { | |
super.onCreate(savedInstanceState) | |
mediaProjectionManager = getSystemService(Service.MEDIA_PROJECTION_SERVICE) as MediaProjectionManager | |
startActivityForResult(mediaProjectionManager.createScreenCaptureIntent(), REQUEST_CAPTURE) | |
} | |
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) { | |
if (requestCode == REQUEST_CAPTURE) { | |
if (resultCode == RESULT_OK) { | |
projection = mediaProjectionManager.getMediaProjection(resultCode, data) | |
val intent = Intent(this, CaptureService::class.java) | |
.setAction(CaptureService.ACTION_ENABLE_CAPTURE) | |
startService(intent) | |
} else { | |
projection = null | |
Toast.makeText(this, R.string.capture_error, Toast.LENGTH_SHORT).show() | |
} | |
} | |
finish() | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package xxx | |
import android.app.Notification | |
import android.app.PendingIntent | |
import android.app.Service | |
import android.content.Intent | |
import android.os.IBinder | |
import android.util.Log | |
import java.util.* | |
import xxx.Capture | |
class CaptureService : Service() { | |
companion object { | |
private val TAG = CaptureService::class.qualifiedName | |
val ACTION_ENABLE_CAPTURE = "enable_capture" | |
} | |
private val notificationId = Random().nextInt() | |
private val capture = Capture(this) | |
// ... snip ... | |
override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int { | |
if (intent != null) { | |
when (intent.action) { | |
ACTION_ENABLE_CAPTURE -> onEnableCapture() | |
} | |
} | |
return Service.START_STICKY | |
} | |
private fun enableCapture() { | |
if (CaptureActivity.projection == null) { | |
Log.d(TAG, "startActivity(CaptureActivity)") | |
val intent = Intent(this, CaptureActivity::class.java) | |
.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK) | |
startActivity(intent) | |
} else { | |
onEnableCapture() | |
} | |
} | |
private fun onEnableCapture() { | |
CaptureActivity.projection?.run { | |
capture.run(this) { | |
capture.stop() | |
// save bitmap | |
} | |
} | |
} | |
private fun disableCapture() { | |
capture.stop() | |
CaptureActivity.projection = null | |
} | |
override fun onDestroy() { | |
super.onDestroy() | |
disableCapture() | |
} | |
} |
sorry i am a newbie, in CaptureService,Which function do I have to call to take a screenshot? Thank you!
CaptureActivity calls CaptureService with startService, and CaptureService uses Capture.
It is a memorandum of 5 years ago, so it is recommended to check the latest information on the official website.
Are you still in the middle of a full project? I am a novice so it is quite difficult to find a similar project.
I also remember having a hard time finding information. I don't remember the details, so it's difficult to provide additional information. sorry.
Please read the following about the service.
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Where is the densityDpi ????