У меня есть пользовательская активность камеры OpenCV, которая снимает фотографию при нажатии экрана. Активность начинается с намерения startActivityForResult
, и путь к файлу возвращается в MainActivity после завершения операции. Однако камера сохраняет фото асинхронно, и поэтому путь к файлу не должен проверяться до тех пор, пока не будет сделана фотография. Я использую путь к файлу для установки imageView
, и его вызов сразу дает пустое изображение. Мне удалось заставить его работать, используя Thread.sleep(3000);
, но это ужасный вариант, поскольку он просто закрывает пользовательский интерфейс, который, как я читал бесчисленное количество раз, является большим, нет, нет! Есть ли способ, который я могу подождать, пока фотография не будет сохранена, прежде чем вызвать возврат к MainActivity
намерениям? Я понимаю, что есть обратный вызов с камеры, но я не понимаю, как это работает или как его использовать, возможно, это лучший способ пойти?Ожидание камеры для сохранения фотографии, что лучше, чем thread.sleep?
Вот какой-то код.
в MainActivity extends FragmentActivity
:
rootView.findViewById(R.id.button_start_camera).setOnClickListener(new View.OnClickListener() {
// Listen for Take Photo button Click, start app's openCV camera
@Override
public void onClick(View view) {
// Start Camera app
Intent intentCamera = new Intent(getActivity(), CameraActivity.class);
startActivityForResult(intentCamera, 2);
}
});
В CameraActivity extends Activity implements CvCameraViewListener2, OnTouchListener
:
@Override
public boolean onTouch(View v, MotionEvent event) {
Log.i(TAG,"onTouch event");
if (takePicture) {
SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd-HHmmss");
String currentDateandTime = sdf.format(new Date());
fileName = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES).getPath() +
"/MatCom_" + currentDateandTime + ".jpg";
mOpenCvCameraView.takePicture(fileName);
Toast.makeText(this, fileName + " saved", Toast.LENGTH_SHORT).show();
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
Intent returnIntent = new Intent();
returnIntent.putExtra("result", fileName);
setResult(RESULT_OK, returnIntent);
finish();
}
return false;
}
А потом обратно MainActivity
:
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent intent)
{
super.onActivityResult(requestCode, resultCode, intent);
Log.i(TAG, "onActivityResult. resultCode = " + requestCode);
if (requestCode == 1) {//My other startActivityForResult...}
if (requestCode == 131074 && resultCode == RESULT_OK){
Bundle bundle = intent.getExtras();
filepath = bundle.getString("result");
Log.i(TAG, filepath);
imageView = (ImageView) findViewById(R.id.imageView);
bmp = BitmapFactory.decodeFile(filepath);
imageView.setBackgroundResource(0);
imageView.setImageBitmap(bmp);
}
}
УВЕДОМЛЕНИЕ: Как и в сторону, по какой-то причине мой requestCode
возвращается как 131074 каждый раз, несмотря на установку его на 2 для startActivityForResult
- сообщите мне, знаете ли вы, почему это так.
Наконец, в случае, если это необходимо, чтобы видеть, вот takePicture
метод из класса CameraView
:
public void takePicture(final String fileName) {
Log.i(TAG, "Taking picture");
PictureCallback callback = new PictureCallback() {
private String mPictureFileName = fileName;
@Override
public void onPictureTaken(byte[] data, Camera camera) {
Log.i(TAG, "Saving a bitmap to file");
Bitmap picture = BitmapFactory.decodeByteArray(data, 0, data.length);
try {
FileOutputStream out = new FileOutputStream(mPictureFileName);
picture.compress(Bitmap.CompressFormat.JPEG, 90, out);
picture.recycle();
// Open the image for analysis
// Read in the image from the file
Mat mOriginalImage = Highgui.imread(fileName);
// Only process the image if it actually exists!
if (mOriginalImage != null) {
// Find the size of the image
org.opencv.core.Size mSizeReadImage = mOriginalImage.size();
// From the number of rows and columns get the coordinates of the largest possible centralised square
double height = mSizeReadImage.height;
double width = mSizeReadImage.width;
double minDim = Math.min(height, width);
double top = height/2.0 - 2.0*minDim/5.0;
double left = width/2.0 - 2.0*minDim/5.0;
// Create a submat of the image based on the centralised square
Mat mOriginalImageSubmat = mOriginalImage.submat((int)Math.round(top), (int)Math.round(top + 4.0*minDim/5.0), (int)Math.round(left), (int)Math.round(left + 4.0*minDim/5.0));
// Create another Mat the required size but same type as mOriginalImageSubmat and resize mOriginalImageSubmat to fit into it
Mat mDrawableSubmat = new Mat(new Size(480.0, 480.0), mOriginalImageSubmat.type());
Imgproc.resize(mOriginalImageSubmat, mDrawableSubmat, mDrawableSubmat.size());
Mat mColourSourceSubmat = mDrawableSubmat.clone();
Mat mCannyOutput = mDrawableSubmat.clone();
double minLineLength = 300.0;
ColourMatrix matrix = new ColourMatrix();
matrix.setColourMatch(colourMatch);
matrix.setColourOrder(colourOrder);
matrix.setComparison(comparison);
matrix.setDisplayHotspots(displayHotspots);
matrix.setDisplayOutline(displayOutline);
matrix.setIntensity(intensity);
matrix.setMatrixType(matrixType);
String output = matrix.decode(mColourSourceSubmat, mCannyOutput, mDrawableSubmat, minLineLength);
Log.i(TAG, "DJH - decoded: " + output);
}
mCamera.startPreview();
} catch (Exception e) {
e.printStackTrace();
}
}
};
mCamera.takePicture(null, null, callback);
}
Вы уже выяснили, почему resultCode всегда 131074? У меня такой же resultCode и интересно, почему это происходит. Фактически resultCode является (131073 + originalResultCode). Поэтому, если я установил свой resultCode на 3 вместо 2, тогда Android даст мне 131075 ... Не могли бы вы проверить, является ли это зависимым от устройства значением? – muetzenflo
Привет, просто нашел решение здесь: http://stackoverflow.com/questions/13659796/why-am-i-getting-wrong-requestcode Звонок getActivity(). StartActvitiyForResult() вместо startActivityForResult() – muetzenflo