У меня есть приложение, которое я делаю с изображением, а затем оно должно отправить данные с изображения на другое действие, используя намерение.
Я пытаюсь вызвать намерение внутри jpegCallback
, но проблема в том, что мне также нужно освободить камеру через класс предварительного просмотра, прежде чем вызывать намерение. Тем не менее, я не могу добраться до исходного объекта предварительного просмотра изнутри обратного вызова, поэтому мне нужен способ вызвать MainActivity.doPictureResults()
из обратного вызова. Или мне нужен способ прослушивателя, который срабатывает после завершения обратных вызовов изображения.
Вот мой класс MainActivity
который содержит экземпляр класса Preview
в переменной mPreview
. jpegCallback
находится внизу, и я хочу вызвать doPictureResults
изнутри или установить другой обратный вызов после завершения этой функции.
public class MainActivity extends Activity {
private final String TAG = "MainActivity";
private Preview mPreview;
Camera mCamera;
int numberOfCameras;
int cameraCurrentlyLocked;
//The first rear facing camera
int defaultCameraId;
/**
* Constructor
* @param savedInstanceState
*/
@Override
protected void onCreate(Bundle savedInstanceState) {Log.e(TAG, "onCreate");
super.onCreate(savedInstanceState);
//Hide the window title.
requestWindowFeature(Window.FEATURE_NO_TITLE);
getWindow().addFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN);
//Create a RelativeLayout container that will hold a SurfaceView,
//and set it as the content of our activity.
this.mPreview = new Preview(this);
setContentView(this.mPreview);
//Find the total number of cameras available
this.numberOfCameras = Camera.getNumberOfCameras();
//Find the ID of the default camera
CameraInfo cameraInfo = new CameraInfo();
for(int i = 0; i < this.numberOfCameras; i++) {
Camera.getCameraInfo(i, cameraInfo);
if(cameraInfo.facing == CameraInfo.CAMERA_FACING_BACK) {
this.defaultCameraId = i;
}
}
}
@Override
protected void onResume() {Log.e(TAG, "onResume");
super.onResume();
//Open the default i.e. the first rear facing camera.
this.mCamera = Camera.open();
this.cameraCurrentlyLocked = this.defaultCameraId;
this.mPreview.setCamera(mCamera);
}
@Override
protected void onPause() {Log.e(TAG, "onPause");
super.onPause();
//Because the Camera object is a shared resource, it very
//Important to release it when the activity is paused.
this.mPreview.releaseCamera();
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
//Inflate our menu which can gather user input for switching camera
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.camera_menu, menu);
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
//Handle item selection
switch (item.getItemId()) {
case R.id.switchCam:
//Check for availability of multiple cameras
if(this.numberOfCameras == 1) {
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setMessage(this.getString(R.string.camera_alert)).setNeutralButton("Close", null);
AlertDialog alert = builder.create();
alert.show();
return true;
}
//OK, we have multiple cameras.
//Release this camera -> cameraCurrentlyLocked
this.mPreview.releaseCamera();
//Acquire the next camera and request Preview to reconfigure parameters.
this.mCamera = Camera.open((this.cameraCurrentlyLocked + 1) % this.numberOfCameras);
this.cameraCurrentlyLocked = (this.cameraCurrentlyLocked + 1) % this.numberOfCameras;
this.mPreview.switchCamera(mCamera);
//Start the preview
this.mCamera.startPreview();
return true;
case R.id.takePicture:
this.mCamera.takePicture(null, null, jpegCallback);
return true;
default:
return super.onOptionsItemSelected(item);
}
}
public void doPictureResults(byte[] data) {
this.mPreview.releaseCamera();
//Release the camera and send the results of the image to the GetResults view
Intent resultsIntent = new Intent(MainActivity.this, ImageProcessorActivity.class);
resultsIntent.putExtra("image_data", data);
startActivity(resultsIntent);
}
/**
* Handles data for jpeg picture when the picture is taken
*/
PictureCallback jpegCallback = new PictureCallback() {
public void onPictureTaken(byte[] data, Camera mCamera) {Log.e(TAG, "jpegCallback");
String baseExternalDir = Environment.getExternalStorageDirectory().getAbsolutePath();
String fileName = String.format("Assist/%d.jpg", System.currentTimeMillis());
FileOutputStream outStream = null;
try {
//Create the directory if needed
File assistDirectory = new File(baseExternalDir + File.separator + "Assist");
assistDirectory.mkdirs();
// Write to SD Card
outStream = new FileOutputStream(baseExternalDir + File.separator + fileName);
outStream.write(data);
outStream.close();
}
catch (FileNotFoundException e) {
Log.e(TAG, "IOException caused by PictureCallback()", e);
}
catch (IOException e) {
Log.e(TAG, "IOException caused by PictureCallback()", e);
}
//This is the type of thing I WANT to do....but its not possible.
MainActivity.doPictureResults();
}
};
}
Одним из вариантов было бы создание реализаций PictureCallback, которые сохраняли эту информацию в doPictureResults
. Не ясно, будут ли doPictureResults
вызываться где-либо еще; если это не так, это чисто и изолирует функциональность.
Другой задачей было бы, чтобы сама деятельность реализовала PictureCallback
поэтому у вас есть прямой доступ ко всем переменным-членам без какой-либо работы. Это позволяет doPictureResults
из других мест.
public class MainActivity extends Activity implements PictureCallback {
...
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
....
case R.id.takePicture:
this.mCamera.takePicture(null, null, this);
return true;
default:
return super.onOptionsItemSelected(item);
}
}
...
public void onPictureTaken(byte[] data, Camera mCamera) {
Log.d(TAG, "jpegCallback");
String baseExternalDir = Environment.getExternalStorageDirectory().getAbsolutePath();
String fileName = String.format("%d.jpg", System.currentTimeMillis());
...
doPictureResults();
}
}
Единственными методами, которые вы можете вызвать в классе без экземпляра, являются статические методы, но я не знаю, будет ли это делать то, что вы хотите здесь.