TestingCamera.java revision abe36163445fb3fe458252fd8d21c3e1ac14ed6d
148f2556e12eeaa8932947fe6c8083e64bb5eb804Eino-Ville Talvala/* 248f2556e12eeaa8932947fe6c8083e64bb5eb804Eino-Ville Talvala * Copyright (C) 2012 The Android Open Source Project 348f2556e12eeaa8932947fe6c8083e64bb5eb804Eino-Ville Talvala * 448f2556e12eeaa8932947fe6c8083e64bb5eb804Eino-Ville Talvala * Licensed under the Apache License, Version 2.0 (the "License"); 548f2556e12eeaa8932947fe6c8083e64bb5eb804Eino-Ville Talvala * you may not use this file except in compliance with the License. 648f2556e12eeaa8932947fe6c8083e64bb5eb804Eino-Ville Talvala * You may obtain a copy of the License at 748f2556e12eeaa8932947fe6c8083e64bb5eb804Eino-Ville Talvala * 848f2556e12eeaa8932947fe6c8083e64bb5eb804Eino-Ville Talvala * http://www.apache.org/licenses/LICENSE-2.0 948f2556e12eeaa8932947fe6c8083e64bb5eb804Eino-Ville Talvala * 1048f2556e12eeaa8932947fe6c8083e64bb5eb804Eino-Ville Talvala * Unless required by applicable law or agreed to in writing, software 1148f2556e12eeaa8932947fe6c8083e64bb5eb804Eino-Ville Talvala * distributed under the License is distributed on an "AS IS" BASIS, 1248f2556e12eeaa8932947fe6c8083e64bb5eb804Eino-Ville Talvala * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1348f2556e12eeaa8932947fe6c8083e64bb5eb804Eino-Ville Talvala * See the License for the specific language governing permissions and 1448f2556e12eeaa8932947fe6c8083e64bb5eb804Eino-Ville Talvala * limitations under the License. 1548f2556e12eeaa8932947fe6c8083e64bb5eb804Eino-Ville Talvala */ 1648f2556e12eeaa8932947fe6c8083e64bb5eb804Eino-Ville Talvala 1748f2556e12eeaa8932947fe6c8083e64bb5eb804Eino-Ville Talvalapackage com.android.testingcamera; 1848f2556e12eeaa8932947fe6c8083e64bb5eb804Eino-Ville Talvala 1948f2556e12eeaa8932947fe6c8083e64bb5eb804Eino-Ville Talvalaimport android.app.Activity; 2048f2556e12eeaa8932947fe6c8083e64bb5eb804Eino-Ville Talvalaimport android.app.Dialog; 21bc88c6ed6508927ad72eefba3f6f63c6436f06d3Eino-Ville Talvalaimport android.app.FragmentManager; 2248f2556e12eeaa8932947fe6c8083e64bb5eb804Eino-Ville Talvalaimport android.graphics.Bitmap; 2348f2556e12eeaa8932947fe6c8083e64bb5eb804Eino-Ville Talvalaimport android.graphics.BitmapFactory; 2448f2556e12eeaa8932947fe6c8083e64bb5eb804Eino-Ville Talvalaimport android.hardware.Camera; 25abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvalaimport android.hardware.Camera.Parameters; 26bc88c6ed6508927ad72eefba3f6f63c6436f06d3Eino-Ville Talvalaimport android.media.CamcorderProfile; 27abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvalaimport android.media.MediaRecorder; 2848f2556e12eeaa8932947fe6c8083e64bb5eb804Eino-Ville Talvalaimport android.os.Bundle; 29abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvalaimport android.os.Environment; 3048f2556e12eeaa8932947fe6c8083e64bb5eb804Eino-Ville Talvalaimport android.view.View; 3148f2556e12eeaa8932947fe6c8083e64bb5eb804Eino-Ville Talvalaimport android.view.SurfaceHolder; 3248f2556e12eeaa8932947fe6c8083e64bb5eb804Eino-Ville Talvalaimport android.view.SurfaceView; 33bc88c6ed6508927ad72eefba3f6f63c6436f06d3Eino-Ville Talvalaimport android.view.View.OnClickListener; 3448f2556e12eeaa8932947fe6c8083e64bb5eb804Eino-Ville Talvalaimport android.widget.AdapterView; 35abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvalaimport android.widget.AdapterView.OnItemSelectedListener; 3648f2556e12eeaa8932947fe6c8083e64bb5eb804Eino-Ville Talvalaimport android.widget.ArrayAdapter; 3748f2556e12eeaa8932947fe6c8083e64bb5eb804Eino-Ville Talvalaimport android.widget.Button; 3848f2556e12eeaa8932947fe6c8083e64bb5eb804Eino-Ville Talvalaimport android.widget.ImageView; 3948f2556e12eeaa8932947fe6c8083e64bb5eb804Eino-Ville Talvalaimport android.widget.LinearLayout.LayoutParams; 4048f2556e12eeaa8932947fe6c8083e64bb5eb804Eino-Ville Talvalaimport android.widget.Spinner; 4148f2556e12eeaa8932947fe6c8083e64bb5eb804Eino-Ville Talvalaimport android.widget.CompoundButton; 4248f2556e12eeaa8932947fe6c8083e64bb5eb804Eino-Ville Talvalaimport android.widget.TextView; 4348f2556e12eeaa8932947fe6c8083e64bb5eb804Eino-Ville Talvalaimport android.widget.ToggleButton; 44abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvalaimport android.text.Layout; 45abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvalaimport android.text.method.ScrollingMovementMethod; 4648f2556e12eeaa8932947fe6c8083e64bb5eb804Eino-Ville Talvalaimport android.util.Log; 4748f2556e12eeaa8932947fe6c8083e64bb5eb804Eino-Ville Talvala 48abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvalaimport java.io.File; 49abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvalaimport java.io.FileDescriptor; 5048f2556e12eeaa8932947fe6c8083e64bb5eb804Eino-Ville Talvalaimport java.io.IOException; 51abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvalaimport java.io.PrintWriter; 52abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvalaimport java.io.StringWriter; 53abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvalaimport java.text.FieldPosition; 54abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvalaimport java.text.SimpleDateFormat; 5548f2556e12eeaa8932947fe6c8083e64bb5eb804Eino-Ville Talvalaimport java.util.ArrayList; 5648f2556e12eeaa8932947fe6c8083e64bb5eb804Eino-Ville Talvalaimport java.util.Comparator; 57abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvalaimport java.util.Date; 58abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvalaimport java.util.HashSet; 5948f2556e12eeaa8932947fe6c8083e64bb5eb804Eino-Ville Talvalaimport java.util.List; 60abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvalaimport java.util.Set; 6148f2556e12eeaa8932947fe6c8083e64bb5eb804Eino-Ville Talvalaimport java.util.TreeSet; 6248f2556e12eeaa8932947fe6c8083e64bb5eb804Eino-Ville Talvala 6348f2556e12eeaa8932947fe6c8083e64bb5eb804Eino-Ville Talvala/** 6448f2556e12eeaa8932947fe6c8083e64bb5eb804Eino-Ville Talvala * A simple test application for the camera API. 6594d24977868e0713cf03f7cec4d6de051f411dcaEino-Ville Talvala * 6694d24977868e0713cf03f7cec4d6de051f411dcaEino-Ville Talvala * The goal of this application is to allow all camera API features to be 67abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala * exercised, and all information provided by the API to be shown. 6848f2556e12eeaa8932947fe6c8083e64bb5eb804Eino-Ville Talvala */ 69b28605e5d09a08c915183772819cb1c7c53cdb34Eino-Ville Talvalapublic class TestingCamera extends Activity implements SurfaceHolder.Callback { 7048f2556e12eeaa8932947fe6c8083e64bb5eb804Eino-Ville Talvala 7148f2556e12eeaa8932947fe6c8083e64bb5eb804Eino-Ville Talvala /** UI elements */ 7248f2556e12eeaa8932947fe6c8083e64bb5eb804Eino-Ville Talvala private SurfaceView mPreviewView; 7348f2556e12eeaa8932947fe6c8083e64bb5eb804Eino-Ville Talvala private SurfaceHolder mPreviewHolder; 7448f2556e12eeaa8932947fe6c8083e64bb5eb804Eino-Ville Talvala 7548f2556e12eeaa8932947fe6c8083e64bb5eb804Eino-Ville Talvala private Spinner mCameraSpinner; 76bc88c6ed6508927ad72eefba3f6f63c6436f06d3Eino-Ville Talvala private Button mInfoButton; 7748f2556e12eeaa8932947fe6c8083e64bb5eb804Eino-Ville Talvala private Spinner mPreviewSizeSpinner; 7848f2556e12eeaa8932947fe6c8083e64bb5eb804Eino-Ville Talvala private ToggleButton mPreviewToggle; 79abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala private Spinner mAutofocusModeSpinner; 80abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala private Button mAutofocusButton; 81abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala private Button mCancelAutofocusButton; 82bc88c6ed6508927ad72eefba3f6f63c6436f06d3Eino-Ville Talvala private Spinner mSnapshotSizeSpinner; 8348f2556e12eeaa8932947fe6c8083e64bb5eb804Eino-Ville Talvala private Button mTakePictureButton; 84bc88c6ed6508927ad72eefba3f6f63c6436f06d3Eino-Ville Talvala private Spinner mCamcorderProfileSpinner; 85bc88c6ed6508927ad72eefba3f6f63c6436f06d3Eino-Ville Talvala private ToggleButton mRecordToggle; 8648f2556e12eeaa8932947fe6c8083e64bb5eb804Eino-Ville Talvala 87abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala private TextView mLogView; 88abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala 89abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala private Set<View> mPreviewOnlyControls = new HashSet<View>(); 90abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala 9148f2556e12eeaa8932947fe6c8083e64bb5eb804Eino-Ville Talvala /** Camera state */ 9248f2556e12eeaa8932947fe6c8083e64bb5eb804Eino-Ville Talvala private int mCameraId = 0; 9348f2556e12eeaa8932947fe6c8083e64bb5eb804Eino-Ville Talvala private Camera mCamera; 9448f2556e12eeaa8932947fe6c8083e64bb5eb804Eino-Ville Talvala private Camera.Parameters mParams; 9548f2556e12eeaa8932947fe6c8083e64bb5eb804Eino-Ville Talvala private List<Camera.Size> mPreviewSizes; 9648f2556e12eeaa8932947fe6c8083e64bb5eb804Eino-Ville Talvala private int mPreviewSize = 0; 97abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala private List<String> mAfModes; 98abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala private int mAfMode = 0; 99bc88c6ed6508927ad72eefba3f6f63c6436f06d3Eino-Ville Talvala private List<Camera.Size> mSnapshotSizes; 100bc88c6ed6508927ad72eefba3f6f63c6436f06d3Eino-Ville Talvala private int mSnapshotSize = 0; 101bc88c6ed6508927ad72eefba3f6f63c6436f06d3Eino-Ville Talvala private List<CamcorderProfile> mCamcorderProfiles; 102bc88c6ed6508927ad72eefba3f6f63c6436f06d3Eino-Ville Talvala private int mCamcorderProfile = 0; 10348f2556e12eeaa8932947fe6c8083e64bb5eb804Eino-Ville Talvala 104abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala private MediaRecorder mRecorder; 105abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala 10648f2556e12eeaa8932947fe6c8083e64bb5eb804Eino-Ville Talvala private static final int CAMERA_UNINITIALIZED = 0; 10748f2556e12eeaa8932947fe6c8083e64bb5eb804Eino-Ville Talvala private static final int CAMERA_OPEN = 1; 10848f2556e12eeaa8932947fe6c8083e64bb5eb804Eino-Ville Talvala private static final int CAMERA_PREVIEW = 2; 10948f2556e12eeaa8932947fe6c8083e64bb5eb804Eino-Ville Talvala private static final int CAMERA_TAKE_PICTURE = 3; 110abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala private static final int CAMERA_RECORD = 4; 11148f2556e12eeaa8932947fe6c8083e64bb5eb804Eino-Ville Talvala private int mState = CAMERA_UNINITIALIZED; 11248f2556e12eeaa8932947fe6c8083e64bb5eb804Eino-Ville Talvala 11348f2556e12eeaa8932947fe6c8083e64bb5eb804Eino-Ville Talvala /** Misc variables */ 11448f2556e12eeaa8932947fe6c8083e64bb5eb804Eino-Ville Talvala 11548f2556e12eeaa8932947fe6c8083e64bb5eb804Eino-Ville Talvala private static final String TAG = "TestingCamera"; 11648f2556e12eeaa8932947fe6c8083e64bb5eb804Eino-Ville Talvala 117abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala /** Activity lifecycle */ 118abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala 11948f2556e12eeaa8932947fe6c8083e64bb5eb804Eino-Ville Talvala @Override 12048f2556e12eeaa8932947fe6c8083e64bb5eb804Eino-Ville Talvala public void onCreate(Bundle savedInstanceState) { 12148f2556e12eeaa8932947fe6c8083e64bb5eb804Eino-Ville Talvala super.onCreate(savedInstanceState); 12248f2556e12eeaa8932947fe6c8083e64bb5eb804Eino-Ville Talvala 12348f2556e12eeaa8932947fe6c8083e64bb5eb804Eino-Ville Talvala setContentView(R.layout.main); 12448f2556e12eeaa8932947fe6c8083e64bb5eb804Eino-Ville Talvala 12548f2556e12eeaa8932947fe6c8083e64bb5eb804Eino-Ville Talvala mPreviewView = (SurfaceView)findViewById(R.id.preview); 12648f2556e12eeaa8932947fe6c8083e64bb5eb804Eino-Ville Talvala mPreviewView.getHolder().addCallback(this); 12748f2556e12eeaa8932947fe6c8083e64bb5eb804Eino-Ville Talvala 12848f2556e12eeaa8932947fe6c8083e64bb5eb804Eino-Ville Talvala mCameraSpinner = (Spinner) findViewById(R.id.camera_spinner); 12948f2556e12eeaa8932947fe6c8083e64bb5eb804Eino-Ville Talvala mCameraSpinner.setOnItemSelectedListener(mCameraSpinnerListener); 13048f2556e12eeaa8932947fe6c8083e64bb5eb804Eino-Ville Talvala 131bc88c6ed6508927ad72eefba3f6f63c6436f06d3Eino-Ville Talvala mInfoButton = (Button) findViewById(R.id.info_button); 132bc88c6ed6508927ad72eefba3f6f63c6436f06d3Eino-Ville Talvala mInfoButton.setOnClickListener(mInfoButtonListener); 133bc88c6ed6508927ad72eefba3f6f63c6436f06d3Eino-Ville Talvala 13448f2556e12eeaa8932947fe6c8083e64bb5eb804Eino-Ville Talvala mPreviewSizeSpinner = (Spinner) findViewById(R.id.preview_size_spinner); 13548f2556e12eeaa8932947fe6c8083e64bb5eb804Eino-Ville Talvala mPreviewSizeSpinner.setOnItemSelectedListener(mPreviewSizeListener); 13648f2556e12eeaa8932947fe6c8083e64bb5eb804Eino-Ville Talvala 13748f2556e12eeaa8932947fe6c8083e64bb5eb804Eino-Ville Talvala mPreviewToggle = (ToggleButton) findViewById(R.id.start_preview); 13848f2556e12eeaa8932947fe6c8083e64bb5eb804Eino-Ville Talvala mPreviewToggle.setOnClickListener(mPreviewToggleListener); 13948f2556e12eeaa8932947fe6c8083e64bb5eb804Eino-Ville Talvala 140abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala mAutofocusModeSpinner = (Spinner) findViewById(R.id.af_mode_spinner); 141abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala mAutofocusModeSpinner.setOnItemSelectedListener(mAutofocusModeListener); 142abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala 143abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala mAutofocusButton = (Button) findViewById(R.id.af_button); 144abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala mAutofocusButton.setOnClickListener(mAutofocusButtonListener); 145abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala mPreviewOnlyControls.add(mAutofocusButton); 146abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala 147abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala mCancelAutofocusButton = (Button) findViewById(R.id.af_cancel_button); 148abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala mCancelAutofocusButton.setOnClickListener(mCancelAutofocusButtonListener); 149abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala mPreviewOnlyControls.add(mCancelAutofocusButton); 150abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala 151bc88c6ed6508927ad72eefba3f6f63c6436f06d3Eino-Ville Talvala mSnapshotSizeSpinner = (Spinner) findViewById(R.id.snapshot_size_spinner); 152bc88c6ed6508927ad72eefba3f6f63c6436f06d3Eino-Ville Talvala mSnapshotSizeSpinner.setOnItemSelectedListener(mSnapshotSizeListener); 153bc88c6ed6508927ad72eefba3f6f63c6436f06d3Eino-Ville Talvala 15448f2556e12eeaa8932947fe6c8083e64bb5eb804Eino-Ville Talvala mTakePictureButton = (Button) findViewById(R.id.take_picture); 15548f2556e12eeaa8932947fe6c8083e64bb5eb804Eino-Ville Talvala mTakePictureButton.setOnClickListener(mTakePictureListener); 156abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala mPreviewOnlyControls.add(mTakePictureButton); 15748f2556e12eeaa8932947fe6c8083e64bb5eb804Eino-Ville Talvala 158bc88c6ed6508927ad72eefba3f6f63c6436f06d3Eino-Ville Talvala mCamcorderProfileSpinner = (Spinner) findViewById(R.id.camcorder_profile_spinner); 159bc88c6ed6508927ad72eefba3f6f63c6436f06d3Eino-Ville Talvala mCamcorderProfileSpinner.setOnItemSelectedListener(mCamcorderProfileListener); 160bc88c6ed6508927ad72eefba3f6f63c6436f06d3Eino-Ville Talvala 161bc88c6ed6508927ad72eefba3f6f63c6436f06d3Eino-Ville Talvala mRecordToggle = (ToggleButton) findViewById(R.id.start_record); 162bc88c6ed6508927ad72eefba3f6f63c6436f06d3Eino-Ville Talvala mRecordToggle.setOnClickListener(mRecordToggleListener); 163abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala mPreviewOnlyControls.add(mRecordToggle); 164bc88c6ed6508927ad72eefba3f6f63c6436f06d3Eino-Ville Talvala 165abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala mLogView = (TextView) findViewById(R.id.log); 166abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala mLogView.setMovementMethod(new ScrollingMovementMethod()); 167bc88c6ed6508927ad72eefba3f6f63c6436f06d3Eino-Ville Talvala 16848f2556e12eeaa8932947fe6c8083e64bb5eb804Eino-Ville Talvala int numCameras = Camera.getNumberOfCameras(); 16948f2556e12eeaa8932947fe6c8083e64bb5eb804Eino-Ville Talvala String[] cameraNames = new String[numCameras]; 17048f2556e12eeaa8932947fe6c8083e64bb5eb804Eino-Ville Talvala for (int i = 0; i < numCameras; i++) { 17148f2556e12eeaa8932947fe6c8083e64bb5eb804Eino-Ville Talvala cameraNames[i] = "Camera " + i; 17248f2556e12eeaa8932947fe6c8083e64bb5eb804Eino-Ville Talvala } 17348f2556e12eeaa8932947fe6c8083e64bb5eb804Eino-Ville Talvala 17448f2556e12eeaa8932947fe6c8083e64bb5eb804Eino-Ville Talvala mCameraSpinner.setAdapter( 17548f2556e12eeaa8932947fe6c8083e64bb5eb804Eino-Ville Talvala new ArrayAdapter<String>(this, 17648f2556e12eeaa8932947fe6c8083e64bb5eb804Eino-Ville Talvala R.layout.spinner_item, cameraNames)); 17748f2556e12eeaa8932947fe6c8083e64bb5eb804Eino-Ville Talvala } 17848f2556e12eeaa8932947fe6c8083e64bb5eb804Eino-Ville Talvala 17948f2556e12eeaa8932947fe6c8083e64bb5eb804Eino-Ville Talvala @Override 18048f2556e12eeaa8932947fe6c8083e64bb5eb804Eino-Ville Talvala public void onResume() { 18148f2556e12eeaa8932947fe6c8083e64bb5eb804Eino-Ville Talvala super.onResume(); 182abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala log("onResume: Setting up camera"); 18348f2556e12eeaa8932947fe6c8083e64bb5eb804Eino-Ville Talvala mPreviewHolder = null; 18448f2556e12eeaa8932947fe6c8083e64bb5eb804Eino-Ville Talvala setUpCamera(); 18548f2556e12eeaa8932947fe6c8083e64bb5eb804Eino-Ville Talvala } 18648f2556e12eeaa8932947fe6c8083e64bb5eb804Eino-Ville Talvala 18748f2556e12eeaa8932947fe6c8083e64bb5eb804Eino-Ville Talvala @Override 18848f2556e12eeaa8932947fe6c8083e64bb5eb804Eino-Ville Talvala public void onPause() { 18948f2556e12eeaa8932947fe6c8083e64bb5eb804Eino-Ville Talvala super.onPause(); 190abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala log("onPause: Releasing camera"); 19148f2556e12eeaa8932947fe6c8083e64bb5eb804Eino-Ville Talvala mCamera.release(); 19248f2556e12eeaa8932947fe6c8083e64bb5eb804Eino-Ville Talvala mState = CAMERA_UNINITIALIZED; 19348f2556e12eeaa8932947fe6c8083e64bb5eb804Eino-Ville Talvala } 19448f2556e12eeaa8932947fe6c8083e64bb5eb804Eino-Ville Talvala 195abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala /** SurfaceHolder.Callback methods */ 19648f2556e12eeaa8932947fe6c8083e64bb5eb804Eino-Ville Talvala public void surfaceChanged(SurfaceHolder holder, 19748f2556e12eeaa8932947fe6c8083e64bb5eb804Eino-Ville Talvala int format, 19848f2556e12eeaa8932947fe6c8083e64bb5eb804Eino-Ville Talvala int width, 19948f2556e12eeaa8932947fe6c8083e64bb5eb804Eino-Ville Talvala int height) { 20048f2556e12eeaa8932947fe6c8083e64bb5eb804Eino-Ville Talvala if (mPreviewHolder != null) return; 20148f2556e12eeaa8932947fe6c8083e64bb5eb804Eino-Ville Talvala 202abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala log("Surface holder available: " + width + " x " + height); 20348f2556e12eeaa8932947fe6c8083e64bb5eb804Eino-Ville Talvala mPreviewHolder = holder; 20448f2556e12eeaa8932947fe6c8083e64bb5eb804Eino-Ville Talvala try { 20548f2556e12eeaa8932947fe6c8083e64bb5eb804Eino-Ville Talvala mCamera.setPreviewDisplay(holder); 20648f2556e12eeaa8932947fe6c8083e64bb5eb804Eino-Ville Talvala } catch (IOException e) { 207abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala logE("Unable to set up preview!"); 20848f2556e12eeaa8932947fe6c8083e64bb5eb804Eino-Ville Talvala } 20948f2556e12eeaa8932947fe6c8083e64bb5eb804Eino-Ville Talvala } 21048f2556e12eeaa8932947fe6c8083e64bb5eb804Eino-Ville Talvala 21148f2556e12eeaa8932947fe6c8083e64bb5eb804Eino-Ville Talvala public void surfaceCreated(SurfaceHolder holder) { 21248f2556e12eeaa8932947fe6c8083e64bb5eb804Eino-Ville Talvala 21348f2556e12eeaa8932947fe6c8083e64bb5eb804Eino-Ville Talvala } 21448f2556e12eeaa8932947fe6c8083e64bb5eb804Eino-Ville Talvala 21548f2556e12eeaa8932947fe6c8083e64bb5eb804Eino-Ville Talvala public void surfaceDestroyed(SurfaceHolder holder) { 216abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala mPreviewHolder = null; 217abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala } 21848f2556e12eeaa8932947fe6c8083e64bb5eb804Eino-Ville Talvala 219abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala /** UI controls enable/disable */ 220abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala private void enablePreviewOnlyControls(boolean enabled) { 221abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala for (View v : mPreviewOnlyControls) { 222abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala v.setEnabled(enabled); 223abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala } 22448f2556e12eeaa8932947fe6c8083e64bb5eb804Eino-Ville Talvala } 22548f2556e12eeaa8932947fe6c8083e64bb5eb804Eino-Ville Talvala 226abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala /** UI listeners */ 22748f2556e12eeaa8932947fe6c8083e64bb5eb804Eino-Ville Talvala 22848f2556e12eeaa8932947fe6c8083e64bb5eb804Eino-Ville Talvala private AdapterView.OnItemSelectedListener mCameraSpinnerListener = 229bc88c6ed6508927ad72eefba3f6f63c6436f06d3Eino-Ville Talvala new AdapterView.OnItemSelectedListener() { 230bc88c6ed6508927ad72eefba3f6f63c6436f06d3Eino-Ville Talvala public void onItemSelected(AdapterView<?> parent, 23148f2556e12eeaa8932947fe6c8083e64bb5eb804Eino-Ville Talvala View view, int pos, long id) { 232bc88c6ed6508927ad72eefba3f6f63c6436f06d3Eino-Ville Talvala if (mCameraId != pos) { 233bc88c6ed6508927ad72eefba3f6f63c6436f06d3Eino-Ville Talvala mCameraId = pos; 234bc88c6ed6508927ad72eefba3f6f63c6436f06d3Eino-Ville Talvala setUpCamera(); 235bc88c6ed6508927ad72eefba3f6f63c6436f06d3Eino-Ville Talvala } 236bc88c6ed6508927ad72eefba3f6f63c6436f06d3Eino-Ville Talvala } 23748f2556e12eeaa8932947fe6c8083e64bb5eb804Eino-Ville Talvala 238abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala public void onNothingSelected(AdapterView<?> parent) { 2394ae1a87883045d820ffd6e1b8a95c13b1919e00aEino-Ville Talvala 240bc88c6ed6508927ad72eefba3f6f63c6436f06d3Eino-Ville Talvala } 241bc88c6ed6508927ad72eefba3f6f63c6436f06d3Eino-Ville Talvala }; 242bc88c6ed6508927ad72eefba3f6f63c6436f06d3Eino-Ville Talvala 243bc88c6ed6508927ad72eefba3f6f63c6436f06d3Eino-Ville Talvala private OnClickListener mInfoButtonListener = new OnClickListener() { 244bc88c6ed6508927ad72eefba3f6f63c6436f06d3Eino-Ville Talvala public void onClick(View v) { 245bc88c6ed6508927ad72eefba3f6f63c6436f06d3Eino-Ville Talvala FragmentManager fm = getFragmentManager(); 246bc88c6ed6508927ad72eefba3f6f63c6436f06d3Eino-Ville Talvala InfoDialogFragment infoDialog = new InfoDialogFragment(); 247bc88c6ed6508927ad72eefba3f6f63c6436f06d3Eino-Ville Talvala infoDialog.updateInfo(mCameraId, mCamera); 248bc88c6ed6508927ad72eefba3f6f63c6436f06d3Eino-Ville Talvala infoDialog.show(fm, "info_dialog_fragment"); 249bc88c6ed6508927ad72eefba3f6f63c6436f06d3Eino-Ville Talvala } 250bc88c6ed6508927ad72eefba3f6f63c6436f06d3Eino-Ville Talvala }; 25148f2556e12eeaa8932947fe6c8083e64bb5eb804Eino-Ville Talvala 25248f2556e12eeaa8932947fe6c8083e64bb5eb804Eino-Ville Talvala private AdapterView.OnItemSelectedListener mPreviewSizeListener = 253bc88c6ed6508927ad72eefba3f6f63c6436f06d3Eino-Ville Talvala new AdapterView.OnItemSelectedListener() { 254bc88c6ed6508927ad72eefba3f6f63c6436f06d3Eino-Ville Talvala public void onItemSelected(AdapterView<?> parent, 255bc88c6ed6508927ad72eefba3f6f63c6436f06d3Eino-Ville Talvala View view, int pos, long id) { 256bc88c6ed6508927ad72eefba3f6f63c6436f06d3Eino-Ville Talvala if (pos == mPreviewSize) return; 257bc88c6ed6508927ad72eefba3f6f63c6436f06d3Eino-Ville Talvala if (mState == CAMERA_PREVIEW) { 258abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala log("Stopping preview to switch resolutions"); 259bc88c6ed6508927ad72eefba3f6f63c6436f06d3Eino-Ville Talvala mCamera.stopPreview(); 260bc88c6ed6508927ad72eefba3f6f63c6436f06d3Eino-Ville Talvala } 26148f2556e12eeaa8932947fe6c8083e64bb5eb804Eino-Ville Talvala 262bc88c6ed6508927ad72eefba3f6f63c6436f06d3Eino-Ville Talvala mPreviewSize = pos; 263bc88c6ed6508927ad72eefba3f6f63c6436f06d3Eino-Ville Talvala int width = mPreviewSizes.get(mPreviewSize).width; 264bc88c6ed6508927ad72eefba3f6f63c6436f06d3Eino-Ville Talvala int height = mPreviewSizes.get(mPreviewSize).height; 265bc88c6ed6508927ad72eefba3f6f63c6436f06d3Eino-Ville Talvala mParams.setPreviewSize(width, height); 26648f2556e12eeaa8932947fe6c8083e64bb5eb804Eino-Ville Talvala 267abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala log("Setting preview size to " + width + "x" + height); 268abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala 269bc88c6ed6508927ad72eefba3f6f63c6436f06d3Eino-Ville Talvala mCamera.setParameters(mParams); 27048f2556e12eeaa8932947fe6c8083e64bb5eb804Eino-Ville Talvala 271bc88c6ed6508927ad72eefba3f6f63c6436f06d3Eino-Ville Talvala if (mState == CAMERA_PREVIEW) { 272abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala log("Restarting preview"); 273abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala resizePreview(width, height); 274bc88c6ed6508927ad72eefba3f6f63c6436f06d3Eino-Ville Talvala mCamera.startPreview(); 275bc88c6ed6508927ad72eefba3f6f63c6436f06d3Eino-Ville Talvala } 276bc88c6ed6508927ad72eefba3f6f63c6436f06d3Eino-Ville Talvala } 27748f2556e12eeaa8932947fe6c8083e64bb5eb804Eino-Ville Talvala 278abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala public void onNothingSelected(AdapterView<?> parent) { 27948f2556e12eeaa8932947fe6c8083e64bb5eb804Eino-Ville Talvala 280bc88c6ed6508927ad72eefba3f6f63c6436f06d3Eino-Ville Talvala } 281bc88c6ed6508927ad72eefba3f6f63c6436f06d3Eino-Ville Talvala }; 28248f2556e12eeaa8932947fe6c8083e64bb5eb804Eino-Ville Talvala 28348f2556e12eeaa8932947fe6c8083e64bb5eb804Eino-Ville Talvala private View.OnClickListener mPreviewToggleListener = 28448f2556e12eeaa8932947fe6c8083e64bb5eb804Eino-Ville Talvala new View.OnClickListener() { 28548f2556e12eeaa8932947fe6c8083e64bb5eb804Eino-Ville Talvala public void onClick(View v) { 28648f2556e12eeaa8932947fe6c8083e64bb5eb804Eino-Ville Talvala if (mState == CAMERA_TAKE_PICTURE) { 287abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala logE("Can't change preview state while taking picture!"); 28848f2556e12eeaa8932947fe6c8083e64bb5eb804Eino-Ville Talvala return; 28948f2556e12eeaa8932947fe6c8083e64bb5eb804Eino-Ville Talvala } 29048f2556e12eeaa8932947fe6c8083e64bb5eb804Eino-Ville Talvala if (mPreviewToggle.isChecked()) { 291abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala log("Starting preview"); 292abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala resizePreview(mPreviewSizes.get(mPreviewSize).width, 293abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala mPreviewSizes.get(mPreviewSize).height); 29448f2556e12eeaa8932947fe6c8083e64bb5eb804Eino-Ville Talvala mCamera.startPreview(); 29548f2556e12eeaa8932947fe6c8083e64bb5eb804Eino-Ville Talvala mState = CAMERA_PREVIEW; 296abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala enablePreviewOnlyControls(true); 29748f2556e12eeaa8932947fe6c8083e64bb5eb804Eino-Ville Talvala } else { 298abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala log("Stopping preview"); 29948f2556e12eeaa8932947fe6c8083e64bb5eb804Eino-Ville Talvala mCamera.stopPreview(); 30048f2556e12eeaa8932947fe6c8083e64bb5eb804Eino-Ville Talvala mState = CAMERA_OPEN; 30148f2556e12eeaa8932947fe6c8083e64bb5eb804Eino-Ville Talvala 302abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala enablePreviewOnlyControls(false); 30348f2556e12eeaa8932947fe6c8083e64bb5eb804Eino-Ville Talvala } 30448f2556e12eeaa8932947fe6c8083e64bb5eb804Eino-Ville Talvala } 30548f2556e12eeaa8932947fe6c8083e64bb5eb804Eino-Ville Talvala }; 30648f2556e12eeaa8932947fe6c8083e64bb5eb804Eino-Ville Talvala 307abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala private OnItemSelectedListener mAutofocusModeListener = 308abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala new OnItemSelectedListener() { 309abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala public void onItemSelected(AdapterView<?> parent, 310abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala View view, int pos, long id) { 311abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala if (pos == mAfMode) return; 312abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala 313abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala mAfMode = pos; 314abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala String focusMode = mAfModes.get(mAfMode); 315abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala log("Setting focus mode to " + focusMode); 316abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala mParams.setFocusMode(focusMode); 317abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala 318abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala mCamera.setParameters(mParams); 319abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala } 320abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala 321abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala public void onNothingSelected(AdapterView<?> arg0) { 322abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala 323abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala } 324abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala }; 325abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala 326abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala private OnClickListener mAutofocusButtonListener = 327abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala new View.OnClickListener() { 328abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala public void onClick(View v) { 329abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala log("Triggering autofocus"); 330abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala mCamera.autoFocus(mAutofocusCallback); 331abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala } 332abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala }; 333abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala 334abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala private OnClickListener mCancelAutofocusButtonListener = 335abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala new View.OnClickListener() { 336abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala public void onClick(View v) { 337abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala log("Cancelling autofocus"); 338abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala mCamera.cancelAutoFocus(); 339abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala } 340abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala }; 341abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala 342abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala private Camera.AutoFocusCallback mAutofocusCallback = 343abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala new Camera.AutoFocusCallback() { 344abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala public void onAutoFocus(boolean success, Camera camera) { 345abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala log("Autofocus completed: " + (success ? "success" : "failure") ); 346abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala } 347abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala }; 348abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala 349abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala private Camera.AutoFocusMoveCallback mAutofocusMoveCallback = 350abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala new Camera.AutoFocusMoveCallback() { 351abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala public void onAutoFocusMoving(boolean start, Camera camera) { 352abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala log("Autofocus movement: " + (start ? "starting" : "stopped") ); 353abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala } 354abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala }; 355abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala 356bc88c6ed6508927ad72eefba3f6f63c6436f06d3Eino-Ville Talvala private AdapterView.OnItemSelectedListener mSnapshotSizeListener = 357abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala new AdapterView.OnItemSelectedListener() { 358bc88c6ed6508927ad72eefba3f6f63c6436f06d3Eino-Ville Talvala public void onItemSelected(AdapterView<?> parent, 359bc88c6ed6508927ad72eefba3f6f63c6436f06d3Eino-Ville Talvala View view, int pos, long id) { 360bc88c6ed6508927ad72eefba3f6f63c6436f06d3Eino-Ville Talvala if (pos == mSnapshotSize) return; 361bc88c6ed6508927ad72eefba3f6f63c6436f06d3Eino-Ville Talvala 362bc88c6ed6508927ad72eefba3f6f63c6436f06d3Eino-Ville Talvala mSnapshotSize = pos; 363bc88c6ed6508927ad72eefba3f6f63c6436f06d3Eino-Ville Talvala int width = mSnapshotSizes.get(mSnapshotSize).width; 364bc88c6ed6508927ad72eefba3f6f63c6436f06d3Eino-Ville Talvala int height = mSnapshotSizes.get(mSnapshotSize).height; 365abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala log("Setting snapshot size to " + width + " x " + height); 366abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala 367bc88c6ed6508927ad72eefba3f6f63c6436f06d3Eino-Ville Talvala mParams.setPictureSize(width, height); 368bc88c6ed6508927ad72eefba3f6f63c6436f06d3Eino-Ville Talvala 369bc88c6ed6508927ad72eefba3f6f63c6436f06d3Eino-Ville Talvala mCamera.setParameters(mParams); 370bc88c6ed6508927ad72eefba3f6f63c6436f06d3Eino-Ville Talvala } 371bc88c6ed6508927ad72eefba3f6f63c6436f06d3Eino-Ville Talvala 372abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala public void onNothingSelected(AdapterView<?> parent) { 373bc88c6ed6508927ad72eefba3f6f63c6436f06d3Eino-Ville Talvala 374bc88c6ed6508927ad72eefba3f6f63c6436f06d3Eino-Ville Talvala } 375bc88c6ed6508927ad72eefba3f6f63c6436f06d3Eino-Ville Talvala }; 376bc88c6ed6508927ad72eefba3f6f63c6436f06d3Eino-Ville Talvala 37748f2556e12eeaa8932947fe6c8083e64bb5eb804Eino-Ville Talvala private View.OnClickListener mTakePictureListener = 37848f2556e12eeaa8932947fe6c8083e64bb5eb804Eino-Ville Talvala new View.OnClickListener() { 37948f2556e12eeaa8932947fe6c8083e64bb5eb804Eino-Ville Talvala public void onClick(View v) { 380abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala log("Taking picture"); 38148f2556e12eeaa8932947fe6c8083e64bb5eb804Eino-Ville Talvala if (mState == CAMERA_PREVIEW) { 38248f2556e12eeaa8932947fe6c8083e64bb5eb804Eino-Ville Talvala mState = CAMERA_TAKE_PICTURE; 383abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala enablePreviewOnlyControls(false); 38448f2556e12eeaa8932947fe6c8083e64bb5eb804Eino-Ville Talvala mPreviewToggle.setChecked(false); 38548f2556e12eeaa8932947fe6c8083e64bb5eb804Eino-Ville Talvala 38648f2556e12eeaa8932947fe6c8083e64bb5eb804Eino-Ville Talvala mCamera.takePicture(mShutterCb, mRawCb, mPostviewCb, mJpegCb); 38748f2556e12eeaa8932947fe6c8083e64bb5eb804Eino-Ville Talvala } else { 388abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala logE("Can't take picture while not running preview!"); 38948f2556e12eeaa8932947fe6c8083e64bb5eb804Eino-Ville Talvala } 39048f2556e12eeaa8932947fe6c8083e64bb5eb804Eino-Ville Talvala } 39148f2556e12eeaa8932947fe6c8083e64bb5eb804Eino-Ville Talvala }; 39248f2556e12eeaa8932947fe6c8083e64bb5eb804Eino-Ville Talvala 393bc88c6ed6508927ad72eefba3f6f63c6436f06d3Eino-Ville Talvala private AdapterView.OnItemSelectedListener mCamcorderProfileListener = 394bc88c6ed6508927ad72eefba3f6f63c6436f06d3Eino-Ville Talvala new AdapterView.OnItemSelectedListener() { 395bc88c6ed6508927ad72eefba3f6f63c6436f06d3Eino-Ville Talvala public void onItemSelected(AdapterView<?> parent, 396bc88c6ed6508927ad72eefba3f6f63c6436f06d3Eino-Ville Talvala View view, int pos, long id) { 397abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala if (pos == mCamcorderProfile) return; 398abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala 399abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala log("Setting camcorder profile to " + ((TextView)view).getText()); 400abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala mCamcorderProfile = pos; 401bc88c6ed6508927ad72eefba3f6f63c6436f06d3Eino-Ville Talvala } 402bc88c6ed6508927ad72eefba3f6f63c6436f06d3Eino-Ville Talvala 403abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala public void onNothingSelected(AdapterView<?> parent) { 404bc88c6ed6508927ad72eefba3f6f63c6436f06d3Eino-Ville Talvala 405bc88c6ed6508927ad72eefba3f6f63c6436f06d3Eino-Ville Talvala } 406bc88c6ed6508927ad72eefba3f6f63c6436f06d3Eino-Ville Talvala }; 407bc88c6ed6508927ad72eefba3f6f63c6436f06d3Eino-Ville Talvala 408bc88c6ed6508927ad72eefba3f6f63c6436f06d3Eino-Ville Talvala private View.OnClickListener mRecordToggleListener = 409abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala new View.OnClickListener() { 410bc88c6ed6508927ad72eefba3f6f63c6436f06d3Eino-Ville Talvala public void onClick(View v) { 411abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala mPreviewToggle.setEnabled(false); 412abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala if (mState == CAMERA_PREVIEW) { 413abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala startRecording(); 414abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala } else if (mState == CAMERA_RECORD) { 415abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala stopRecording(); 416abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala } else { 417abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala logE("Can't toggle recording in current state!"); 418abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala } 419abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala mPreviewToggle.setEnabled(true); 420bc88c6ed6508927ad72eefba3f6f63c6436f06d3Eino-Ville Talvala } 421bc88c6ed6508927ad72eefba3f6f63c6436f06d3Eino-Ville Talvala }; 422bc88c6ed6508927ad72eefba3f6f63c6436f06d3Eino-Ville Talvala 42348f2556e12eeaa8932947fe6c8083e64bb5eb804Eino-Ville Talvala private Camera.ShutterCallback mShutterCb = new Camera.ShutterCallback() { 42448f2556e12eeaa8932947fe6c8083e64bb5eb804Eino-Ville Talvala public void onShutter() { 425abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala log("Shutter callback received"); 42648f2556e12eeaa8932947fe6c8083e64bb5eb804Eino-Ville Talvala } 42748f2556e12eeaa8932947fe6c8083e64bb5eb804Eino-Ville Talvala }; 42848f2556e12eeaa8932947fe6c8083e64bb5eb804Eino-Ville Talvala 42948f2556e12eeaa8932947fe6c8083e64bb5eb804Eino-Ville Talvala private Camera.PictureCallback mRawCb = new Camera.PictureCallback() { 43048f2556e12eeaa8932947fe6c8083e64bb5eb804Eino-Ville Talvala public void onPictureTaken(byte[] data, Camera camera) { 431abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala log("Raw callback received"); 43248f2556e12eeaa8932947fe6c8083e64bb5eb804Eino-Ville Talvala } 43348f2556e12eeaa8932947fe6c8083e64bb5eb804Eino-Ville Talvala }; 43448f2556e12eeaa8932947fe6c8083e64bb5eb804Eino-Ville Talvala 43548f2556e12eeaa8932947fe6c8083e64bb5eb804Eino-Ville Talvala private Camera.PictureCallback mPostviewCb = new Camera.PictureCallback() { 43648f2556e12eeaa8932947fe6c8083e64bb5eb804Eino-Ville Talvala public void onPictureTaken(byte[] data, Camera camera) { 437abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala log("Postview callback received"); 43848f2556e12eeaa8932947fe6c8083e64bb5eb804Eino-Ville Talvala } 43948f2556e12eeaa8932947fe6c8083e64bb5eb804Eino-Ville Talvala }; 44048f2556e12eeaa8932947fe6c8083e64bb5eb804Eino-Ville Talvala 44148f2556e12eeaa8932947fe6c8083e64bb5eb804Eino-Ville Talvala private Camera.PictureCallback mJpegCb = new Camera.PictureCallback() { 44248f2556e12eeaa8932947fe6c8083e64bb5eb804Eino-Ville Talvala public void onPictureTaken(byte[] data, Camera camera) { 443abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala log("JPEG picture callback received"); 444bc88c6ed6508927ad72eefba3f6f63c6436f06d3Eino-Ville Talvala FragmentManager fm = getFragmentManager(); 445bc88c6ed6508927ad72eefba3f6f63c6436f06d3Eino-Ville Talvala SnapshotDialogFragment snapshotDialog = new SnapshotDialogFragment(); 44648f2556e12eeaa8932947fe6c8083e64bb5eb804Eino-Ville Talvala 44748f2556e12eeaa8932947fe6c8083e64bb5eb804Eino-Ville Talvala Bitmap img = BitmapFactory.decodeByteArray(data, 0, data.length); 448bc88c6ed6508927ad72eefba3f6f63c6436f06d3Eino-Ville Talvala snapshotDialog.updateImage(img); 449bc88c6ed6508927ad72eefba3f6f63c6436f06d3Eino-Ville Talvala snapshotDialog.show(fm, "snapshot_dialog_fragment"); 45048f2556e12eeaa8932947fe6c8083e64bb5eb804Eino-Ville Talvala 45148f2556e12eeaa8932947fe6c8083e64bb5eb804Eino-Ville Talvala mPreviewToggle.setEnabled(true); 45248f2556e12eeaa8932947fe6c8083e64bb5eb804Eino-Ville Talvala 45348f2556e12eeaa8932947fe6c8083e64bb5eb804Eino-Ville Talvala mState = CAMERA_OPEN; 45448f2556e12eeaa8932947fe6c8083e64bb5eb804Eino-Ville Talvala } 45548f2556e12eeaa8932947fe6c8083e64bb5eb804Eino-Ville Talvala }; 45648f2556e12eeaa8932947fe6c8083e64bb5eb804Eino-Ville Talvala 45748f2556e12eeaa8932947fe6c8083e64bb5eb804Eino-Ville Talvala // Internal methods 45848f2556e12eeaa8932947fe6c8083e64bb5eb804Eino-Ville Talvala 45948f2556e12eeaa8932947fe6c8083e64bb5eb804Eino-Ville Talvala void setUpCamera() { 460abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala log("Setting up camera " + mCameraId); 461abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala logIndent(1); 46248f2556e12eeaa8932947fe6c8083e64bb5eb804Eino-Ville Talvala if (mState >= CAMERA_OPEN) { 463abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala log("Closing old camera"); 46448f2556e12eeaa8932947fe6c8083e64bb5eb804Eino-Ville Talvala mCamera.release(); 46548f2556e12eeaa8932947fe6c8083e64bb5eb804Eino-Ville Talvala mState = CAMERA_UNINITIALIZED; 46648f2556e12eeaa8932947fe6c8083e64bb5eb804Eino-Ville Talvala } 467abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala log("Opening camera " + mCameraId); 46848f2556e12eeaa8932947fe6c8083e64bb5eb804Eino-Ville Talvala mCamera = Camera.open(mCameraId); 46948f2556e12eeaa8932947fe6c8083e64bb5eb804Eino-Ville Talvala mState = CAMERA_OPEN; 47048f2556e12eeaa8932947fe6c8083e64bb5eb804Eino-Ville Talvala 47148f2556e12eeaa8932947fe6c8083e64bb5eb804Eino-Ville Talvala mParams = mCamera.getParameters(); 472bc88c6ed6508927ad72eefba3f6f63c6436f06d3Eino-Ville Talvala 473bc88c6ed6508927ad72eefba3f6f63c6436f06d3Eino-Ville Talvala // Set up preview size selection 474abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala 475abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala log("Configuring camera"); 476abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala logIndent(1); 477abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala 478abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala updatePreviewSizes(mParams); 479abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala updateAfModes(mParams); 480abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala updateSnapshotSizes(mParams); 481abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala updateCamcorderProfile(mCameraId); 482abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala 483abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala // Update parameters based on above updates 484abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala mCamera.setParameters(mParams); 485abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala 486abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala mCamera.setAutoFocusMoveCallback(mAutofocusMoveCallback); 487abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala 488abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala if (mPreviewHolder != null) { 489abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala log("Setting preview display"); 490abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala try { 491abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala mCamera.setPreviewDisplay(mPreviewHolder); 492abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala } catch(IOException e) { 493abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala Log.e(TAG, "Unable to set up preview!"); 494abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala } 495abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala } 496abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala 497abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala logIndent(-1); 498abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala 499abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala mPreviewToggle.setEnabled(true); 500abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala mPreviewToggle.setChecked(false); 501abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala enablePreviewOnlyControls(false); 502abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala 503abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala int width = mPreviewSizes.get(mPreviewSize).width; 504abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala int height = mPreviewSizes.get(mPreviewSize).height; 505abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala resizePreview(width, height); 506abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala if (mPreviewToggle.isChecked()) { 507abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala log("Starting preview" ); 508abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala mCamera.startPreview(); 509abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala mState = CAMERA_PREVIEW; 510abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala } 511abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala logIndent(-1); 512abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala } 513abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala 514abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala private void updateAfModes(Parameters params) { 515abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala mAfModes = params.getSupportedFocusModes(); 516abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala 517abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala mAutofocusModeSpinner.setAdapter( 518abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala new ArrayAdapter<String>(this, R.layout.spinner_item, 519abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala mAfModes.toArray(new String[0]))); 520abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala 521abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala mAfMode = 0; 522abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala 523abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala params.setFocusMode(mAfModes.get(mAfMode)); 524abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala 525abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala log("Setting AF mode to " + mAfModes.get(mAfMode)); 526abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala } 527abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala 528abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala private void updatePreviewSizes(Camera.Parameters params) { 529abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala mPreviewSizes = params.getSupportedPreviewSizes(); 53048f2556e12eeaa8932947fe6c8083e64bb5eb804Eino-Ville Talvala 53148f2556e12eeaa8932947fe6c8083e64bb5eb804Eino-Ville Talvala String[] availableSizeNames = new String[mPreviewSizes.size()]; 532bc88c6ed6508927ad72eefba3f6f63c6436f06d3Eino-Ville Talvala int i = 0; 533bc88c6ed6508927ad72eefba3f6f63c6436f06d3Eino-Ville Talvala for (Camera.Size previewSize: mPreviewSizes) { 534bc88c6ed6508927ad72eefba3f6f63c6436f06d3Eino-Ville Talvala availableSizeNames[i++] = 535abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala Integer.toString(previewSize.width) + " x " + 536abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala Integer.toString(previewSize.height); 53748f2556e12eeaa8932947fe6c8083e64bb5eb804Eino-Ville Talvala } 53848f2556e12eeaa8932947fe6c8083e64bb5eb804Eino-Ville Talvala mPreviewSizeSpinner.setAdapter( 539abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala new ArrayAdapter<String>( 540abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala this, R.layout.spinner_item, availableSizeNames)); 54148f2556e12eeaa8932947fe6c8083e64bb5eb804Eino-Ville Talvala 54248f2556e12eeaa8932947fe6c8083e64bb5eb804Eino-Ville Talvala mPreviewSize = 0; 54348f2556e12eeaa8932947fe6c8083e64bb5eb804Eino-Ville Talvala 54448f2556e12eeaa8932947fe6c8083e64bb5eb804Eino-Ville Talvala int width = mPreviewSizes.get(mPreviewSize).width; 54548f2556e12eeaa8932947fe6c8083e64bb5eb804Eino-Ville Talvala int height = mPreviewSizes.get(mPreviewSize).height; 546abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala params.setPreviewSize(width, height); 547abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala log("Setting preview size to " + width + " x " + height); 548abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala } 549bc88c6ed6508927ad72eefba3f6f63c6436f06d3Eino-Ville Talvala 550abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala private void updateSnapshotSizes(Camera.Parameters params) { 551abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala String[] availableSizeNames; 552abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala mSnapshotSizes = params.getSupportedPictureSizes(); 553bc88c6ed6508927ad72eefba3f6f63c6436f06d3Eino-Ville Talvala 554bc88c6ed6508927ad72eefba3f6f63c6436f06d3Eino-Ville Talvala availableSizeNames = new String[mSnapshotSizes.size()]; 555abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala int i = 0; 556bc88c6ed6508927ad72eefba3f6f63c6436f06d3Eino-Ville Talvala for (Camera.Size snapshotSize : mSnapshotSizes) { 557bc88c6ed6508927ad72eefba3f6f63c6436f06d3Eino-Ville Talvala availableSizeNames[i++] = 558abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala Integer.toString(snapshotSize.width) + " x " + 559abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala Integer.toString(snapshotSize.height); 560bc88c6ed6508927ad72eefba3f6f63c6436f06d3Eino-Ville Talvala } 561bc88c6ed6508927ad72eefba3f6f63c6436f06d3Eino-Ville Talvala mSnapshotSizeSpinner.setAdapter( 562abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala new ArrayAdapter<String>( 563abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala this, R.layout.spinner_item, availableSizeNames)); 564bc88c6ed6508927ad72eefba3f6f63c6436f06d3Eino-Ville Talvala 565bc88c6ed6508927ad72eefba3f6f63c6436f06d3Eino-Ville Talvala mSnapshotSize = 0; 566bc88c6ed6508927ad72eefba3f6f63c6436f06d3Eino-Ville Talvala 567abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala int snapshotWidth = mSnapshotSizes.get(mSnapshotSize).width; 568abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala int snapshotHeight = mSnapshotSizes.get(mSnapshotSize).height; 569abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala params.setPictureSize(snapshotWidth, snapshotHeight); 570abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala log("Setting snapshot size to " + snapshotWidth + " x " + snapshotHeight); 57148f2556e12eeaa8932947fe6c8083e64bb5eb804Eino-Ville Talvala } 57248f2556e12eeaa8932947fe6c8083e64bb5eb804Eino-Ville Talvala 573bc88c6ed6508927ad72eefba3f6f63c6436f06d3Eino-Ville Talvala private void updateCamcorderProfile(int cameraId) { 574bc88c6ed6508927ad72eefba3f6f63c6436f06d3Eino-Ville Talvala // Have to query all of these individually, 575bc88c6ed6508927ad72eefba3f6f63c6436f06d3Eino-Ville Talvala final int PROFILES[] = new int[] { 576abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala CamcorderProfile.QUALITY_1080P, 577abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala CamcorderProfile.QUALITY_480P, 578abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala CamcorderProfile.QUALITY_720P, 579abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala CamcorderProfile.QUALITY_CIF, 580abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala CamcorderProfile.QUALITY_HIGH, 581abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala CamcorderProfile.QUALITY_LOW, 582abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala CamcorderProfile.QUALITY_QCIF, 583abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala CamcorderProfile.QUALITY_QVGA, 584abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala CamcorderProfile.QUALITY_TIME_LAPSE_1080P, 585abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala CamcorderProfile.QUALITY_TIME_LAPSE_480P, 586abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala CamcorderProfile.QUALITY_TIME_LAPSE_720P, 587abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala CamcorderProfile.QUALITY_TIME_LAPSE_CIF, 588abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala CamcorderProfile.QUALITY_TIME_LAPSE_HIGH, 589abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala CamcorderProfile.QUALITY_TIME_LAPSE_LOW, 590abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala CamcorderProfile.QUALITY_TIME_LAPSE_QCIF, 591abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala CamcorderProfile.QUALITY_TIME_LAPSE_QVGA 592bc88c6ed6508927ad72eefba3f6f63c6436f06d3Eino-Ville Talvala }; 593bc88c6ed6508927ad72eefba3f6f63c6436f06d3Eino-Ville Talvala 594bc88c6ed6508927ad72eefba3f6f63c6436f06d3Eino-Ville Talvala final String PROFILE_NAMES[] = new String[] { 595abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala "1080P", 596abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala "480P", 597abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala "720P", 598abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala "CIF", 599abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala "HIGH", 600abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala "LOW", 601abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala "QCIF", 602abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala "QVGA", 603abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala "TIME_LAPSE_1080P", 604abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala "TIME_LAPSE_480P", 605abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala "TIME_LAPSE_720P", 606abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala "TIME_LAPSE_CIF", 607abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala "TIME_LAPSE_HIGH", 608abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala "TIME_LAPSE_LOW", 609abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala "TIME_LAPSE_QCIF", 610abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala "TIME_LAPSE_QVGA" 611bc88c6ed6508927ad72eefba3f6f63c6436f06d3Eino-Ville Talvala }; 612bc88c6ed6508927ad72eefba3f6f63c6436f06d3Eino-Ville Talvala 613bc88c6ed6508927ad72eefba3f6f63c6436f06d3Eino-Ville Talvala List<String> availableCamcorderProfileNames = new ArrayList<String>(); 614bc88c6ed6508927ad72eefba3f6f63c6436f06d3Eino-Ville Talvala mCamcorderProfiles = new ArrayList<CamcorderProfile>(); 615bc88c6ed6508927ad72eefba3f6f63c6436f06d3Eino-Ville Talvala 616bc88c6ed6508927ad72eefba3f6f63c6436f06d3Eino-Ville Talvala for (int i = 0; i < PROFILES.length; i++) { 617abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala if (CamcorderProfile.hasProfile(cameraId, PROFILES[i])) { 618abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala availableCamcorderProfileNames.add(PROFILE_NAMES[i]); 619abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala mCamcorderProfiles.add(CamcorderProfile.get(cameraId, PROFILES[i])); 620abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala } 621bc88c6ed6508927ad72eefba3f6f63c6436f06d3Eino-Ville Talvala } 622bc88c6ed6508927ad72eefba3f6f63c6436f06d3Eino-Ville Talvala String[] nameArray = (String[])availableCamcorderProfileNames.toArray(new String[0]); 623bc88c6ed6508927ad72eefba3f6f63c6436f06d3Eino-Ville Talvala mCamcorderProfileSpinner.setAdapter( 624abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala new ArrayAdapter<String>( 625abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala this, R.layout.spinner_item, nameArray)); 626abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala 627abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala mCamcorderProfile = 0; 628abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala log("Setting camcorder profile to " + nameArray[mCamcorderProfile]); 629abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala 630bc88c6ed6508927ad72eefba3f6f63c6436f06d3Eino-Ville Talvala } 631bc88c6ed6508927ad72eefba3f6f63c6436f06d3Eino-Ville Talvala 63248f2556e12eeaa8932947fe6c8083e64bb5eb804Eino-Ville Talvala void resizePreview(int width, int height) { 63348f2556e12eeaa8932947fe6c8083e64bb5eb804Eino-Ville Talvala if (mPreviewHolder != null) { 63448f2556e12eeaa8932947fe6c8083e64bb5eb804Eino-Ville Talvala int viewHeight = mPreviewView.getHeight(); 63548f2556e12eeaa8932947fe6c8083e64bb5eb804Eino-Ville Talvala int viewWidth = (int)(((double)width)/height * viewHeight); 63648f2556e12eeaa8932947fe6c8083e64bb5eb804Eino-Ville Talvala 63748f2556e12eeaa8932947fe6c8083e64bb5eb804Eino-Ville Talvala mPreviewView.setLayoutParams( 63848f2556e12eeaa8932947fe6c8083e64bb5eb804Eino-Ville Talvala new LayoutParams(viewWidth, viewHeight)); 63948f2556e12eeaa8932947fe6c8083e64bb5eb804Eino-Ville Talvala } 64048f2556e12eeaa8932947fe6c8083e64bb5eb804Eino-Ville Talvala 64148f2556e12eeaa8932947fe6c8083e64bb5eb804Eino-Ville Talvala } 642abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala 643abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala static final int MEDIA_TYPE_IMAGE = 0; 644abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala static final int MEDIA_TYPE_VIDEO = 1; 645abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala private File getOutputMediaFile(int type){ 646abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala // To be safe, you should check that the SDCard is mounted 647abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala // using Environment.getExternalStorageState() before doing this. 648abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala 649abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala String state = Environment.getExternalStorageState(); 650abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala if (!Environment.MEDIA_MOUNTED.equals(state)) { 651abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala return null; 652abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala } 653abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala 654abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala File mediaStorageDir = new File(Environment.getExternalStoragePublicDirectory( 655abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala Environment.DIRECTORY_PICTURES), "TestingCamera"); 656abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala // This location works best if you want the created images to be shared 657abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala // between applications and persist after your app has been uninstalled. 658abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala 659abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala // Create the storage directory if it does not exist 660abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala if (! mediaStorageDir.exists()){ 661abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala if (! mediaStorageDir.mkdirs()){ 662abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala logE("Failed to create directory for pictures/video"); 663abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala return null; 664abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala } 665abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala } 666abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala 667abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala // Create a media file name 668abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date()); 669abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala File mediaFile; 670abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala if (type == MEDIA_TYPE_IMAGE){ 671abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala mediaFile = new File(mediaStorageDir.getPath() + File.separator + 672abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala "IMG_"+ timeStamp + ".jpg"); 673abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala } else if(type == MEDIA_TYPE_VIDEO) { 674abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala mediaFile = new File(mediaStorageDir.getPath() + File.separator + 675abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala "VID_"+ timeStamp + ".mp4"); 676abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala } else { 677abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala return null; 678abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala } 679abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala 680abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala return mediaFile; 681abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala } 682abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala 683abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala private void startRecording() { 684abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala log("Starting recording"); 685abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala logIndent(1); 686abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala log("Configuring MediaRecoder"); 687abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala mCamera.unlock(); 688abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala mRecorder = new MediaRecorder(); 689abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala mRecorder.setOnErrorListener(mRecordingErrorListener); 690abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala mRecorder.setOnInfoListener(mRecordingInfoListener); 691abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala mRecorder.setCamera(mCamera); 692abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala mRecorder.setAudioSource(MediaRecorder.AudioSource.CAMCORDER); 693abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala mRecorder.setVideoSource(MediaRecorder.VideoSource.CAMERA); 694abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala mRecorder.setProfile(mCamcorderProfiles.get(mCamcorderProfile)); 695abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala File outputFile = getOutputMediaFile(MEDIA_TYPE_VIDEO); 696abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala log("File name:" + outputFile.toString()); 697abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala mRecorder.setOutputFile(outputFile.toString()); 698abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala 699abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala boolean ready = false; 700abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala log("Preparing MediaRecorder"); 701abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala try { 702abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala mRecorder.prepare(); 703abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala ready = true; 704abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala } catch (Exception e) { 705abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala StringWriter writer = new StringWriter(); 706abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala e.printStackTrace(new PrintWriter(writer)); 707abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala logE("Exception preparing MediaRecorder:\n" + writer.toString()); 708abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala } 709abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala 710abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala if (ready) { 711abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala try { 712abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala log("Starting MediaRecorder"); 713abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala mRecorder.start(); 714abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala mState = CAMERA_RECORD; 715abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala log("Recording active"); 716abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala } catch (Exception e) { 717abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala StringWriter writer = new StringWriter(); 718abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala e.printStackTrace(new PrintWriter(writer)); 719abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala logE("Exception starting MediaRecorder:\n" + writer.toString()); 720abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala } 721abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala } else { 722abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala mPreviewToggle.setChecked(false); 723abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala } 724abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala logIndent(-1); 725abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala } 726abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala 727abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala private MediaRecorder.OnErrorListener mRecordingErrorListener = 728abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala new MediaRecorder.OnErrorListener() { 729abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala public void onError(MediaRecorder mr, int what, int extra) { 730abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala logE("MediaRecorder reports error: " + what + ", extra " 731abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala + extra); 732abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala if (mState == CAMERA_RECORD) { 733abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala stopRecording(); 734abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala } 735abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala } 736abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala }; 737abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala 738abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala private MediaRecorder.OnInfoListener mRecordingInfoListener = 739abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala new MediaRecorder.OnInfoListener() { 740abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala public void onInfo(MediaRecorder mr, int what, int extra) { 741abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala log("MediaRecorder reports info: " + what + ", extra " 742abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala + extra); 743abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala } 744abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala }; 745abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala 746abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala private void stopRecording() { 747abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala log("Stopping recording"); 748abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala if (mRecorder != null) { 749abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala mRecorder.stop(); 750abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala mCamera.lock(); 751abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala mState = CAMERA_PREVIEW; 752abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala mRecorder.release(); 753abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala mRecorder = null; 754abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala } else { 755abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala logE("Recorder is unexpectedly null!"); 756abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala } 757abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala } 758abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala 759abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala private int mLogIndentLevel = 0; 760abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala private String mLogIndent = "\t"; 761abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala /** Increment or decrement log indentation level */ 762abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala private void logIndent(int delta) { 763abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala mLogIndentLevel += delta; 764abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala if (mLogIndentLevel < 0) mLogIndentLevel = 0; 765abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala char[] mLogIndentArray = new char[mLogIndentLevel + 1]; 766abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala for (int i = -1; i < mLogIndentLevel; i++) { 767abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala mLogIndentArray[i + 1] = '\t'; 768abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala } 769abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala mLogIndent = new String(mLogIndentArray); 770abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala } 771abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala 772abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala SimpleDateFormat mDateFormatter = new SimpleDateFormat("HH:mm:ss.SSS"); 773abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala /** Log both to log text view and to device logcat */ 774abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala private void log(String logLine) { 775abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala Log.d(TAG, logLine); 776abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala logAndScrollToBottom(logLine, mLogIndent); 777abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala } 778abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala 779abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala private void logE(String logLine) { 780abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala Log.e(TAG, logLine); 781abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala logAndScrollToBottom(logLine, mLogIndent + "!!! "); 782abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala } 783abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala 784abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala private void logAndScrollToBottom(String logLine, String logIndent) { 785abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala StringBuffer logEntry = new StringBuffer(32); 786abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala logEntry.append("\n").append(mDateFormatter.format(new Date())).append(logIndent); 787abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala logEntry.append(logLine); 788abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala mLogView.append(logEntry); 789abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala final Layout layout = mLogView.getLayout(); 790abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala if (layout != null){ 791abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala int scrollDelta = layout.getLineBottom(mLogView.getLineCount() - 1) 792abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala - mLogView.getScrollY() - mLogView.getHeight(); 793abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala if(scrollDelta > 0) { 794abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala mLogView.scrollBy(0, scrollDelta); 795abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala } 796abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala } 797abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala } 798abe36163445fb3fe458252fd8d21c3e1ac14ed6dEino-Ville Talvala 79948f2556e12eeaa8932947fe6c8083e64bb5eb804Eino-Ville Talvala}