屏幕截图使用媒体投影不执行任何操作

时间:2017-12-14 12:01:43

标签: android screenshot android-mediaprojection foreground-service

大家好,我有一个来自(@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));
}

}

还有imagetransmofrifier类:

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();
}

}

1 个答案:

答案 0 :(得分:0)

只有在按下录制按钮时才会有效。[![按钮] [1]] [1]。然后,您将能够在作者建议的目录中找到