import android.annotation.TargetApi;
import android.app.AlertDialog;
-import android.content.Context;
+import android.app.Dialog;
import android.content.DialogInterface;
import android.hardware.Camera;
+import android.hardware.Camera.CameraInfo;
import android.hardware.Camera.Parameters;
+import android.os.Bundle;
import android.view.Surface;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.View;
-import android.view.WindowManager;
import android.widget.TextView;
public class CameraDialogFragment extends BaseAlertDialogFragment implements SurfaceHolder.Callback {
public static final String FRAGMENT_TAG = "fragment_camera";
- private DecodeAsyncTask mDecodeAsyncTask;
+ private final CameraInfo mCameraInfo = new CameraInfo();
+ private final DecodeAsyncTask mDecodeAsyncTask;
+ private final int mCameraId;
private Camera mCamera;
public CameraDialogFragment() {
super(R.string.scan_qr_code, R.layout.camera,
android.R.string.cancel, R.string.manual_entry, 0);
- }
- @Override
- protected void onViewInflated(View view) {
- SurfaceView sv = (SurfaceView) view.findViewById(R.id.camera_surfaceview);
- sv.getHolder().addCallback(this);
+ // Find a back-facing camera
+ int cameraId;
+ for (cameraId = Camera.getNumberOfCameras() - 1; cameraId >= 0; cameraId--) {
+ Camera.getCameraInfo(cameraId, mCameraInfo);
+ if (mCameraInfo.facing == CameraInfo.CAMERA_FACING_BACK)
+ break;
+ }
+ mCameraId = cameraId;
+
+ // Create the decoder thread
+ mDecodeAsyncTask = new DecodeAsyncTask() {
+ @Override
+ protected void onPostExecute(String result) {
+ super.onPostExecute(result);
+ if (result != null)
+ ((MainActivity) getActivity()).tokenURIReceived(result);
+ dismiss();
+ }
+ };
}
@Override
- public void onClick(DialogInterface dialog, int which) {
- if (which == AlertDialog.BUTTON_NEUTRAL) {
+ public void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+
+ // If we have no back facing camera, open the manual dialog
+ if (mCameraId < 0) {
new ManualDialogFragment().show(getFragmentManager(),
ManualDialogFragment.FRAGMENT_TAG);
+ dismiss();
+ return;
}
+
+ mDecodeAsyncTask.execute();
}
@Override
- public void onDestroyView() {
- if (mDecodeAsyncTask != null)
- mDecodeAsyncTask.cancel(true);
+ public void onDestroy() {
+ super.onDestroy();
+ mDecodeAsyncTask.cancel(true);
+ }
- super.onDestroyView();
+ @Override
+ protected void onViewInflated(View view) {
+ SurfaceView sv = (SurfaceView) view.findViewById(R.id.camera_surfaceview);
+ sv.getHolder().addCallback(this);
+ }
+
+ @Override
+ public void onClick(DialogInterface dialog, int which) {
+ if (which != AlertDialog.BUTTON_NEUTRAL)
+ return;
+
+ new ManualDialogFragment().show(getFragmentManager(),
+ ManualDialogFragment.FRAGMENT_TAG);
}
@Override
if (mCamera == null)
return;
- WindowManager wm = (WindowManager) getActivity().getSystemService(Context.WINDOW_SERVICE);
- switch (wm.getDefaultDisplay().getRotation()) {
+ int rotation = 0;
+ switch (getActivity().getWindowManager().getDefaultDisplay().getRotation()) {
case Surface.ROTATION_0:
- mCamera.setDisplayOrientation(90);
+ rotation = 0;
+ break;
+ case Surface.ROTATION_90:
+ rotation = 90;
+ break;
+ case Surface.ROTATION_180:
+ rotation = 180;
break;
case Surface.ROTATION_270:
- mCamera.setDisplayOrientation(180);
+ rotation = 270;
break;
}
+ mCamera.setDisplayOrientation((mCameraInfo.orientation - rotation + 360) % 360);
mCamera.startPreview();
}
@Override
@TargetApi(14)
public void surfaceCreated(SurfaceHolder holder) {
+ surfaceDestroyed(holder);
+
try {
- mCamera = Camera.open();
+ // Open the camera
+ mCamera = Camera.open(mCameraId);
mCamera.setPreviewDisplay(holder);
-
- // Create the decoder thread
- mDecodeAsyncTask = new DecodeAsyncTask() {
- @Override
- protected void onPostExecute(String result) {
- super.onPostExecute(result);
- if (result != null)
- ((MainActivity) getActivity()).tokenURIReceived(result);
- mDecodeAsyncTask = null;
- dismiss();
- }
- };
- mDecodeAsyncTask.execute();
mCamera.setPreviewCallback(mDecodeAsyncTask);
-
- // Set auto-focus mode
- Parameters params = mCamera.getParameters();
- List<String> modes = params.getSupportedFocusModes();
- if (modes.contains(Parameters.FOCUS_MODE_CONTINUOUS_PICTURE))
- params.setFocusMode(Parameters.FOCUS_MODE_CONTINUOUS_PICTURE);
- else if (modes.contains(Parameters.FOCUS_MODE_CONTINUOUS_VIDEO))
- params.setFocusMode(Parameters.FOCUS_MODE_CONTINUOUS_VIDEO);
- else if (modes.contains(Parameters.FOCUS_MODE_AUTO))
- params.setFocusMode(Parameters.FOCUS_MODE_AUTO);
- mCamera.setParameters(params);
} catch (Exception e) {
- SurfaceView sv = (SurfaceView) getDialog().findViewById(R.id.camera_surfaceview);
+ e.printStackTrace();
+ surfaceDestroyed(holder);
+
+ // Show error message
+ Dialog d = getDialog();
+ SurfaceView sv = (SurfaceView) d.findViewById(R.id.camera_surfaceview);
+ TextView tv = (TextView) d.findViewById(R.id.camera_textview);
sv.setVisibility(View.INVISIBLE);
- TextView tv = (TextView) getDialog().findViewById(R.id.camera_textview);
tv.setVisibility(View.VISIBLE);
- e.printStackTrace();
+ return;
}
+
+ // Set auto-focus mode
+ Parameters params = mCamera.getParameters();
+ List<String> modes = params.getSupportedFocusModes();
+ if (modes.contains(Parameters.FOCUS_MODE_CONTINUOUS_PICTURE))
+ params.setFocusMode(Parameters.FOCUS_MODE_CONTINUOUS_PICTURE);
+ else if (modes.contains(Parameters.FOCUS_MODE_CONTINUOUS_VIDEO))
+ params.setFocusMode(Parameters.FOCUS_MODE_CONTINUOUS_VIDEO);
+ else if (modes.contains(Parameters.FOCUS_MODE_AUTO))
+ params.setFocusMode(Parameters.FOCUS_MODE_AUTO);
+ mCamera.setParameters(params);
}
@Override
import org.fedorahosted.freeotp.adapters.TokenAdapter;
import android.app.Activity;
-import android.content.pm.PackageManager;
import android.database.DataSetObserver;
-import android.hardware.Camera;
-import android.hardware.Camera.CameraInfo;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
public boolean onMenuItemClick(MenuItem item) {
switch (item.getItemId()) {
case R.id.action_add:
- // Look for a back-facing camera.
- boolean backCamera = getPackageManager().hasSystemFeature(PackageManager.FEATURE_CAMERA);
-
- // If the above method doesn't return a camera, try to work around it.
- // Some buggy implementations return false above even when there is a camera.
- for (int i = Camera.getNumberOfCameras() - 1; i >= 0 && !backCamera; i--) {
- CameraInfo ci = new CameraInfo();
- Camera.getCameraInfo(i, ci);
- backCamera = ci.facing == CameraInfo.CAMERA_FACING_BACK;
- }
-
- // If the device has a camera available, try to scan for QR code
- if (backCamera) {
- new CameraDialogFragment().show(getFragmentManager(),
- CameraDialogFragment.FRAGMENT_TAG);
- } else {
- new ManualDialogFragment().show(getFragmentManager(),
- ManualDialogFragment.FRAGMENT_TAG);
- }
-
+ new CameraDialogFragment().show(getFragmentManager(),
+ CameraDialogFragment.FRAGMENT_TAG);
return true;
case R.id.action_about: