Есть ли способ вызвать функцию класса из другого класса напрямую, без его экземпляра в Java?

1

У меня есть приложение, которое я делаю с изображением, а затем оно должно отправить данные с изображения на другое действие, используя намерение.

Я пытаюсь вызвать намерение внутри 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();
        }
    };
}
Теги:

2 ответа

1
Лучший ответ

Одним из вариантов было бы создание реализаций 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();
    }
}
  • 0
    Да! Этот второй вариант - то, что я ищу, но я не знаю, как поместить PictureCallback внутри MainActivity? Если бы вы могли показать мне это, это решило бы мою проблему. Я подумал, что есть способ, но я очень новичок в этом программировании, и единственные примеры, которые я видел, работают так, как этот.
  • 1
    @ Metropolis Смотрите обновленный ответ (100% не проверено).
Показать ещё 5 комментариев
0

Единственными методами, которые вы можете вызвать в классе без экземпляра, являются статические методы, но я не знаю, будет ли это делать то, что вы хотите здесь.

  • 0
    Я думал, что статические методы могут быть возможны .... Но я не хочу, чтобы экземпляр был статическим, чтобы он не работал. Как насчет обратного вызова? Могу ли я создать обратный вызов, который срабатывает после завершения этой функции? Или я могу настроить jpegCallback как часть моего класса MainActivity? Я очень новичок в Java / Android, так что извините за вопросы новичка.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню