Sync sample prebuilts for mnc-docs
Synced to //developers/samples/android commit 7c1cbd61d1dea342322530bee4228d0d86bdeca1. Change-Id: I682ebe15bb1d495866dbc8d43453cd7351aef5db
This commit is contained in:
@@ -16,6 +16,7 @@
|
||||
|
||||
package com.example.android.camera2basic;
|
||||
|
||||
import android.Manifest;
|
||||
import android.app.Activity;
|
||||
import android.app.AlertDialog;
|
||||
import android.app.Dialog;
|
||||
@@ -23,6 +24,7 @@ import android.app.DialogFragment;
|
||||
import android.app.Fragment;
|
||||
import android.content.Context;
|
||||
import android.content.DialogInterface;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.content.res.Configuration;
|
||||
import android.graphics.ImageFormat;
|
||||
import android.graphics.Matrix;
|
||||
@@ -43,7 +45,8 @@ import android.media.ImageReader;
|
||||
import android.os.Bundle;
|
||||
import android.os.Handler;
|
||||
import android.os.HandlerThread;
|
||||
import android.os.Message;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.v13.app.FragmentCompat;
|
||||
import android.util.Log;
|
||||
import android.util.Size;
|
||||
import android.util.SparseIntArray;
|
||||
@@ -66,12 +69,15 @@ import java.util.List;
|
||||
import java.util.concurrent.Semaphore;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
public class Camera2BasicFragment extends Fragment implements View.OnClickListener {
|
||||
public class Camera2BasicFragment extends Fragment
|
||||
implements View.OnClickListener, FragmentCompat.OnRequestPermissionsResultCallback {
|
||||
|
||||
/**
|
||||
* Conversion from screen rotation to JPEG orientation.
|
||||
*/
|
||||
private static final SparseIntArray ORIENTATIONS = new SparseIntArray();
|
||||
private static final int REQUEST_CAMERA_PERMISSION = 1;
|
||||
private static final String FRAGMENT_DIALOG = "dialog";
|
||||
|
||||
static {
|
||||
ORIENTATIONS.append(Surface.ROTATION_0, 90);
|
||||
@@ -94,14 +100,17 @@ public class Camera2BasicFragment extends Fragment implements View.OnClickListen
|
||||
* Camera state: Waiting for the focus to be locked.
|
||||
*/
|
||||
private static final int STATE_WAITING_LOCK = 1;
|
||||
|
||||
/**
|
||||
* Camera state: Waiting for the exposure to be precapture state.
|
||||
*/
|
||||
private static final int STATE_WAITING_PRECAPTURE = 2;
|
||||
|
||||
/**
|
||||
* Camera state: Waiting for the exposure state to be something other than precapture.
|
||||
*/
|
||||
private static final int STATE_WAITING_NON_PRECAPTURE = 3;
|
||||
|
||||
/**
|
||||
* Camera state: Picture was taken.
|
||||
*/
|
||||
@@ -148,17 +157,16 @@ public class Camera2BasicFragment extends Fragment implements View.OnClickListen
|
||||
/**
|
||||
* A {@link CameraCaptureSession } for camera preview.
|
||||
*/
|
||||
|
||||
private CameraCaptureSession mCaptureSession;
|
||||
|
||||
/**
|
||||
* A reference to the opened {@link CameraDevice}.
|
||||
*/
|
||||
|
||||
private CameraDevice mCameraDevice;
|
||||
|
||||
/**
|
||||
* The {@link android.util.Size} of camera preview.
|
||||
*/
|
||||
|
||||
private Size mPreviewSize;
|
||||
|
||||
/**
|
||||
@@ -167,7 +175,7 @@ public class Camera2BasicFragment extends Fragment implements View.OnClickListen
|
||||
private final CameraDevice.StateCallback mStateCallback = new CameraDevice.StateCallback() {
|
||||
|
||||
@Override
|
||||
public void onOpened(CameraDevice cameraDevice) {
|
||||
public void onOpened(@NonNull CameraDevice cameraDevice) {
|
||||
// This method is called when the camera is opened. We start camera preview here.
|
||||
mCameraOpenCloseLock.release();
|
||||
mCameraDevice = cameraDevice;
|
||||
@@ -175,14 +183,14 @@ public class Camera2BasicFragment extends Fragment implements View.OnClickListen
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDisconnected(CameraDevice cameraDevice) {
|
||||
public void onDisconnected(@NonNull CameraDevice cameraDevice) {
|
||||
mCameraOpenCloseLock.release();
|
||||
cameraDevice.close();
|
||||
mCameraDevice = null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onError(CameraDevice cameraDevice, int error) {
|
||||
public void onError(@NonNull CameraDevice cameraDevice, int error) {
|
||||
mCameraOpenCloseLock.release();
|
||||
cameraDevice.close();
|
||||
mCameraDevice = null;
|
||||
@@ -303,43 +311,36 @@ public class Camera2BasicFragment extends Fragment implements View.OnClickListen
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCaptureProgressed(CameraCaptureSession session, CaptureRequest request,
|
||||
CaptureResult partialResult) {
|
||||
public void onCaptureProgressed(@NonNull CameraCaptureSession session,
|
||||
@NonNull CaptureRequest request,
|
||||
@NonNull CaptureResult partialResult) {
|
||||
process(partialResult);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCaptureCompleted(CameraCaptureSession session, CaptureRequest request,
|
||||
TotalCaptureResult result) {
|
||||
public void onCaptureCompleted(@NonNull CameraCaptureSession session,
|
||||
@NonNull CaptureRequest request,
|
||||
@NonNull TotalCaptureResult result) {
|
||||
process(result);
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
/**
|
||||
* A {@link Handler} for showing {@link Toast}s.
|
||||
*/
|
||||
private Handler mMessageHandler = new Handler() {
|
||||
@Override
|
||||
public void handleMessage(Message msg) {
|
||||
Activity activity = getActivity();
|
||||
if (activity != null) {
|
||||
Toast.makeText(activity, (String) msg.obj, Toast.LENGTH_SHORT).show();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Shows a {@link Toast} on the UI thread.
|
||||
*
|
||||
* @param text The message to show
|
||||
*/
|
||||
private void showToast(String text) {
|
||||
// We show a Toast by sending request message to mMessageHandler. This makes sure that the
|
||||
// Toast is shown on the UI thread.
|
||||
Message message = Message.obtain();
|
||||
message.obj = text;
|
||||
mMessageHandler.sendMessage(message);
|
||||
private void showToast(final String text) {
|
||||
final Activity activity = getActivity();
|
||||
if (activity != null) {
|
||||
activity.runOnUiThread(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
Toast.makeText(activity, text, Toast.LENGTH_SHORT).show();
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -355,7 +356,7 @@ public class Camera2BasicFragment extends Fragment implements View.OnClickListen
|
||||
*/
|
||||
private static Size chooseOptimalSize(Size[] choices, int width, int height, Size aspectRatio) {
|
||||
// Collect the supported resolutions that are at least as big as the preview Surface
|
||||
List<Size> bigEnough = new ArrayList<Size>();
|
||||
List<Size> bigEnough = new ArrayList<>();
|
||||
int w = aspectRatio.getWidth();
|
||||
int h = aspectRatio.getHeight();
|
||||
for (Size option : choices) {
|
||||
@@ -375,9 +376,7 @@ public class Camera2BasicFragment extends Fragment implements View.OnClickListen
|
||||
}
|
||||
|
||||
public static Camera2BasicFragment newInstance() {
|
||||
Camera2BasicFragment fragment = new Camera2BasicFragment();
|
||||
fragment.setRetainInstance(true);
|
||||
return fragment;
|
||||
return new Camera2BasicFragment();
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -422,6 +421,28 @@ public class Camera2BasicFragment extends Fragment implements View.OnClickListen
|
||||
super.onPause();
|
||||
}
|
||||
|
||||
private void requestCameraPermission() {
|
||||
if (FragmentCompat.shouldShowRequestPermissionRationale(this, Manifest.permission.CAMERA)) {
|
||||
new ConfirmationDialog().show(getChildFragmentManager(), FRAGMENT_DIALOG);
|
||||
} else {
|
||||
FragmentCompat.requestPermissions(this, new String[]{Manifest.permission.CAMERA},
|
||||
REQUEST_CAMERA_PERMISSION);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions,
|
||||
@NonNull int[] grantResults) {
|
||||
if (requestCode == REQUEST_CAMERA_PERMISSION) {
|
||||
if (grantResults.length != 1 || grantResults[0] != PackageManager.PERMISSION_GRANTED) {
|
||||
ErrorDialog.newInstance(getString(R.string.request_permission))
|
||||
.show(getChildFragmentManager(), FRAGMENT_DIALOG);
|
||||
}
|
||||
} else {
|
||||
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets up member variables related to camera.
|
||||
*
|
||||
@@ -437,13 +458,16 @@ public class Camera2BasicFragment extends Fragment implements View.OnClickListen
|
||||
= manager.getCameraCharacteristics(cameraId);
|
||||
|
||||
// We don't use a front facing camera in this sample.
|
||||
if (characteristics.get(CameraCharacteristics.LENS_FACING)
|
||||
== CameraCharacteristics.LENS_FACING_FRONT) {
|
||||
Integer facing = characteristics.get(CameraCharacteristics.LENS_FACING);
|
||||
if (facing != null && facing == CameraCharacteristics.LENS_FACING_FRONT) {
|
||||
continue;
|
||||
}
|
||||
|
||||
StreamConfigurationMap map = characteristics.get(
|
||||
CameraCharacteristics.SCALER_STREAM_CONFIGURATION_MAP);
|
||||
if (map == null) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// For still image captures, we use the largest available size.
|
||||
Size largest = Collections.max(
|
||||
@@ -478,7 +502,8 @@ public class Camera2BasicFragment extends Fragment implements View.OnClickListen
|
||||
} catch (NullPointerException e) {
|
||||
// Currently an NPE is thrown when the Camera2API is used but not supported on the
|
||||
// device this code runs.
|
||||
new ErrorDialog().show(getFragmentManager(), "dialog");
|
||||
ErrorDialog.newInstance(getString(R.string.camera_error))
|
||||
.show(getChildFragmentManager(), FRAGMENT_DIALOG);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -486,6 +511,11 @@ public class Camera2BasicFragment extends Fragment implements View.OnClickListen
|
||||
* Opens the camera specified by {@link Camera2BasicFragment#mCameraId}.
|
||||
*/
|
||||
private void openCamera(int width, int height) {
|
||||
if (getActivity().checkSelfPermission(Manifest.permission.CAMERA)
|
||||
!= PackageManager.PERMISSION_GRANTED) {
|
||||
requestCameraPermission();
|
||||
return;
|
||||
}
|
||||
setUpCameraOutputs(width, height);
|
||||
configureTransform(width, height);
|
||||
Activity activity = getActivity();
|
||||
@@ -574,7 +604,7 @@ public class Camera2BasicFragment extends Fragment implements View.OnClickListen
|
||||
new CameraCaptureSession.StateCallback() {
|
||||
|
||||
@Override
|
||||
public void onConfigured(CameraCaptureSession cameraCaptureSession) {
|
||||
public void onConfigured(@NonNull CameraCaptureSession cameraCaptureSession) {
|
||||
// The camera is already closed
|
||||
if (null == mCameraDevice) {
|
||||
return;
|
||||
@@ -600,7 +630,8 @@ public class Camera2BasicFragment extends Fragment implements View.OnClickListen
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onConfigureFailed(CameraCaptureSession cameraCaptureSession) {
|
||||
public void onConfigureFailed(
|
||||
@NonNull CameraCaptureSession cameraCaptureSession) {
|
||||
showToast("Failed");
|
||||
}
|
||||
}, null
|
||||
@@ -668,8 +699,8 @@ public class Camera2BasicFragment extends Fragment implements View.OnClickListen
|
||||
}
|
||||
|
||||
/**
|
||||
* Run the precapture sequence for capturing a still image. This method should be called when we
|
||||
* get a response in {@link #mCaptureCallback} from {@link #lockFocus()}.
|
||||
* Run the precapture sequence for capturing a still image. This method should be called when
|
||||
* we get a response in {@link #mCaptureCallback} from {@link #lockFocus()}.
|
||||
*/
|
||||
private void runPrecaptureSequence() {
|
||||
try {
|
||||
@@ -714,9 +745,11 @@ public class Camera2BasicFragment extends Fragment implements View.OnClickListen
|
||||
= new CameraCaptureSession.CaptureCallback() {
|
||||
|
||||
@Override
|
||||
public void onCaptureCompleted(CameraCaptureSession session, CaptureRequest request,
|
||||
TotalCaptureResult result) {
|
||||
public void onCaptureCompleted(@NonNull CameraCaptureSession session,
|
||||
@NonNull CaptureRequest request,
|
||||
@NonNull TotalCaptureResult result) {
|
||||
showToast("Saved: " + mFile);
|
||||
Log.d(TAG, mFile.toString());
|
||||
unlockFocus();
|
||||
}
|
||||
};
|
||||
@@ -729,11 +762,12 @@ public class Camera2BasicFragment extends Fragment implements View.OnClickListen
|
||||
}
|
||||
|
||||
/**
|
||||
* Unlock the focus. This method should be called when still image capture sequence is finished.
|
||||
* Unlock the focus. This method should be called when still image capture sequence is
|
||||
* finished.
|
||||
*/
|
||||
private void unlockFocus() {
|
||||
try {
|
||||
// Reset the autofucos trigger
|
||||
// Reset the auto-focus trigger
|
||||
mPreviewRequestBuilder.set(CaptureRequest.CONTROL_AF_TRIGGER,
|
||||
CameraMetadata.CONTROL_AF_TRIGGER_CANCEL);
|
||||
mPreviewRequestBuilder.set(CaptureRequest.CONTROL_AE_MODE,
|
||||
@@ -827,13 +861,26 @@ public class Camera2BasicFragment extends Fragment implements View.OnClickListen
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Shows an error message dialog.
|
||||
*/
|
||||
public static class ErrorDialog extends DialogFragment {
|
||||
|
||||
private static final String ARG_MESSAGE = "message";
|
||||
|
||||
public static ErrorDialog newInstance(String message) {
|
||||
ErrorDialog dialog = new ErrorDialog();
|
||||
Bundle args = new Bundle();
|
||||
args.putString(ARG_MESSAGE, message);
|
||||
dialog.setArguments(args);
|
||||
return dialog;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Dialog onCreateDialog(Bundle savedInstanceState) {
|
||||
final Activity activity = getActivity();
|
||||
return new AlertDialog.Builder(activity)
|
||||
.setMessage("This device doesn't support Camera2 API.")
|
||||
.setMessage(getArguments().getString(ARG_MESSAGE))
|
||||
.setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(DialogInterface dialogInterface, int i) {
|
||||
@@ -845,4 +892,36 @@ public class Camera2BasicFragment extends Fragment implements View.OnClickListen
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Shows OK/Cancel confirmation dialog about camera permission.
|
||||
*/
|
||||
public static class ConfirmationDialog extends DialogFragment {
|
||||
|
||||
@Override
|
||||
public Dialog onCreateDialog(Bundle savedInstanceState) {
|
||||
final Fragment parent = getParentFragment();
|
||||
return new AlertDialog.Builder(getActivity())
|
||||
.setMessage(R.string.request_permission)
|
||||
.setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(DialogInterface dialog, int which) {
|
||||
FragmentCompat.requestPermissions(parent,
|
||||
new String[]{Manifest.permission.CAMERA},
|
||||
REQUEST_CAMERA_PERMISSION);
|
||||
}
|
||||
})
|
||||
.setNegativeButton(android.R.string.cancel,
|
||||
new DialogInterface.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(DialogInterface dialog, int which) {
|
||||
Activity activity = parent.getActivity();
|
||||
if (activity != null) {
|
||||
activity.finish();
|
||||
}
|
||||
}
|
||||
})
|
||||
.create();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user