Autore Topic: textureView cambia la dimensione dopo W/SplitWindow: update focus...  (Letto 494 volte)

Offline alpha_php

  • Nuovo arrivato
  • *
  • Post: 12
  • Respect: 0
    • Mostra profilo
  • Dispositivo Android:
    Acer Liquid A1
  • Sistema operativo:
    Windows 7
Sto provando a costruire un'applicazione che usa la fotocamera, attraverso le API camera2. La mia app deve funzionare solo in landscape, quindi ho scritto nel file manifest:

Codice (XML): [Seleziona]
Il mio problema è che quando avvio l'app, la camera occupa solo una parte del display, ma è orientata in modo corretto. Ho visto nel Logcat che la textureView cambia la dimensione dopo un warning SplitWindow, che sinceramente non so cosa sia.

Codice: [Seleziona]
I/InstantRun: starting instant run server: is main process
W/art: Before Android 4.1, method, android.content.res.ColorStateList,$Mode) would have incorrectly overridden the package-private method in
I/PhoneWindow: [generateLayout] setColorNavigationBar => color=0x ff000001
D/PhoneWindowEx: Ex2. SystemProperties.get result >> #ff000000
D/PhoneWindowEx: [PWEx][generateLayout] setNavigationBarColor2 : colors=0xff000000
I/PhoneWindow: [setNavigationBarColor2] color=0x ff000000
E/MyAppMainActivity: onResume
I/Adreno: QUALCOMM build                   : ac1ef73, I86756fd4a8
                                                                    Build Date                       : 10/05/15
                                                                    OpenGL ES Shader Compiler Version: XE031.06.00.00
                                                                    Local Branch                     :
                                                                    Remote Branch                    :
                                                                    Remote Branch                    :
                                                                    Reconstruct Branch               :
I/OpenGLRenderer: Initialized EGL, version 1.4
E/MyAppMainActivity: is camera open
I/MyAppMainActivity: Connecting to camera service
E/MyAppMainActivity: openCamera X
D/MyAppMainActivity: function openCamera(), Width: 2560 Height: 1440
D/MyAppMainActivity: function transformCamera(), Width: 2560 Height: 1440
D/MyAppMainActivity: function transformCamera(), optimal Width:1280 optimal Height:720
D/MyAppMainActivity: function transformCamera(), rotation:1 centerX:1280.0 centerY:720.0
W/SplitWindow: update focus...
I/Choreographer: Skipped 33 frames!  The application may be doing too much work on its main thread.
D/MyAppMainActivity: Event onSurfaceTextureSizeChanged(), width: 810 height: 1440
D/MyAppMainActivity: function transformCamera(), Width: 810 Height: 1440
D/MyAppMainActivity: function transformCamera(), optimal Width:1280 optimal Height:720
D/MyAppMainActivity: function transformCamera(), rotation:1 centerX:405.0 centerY:720.0
V/ViewRootImpl: Contents drawing finished : com.example.myapp/com.example.myapp.MyAppMainActivity
E/MyAppMainActivity: onOpened
I/Timeline: Timeline: Activity_idle id: android.os.BinderProxy@dfe0103 time:137555476

Posto parte del codice dove credo sia il problema.
Codice (Java): [Seleziona]
private static Size chooseOptimalSize(Size[] choices, int textureViewWidth,
                                      int textureViewHeight, int maxWidth, int maxHeight, Size aspectRatio) {
    // Collect the supported resolutions that are at least as big as the preview Surface
    List<Size> bigEnough = new ArrayList<>();
    // Collect the supported resolutions that are smaller than the preview Surface
    List<Size> notBigEnough = new ArrayList<>();
    int w = aspectRatio.getWidth();
    int h = aspectRatio.getHeight();
    for (Size option : choices) {
        if (option.getWidth() <= maxWidth && option.getHeight() <= maxHeight &&
                option.getHeight() == option.getWidth() * h / w) {
            if (option.getWidth() >= textureViewWidth &&
                    option.getHeight() >= textureViewHeight) {
            } else {
// Pick the smallest of those big enough. If there is no one big enough, pick the
    // largest of those not big enough.
    if (bigEnough.size() > 0) {
        return Collections.min(bigEnough, new CompareSizesByArea());
    } else if (notBigEnough.size() > 0) {
        return Collections.max(notBigEnough, new CompareSizesByArea());
    } else {
        Log.e(TAG, "Couldn't find any suitable preview size");
        return choices[0];

Codice (Java): [Seleziona]
private void  transformCamera(int width, int height){
    Log.d(TAG, "function transformCamera(), Width: "+ width+" Height: "+ height);
    if (null == textureView) {

    StreamConfigurationMap map = characteristics.get(CameraCharacteristics.SCALER_STREAM_CONFIGURATION_MAP);
    Display display = ((WindowManager) getSystemService(Context.WINDOW_SERVICE)).getDefaultDisplay();
    Point displaySize = new Point();
    //salvo la rotazione in formato 0,1,2,3
    int devRotation = display.getRotation();

    int totalRotation = absoluteRotation(characteristics, devRotation);

    boolean swappedDimensions = (totalRotation == 90) || (totalRotation == 270);
    int rotatedVW;
    int rotatedVH;
    int maxPreviewW;
    int maxPreviewH;

    if (swappedDimensions) {
        rotatedVW = height;
        rotatedVH = width;
        maxPreviewW = displaySize.y;
        maxPreviewH = displaySize.x;
    else {
        rotatedVW = width;
        rotatedVH = height;
        maxPreviewW = displaySize.x;
        maxPreviewH = displaySize.y;

    // Preview should not be larger than display size and 1080p.
    if (maxPreviewW > MAX_PREVIEW_WIDTH) {
        maxPreviewW = MAX_PREVIEW_WIDTH;

    if (maxPreviewH > MAX_PREVIEW_HEIGHT) {
        maxPreviewH = MAX_PREVIEW_HEIGHT;

    // Find the best preview size for these view dimensions and configured JPEG size.
    assert map != null;
    Size previewSize = chooseOptimalSize(map.getOutputSizes(SurfaceTexture.class),
            rotatedVW, rotatedVH, maxPreviewW, maxPreviewH,

    if (swappedDimensions) {
        textureView.setAspectRatio(previewSize.getHeight(), previewSize.getWidth());
    } else {
        textureView.setAspectRatio(previewSize.getWidth(), previewSize.getHeight());

    Matrix matrix = new Matrix();
    RectF viewRect = new RectF(0, 0, width, height);
    RectF bufferRect = new RectF(0, 0, previewSize.getHeight(), previewSize.getWidth());
    float centerX = viewRect.centerX();
    float centerY = viewRect.centerY();
    Log.d(TAG, "function transformCamera(), optimal Width:"+ previewSize.getWidth() + " optimal Height:"+ previewSize.getHeight());

    if (Surface.ROTATION_90 == devRotation || Surface.ROTATION_270 == devRotation) {
        bufferRect.offset(centerX - bufferRect.centerX(), centerY - bufferRect.centerY());
        matrix.setRectToRect(viewRect, bufferRect, Matrix.ScaleToFit.FILL);
        float scale = Math.max(
                (float) height / previewSize.getHeight(),
                (float) width / previewSize.getWidth());
        matrix.postScale(scale, scale, centerX, centerY);
        matrix.postRotate(90*(devRotation-2), centerX, centerY);
    } else if (Surface.ROTATION_180 == devRotation){
        matrix.postRotate(180, centerX, centerY);
    } else if (Surface.ROTATION_0 == devRotation){
        matrix.postRotate(0, centerX, centerY);

    Log.d(TAG, "function transformCamera(), rotation:"+ devRotation + " centerX:"+ centerX + " centerY:"+ centerY);

Codice (Java): [Seleziona]
private void openCamera(int width, int height) {
    CameraManager manager = (CameraManager) getSystemService(Context.CAMERA_SERVICE);
    Log.e(TAG, "is camera open");
    try {
        cameraId = manager.getCameraIdList()[0];
        characteristics = manager.getCameraCharacteristics(cameraId);
        StreamConfigurationMap map = characteristics.get(CameraCharacteristics.SCALER_STREAM_CONFIGURATION_MAP);
        assert map != null;
        imageDimension = map.getOutputSizes(SurfaceTexture.class)[0];
        // Add permission for camera and let user grant the permission
        if (ActivityCompat.checkSelfPermission(this, Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {
            ActivityCompat.requestPermissions(AydaMainActivity.this, new String[]{Manifest.permission.CAMERA, Manifest.permission.WRITE_EXTERNAL_STORAGE}, REQUEST_CAMERA_PERMISSION);
        manager.openCamera(cameraId, stateCallback, null);
    } catch (CameraAccessException e) {
    Log.e(TAG, "openCamera X");
    Log.d(TAG, "function openCamera(), Width: "+textureView.getWidth()+ " Height: "+textureView.getHeight());

Codice (Java): [Seleziona]
TextureView.SurfaceTextureListener textureListener = new TextureView.SurfaceTextureListener() {
    public void onSurfaceTextureAvailable(SurfaceTexture surface, int width, int height) {
        openCamera(width, height);
        transformCamera(width, height);
    public void onSurfaceTextureSizeChanged(SurfaceTexture surface, int width, int height) {
            Log.d(TAG, "Event onSurfaceTextureSizeChanged(), width: " +width+ " height: "+height);
            transformCamera(width, height);

    public boolean onSurfaceTextureDestroyed(SurfaceTexture surface) {
        return false;
    public void onSurfaceTextureUpdated(SurfaceTexture surface) {