Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Custom view has setOnTouchListener called on it but does not override performClick (class extends Activity NOT View)

I have created an Android Activity implementing a bit of OpenCV. What it does is to simply create a Custom Camera View, and when the screen is touched, the photo will be saved.

My only problem is that the code mOpenCvCameraView.setOnTouchListener(MainActivity.this); inside the BaseLoaderCallback contains a warning.

mOpenCvCameraView.setOnTouchListener(MainActivity.this); warns about

Custom view com/example/zcameratestv2/Version2CameraView has setOnTouchListener called on it but does not override performClick

Unlike other questions, my class extends an Activity not View, so when i try to override the function private boolean performClick() { ...super.performClick(); } it is not recognized. Here are my classes

package com.example.zcameratestv2;

import java.text.SimpleDateFormat;
import java.util.Date;

import org.opencv.android.BaseLoaderCallback;
import org.opencv.android.OpenCVLoader;
import org.opencv.android.CameraBridgeViewBase.CvCameraViewListener;
import org.opencv.android.LoaderCallbackInterface;
import org.opencv.core.Mat;

import android.annotation.SuppressLint;
import android.app.Activity;
import android.os.Bundle;
import android.os.Environment;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import android.view.MotionEvent;
import android.view.SurfaceView;
import android.view.View;
import android.view.WindowManager;
import android.view.View.OnTouchListener;
import android.widget.Toast;

public class MainActivity extends Activity implements CvCameraViewListener, OnTouchListener {

private Version2CameraView mOpenCvCameraView;
private static final String TAG = "Version 2::Activity";

private BaseLoaderCallback mLoaderCallback = new BaseLoaderCallback(this) {
    @Override
    public void onManagerConnected(int status) {
        switch (status) {
            case LoaderCallbackInterface.SUCCESS:
            {
                Log.i(TAG, "OpenCV loaded successfully");
                mOpenCvCameraView.enableView();
                mOpenCvCameraView.setOnTouchListener(MainActivity.this);
            } break;
            default:
            {
                super.onManagerConnected(status);
            } break;
        }
    }
};

public MainActivity() {
    Log.i(TAG, "Version 2 Class instantiated");
}

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);

    setContentView(R.layout.activity_main);

    mOpenCvCameraView = (Version2CameraView) findViewById(R.id.java_surface_view);

    mOpenCvCameraView.setVisibility(SurfaceView.VISIBLE);

    mOpenCvCameraView.setCvCameraViewListener(this);

}

public void onPause()
{
    super.onPause();
    if (mOpenCvCameraView != null)
        mOpenCvCameraView.disableView();
}

@Override
public void onResume()
{
    super.onResume();
    OpenCVLoader.initAsync(OpenCVLoader.OPENCV_VERSION_2_4_3, this, mLoaderCallback);
}

public void onDestroy() {
    super.onDestroy();
    if (mOpenCvCameraView != null)
        mOpenCvCameraView.disableView();
}

@Override
public boolean onCreateOptionsMenu(Menu menu) {
    // Inflate the menu; this adds items to the action bar if it is present.
    getMenuInflater().inflate(R.menu.main, menu);
    return true;
}

@Override
public boolean onOptionsItemSelected(MenuItem item) {
    // Handle action bar item clicks here. The action bar will
    // automatically handle clicks on the Home/Up button, so long
    // as you specify a parent activity in AndroidManifest.xml.
    int id = item.getItemId();
    if (id == R.id.action_settings) {
        return true;
    }
    return super.onOptionsItemSelected(item);
}

@Override
public void onCameraViewStarted(int width, int height) {
    // TODO Auto-generated method stub

}

@Override
public void onCameraViewStopped() {
    // TODO Auto-generated method stub

}

@Override
public Mat onCameraFrame(Mat inputFrame) {
    // TODO Auto-generated method stub
    return null;
}

@SuppressLint("SimpleDateFormat")
@Override
public boolean onTouch(View v, MotionEvent event) {
    switch (event.getAction()) {
    case MotionEvent.ACTION_DOWN:
        //some code....
        break;
    case MotionEvent.ACTION_UP:
        Log.i(TAG,"onTouch event");
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd_HH-mm-ss");
        String currentDateandTime = sdf.format(new Date());
        String fileName = Environment.getExternalStorageDirectory().getPath() +
                               "/sample_picture_" + currentDateandTime + ".jpg";
        mOpenCvCameraView.takePicture(fileName);
        Toast.makeText(this, fileName + " saved", Toast.LENGTH_SHORT).show();
        v.performClick();
        break;
    default:
        break;
    }
    return true;
 }


}

Previously the public boolean onTouch(View v, MotionEvent event) event had a similar warning similar to the OnTouchListener, it displays that I should use a performClick(); method but I cant override it since I extend to an Activity not a View. And I have discovered that applying v.PerformClick(); fixes this.

This other class handles the camera processes

package com.example.zcameratestv2;

import java.io.FileOutputStream;

import org.opencv.android.JavaCameraView;

import android.content.Context;
import android.hardware.Camera;
import android.hardware.Camera.PictureCallback;
import android.util.AttributeSet;
import android.util.Log;

public class Version2CameraView extends JavaCameraView implements PictureCallback {

private static final String TAG = "Version2::CameraView";
private String mPictureFileName;

public Version2CameraView(Context context, AttributeSet attrs) {
    super(context, attrs);
}

public void takePicture(final String fileName) {
    Log.i(TAG, "Taking picture");
    this.mPictureFileName = fileName;
    // Postview and jpeg are sent in the same buffers if the queue is not empty when performing a capture.
    // Clear up buffers to avoid mCamera.takePicture to be stuck because of a memory issue
    mCamera.setPreviewCallback(null);

    // PictureCallback is implemented by the current class
    mCamera.takePicture(null, null, this);
}

@Override
public void onPictureTaken(byte[] data, Camera camera) {
    Log.i(TAG, "Saving a bitmap to file");
    // The camera preview was automatically stopped. Start it again.
    mCamera.startPreview();
    mCamera.setPreviewCallback(this);

    // Write the image in a file (in jpeg format)
    try {
        FileOutputStream fos = new FileOutputStream(mPictureFileName);

        fos.write(data);
        fos.close();

    } catch (java.io.IOException e) {
        Log.e("PictureDemo", "Exception in photoCallback", e);
    }

}
}

I have included the required permissions in the Manifest File such as the CAMERA and the WRITE_EXTERNAL_STORAGE

Can someone determine the problem? Need your help. Thanks in advance!

like image 790
Sinned Avatar asked Aug 18 '15 06:08

Sinned


1 Answers

onTouch() method gets every touch event from underlying view that hasn't been marked as "processed". If your Version2CameraView doesn't handle touch events, they are processed in Activity and your Version2CameraView is passed as View v parameter.

Unfortunately, your JavaCameraView doesn't override performClick(), but you're trying call it on this view. Solution? Add this method to your Version2CameraView class:

@Override
public boolean performClick() {
    // do what you want
    return true;
}
like image 57
skywall Avatar answered Oct 05 '22 14:10

skywall