Commit 2734291b authored by Giles Payne's avatar Giles Payne

Add CameraActivity utility class to automate Camera permission request handling

parent f6ec0cd8
package org.opencv.android;
import android.annotation.TargetApi;
import android.app.Activity;
import android.content.Context;
import android.content.pm.PackageManager;
import android.os.Build;
import android.util.AttributeSet;
import android.view.View;
import java.util.ArrayList;
import java.util.List;
import static android.Manifest.permission.CAMERA;
public class CameraActivity extends Activity {
private static final int CAMERA_PERMISSION_REQUEST_CODE = 200;
protected List<? extends CameraBridgeViewBase> getCameraViewList() {
return new ArrayList<CameraBridgeViewBase>();
}
protected void onCameraPermissionGranted() {
List<? extends CameraBridgeViewBase> cameraViews = getCameraViewList();
if (cameraViews == null) {
return;
}
for (CameraBridgeViewBase cameraBridgeViewBase: cameraViews) {
if (cameraBridgeViewBase != null) {
cameraBridgeViewBase.setCameraPermissionGranted();
}
}
}
@Override
protected void onStart() {
super.onStart();
boolean havePermission = true;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
if (checkSelfPermission(CAMERA) != PackageManager.PERMISSION_GRANTED) {
requestPermissions(new String[]{CAMERA}, CAMERA_PERMISSION_REQUEST_CODE);
havePermission = false;
}
}
if (havePermission) {
onCameraPermissionGranted();
}
}
@Override
@TargetApi(Build.VERSION_CODES.M)
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
if (requestCode == CAMERA_PERMISSION_REQUEST_CODE && grantResults.length > 0
&& grantResults[0] == PackageManager.PERMISSION_GRANTED) {
onCameraPermissionGranted();
}
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
}
}
......@@ -48,6 +48,7 @@ public abstract class CameraBridgeViewBase extends SurfaceView implements Surfac
protected int mPreviewFormat = RGBA;
protected int mCameraIndex = CAMERA_ID_ANY;
protected boolean mEnabled;
protected boolean mCameraPermissionGranted = false;
protected FpsMeter mFpsMeter = null;
public static final int CAMERA_ID_ANY = -1;
......@@ -219,9 +220,24 @@ public abstract class CameraBridgeViewBase extends SurfaceView implements Surfac
}
}
/**
* This method is provided for clients, so they can signal camera permission has been granted.
* The actual onCameraViewStarted callback will be delivered only after setCameraPermissionGranted
* and enableView have been called and surface is available
*/
public void setCameraPermissionGranted() {
synchronized(mSyncObject) {
mCameraPermissionGranted = true;
checkCurrentState();
}
}
/**
* This method is provided for clients, so they can enable the camera connection.
* The actual onCameraViewStarted callback will be delivered only after both this method is called and surface is available
* The actual onCameraViewStarted callback will be delivered only after setCameraPermissionGranted
* and enableView have been called and surface is available
*/
public void enableView() {
synchronized(mSyncObject) {
......@@ -300,7 +316,7 @@ public abstract class CameraBridgeViewBase extends SurfaceView implements Surfac
Log.d(TAG, "call checkCurrentState");
int targetState;
if (mEnabled && mSurfaceExist && getVisibility() == VISIBLE) {
if (mEnabled && mCameraPermissionGranted && mSurfaceExist && getVisibility() == VISIBLE) {
targetState = STARTED;
} else {
targetState = STOPPED;
......
package org.opencv.samples.puzzle15;
import org.opencv.android.BaseLoaderCallback;
import org.opencv.android.CameraActivity;
import org.opencv.android.LoaderCallbackInterface;
import org.opencv.android.OpenCVLoader;
import org.opencv.core.Mat;
......@@ -9,7 +10,6 @@ import org.opencv.android.CameraBridgeViewBase.CvCameraViewListener;
import org.opencv.android.JavaCameraView;
import android.os.Bundle;
import android.app.Activity;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
......@@ -17,7 +17,10 @@ import android.view.MotionEvent;
import android.view.View;
import android.view.WindowManager;
public class Puzzle15Activity extends Activity implements CvCameraViewListener, View.OnTouchListener {
import java.util.Collections;
import java.util.List;
public class Puzzle15Activity extends CameraActivity implements CvCameraViewListener, View.OnTouchListener {
private static final String TAG = "Sample::Puzzle15::Activity";
......@@ -86,6 +89,11 @@ public class Puzzle15Activity extends Activity implements CvCameraViewListener,
}
}
@Override
protected List<? extends CameraBridgeViewBase> getCameraViewList() {
return Collections.singletonList(mOpenCvCameraView);
}
public void onDestroy() {
super.onDestroy();
if (mOpenCvCameraView != null)
......
......@@ -14,6 +14,7 @@
package org.opencv.samples.cameracalibration;
import org.opencv.android.BaseLoaderCallback;
import org.opencv.android.CameraActivity;
import org.opencv.android.CameraBridgeViewBase;
import org.opencv.android.CameraBridgeViewBase.CvCameraViewFrame;
import org.opencv.android.CameraBridgeViewBase.CvCameraViewListener2;
......@@ -21,7 +22,6 @@ import org.opencv.android.LoaderCallbackInterface;
import org.opencv.android.OpenCVLoader;
import org.opencv.core.Mat;
import android.app.Activity;
import android.app.ProgressDialog;
import android.content.res.Resources;
import android.os.AsyncTask;
......@@ -36,12 +36,16 @@ import android.view.View.OnTouchListener;
import android.view.WindowManager;
import android.widget.Toast;
public class CameraCalibrationActivity extends Activity implements CvCameraViewListener2, OnTouchListener {
import java.util.Collections;
import java.util.List;
public class CameraCalibrationActivity extends CameraActivity implements CvCameraViewListener2, OnTouchListener {
private static final String TAG = "OCVSample::Activity";
private CameraBridgeViewBase mOpenCvCameraView;
private CameraCalibrator mCalibrator;
private OnCameraFrameRender mOnCameraFrameRender;
private Menu mMenu;
private int mWidth;
private int mHeight;
......@@ -101,6 +105,11 @@ public class CameraCalibrationActivity extends Activity implements CvCameraViewL
}
}
@Override
protected List<? extends CameraBridgeViewBase> getCameraViewList() {
return Collections.singletonList(mOpenCvCameraView);
}
public void onDestroy() {
super.onDestroy();
if (mOpenCvCameraView != null)
......@@ -111,7 +120,7 @@ public class CameraCalibrationActivity extends Activity implements CvCameraViewL
public boolean onCreateOptionsMenu(Menu menu) {
super.onCreateOptionsMenu(menu);
getMenuInflater().inflate(R.menu.calibration, menu);
mMenu = menu;
return true;
}
......@@ -119,9 +128,9 @@ public class CameraCalibrationActivity extends Activity implements CvCameraViewL
public boolean onPrepareOptionsMenu (Menu menu) {
super.onPrepareOptionsMenu(menu);
menu.findItem(R.id.preview_mode).setEnabled(true);
if (!mCalibrator.isCalibrated())
if (mCalibrator != null && !mCalibrator.isCalibrated()) {
menu.findItem(R.id.preview_mode).setEnabled(false);
}
return true;
}
......@@ -199,6 +208,10 @@ public class CameraCalibrationActivity extends Activity implements CvCameraViewL
mCalibrator = new CameraCalibrator(mWidth, mHeight);
if (CalibrationResult.tryLoad(this, mCalibrator.getCameraMatrix(), mCalibrator.getDistortionCoefficients())) {
mCalibrator.setCalibrated();
} else {
if (mMenu != null && !mCalibrator.isCalibrated()) {
mMenu.findItem(R.id.preview_mode).setEnabled(false);
}
}
mOnCameraFrameRender = new OnCameraFrameRender(new CalibrationFrameRender(mCalibrator));
......
package org.opencv.samples.colorblobdetect;
import java.util.Collections;
import java.util.List;
import org.opencv.android.BaseLoaderCallback;
import org.opencv.android.CameraActivity;
import org.opencv.android.CameraBridgeViewBase.CvCameraViewFrame;
import org.opencv.android.LoaderCallbackInterface;
import org.opencv.android.OpenCVLoader;
......@@ -27,7 +29,7 @@ import android.view.WindowManager;
import android.view.View.OnTouchListener;
import android.view.SurfaceView;
public class ColorBlobDetectionActivity extends Activity implements OnTouchListener, CvCameraViewListener2 {
public class ColorBlobDetectionActivity extends CameraActivity implements OnTouchListener, CvCameraViewListener2 {
private static final String TAG = "OCVSample::Activity";
private boolean mIsColorSelected = false;
......@@ -99,6 +101,11 @@ public class ColorBlobDetectionActivity extends Activity implements OnTouchListe
}
}
@Override
protected List<? extends CameraBridgeViewBase> getCameraViewList() {
return Collections.singletonList(mOpenCvCameraView);
}
public void onDestroy() {
super.onDestroy();
if (mOpenCvCameraView != null)
......
......@@ -4,8 +4,11 @@ import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.Collections;
import java.util.List;
import org.opencv.android.BaseLoaderCallback;
import org.opencv.android.CameraActivity;
import org.opencv.android.CameraBridgeViewBase.CvCameraViewFrame;
import org.opencv.android.LoaderCallbackInterface;
import org.opencv.android.OpenCVLoader;
......@@ -28,7 +31,7 @@ import android.view.Menu;
import android.view.MenuItem;
import android.view.WindowManager;
public class FdActivity extends Activity implements CvCameraViewListener2 {
public class FdActivity extends CameraActivity implements CvCameraViewListener2 {
private static final String TAG = "OCVSample::Activity";
private static final Scalar FACE_RECT_COLOR = new Scalar(0, 255, 0, 255);
......@@ -150,6 +153,11 @@ public class FdActivity extends Activity implements CvCameraViewListener2 {
}
}
@Override
protected List<? extends CameraBridgeViewBase> getCameraViewList() {
return Collections.singletonList(mOpenCvCameraView);
}
public void onDestroy() {
super.onDestroy();
mOpenCvCameraView.disableView();
......
package org.opencv.samples.imagemanipulations;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import org.opencv.android.BaseLoaderCallback;
import org.opencv.android.CameraActivity;
import org.opencv.android.CameraBridgeViewBase.CvCameraViewFrame;
import org.opencv.android.LoaderCallbackInterface;
import org.opencv.android.OpenCVLoader;
......@@ -18,14 +21,13 @@ import org.opencv.android.CameraBridgeViewBase;
import org.opencv.android.CameraBridgeViewBase.CvCameraViewListener2;
import org.opencv.imgproc.Imgproc;
import android.app.Activity;
import android.os.Bundle;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import android.view.WindowManager;
public class ImageManipulationsActivity extends Activity implements CvCameraViewListener2 {
public class ImageManipulationsActivity extends CameraActivity implements CvCameraViewListener2 {
private static final String TAG = "OCVSample::Activity";
public static final int VIEW_MODE_RGBA = 0;
......@@ -121,6 +123,11 @@ public class ImageManipulationsActivity extends Activity implements CvCameraView
}
}
@Override
protected List<? extends CameraBridgeViewBase> getCameraViewList() {
return Collections.singletonList(mOpenCvCameraView);
}
public void onDestroy() {
super.onDestroy();
if (mOpenCvCameraView != null)
......
package org.opencv.samples.tutorial1;
import org.opencv.android.BaseLoaderCallback;
import org.opencv.android.CameraActivity;
import org.opencv.android.CameraBridgeViewBase.CvCameraViewFrame;
import org.opencv.android.LoaderCallbackInterface;
import org.opencv.android.OpenCVLoader;
......@@ -8,16 +9,16 @@ import org.opencv.core.Mat;
import org.opencv.android.CameraBridgeViewBase;
import org.opencv.android.CameraBridgeViewBase.CvCameraViewListener2;
import android.app.Activity;
import android.os.Bundle;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import android.view.SurfaceView;
import android.view.WindowManager;
import android.widget.Toast;
public class Tutorial1Activity extends Activity implements CvCameraViewListener2 {
import java.util.Collections;
import java.util.List;
public class Tutorial1Activity extends CameraActivity implements CvCameraViewListener2 {
private static final String TAG = "OCVSample::Activity";
private CameraBridgeViewBase mOpenCvCameraView;
......@@ -82,6 +83,11 @@ public class Tutorial1Activity extends Activity implements CvCameraViewListener2
}
}
@Override
protected List<? extends CameraBridgeViewBase> getCameraViewList() {
return Collections.singletonList(mOpenCvCameraView);
}
public void onDestroy() {
super.onDestroy();
if (mOpenCvCameraView != null)
......
package org.opencv.samples.tutorial2;
import org.opencv.android.BaseLoaderCallback;
import org.opencv.android.CameraActivity;
import org.opencv.android.CameraBridgeViewBase.CvCameraViewFrame;
import org.opencv.android.LoaderCallbackInterface;
import org.opencv.android.OpenCVLoader;
......@@ -10,14 +11,16 @@ import org.opencv.android.CameraBridgeViewBase;
import org.opencv.android.CameraBridgeViewBase.CvCameraViewListener2;
import org.opencv.imgproc.Imgproc;
import android.app.Activity;
import android.os.Bundle;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import android.view.WindowManager;
public class Tutorial2Activity extends Activity implements CvCameraViewListener2 {
import java.util.Collections;
import java.util.List;
public class Tutorial2Activity extends CameraActivity implements CvCameraViewListener2 {
private static final String TAG = "OCVSample::Activity";
private static final int VIEW_MODE_RGBA = 0;
......@@ -107,6 +110,11 @@ public class Tutorial2Activity extends Activity implements CvCameraViewListener2
}
}
@Override
protected List<? extends CameraBridgeViewBase> getCameraViewList() {
return Collections.singletonList(mOpenCvCameraView);
}
public void onDestroy() {
super.onDestroy();
if (mOpenCvCameraView != null)
......
package org.opencv.samples.tutorial3;
import java.text.SimpleDateFormat;
import java.util.Collections;
import java.util.Date;
import java.util.List;
import java.util.ListIterator;
import org.opencv.android.BaseLoaderCallback;
import org.opencv.android.CameraActivity;
import org.opencv.android.CameraBridgeViewBase;
import org.opencv.android.CameraBridgeViewBase.CvCameraViewFrame;
import org.opencv.android.LoaderCallbackInterface;
import org.opencv.android.OpenCVLoader;
......@@ -13,7 +16,6 @@ import org.opencv.core.Mat;
import org.opencv.android.CameraBridgeViewBase.CvCameraViewListener2;
import android.annotation.SuppressLint;
import android.app.Activity;
import android.hardware.Camera.Size;
import android.os.Bundle;
import android.os.Environment;
......@@ -28,11 +30,14 @@ import android.view.View.OnTouchListener;
import android.view.WindowManager;
import android.widget.Toast;
public class Tutorial3Activity extends Activity implements CvCameraViewListener2, OnTouchListener {
public class Tutorial3Activity extends CameraActivity implements CvCameraViewListener2, OnTouchListener {
private static final String TAG = "OCVSample::Activity";
private Tutorial3View mOpenCvCameraView;
private List<Size> mResolutionList;
private Menu mMenu;
private boolean mCameraStarted = false;
private boolean mMenuItemsCreated = false;
private MenuItem[] mEffectMenuItems;
private SubMenu mColorEffectsMenu;
private MenuItem[] mResolutionMenuItems;
......@@ -97,13 +102,21 @@ public class Tutorial3Activity extends Activity implements CvCameraViewListener2
}
}
@Override
protected List<? extends CameraBridgeViewBase> getCameraViewList() {
return Collections.singletonList(mOpenCvCameraView);
}
public void onDestroy() {
super.onDestroy();
if (mOpenCvCameraView != null)
mOpenCvCameraView.disableView();
}
@Override
public void onCameraViewStarted(int width, int height) {
mCameraStarted = true;
setupMenuItems();
}
public void onCameraViewStopped() {
......@@ -115,38 +128,43 @@ public class Tutorial3Activity extends Activity implements CvCameraViewListener2
@Override
public boolean onCreateOptionsMenu(Menu menu) {
mMenu = menu;
setupMenuItems();
return true;
}
private void setupMenuItems() {
if (mMenu == null || !mCameraStarted || mMenuItemsCreated) {
return;
}
List<String> effects = mOpenCvCameraView.getEffectList();
if (effects == null) {
Log.e(TAG, "Color effects are not supported by device!");
return true;
return;
}
mColorEffectsMenu = menu.addSubMenu("Color Effect");
mColorEffectsMenu = mMenu.addSubMenu("Color Effect");
mEffectMenuItems = new MenuItem[effects.size()];
int idx = 0;
ListIterator<String> effectItr = effects.listIterator();
while(effectItr.hasNext()) {
String element = effectItr.next();
mEffectMenuItems[idx] = mColorEffectsMenu.add(1, idx, Menu.NONE, element);
idx++;
for (String effect: effects) {
mEffectMenuItems[idx] = mColorEffectsMenu.add(1, idx, Menu.NONE, effect);
idx++;
}
mResolutionMenu = menu.addSubMenu("Resolution");
mResolutionMenu = mMenu.addSubMenu("Resolution");
mResolutionList = mOpenCvCameraView.getResolutionList();
mResolutionMenuItems = new MenuItem[mResolutionList.size()];
ListIterator<Size> resolutionItr = mResolutionList.listIterator();
idx = 0;
while(resolutionItr.hasNext()) {
Size element = resolutionItr.next();
for (Size resolution: mResolutionList) {
mResolutionMenuItems[idx] = mResolutionMenu.add(2, idx, Menu.NONE,
Integer.valueOf(element.width).toString() + "x" + Integer.valueOf(element.height).toString());
Integer.valueOf(resolution.width).toString() + "x" + Integer.valueOf(resolution.height).toString());
idx++;
}
return true;
}
mMenuItemsCreated = true;
}
public boolean onOptionsItemSelected(MenuItem item) {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment