androidsurfaceviewandroid-hardware

Android CameraControls / Camera Zoom / SurfaceView issues - what's the reason?


I'm still on my way to implement few camera1 features, and now I've faced a ZOOM concerned matter, which is about that, although I've included zoomControls in layout, and created a clickClisteners, no matter this after running program, the zoomControl Button just doesnt response at all. I was trying all the methods shown in related topics here at SO, but none of them didn't work for me.

As it's my first project, could You please correct my code, as to be honest Android Documentation is way to general

Attaching my code above, I'd very thankful for directions

package com.example.arturs.camerahowitworks;

import android.app.Activity;
import android.hardware.Camera;
import android.os.Bundle;
import android.util.Log;
import android.widget.FrameLayout;
import android.widget.ZoomControls;

public class MainActivity extends Activity
{

private Camera mcamera;
private CameraPreview Preview;
private static final String TAG = " => Main Activity: ";
private ZoomControls zoomControls;
//private FrameLayout pCameraLayout = null;


@Override
protected void onCreate(Bundle savedInstanceState)
{
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);  
    //enableZoom();
    FrameLayout preview = (FrameLayout)     findViewById(R.id.camera_preview); 

    mcamera = openFrontCamera(); 

    Preview = new CameraPreview(this, mcamera); 
    preview.addView(Preview);

    //ZoomControls zoomControls = (ZoomControls)  
    findViewById(R.id.zoomControls);

}

@Override 
protected void onResume()
{
super.onResume();
    Log.d(TAG, " -> onResume");
    try
    {

    }
    catch (Exception e)
    {
        e.printStackTrace();
        // finish();
    }
    Log.d(TAG, " -> onResume");
}

@Override
protected void onPause()
{
    Log.d(TAG, " -> onPause");
    mcamera.release();
    mcamera = null;
    super.onPause();
    Log.d(TAG, " <- onPause");

}

@Override
protected void onStop()
{
    Log.d(TAG, " -> onStop");
    finish();
    super.onStop();
    Log.d(TAG, " <- onStop");
}

public Camera openFrontCamera()
{
    int cameraCount = 0; 
    Camera cam; 
    Camera.CameraInfo cameraInfo = new Camera.CameraInfo(); 
    cameraCount = Camera.getNumberOfCameras(); 
    for (int camID = 0; camID < cameraCount; camID++)  
    {
        Camera.getCameraInfo(camID, cameraInfo);
        Log.d(TAG, "CameraInfo" + cameraInfo.facing );
        if(cameraInfo.facing == Camera.CameraInfo.CAMERA_FACING_BACK) 
        {
            try
            {
                //return cam = Camera.open(camID); 
                return Camera.open(camID);
            }
            catch (RuntimeException e)
            {
                Log.e(TAG, "Camera failed to open" + e.getLocalizedMessage());
            }
        }

    }

    return null;
}


}

CameraPreview class

           package com.example.arturs.camerahowitworks;

 import android.content.Context;
 import android.hardware.Camera;
 import android.util.Log;
 import android.view.Display;
 import android.view.Surface;
 import android.view.SurfaceHolder;
 import android.view.SurfaceView;
 import android.view.View;
 import android.view.WindowManager;
 import android.widget.ZoomControls;
 import java.io.IOException;
 import java.util.List;

 public class CameraPreview extends SurfaceView implements  
 SurfaceHolder.Callback
 {
private static final String TAG = " => Main Activity: ";
private SurfaceHolder holder;
private Camera mcamera;
private Context mContext;
int currentZoomLevel = 0;
int maxZoomLevel = 0;
ZoomControls zoomControls;



public CameraPreview(Context context, Camera camera)
{
    super(context); 
    mContext = context;
    this.mcamera = camera;
    holder = getHolder();
    holder.addCallback(this); 
    holder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);

}


@Override
public void surfaceCreated(SurfaceHolder holder)
{
    if(mcamera == null) return; 
    try
    {
        mcamera.setDisplayOrientation(90); 
        mcamera.setPreviewDisplay(holder); 
        mcamera.startPreview(); 
    }
    catch (IOException e)
    {
        Log.d(TAG, "Blad wlaczania podgladu kamery: " + e.getMessage());
    }

}

