Androidアクティビティを少しOpenCVを実装するアクティビティを作成しました。これは、カスタムカメラビューを作成するだけで、画面に触れると写真が保存されます。
私の唯一の問題は、BaseLoaderCallback内のコードmOpenCvCameraView.setOnTouchListener(MainActivity.this);
に警告が含まれていることです。
mOpenCvCameraView.setOnTouchListener(MainActivity.this);
について警告
カスタムビューcom/example/zcameratestv2/Version2CameraViewでsetOnTouchListenerが呼び出されましたが、performClickをオーバーライドしていません
他の質問とは異なり、私のクラスはビューではなくアクティビティを拡張しているため、関数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;
}
}
_
以前、public boolean onTouch(View v, MotionEvent event)
イベントにはOnTouchListenerと同様の警告がありましたが、performClick()を使用する必要があることを示しています。メソッドですが、Activity
ではなくView
に拡張しているため、オーバーライドできません。そして、v.PerformClick();
を適用することでこれが修正されることを発見しました。
この他のクラスはカメラプロセスを処理します
_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);
}
}
}
_
CAMERAやWRITE_EXTERNAL_STORAGEなどのマニフェストファイルに必要な権限を含めました
誰かが問題を特定できますか?君の力が必要。前もって感謝します!
onTouch()
メソッドは、「処理済み」としてマークされていない、基になるビューからすべてのタッチイベントを取得します。 _Version2CameraView
_がタッチイベントを処理しない場合、それらはアクティビティで処理され、_Version2CameraView
_は_View v
_パラメーターとして渡されます。
残念ながら、あなたのJavaCameraView
はperformClick()
をオーバーライドしませんが、あなたはこのビューでそれを呼び出そうとしています。解決?このメソッドを_Version2CameraView
_クラスに追加します。
_@Override
public boolean performClick() {
// do what you want
return true;
}
_
少し遅れると思いますが、解決策は簡単です。 Button
、TextView
のようなクラスは、View
のサブクラスであり、SurfaceView
および_Version2CameraView
_の親であるJavaCameraView
のサブクラスでもあります。サブクラス。
そして、違いは何ですか?違いは、TextView
が 'ViewTreeObserver.OnPreDrawListener'インターフェイスを実装することです。このため、Button(TextView
のサブクラス)はperformClick()
メソッドをオーバーライドできます。
_Version2CameraView
_クラスを使用してどうすればよいですか?performClick()
メソッドをオーバーライドするインターフェイスを実装するだけです。 「ViewTreeObserver.OnPreDrawListener」はどれですか?いいえ、次のように_SurfaceHolder.Callback
_を使用する必要があります。
_public class Version2CameraView extends JavaCameraView implements PictureCallback, SurfaceHolder.Callback
{
...
/**
* Process the MotionEvent.
*/
@Override
public boolean onTouchEvent(MotionEvent event) {
synchronized (getHolder()) {
// Do something
...
return true;
}
}
@Override
public boolean performClick() {
// Calls the super implementation, which generates an AccessibilityEvent
// and calls the onClick() listener on the view, if any
super.performClick();
// Handle the action for the custom click here
return true;
}
...
}
_
このソリューションでは、警告を削除する必要があります。
ビューがsetOnTouchListener()
を呼び出したため、タッチイベントを処理するメソッドを追加する必要があります。デフォルトメソッドのオーバーライドを追加します。「メソッドはメソッドをオーバーライドしないそのスーパークラスから」、あなたがそこにタッチイベントを処理しないのであれば、あなたはそれを私のサンプルのように残すことができます:
@Override
public boolean performClick() {
super.performClick();
return true;
}