【问题标题】:Camera Preview freezing on Menu Intent菜单意图上的相机预览冻结
【发布时间】:2015-02-05 04:17:07
【问题描述】:

我有一个 Glass 应用程序,我在其中尝试使用 Live Card 从菜单选项启动相机预览活动。当我离开 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;
        }
    }

我似乎无法弄清楚为什么相机预览最初可以工作,但在导航离开时却无法工作。我觉得我在这里缺少一些简单的东西。任何帮助将不胜感激!

【问题讨论】:

    标签: java android camera google-glass


    【解决方案1】:

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

    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;
        }
    } 
    

    我还会检查mCameragetSurfaceinitPreview 中是否为空。

    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");
        }
    }
    

    【讨论】:

    • 感谢您的建议。今晚晚些时候我会试一试。希望我会得到一些错误,现在可以指导我们进一步前进。
    • 不幸的是,这并没有解决任何问题。在查看日志后,它似乎通过 onCreate、onResume 和相机中的所有内容运行,但在菜单上冻结并且没有显示活动屏幕。有什么想法吗?
    • 这似乎也与 Surface View 有关。我删除了程序的那部分但仍然有摄像头,并且在尝试打开/关闭时它工作
    • 对不起,我不确定这里还有什么问题。如果您认为问题与 SurfaceView 有关,您可以尝试以不同的方式实例化它(例如 mPreview = new SurfaceView(this);)并将其添加到您的布局中。
    • 事实证明这是 Google Glass GDK 的另一个问题。不过,感谢您的建议! code.google.com/p/google-glass-api/issues/…
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-04-30
    • 2019-04-13
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多