如何正确地子类化 SimpleCameraHost 以便在 caac-camera 中使用?

How to correctly subclass SimpleCameraHost for use in caac-camera?

这是我在尝试当前方法时遇到的完整错误。

05-28 09:33:13.022    8163-8163/? E/AndroidRuntime﹕ FATAL EXCEPTION: main
    Process: com.snappiesticker.cwac4, PID: 8163
    java.lang.RuntimeException: Unable to start activity ComponentInfo{com.snappiesticker.cwac4/com.snappiesticker.cwac4.MainActivity}: android.view.InflateException: Binary XML file line #5: Error inflating class com.commonsware.cwac.camera.CameraView
            at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2325)
            at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2387)
            at android.app.ActivityThread.access0(ActivityThread.java:151)
            at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1303)
            at android.os.Handler.dispatchMessage(Handler.java:102)
            at android.os.Looper.loop(Looper.java:135)
            at android.app.ActivityThread.main(ActivityThread.java:5254)
            at java.lang.reflect.Method.invoke(Native Method)
            at java.lang.reflect.Method.invoke(Method.java:372)
            at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:903)
            at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:698)
     Caused by: android.view.InflateException: Binary XML file line #5: Error inflating class com.commonsware.cwac.camera.CameraView
            at android.view.LayoutInflater.createView(LayoutInflater.java:633)
            at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:743)
            at android.view.LayoutInflater.rInflate(LayoutInflater.java:806)
            at android.view.LayoutInflater.inflate(LayoutInflater.java:504)
            at android.view.LayoutInflater.inflate(LayoutInflater.java:414)
            at com.snappiesticker.cwac4.DemoCameraFragment.onCreateView(DemoCameraFragment.java:28)
            at android.app.Fragment.performCreateView(Fragment.java:2053)
            at android.app.FragmentManagerImpl.moveToState(FragmentManager.java:894)
            at android.app.FragmentManagerImpl.moveToState(FragmentManager.java:1067)
            at android.app.BackStackRecord.run(BackStackRecord.java:834)
            at android.app.FragmentManagerImpl.execPendingActions(FragmentManager.java:1452)
            at android.app.Activity.performStart(Activity.java:6005)
            at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2288)
            at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2387)
            at android.app.ActivityThread.access0(ActivityThread.java:151)
            at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1303)
            at android.os.Handler.dispatchMessage(Handler.java:102)
            at android.os.Looper.loop(Looper.java:135)
            at android.app.ActivityThread.main(ActivityThread.java:5254)
            at java.lang.reflect.Method.invoke(Native Method)
            at java.lang.reflect.Method.invoke(Method.java:372)
            at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:903)
            at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:698)
     Caused by: java.lang.reflect.InvocationTargetException
            at java.lang.reflect.Constructor.newInstance(Native Method)
            at java.lang.reflect.Constructor.newInstance(Constructor.java:288)
            at android.view.LayoutInflater.createView(LayoutInflater.java:607)
            at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:743)
            at android.view.LayoutInflater.rInflate(LayoutInflater.java:806)
            at android.view.LayoutInflater.inflate(LayoutInflater.java:504)
            at android.view.LayoutInflater.inflate(LayoutInflater.java:414)
            at com.snappiesticker.cwac4.DemoCameraFragment.onCreateView(DemoCameraFragment.java:28)
            at android.app.Fragment.performCreateView(Fragment.java:2053)
            at android.app.FragmentManagerImpl.moveToState(FragmentManager.java:894)
            at android.app.FragmentManagerImpl.moveToState(FragmentManager.java:1067)
            at android.app.BackStackRecord.run(BackStackRecord.java:834)
            at android.app.FragmentManagerImpl.execPendingActions(FragmentManager.java:1452)
            at android.app.Activity.performStart(Activity.java:6005)
            at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2288)
            at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2387)
            at android.app.ActivityThread.access0(ActivityThread.java:151)
            at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1303)
            at android.os.Handler.dispatchMessage(Handler.java:102)
            at android.os.Looper.loop(Looper.java:135)
            at android.app.ActivityThread.main(ActivityThread.java:5254)
            at java.lang.reflect.Method.invoke(Native Method)
            at java.lang.reflect.Method.invoke(Method.java:372)
            at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:903)
            at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:698)
     Caused by: java.lang.IllegalArgumentException: To use the two- or three-parameter constructors on CameraView, your activity needs to implement the CameraHostProvider interface
            at com.commonsware.cwac.camera.CameraView.<init>(CameraView.java:74)
            at com.commonsware.cwac.camera.CameraView.<init>(CameraView.java:62)
            at java.lang.reflect.Constructor.newInstance(Native Method)
            at java.lang.reflect.Constructor.newInstance(Constructor.java:288)
            at android.view.LayoutInflater.createView(LayoutInflater.java:607)
            at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:743)
            at android.view.LayoutInflater.rInflate(LayoutInflater.java:806)
            at android.view.LayoutInflater.inflate(LayoutInflater.java:504)
            at android.view.LayoutInflater.inflate(LayoutInflater.java:414)
            at com.snappiesticker.cwac4.DemoCameraFragment.onCreateView(DemoCameraFragment.java:28)
            at android.app.Fragment.performCreateView(Fragment.java:2053)
            at android.app.FragmentManagerImpl.moveToState(FragmentManager.java:894)
            at android.app.FragmentManagerImpl.moveToState(FragmentManager.java:1067)
            at android.app.BackStackRecord.run(BackStackRecord.java:834)
            at android.app.FragmentManagerImpl.execPendingActions(FragmentManager.java:1452)
            at android.app.Activity.performStart(Activity.java:6005)
            at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2288)
            at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2387)
            at android.app.ActivityThread.access0(ActivityThread.java:151)
            at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1303)
            at android.os.Handler.dispatchMessage(Handler.java:102)
            at android.os.Looper.loop(Looper.java:135)
            at android.app.ActivityThread.main(ActivityThread.java:5254)
            at java.lang.reflect.Method.invoke(Native Method)
            at java.lang.reflect.Method.invoke(Method.java:372)
            at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:903)
            at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:698)