@Override
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height)
{


    if(holder.getSurface() == null) 
    {
        return;
    }
    try
    {
        mcamera.stopPreview();
    }
    catch (Exception e)
    {

    }
    Camera.Parameters params = mcamera.getParameters(); 
    List<Camera.Size> sizes = params.getSupportedPreviewSizes(); 
    Camera.Size optionalSize = getBestPreviewSize(width, height); 
    params.setPreviewSize(optionalSize.width, optionalSize.height); 

    mcamera.setParameters(params); 

    Display display = ((WindowManager) mContext.getSystemService(Context.WINDOW_SERVICE)).getDefaultDisplay();
    switch (display.getRotation())
    {
        case Surface.ROTATION_0: mcamera.setDisplayOrientation(90); break;
        case Surface.ROTATION_90: mcamera.setDisplayOrientation(0); break;
        case Surface.ROTATION_180: mcamera.setDisplayOrientation(270); break;
        case Surface.ROTATION_270: mcamera.setDisplayOrientation(180); break;
    }

    try
    {
        mcamera.setParameters(params); 
        mcamera.setPreviewDisplay(holder);
        mcamera.startPreview();


    }
    catch (IOException e)
    {
        Log.d(TAG, "Blad wlaczania podgladu kamery" + e.getStackTrace());
    }


    ZoomControls zoomControls = (ZoomControls) findViewById(R.id.zoomControls);

    if (params.isZoomSupported()) {
        maxZoomLevel = params.getMaxZoom();

        try {

            zoomControls.setIsZoomInEnabled(true);
            zoomControls.setIsZoomOutEnabled(true);

            zoomControls.setOnZoomInClickListener(new View.OnClickListener() {
                public void onClick(View v) {
                    if (currentZoomLevel < 500) {
                        currentZoomLevel++;
                        mcamera.startSmoothZoom(currentZoomLevel);
                    }
                }
            });

            zoomControls.setOnZoomOutClickListener(new OnClickListener() {
                public void onClick(View v) {
                    if (currentZoomLevel > 0) {
                        currentZoomLevel--;
                        mcamera.startSmoothZoom(currentZoomLevel);
                    }
                }
            });
        }
        catch (Exception e)
        {
            e.printStackTrace();
        }



    }
    else {
        zoomControls.hide();
    }


@Override
public void surfaceDestroyed(SurfaceHolder holder)
{
    mcamera.release(); 
    mcamera = null; 
}

private Camera.Size getBestPreviewSize(int width, int height) {
    Camera.Size result = null;
    Camera.Parameters p = mcamera.getParameters(); 
    for (Camera.Size size : p.getSupportedPreviewSizes()) { 
        if (size.width <= width && size.height <= height) {
            if (result == null) {
                result = size;
            } else {
                int resultArea = result.width * result.height;
                int newArea = size.width * size.height;

                if (newArea > resultArea) {
                    result = size;
                }
            }
        }
    }
    return result;
 }

 }

main_activity.xml

 <RelativeLayout  
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="horizontal">

<FrameLayout
    android:id="@+id/camera_preview"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:layout_weight="1" >


</FrameLayout>

<ZoomControls
    android:id="@+id/zoomControls"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_alignParentBottom="true"
    android:layout_alignParentRight="true"/>
</RelativeLayout>

android manifest

   <?xml version="1.0" encoding="utf-8"?>
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
 package="com.example.arturs.camerahowitworks">

<uses-feature android:name="android.hardware.Camera"/>
<uses-permission android:name="android.permission.CAMERA"/>

<application
    android:allowBackup="true"
    android:icon="@mipmap/ic_launcher"
    android:label="@string/app_name"
    android:supportsRtl="true"
    android:theme="@style/AppTheme">
    <activity android:name=".MainActivity"
        android:configChanges="orientation|screenSize">

        <intent-filter>
            <action android:name="android.intent.action.MAIN" />

            <category android:name="android.intent.category.LAUNCHER" />
        </intent-filter>
    </activity>
</application>

Added LOGS

 $ adb shell am start -n 
