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

The name of the pictureThe name of the pictureThe name of the pictureClash Royale CLAN TAG#URR8PPP


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



mOpenCvCameraView.setOnTouchListener(MainActivity.this); warns about


mOpenCvCameraView.setOnTouchListener(MainActivity.this);



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


private boolean performClick() { ...super.performClick(); }


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.


public boolean onTouch(View v, MotionEvent event)


Activity


View


v.PerformClick();



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!




2 Answers
2



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.


onTouch()


Version2CameraView


Version2CameraView


View v



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


JavaCameraView


performClick()


Version2CameraView


@Override
public boolean performClick() {
// do what you want
return true;
}





When I add performClick function in my Class (as above), it says "Method does not override method from its superclass" (error) and "performClick is never used". My class implements onTouchListener and I have onTouch function with v.perfomrClick(); inside. What did I missed ? Before last Android Studio update, it was working fine...
– Christian
Apr 16 '17 at 7:07







Did you find a solution ?
– Regis_AG
Dec 6 '17 at 15:13



You need to add a method to handle the touch events since your view has called setOnTouchListener(), add an override of the default method, be sure to call de super method inside, you can leave it like my sample if you are not going to process the touch events in there:


@Override
public boolean performClick() {
super.performClick();
return true;
}






By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

Popular posts from this blog

Makefile test if variable is not empty

Will Oldham

Visual Studio Code: How to configure includePath for better IntelliSense results