Sebek
Sebek

Reputation: 682

Camera orientation change

I've been working on a barcode scanner app built off of Redlaser's scanner library, and I'm trying to implement a button on the scanner overlay that will toggle the camera's orientation. I've been at this problem for a lot of time and I still can't find any solution. Below is a list of the solutions I tried but haven't managed to get to work. Maybe someone can improve on them or come up with something different.

1.Rotate UI -> keep orientation as it is and just rotate the buttons. Unacceptable: rotation not available for Android 2.3 and the app needs to be compatible with 2.3.

2.Use android:configChanges="keyboardHidden|orientation|screenSize" and setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE); to change orientation. Not Functional: this rotates the view, but the image is distorted and when I move the phone up, the camera goes left.

3.Use camera.setDisplayOrientation(90); with solution 2. Impossible: The camera object is located within the RedLaser library code and I don't have access to it. That is to say that in my ScannerActivity.java I don't have any Camera objects. So I don't know how to make a reference to the one that is being used.

4.Use setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE); Unsure: seems to work but this restarts the activity and I need to keep the data. I am familiar with this article, but I haven't found a good way to use it. I want all the data from the activity to be saved that includes some ArrayList<BarcodeResult>.

Any ideas?

Upvotes: 1

Views: 379

Answers (1)

Sebek
Sebek

Reputation: 682

OK, I got it! My pm had this great idea:

5.In the layout xml copy paste the entire UI and use the original for portrait and the new one for landscape:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent" >

 <LinearLayout
    android:id="@+id/preview_frame_overlay"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:layout_centerInParent="true"
    android:orientation="vertical"
    android:visibility="visible" >

  <!-- here is the rest of the portait layout code -->

 </LinearLayout>

<LinearLayout
    android:id="@+id/preview_frame_overlay2"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:layout_centerInParent="true"
    android:orientation="vertical"
    android:rotation="90"
    android:visibility="gone" >

<!-- here is the  rest of the landscape layout code -->

</LinearLayout>

Of course you should use android:configChanges="keyboardHidden|orientation|screenSize"

And in your scanning activity you should change what buttons are visible and usable depending on orientation:

//in onCreate
if (!ProductionActivity.settingLandscape) // if landscape set to portait
                {

                    portraitView.setVisibility(View.VISIBLE);
                    landscapeView.setVisibility(View.GONE);
                    findViewById(R.id.view_finder).setVisibility(View.VISIBLE);
                    findViewById(R.id.view_finder2).setVisibility(View.GONE);
                    ChangeToLandscape(false);

                } else
                {

                    portraitView.setVisibility(View.GONE);
                    landscapeView.setVisibility(View.VISIBLE);
                    findViewById(R.id.view_finder).setVisibility(View.GONE);
                    findViewById(R.id.view_finder2).setVisibility(View.VISIBLE);
                    ChangeToLandscape(true); 

                    android.view.ViewGroup.LayoutParams params1 = landscapeView.getLayoutParams(); //used to resize screen
                    params1.height = mDisplay.getWidth();
                    landscapeView.setLayoutParams(params1);

                }

And the ChangeToLandscape method where we update the button references and delegates:

    private void ChangeToLandscape(boolean landscape)
        {
            if (landscape)
                {
                    hintTextView = (TextView) findViewById(R.id.hint_text2);
                    foundTextView = (TextView) findViewById(R.id.num_found_text2);
                    tvLastBarcode = (TextView) findViewById(R.id.tv_lastBarcode2);
                    doneButton = (Button) findViewById(R.id.button_done2);
                    bMultiscan = (Button) findViewById(R.id.bMultiscan2);
                    toggleTorchButton = (Button) findViewById(R.id.button_toggle_torch2);
                    toggleLineButton = (Button) findViewById(R.id.button_toggle_line2);
                    bRotate = (Button) findViewById(R.id.bRotate2);
                    viewfinderView = findViewById(R.id.view_finder2);

                } else
                {
                    hintTextView = (TextView) findViewById(R.id.hint_text);
                    foundTextView = (TextView) findViewById(R.id.num_found_text);
                    tvLastBarcode = (TextView) findViewById(R.id.tv_lastBarcode);
                    doneButton = (Button) findViewById(R.id.button_done);
                    bMultiscan = (Button) findViewById(R.id.bMultiscan);
                    toggleTorchButton = (Button) findViewById(R.id.button_toggle_torch);
                    toggleLineButton = (Button) findViewById(R.id.button_toggle_line);
                    bRotate = (Button) findViewById(R.id.bRotate);
                    viewfinderView = findViewById(R.id.view_finder);
                }
    //and then we re-assign the buttons delegates
    doneButton.setOnClickListener(new OnClickListener()
                {
                    public void onClick(View v)
                        {
                            doneScanning();
                        }
                }); //....etc
    }

Using this idea the activity never restarts so my data is preserved and it works great.

Upvotes: 1

Related Questions