"com.example.arturs.camerahowitworksv2/com.example.arturs.camerahowitwork 
sv2.MainActivity" -a android.intent.action.MAIN -c 
android.intent.category.LAUNCHER -D
Waiting for application to come online:  
com.example.arturs.camerahowitworksv2 |    
com.example.arturs.camerahowitworksv2.test
Waiting for application to come online: 
com.example.arturs.camerahowitworksv2 | 
com.example.arturs.camerahowitworksv2.test
Connecting to com.example.arturs.camerahowitworksv2
E/Trace: error opening trace file: No such file or directory (2)
D/ActivityThread: setTargetHeapUtilization:0.25
D/ActivityThread: setTargetHeapIdealFree:8388608
D/ActivityThread: setTargetHeapConcurrentStart:2097152
W/ActivityThread: Application com.example.arturs.camerahowitworksv2    
is waiting for the debugger on port 8100...
I/System.out: Sending WAIT chunk
I/dalvikvm: Debugger is active
Connected to the target VM, address: 'localhost:8609', transport:    
'socket'
I/System.out: Debugger has connected
I/System.out: waiting for debugger to settle...
I/System.out: waiting for debugger to settle...
I/System.out: waiting for debugger to settle...
I/System.out: waiting for debugger to settle...
I/System.out: waiting for debugger to settle...
I/System.out: waiting for debugger to settle...
I/System.out: waiting for debugger to settle...
I/System.out: debugger has settled (1456)
D/ => Main Activity:: CameraInfo0
D/ => Main Activity::  -> onResume
D/ => Main Activity::  -> onResume
D/libEGL: loaded /system/lib/egl/libEGL_adreno200.so
D/libEGL: loaded /system/lib/egl/libGLESv1_CM_adreno200.so
D/libEGL: loaded /system/lib/egl/libGLESv2_adreno200.so
I/Adreno200-EGL: <qeglDrvAPI_eglInitialize:299>: EGL 1.4 QUALCOMM   
build:  (Merge)
             Build Date: 07/09/13 Tue
             Local Branch: AU_41
             Remote Branch: 
             Local Patches: 
             Reconstruct Branch: 
D/OpenGLRenderer: Enabling debug mode 0
W/System.err: java.lang.NullPointerException
W/System.err:     at     


com.example.arturs.camerahowitworksv2.CameraPreview.surfaceChanged
(Camera . Preview.java:131)
W/System.err:     at   
android.view.SurfaceView.updateWindow(SurfaceView.java:558)
W/System.err:     at   
android.view.SurfaceView.access$000(SurfaceView.java:85)
W/System.err:     at   
android.view.SurfaceView$3.onPreDraw(SurfaceView.java:173)
W/System.err:     at   
 android.view.ViewTreeObserver.dispatchOnPreDraw(ViewTreeObserver.java:671)
W/System.err:     at   
android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:1828)
W/System.err:     at   
android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:1004)
W/System.err:     at   
android.view.ViewRootImpl$TraversalRunnable.run
(ViewRootImpl.java:4223)
W/System.err:     at android.view.Choreographer$CallbackRecord.run
(Choreographer.java:725)
W/System.err:     at android.view.Choreographer.doCallbacks
(Choreographer.java:555)
W/System.err:     at   
android.view.Choreographer.doFrame(Choreographer.java:525)
W/System.err:     at 
android.view.Choreographer$FrameDisplayEventReceiver.run
 (Choreographer.java:711)
 W/System.err:     at  
 android.os.Handler.handleCallback(Handler.java:615)
 W/System.err:     at   
 android.os.Handler.dispatchMessage(Handler.java:92)
 W/System.err:     at android.os.Looper.loop(Looper.java:213)
 W/System.err:     at    
 android.app.ActivityThread.main(ActivityThread.java:4787)
 W/System.err:     at java.lang.reflect.Method.invokeNative(Native   
 Method)
 W/System.err:     at   
 java.lang.reflect.Method.invoke(Method.java:511)
 W/System.err:     at   
 com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run
(ZygoteInit.java:789)
W/System.err:     at com.android.internal.os.ZygoteInit.main
(ZygoteInit.java:556)
W/System.err:     at dalvik.system.NativeStart.main
(Native Method)
I/Choreographer: Skipped 108 frames!  The application may be doing   
too much work on its main thread.
W/Adreno200-ES20: <qgl2DrvAPI_glBufferSubData:778>: GL_INVALID_VALUE
D/OpenGLRenderer: GL error from OpenGLRenderer: 0x501
E/OpenGLRenderer:   GL_INVALID_VALUE

Solution

  • From the documentation:

    https://developer.android.com/reference/android/widget/ZoomControls.html

    The ZoomControls class displays a simple set of controls used for zooming and provides callbacks to register for events.

    You need to set Click Listeners for your zoom controls. Adding it just adds the UI not the functionality.

    For instance: https://developer.android.com/reference/android/widget/ZoomControls.html#setOnZoomInClickListener(android.view.View.OnClickListener)

    ((ZoomControls) findViewById(R.id.zoomControls)).setOnZoomInClickListener( new View.OnClickListener() {
    
       @Override
       public void onClick(View button) {
           // TODO zoom in
       }
    
    });
    

    __

    At the moment you just have this

    //ZoomControls zoomControls = (ZoomControls)  
    findViewById(R.id.zoomControls);
    

    which does nothing