菜单意图上的相机预览冻结

时间:2015-02-05 04:17:07

标签: java android camera google-glass

我有一个Glass应用程序,我正在尝试使用Live Card从菜单选项启动Camera Preview活动。当我离开Live Card(比如天气)并返回时,应用程序似乎冻结,然后尝试通过菜单选项调出相机。对不起,所有代码都是以下文件:

Service.java

. . .
   @Override
    public IBinder onBind(Intent intent) { return mBinder; }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {

        if (mLiveCard == null) {
            mLiveCard = new LiveCard(this, LIVE_CARD_TAG);

            mRemoteViews = new RemoteViews(getPackageName(), R.layout.service_layout);
            mLiveCard.setViews(mRemoteViews);

            // Display the options menu when the live card is tapped.
            Intent menuIntent = new Intent(this, MenuActivity.class);
            menuIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK |
                    Intent.FLAG_ACTIVITY_CLEAR_TASK);

            mLiveCard.setAction(PendingIntent.getActivity(this, 0, menuIntent, 0));
            mLiveCard.attach(this);
            mLiveCard.publish(PublishMode.REVEAL);

        } else {
            mLiveCard.navigate();
        }
        return START_STICKY;
    }

    @Override
    public void onDestroy() {
        if (mLiveCard != null && mLiveCard.isPublished()) {
            mLiveCard.unpublish();
            mLiveCard = null;
        }
        super.onDestroy();
    }
}

MenuActivity.java

public class MenuActivity extends Activity {

    @Override
    public void onAttachedToWindow() {
        super.onAttachedToWindow();
        // Open the options menu right away.
        openOptionsMenu();
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        getMenuInflater().inflate(R.menu.layout, menu);
        return true;
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {

        switch (item.getItemId()) {
            case R.id.action_stop:
                // Stop the service which will unpublish the live card.
                stopService(new Intent(MenuActivity.this, Service.class));
                return true;

            case R.id.action_camera:
                startActivity(new Intent(MenuActivity.this, Camera.class));
                return true;

            default:
                return super.onOptionsItemSelected(item);
        }
    }

    @Override
    public void onOptionsMenuClosed(Menu menu) { finish(); }
}

Camera.java

public class Camera extends Activity {

    private SurfaceView mPreview = null;
    private SurfaceHolder mPreviewHolder = null;
    private Camera mCamera = null;
    private boolean inPreview = false;
    private boolean cameraConfigured = false;

    @Override
    public void onCreate(Bundle savedInstanceState) {

        super.onCreate(savedInstanceState);
        setContentView(R.layout.camera);


        mPreview = (SurfaceView) findViewById(R.id.camera_preview);
        mPreviewHolder = mPreview.getHolder();
        mPreviewHolder.addCallback(surfaceCallback);
    }


    @Override
    public void onResume() {
        super.onResume();

        mCamera = Camera.open();
        startPreview();
    }

    @Override
    public void onPause() {
        super.onPause();

        if (inPreview) {
            mCamera.stopPreview();
        }

        mCamera.release();
        mCamera = null;
        inPreview = false;
    }

    private Camera.Size getBestPreviewSize(int width, int height,
                                           Camera.Parameters parameters) {
        Camera.Size result = null;

        for (Camera.Size size : parameters.getSupportedPreviewSizes()) {
            if (size.width <= width && size.height <= height) {
                if (result == null) {
                    result = size;
                } else {
                    int resultArea = result.width * result.height;
                    int newArea = size.width * size.height;

                    if (newArea > resultArea) {
                        result = size;
                    }
                }
            }
        }
        return (result);
    }

    private void initPreview(int width, int height) {
        if (mCamera != null && mPreviewHolder.getSurface() != null) {
            try {
                mCamera.setPreviewDisplay(mPreviewHolder);
            } catch (Throwable t) {
                Log.e("PreviewDemo-surfaceCallback",
                        "Exception in setPreviewDisplay()", t);
            }

            if (!cameraConfigured) {
                Camera.Parameters parameters = mCamera.getParameters();
                Camera.Size size = getBestPreviewSize(width, height,
                        parameters);

                if (size != null) {
                    parameters.setPreviewSize(size.width, size.height);
                    mCamera.setParameters(parameters);
                    cameraConfigured = true;
                }
            }
        }
    }

    private void startPreview() {
        if (cameraConfigured && mCamera != null) {
            mCamera.startPreview();
            inPreview = true;
        }
    }

我似乎无法弄清楚为什么相机预览最初会起作用,但在导航时不起作用。我觉得有一些简单的东西,我在这里失踪了。任何帮助将不胜感激!

1 个答案:

答案 0 :(得分:2)

我不确定这是否可以解决您的问题,但我会以这种方式启动和停止相机:

private Camera getCameraInstance() {
    Camera mCamera = null;
    try {
        /* attempt to get a Camera instance */
        mCamera = Camera.open();
    } catch (Exception e) {
        /* Camera is not available (in use or does not exist) */
        Log.e(TAG, "Error getting camera: " + e.getMessage());
        // process null error here
        // finish();
    }

    /* returns null if camera is unavailable */
    return mCamera;
}


@Override
public void onResume() {
    super.onResume();

    if (mCamera == null) {

        mCamera = getCameraInstance();

        if (mCamera != null) {
            startPreview();
        } else {
            // process null error here
        }
    }
}

@Override
public void onPause() {
    super.onPause();

    if (mCamera != null) {
        /* stop preview */
        if (inPreview) {
            try {
                mCamera.stopPreview();
            } catch (Exception e) {
                /* ignore: tried to stop a non-existent preview */
            }
        }

        /* release the camera */
        mCamera.release();
        mCamera = null;
        inPreview = false;
    }
} 

我还会在mCamera中检查getSurfaceinitPreview是否为空。

private void initPreview(int width, int height) {
    if (mCamera != null && mPreviewHolder.getSurface() != null) {
        try {
            mCamera.setPreviewDisplay(mPreviewHolder);
        } catch (Throwable t) {
            Log.e("PreviewDemo-surfaceCallback",
                    "Exception in setPreviewDisplay()", t);
        }

        if (!cameraConfigured) {
            Camera.Parameters parameters = mCamera.getParameters();
            Camera.Size size = getBestPreviewSize(width, height,
                    parameters);

            if (size != null) {
                parameters.setPreviewSize(size.width, size.height);
                mCamera.setParameters(parameters);
                cameraConfigured = true;
            }
        }
    } else {
        Log.e(TAG, "Camera or getSurface is null");
    }
}