java - 有没有一种方法可以直接从另一个类调用类函数而无需在 Java 中使用它的实例?

标签 java android

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

我试图在 jpegCallback 中调用 Intent ,但问题是我还需要在调用 Intent 之前通过预览类释放相机。但是,我无法从回调内部获取原始预览对象,因此我需要一种从回调内部调用 MainActivity.doPictureResults() 的方法。或者我需要一种方法来让监听器在完成所有图片回调后触发。

这是我的 MainActivity 类,它在 mPreview 变量中包含一个 Preview 类的实例。 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();
        }
    };
}

最佳答案

一个选项是创建一个 PictureCallback 实现来保存 doPictureResults 中需要的信息。不清楚 doPictureResults 是否会在其他任何地方被调用;如果不是,这是干净的并隔离了功能。

另一种方法是让 Activity 本身实现 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();
    }
}

关于java - 有没有一种方法可以直接从另一个类调用类函数而无需在 Java 中使用它的实例?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8459209/

相关文章:

java - 无法在 Resteasy 和 EJB 3.0 中转换为 javax.ws.rs.core.Application

java - 当我将图像通过 HTTP 服务器传输时,为什么该图像无法正确显示?

java - 错误“找不到符号 - 方法 isCompleted()

java - 致命异常 : java. lang.UnsupportedOperationException:无法解析索引 6 处的属性:TypedValue{t=0x2/d=0x101009b a=1}

java - 找不到 com.android.support :cardview-v7:27. 0.2

java - 从docker-compose使用时,flyway不会拾取迁移

Java 'constructor in class cannot be applied to given types' 'required: no arguments found: String'

java - 点击(160.0,120.0)无法完成! (java.lang.SecurityException : Injecting to another application requires INJECT_EVENTS permission)

python - 如何在kivy python中通过滑动来更改屏幕

java - 无法将数据检索到 ListView - android