有没有办法直接从另一个类调用类函数而没有Java中的实例?

时间:2011-12-10 19:25:24

标签: java android

我有一个应用程序,我已拍照,然后它应该使用意图将图片中的数据发送到另一个活动。

我试图在jpegCallback内调用intent,但问题是我还需要在调用intent之前通过预览类释放相机。但是,我无法从回调内部获取原始预览对象,因此我需要一种从回调内部调用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's 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 个答案:

答案 0 :(得分: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();
    }
}

答案 1 :(得分:0)

您可以在没有实例的类上调用的唯一方法是静态方法,但我不知道这是否会在此处执行。