черный скриншот на андроиде 7.1.1

Я использую следующий код для захвата экрана моего устройства (Android 5.1.1). Но при тестировании этого же кода на смартфоне моего друга (Android 7.1.1) все изображение черное.

Есть некоторые модификации, которые я могу сделать, чтобы решить эту проблему?

Или это случай, который не имеет решения?

Вот код:

===========================================================================

Снимок экрана:

import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.Bitmap.Config;
import android.graphics.PixelFormat;
import android.graphics.Point;
import android.hardware.display.DisplayManager;
import android.hardware.display.VirtualDisplay;
import android.media.Image;
import android.media.Image.Plane;
import android.media.ImageReader;
import android.media.ImageReader.OnImageAvailableListener;
import android.media.projection.MediaProjection;
import android.media.projection.MediaProjection.Callback;
import android.media.projection.MediaProjectionManager;
import android.os.AsyncTask;
import android.support.annotation.NonNull;
import android.support.annotation.UiThread;
import android.util.Log;
import android.view.WindowManager;
import android.widget.Toast;

import java.io.FileOutputStream;

import static android.os.Environment.getExternalStorageDirectory;

public class ScreenShotManager {

    private static final String SCREENCAP_NAME = "screencap";
    private static final int VIRTUAL_DISPLAY_FLAGS = DisplayManager.VIRTUAL_DISPLAY_FLAG_OWN_CONTENT_ONLY | DisplayManager.VIRTUAL_DISPLAY_FLAG_PUBLIC;
    public static final ScreenShotManager INSTANCE = new ScreenShotManager();
    private Intent mIntent;

    private ScreenShotManager() {
    }

    public void requestScreenshotPermission(@NonNull Activity activity, int requestId) {
        MediaProjectionManager mediaProjectionManager = (MediaProjectionManager) activity.getSystemService(Context.MEDIA_PROJECTION_SERVICE);
        activity.startActivityForResult(mediaProjectionManager.createScreenCaptureIntent(), requestId);
    }


    public void onActivityResult(int resultCode, Intent data) {
        if (resultCode == Activity.RESULT_OK && data != null)
            mIntent = data;
        else mIntent = null;
    }

    @UiThread
    public boolean takeScreenshot(@NonNull Context context) {
        if (mIntent == null)
            return false;
        final MediaProjectionManager mediaProjectionManager = (MediaProjectionManager) context.getSystemService(Context.MEDIA_PROJECTION_SERVICE);
        final MediaProjection mediaProjection = mediaProjectionManager.getMediaProjection(Activity.RESULT_OK, mIntent);
        if (mediaProjection == null)
            return false;
        final int density = context.getResources().getDisplayMetrics().densityDpi;
        final Point windowSize = new Point();
        WindowManager windowManager = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
        windowManager.getDefaultDisplay().getRealSize(windowSize);
        final int width = windowSize.x, height = windowSize.y;
        final Context applicationContext = context.getApplicationContext();

        // start capture reader
        final ImageReader imageReader = ImageReader.newInstance(width, height, PixelFormat.RGBA_8888, 1);
        final VirtualDisplay virtualDisplay = mediaProjection.createVirtualDisplay(SCREENCAP_NAME, width, height, density, VIRTUAL_DISPLAY_FLAGS, imageReader.getSurface(), null, null);

        imageReader.setOnImageAvailableListener(new OnImageAvailableListener() {
            @Override
            public void onImageAvailable(final ImageReader reader) {
                Log.d("AppLog", "onImageAvailable");
                mediaProjection.stop();
                new AsyncTask<Void, Void, Bitmap>() {
                    @Override
                    protected Bitmap doInBackground(final Void... params) {
                        Image image = null;
                        Bitmap bitmap = null;
                        try {
                            image = reader.acquireLatestImage();
                            if (image != null) {
                                Plane[] planes = image.getPlanes();
                                ByteBuffer buffer = planes[0].getBuffer();
                                int pixelStride = planes[0].getPixelStride(), rowStride = planes[0].getRowStride(), rowPadding = rowStride - pixelStride * width;
                                bitmap = Bitmap.createBitmap(width + rowPadding / pixelStride, height, Config.ARGB_8888);
                                bitmap.copyPixelsFromBuffer(buffer);

                                FileOutputStream out = null;
                                out = new FileOutputStream(getExternalStorageDirectory() + File.separator + "test.jpeg");
                                bitmap.compress(Bitmap.CompressFormat.JPEG, 100, out);


                                // fix the extra width from Image
                                Bitmap croppedBitmap;
                                croppedBitmap = Bitmap.createBitmap(bitmap, 0, 0, windowSize.x, windowSize.y);
                                if (croppedBitmap != bitmap)
                                    bitmap.recycle();
                                return croppedBitmap;
                            }
                        } catch (Exception e) {
                            if (bitmap != null)
                                bitmap.recycle();
                            e.printStackTrace();
                        }
                        if (image != null)
                            image.close();
                        reader.close();
                        return null;
                    }

                    @Override
                    protected void onPostExecute(final Bitmap bitmap) {
                        super.onPostExecute(bitmap);
                        Log.d("AppLog", "Got bitmap?" + (bitmap != null));
                        Toast.makeText(applicationContext, "Got bitmap?" + (bitmap != null), Toast.LENGTH_SHORT).show();
                    }
                }.execute();
            }
        }, null);

        mediaProjection.registerCallback(new Callback() {
            @Override
            public void onStop() {
                super.onStop();
                if (virtualDisplay != null)
                    virtualDisplay.release();
                imageReader.setOnImageAvailableListener(null, null);
                mediaProjection.unregisterCallback(this);
            }
        }, null);

        return true;
    }
}