我认为这是因为我在此处的片段中使用了错误的上下文:

public class DemoCameraFragment extends CameraFragment implements View.OnClickListener {
    //private CapturedImage next = null;

    @Override
    public View onCreateView(LayoutInflater inflater,
                             ViewGroup container,
                             Bundle savedInstanceState) {
        View content=inflater.inflate(R.layout.camera, container, false);
        CameraView cameraView=(CameraView)content.findViewById(R.id.camera);

        setCameraView(cameraView);

        return(content);
    }
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setHost(new DemoCameraHost(getActivity()));
    }

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

        getView().setOnClickListener(this);
    }
    @Override

    public void onClick(View v) {
        takePicture();
        Toast.makeText(getActivity(), "picture taken!",
                Toast.LENGTH_LONG).show();
    }
    public class DemoCameraHost extends SimpleCameraHost {
        public DemoCameraHost(Context _ctxt) {
            super(_ctxt);
        }

        @Override
        public boolean useFrontFacingCamera() {
            return true;
        }
/*
        @Override
        public void onCameraFail(CameraHost.FailureReason reason) {
            super.onCameraFail(reason);

            Toast.makeText(getActivity(),
                    "Sorry, but you cannot use the camera now!",
                    Toast.LENGTH_LONG).show();
        }

        @Override
        public void saveImage(PictureTransaction xact, Bitmap bitmap) {
            super.saveImage(xact, bitmap);

            next = new CapturedImage();
            getFragmentManager().beginTransaction()
                    .replace(R.id.fragment_container, next).addToBackStack(null).commit();
        }*/
    }
}

我认为需要改进的行是 setHost(new DemoCameraHost(getActivity())); 我使用 getActivity 假设相机片段的上下文等同于它所在的主要 activity 的上下文,但我不确定

我想做的就是将 SimpleCameraHost 子类化,这样我就可以覆盖方法而不是使用默认方法。

但是,它还提到了主要 activity 上的二进制 xml 问题,所以问题可能出在这里

这里是MainActivity.java:

public class MainActivity extends Activity {
    private DemoCameraFragment current = null;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        setContentView(R.layout.activity_main);

        current = new DemoCameraFragment();

        getFragmentManager().beginTransaction()
                .replace(R.id.fragment_container, current).commit();
    }
}

连同activity_main.xml

<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/fragment_container"
    android:layout_width="match_parent"
    android:layout_height="match_parent" />

引用异常:

Caused by: java.lang.IllegalArgumentException: To use the two- or three-parameter constructors on CameraView, your activity needs to implement the CameraHostProvider interface

您的 activity 没有实现 CameraHostProvider 接口。请参阅 the documentation 中的 "Using CameraView in a Layout Resource"(我很想直接 link 到该部分,但是 GitHub 和我的浏览器目前不兼容...)。