大家好,我有一个来自(@commonsware)的示例屏幕截图项目,使用媒体项目在任何屏幕上执行屏幕截图(在前台服务模式下运行并带有通知)
但是它没有拍任何照片,只是在按钮点击时发出哔哔声
我的方法也是更改目录,但不知道我需要如何更改它,因为我想将所有图像加载到应用程序内的 recyclerview 中
任何帮助将不胜感激
这是整个服务代码:
public class ScreenShotService extends Service {
private static final int NOTIFY_ID = 9906;
static final String EXTRA_RESULT_CODE = "resultCode";
static final String EXTRA_RESULT_INTENT = "resultIntent";
static final String ACTION_RECORD = BuildConfig.APPLICATION_ID + ".RECORD";
static final String ACTION_SHUTDOWN = BuildConfig.APPLICATION_ID + ".SHUTDOWN";
static final int VIRT_DISPLAY_FLAGS = DisplayManager.VIRTUAL_DISPLAY_FLAG_OWN_CONTENT_ONLY | DisplayManager.VIRTUAL_DISPLAY_FLAG_PUBLIC;
private MediaProjection projection;
private VirtualDisplay vdisplay;
final private HandlerThread handlerThread = new HandlerThread(getClass().getSimpleName(), android.os.Process.THREAD_PRIORITY_BACKGROUND);
private Handler handler;
private WindowManager windowManager;
private MediaProjectionManager mediaProjectionManager;
private int resultCode;
private Intent resultData;
final private ToneGenerator beeper = new ToneGenerator(AudioManager.STREAM_NOTIFICATION, 100);
@Override
public void onCreate() {
super.onCreate();
mediaProjectionManager = (MediaProjectionManager) getSystemService(MEDIA_PROJECTION_SERVICE);
windowManager = (WindowManager)getSystemService(WINDOW_SERVICE);
handlerThread.start();
handler=new Handler(handlerThread.getLooper());
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
if (intent.getAction() == null) {
resultCode = intent.getIntExtra(EXTRA_RESULT_CODE, 1337);
resultData = intent.getParcelableExtra(EXTRA_RESULT_INTENT);
foregroundify();
}
else if (intent.getAction().equals(ACTION_RECORD)) {
if (resultData!=null) {
startCapture();
}
else {
Intent ui=
new Intent(this, Main.class)
.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(ui);
}
}
else if (intent.getAction().equals(ACTION_SHUTDOWN)) {
beeper.startTone(ToneGenerator.TONE_PROP_NACK);
stopForeground(true);
stopSelf();
}
return(START_NOT_STICKY);
}
@Override
public void onDestroy() {
stopCapture();
super.onDestroy();
}
@Nullable
@Override
public IBinder onBind(Intent intent) {
throw new IllegalStateException("Binding not supported. Go away.");
}
WindowManager getWindowManager() {
return(windowManager);
}
Handler getHandler() {
return(handler);
}
void processImage(final byte[] png) {
new Thread() {
@Override
public void run() {File output=new File(getExternalFilesDir(null),
"screenshot.png");
try {
FileOutputStream fos=new FileOutputStream(output);
fos.write(png);
fos.flush();
fos.getFD().sync();
fos.close();
MediaScannerConnection.scanFile(ScreenShotService.this,
new String[] {output.getAbsolutePath()},
new String[] {"image/png"},
null);
}
catch (Exception e) {
Log.e(getClass().getSimpleName(), "Exception writing out screenshot", e);
}
}
}.start();
beeper.startTone(ToneGenerator.TONE_PROP_ACK);
stopCapture();
}
private void stopCapture() {
if (projection!=null) {
projection.stop();
vdisplay.release();
projection=null;
}
}
private void startCapture() {
projection = mediaProjectionManager.getMediaProjection(resultCode, resultData);
ImageTransmogrifier it = new ImageTransmogrifier(this);
MediaProjection.Callback cb = new MediaProjection.Callback() {
@Override
public void onStop() {
vdisplay.release();
}
};
vdisplay=projection.createVirtualDisplay("shooter",
it.getWidth(), it.getHeight(),
getResources().getDisplayMetrics().densityDpi,
VIRT_DISPLAY_FLAGS, it.getSurface(), null, handler);
projection.registerCallback(cb, handler);
}
private void foregroundify() {
NotificationCompat.Builder builder = new NotificationCompat.Builder(this);
builder.setAutoCancel(true)
.setDefaults(Notification.DEFAULT_ALL);
builder.setContentTitle(getString(R.string.app_name))
.setSmallIcon(R.drawable.rec_icon)
.setTicker(getString(R.string.app_name));
builder.addAction(R.drawable.ic_record_white_24dp,
getString(R.string.notify_record),
buildPendingIntent(ACTION_RECORD));
builder.addAction(R.drawable.ic_eject_white_24dp,
getString(R.string.notify_shutdown),
buildPendingIntent(ACTION_SHUTDOWN));
startForeground(NOTIFY_ID, builder.build());
}
private PendingIntent buildPendingIntent(String action) {
Intent i=new Intent(this, getClass());
i.setAction(action);
return(PendingIntent.getService(this, 0, i, 0));
}
}
还有图像变换器类:
public class ImageTransmogrifier implements ImageReader.OnImageAvailableListener {
private final int width;
private final int height;
private final ImageReader imageReader;
private final ScreenShotService svc;
private Bitmap latestBitmap=null;
ImageTransmogrifier(ScreenShotService svc) {
this.svc=svc;
Display display=svc.getWindowManager().getDefaultDisplay();
Point size=new Point();
display.getSize(size);
int width=size.x;
int height=size.y;
while (width*height > (2<<19)) {
width=width>>1;
height=height>>1;
}
this.width=width;
this.height=height;
imageReader=ImageReader.newInstance(width, height,
PixelFormat.RGBA_8888, 2);
imageReader.setOnImageAvailableListener(this, svc.getHandler());
}
@Override
public void onImageAvailable(ImageReader reader) {
final Image image=imageReader.acquireLatestImage();
if (image!=null) {
Image.Plane[] planes=image.getPlanes();
ByteBuffer buffer=planes[0].getBuffer();
int pixelStride=planes[0].getPixelStride();
int rowStride=planes[0].getRowStride();
int rowPadding=rowStride - pixelStride * width;
int bitmapWidth=width + rowPadding / pixelStride;
if (latestBitmap == null ||
latestBitmap.getWidth() != bitmapWidth ||
latestBitmap.getHeight() != height) {
if (latestBitmap != null) {
latestBitmap.recycle();
}
latestBitmap=Bitmap.createBitmap(bitmapWidth,
height, Bitmap.Config.ARGB_8888);
}
latestBitmap.copyPixelsFromBuffer(buffer);
if (image != null) {
image.close();
}
ByteArrayOutputStream baos=new ByteArrayOutputStream();
Bitmap cropped=Bitmap.createBitmap(latestBitmap, 0, 0,
width, height);
cropped.compress(Bitmap.CompressFormat.PNG, 100, baos);
byte[] newPng=baos.toByteArray();
svc.processImage(newPng);
}
}
Surface getSurface() {
return(imageReader.getSurface());
}
int getWidth() {
return(width);
}
int getHeight() {
return(height);
}
void close() {
imageReader.close();
}
}