Главная

class PermissionUtils {
    public static final int REQUEST_EXTERNAL_STORAGE = 2000;

    public static void requestExternal(Activity context) {
        if (!checkExternal(context)) {
            ActivityCompat.requestPermissions(context, new String[]{
                            Manifest.permission.READ_EXTERNAL_STORAGE,
                            Manifest.permission.WRITE_EXTERNAL_STORAGE},
                    REQUEST_EXTERNAL_STORAGE);
        }
    }

    public static boolean checkExternal(Context context) {
        return !(ActivityCompat.checkSelfPermission(context, Manifest.permission.READ_EXTERNAL_STORAGE)
                != PackageManager.PERMISSION_GRANTED
                && ActivityCompat.checkSelfPermission(context, Manifest.permission.WRITE_EXTERNAL_STORAGE)
                != PackageManager.PERMISSION_GRANTED);
    }

}

private final int REQUEST_CODE_CAPTURE_PERM = 1234;

@Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        PermissionUtils.requestExternal(this);
        ScreenShotManager.INSTANCE.requestScreenshotPermission(MainActivity.this, REQUEST_CODE_CAPTURE_PERM);
    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        if (requestCode == REQUEST_CODE_CAPTURE_PERM) {
            ScreenShotManager.INSTANCE.onActivityResult(resultCode, data);
            ScreenShotManager.INSTANCE.takeScreenshot(MainActivity.this);
        }
    }

person Community    schedule 29.12.2017    source источник


Ответы (1)


Я прочитал ваш вопрос, и мне все кажется правильным. Единственное, о чем вам нужно помнить при переходе между версиями, это то, что код для каждой версии может немного отличаться, поэтому вам может потребоваться проверить, совпадает ли код, который использует версия 5.1.1, с версией кода. 7.1.1 использование. Если это не сработает, пожалуйста, ответьте, и я найду другое решение и сообщу его вам. Удачи!

person Chris Liu    schedule 29.12.2017
comment
вот код, который я тестировал и работает на 7.1.1, но не узнайте, работает ли он также на 5.1 или 6.0. Тем не менее, этот код не соответствует моей потребности, потому что использует Looper (например, falha на стороне сервера, когда мы хотим отправить эти снимки экрана через сокет из-за этого бесконечного цикла, который создает Looper). - person ; 29.12.2017