├── .gitignore
├── .google
└── packaging.yaml
├── .idea
└── runConfigurations.xml
├── Application
├── build.gradle
├── src
│ └── main
│ │ ├── AndroidManifest.xml
│ │ ├── java
│ │ └── com
│ │ │ └── example
│ │ │ └── android
│ │ │ └── camera2basic
│ │ │ ├── AutoFitTextureView.java
│ │ │ ├── Camera2BasicFragment.java
│ │ │ ├── CameraActivity.java
│ │ │ └── OverlayView.java
│ │ └── res
│ │ ├── drawable-hdpi
│ │ ├── ic_action_info.png
│ │ ├── ic_launcher.png
│ │ └── tile.9.png
│ │ ├── drawable-mdpi
│ │ ├── ic_action_info.png
│ │ └── ic_launcher.png
│ │ ├── drawable-xhdpi
│ │ ├── ic_action_info.png
│ │ └── ic_launcher.png
│ │ ├── drawable-xxhdpi
│ │ ├── ic_action_info.png
│ │ └── ic_launcher.png
│ │ ├── layout-land
│ │ └── fragment_camera2_basic.xml
│ │ ├── layout
│ │ ├── activity_camera.xml
│ │ └── fragment_camera2_basic.xml
│ │ ├── values-sw600dp
│ │ ├── template-dimens.xml
│ │ └── template-styles.xml
│ │ ├── values-v11
│ │ └── template-styles.xml
│ │ ├── values-v21
│ │ ├── base-colors.xml
│ │ └── base-template-styles.xml
│ │ └── values
│ │ ├── base-strings.xml
│ │ ├── colors.xml
│ │ ├── strings.xml
│ │ ├── styles.xml
│ │ ├── template-dimens.xml
│ │ └── template-styles.xml
└── tests
│ ├── AndroidManifest.xml
│ └── src
│ └── com
│ └── example
│ └── android
│ └── camera2basic
│ └── tests
│ └── SampleTests.java
├── CONTRIB.md
├── CONTRIBUTING.md
├── LICENSE
├── README.md
├── build.gradle
├── gradle
└── wrapper
│ ├── gradle-wrapper.jar
│ └── gradle-wrapper.properties
├── gradlew
├── gradlew.bat
├── packaging.yaml
└── settings.gradle
/.gitignore:
--------------------------------------------------------------------------------
1 | # Created by https://www.gitignore.io/api/osx,windows,android,androidstudio
2 |
3 | ### Android ###
4 | # Built application files
5 | *.apk
6 | *.ap_
7 |
8 | # Files for the ART/Dalvik VM
9 | *.dex
10 |
11 | # Java class files
12 | *.class
13 |
14 | # Generated files
15 | bin/
16 | gen/
17 | out/
18 |
19 | # Gradle files
20 | .gradle/
21 | build/
22 |
23 | # Local configuration file (sdk path, etc)
24 | local.properties
25 |
26 | # Proguard folder generated by Eclipse
27 | proguard/
28 |
29 | # Log Files
30 | *.log
31 |
32 | # Android Studio Navigation editor temp files
33 | .navigation/
34 |
35 | # Android Studio captures folder
36 | captures/
37 |
38 | # Intellij
39 | *.iml
40 | .idea/workspace.xml
41 | .idea/tasks.xml
42 | .idea/gradle.xml
43 | .idea/dictionaries
44 | .idea/libraries
45 |
46 | # External native build folder generated in Android Studio 2.2 and later
47 | .externalNativeBuild
48 |
49 | # Freeline
50 | freeline.py
51 | freeline/
52 | freeline_project_description.json
53 |
54 | ### Android Patch ###
55 | gen-external-apklibs
56 |
57 | ### AndroidStudio ###
58 | # Covers files to be ignored for android development using Android Studio.
59 |
60 | # Built application files
61 |
62 | # Files for the ART/Dalvik VM
63 |
64 | # Java class files
65 |
66 | # Generated files
67 |
68 | # Gradle files
69 | .gradle
70 |
71 | # Signing files
72 | .signing/
73 |
74 | # Local configuration file (sdk path, etc)
75 |
76 | # Proguard folder generated by Eclipse
77 |
78 | # Log Files
79 |
80 | # Android Studio
81 | /*/build/
82 | /*/local.properties
83 | /*/out
84 | /*/*/build
85 | /*/*/production
86 | *.ipr
87 | *~
88 | *.swp
89 |
90 | # Android Patch
91 |
92 | # External native build folder generated in Android Studio 2.2 and later
93 |
94 | # NDK
95 | obj/
96 |
97 | # IntelliJ IDEA
98 | *.iws
99 | /out/
100 |
101 | # User-specific configurations
102 | .idea/libraries/
103 | .idea/.name
104 | .idea/compiler.xml
105 | .idea/copyright/profiles_settings.xml
106 | .idea/encodings.xml
107 | .idea/misc.xml
108 | .idea/modules.xml
109 | .idea/scopes/scope_settings.xml
110 | .idea/vcs.xml
111 | .idea/jsLibraryMappings.xml
112 | .idea/datasources.xml
113 | .idea/dataSources.ids
114 | .idea/sqlDataSources.xml
115 | .idea/dynamic.xml
116 | .idea/uiDesigner.xml
117 |
118 | # OS-specific files
119 | .DS_Store
120 | .DS_Store?
121 | ._*
122 | .Spotlight-V100
123 | .Trashes
124 | ehthumbs.db
125 | Thumbs.db
126 |
127 | # Legacy Eclipse project files
128 | .classpath
129 | .project
130 | .cproject
131 | .settings/
132 |
133 | # Mobile Tools for Java (J2ME)
134 | .mtj.tmp/
135 |
136 | # Package Files #
137 | *.war
138 | *.ear
139 |
140 | # virtual machine crash logs (Reference: http://www.java.com/en/download/help/error_hotspot.xml)
141 | hs_err_pid*
142 |
143 | ## Plugin-specific files:
144 |
145 | # mpeltonen/sbt-idea plugin
146 | .idea_modules/
147 |
148 | # JIRA plugin
149 | atlassian-ide-plugin.xml
150 |
151 | # Mongo Explorer plugin
152 | .idea/mongoSettings.xml
153 |
154 | # Crashlytics plugin (for Android Studio and IntelliJ)
155 | com_crashlytics_export_strings.xml
156 | crashlytics.properties
157 | crashlytics-build.properties
158 | fabric.properties
159 |
160 | ### AndroidStudio Patch ###
161 |
162 | !/gradle/wrapper/gradle-wrapper.jar
163 |
164 | ### OSX ###
165 | *.DS_Store
166 | .AppleDouble
167 | .LSOverride
168 |
169 | # Icon must end with two \r
170 | Icon
171 |
172 | # Thumbnails
173 |
174 | # Files that might appear in the root of a volume
175 | .DocumentRevisions-V100
176 | .fseventsd
177 | .TemporaryItems
178 | .VolumeIcon.icns
179 | .com.apple.timemachine.donotpresent
180 |
181 | # Directories potentially created on remote AFP share
182 | .AppleDB
183 | .AppleDesktop
184 | Network Trash Folder
185 | Temporary Items
186 | .apdisk
187 |
188 | ### Windows ###
189 | # Windows thumbnail cache files
190 | ehthumbs_vista.db
191 |
192 | # Folder config file
193 | Desktop.ini
194 |
195 | # Recycle Bin used on file shares
196 | $RECYCLE.BIN/
197 |
198 | # Windows Installer files
199 | *.cab
200 | *.msi
201 | *.msm
202 | *.msp
203 |
204 | # Windows shortcuts
205 | *.lnk
206 |
207 |
208 | # End of https://www.gitignore.io/api/osx,windows,android,androidstudio
209 |
--------------------------------------------------------------------------------
/.google/packaging.yaml:
--------------------------------------------------------------------------------
1 |
2 | # GOOGLE SAMPLE PACKAGING DATA
3 | #
4 | # This file is used by Google as part of our samples packaging process.
5 | # End users may safely ignore this file. It has no relevance to other systems.
6 | ---
7 | status: PUBLISHED
8 | technologies: [Android]
9 | categories: [Media, Camera, Camera2]
10 | languages: [Java]
11 | solutions: [Mobile]
12 | github: android-Camera2Basic
13 | level: INTERMEDIATE
14 | icon: screenshots/icon-web.png
15 | apiRefs:
16 | - android:android.hardware.camera2.CameraManager
17 | - android:android.hardware.camera2.CameraDevice
18 | - android:android.hardware.camera2.CameraCharacteristics
19 | - android:android.hardware.camera2.CameraCaptureSession
20 | - android:android.hardware.camera2.CaptureRequest
21 | - android:android.hardware.camera2.CaptureResult
22 | - android:android.view.TextureView
23 | license: apache2
24 |
--------------------------------------------------------------------------------
/.idea/runConfigurations.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
11 |
12 |
--------------------------------------------------------------------------------
/Application/build.gradle:
--------------------------------------------------------------------------------
1 |
2 | buildscript {
3 | repositories {
4 | jcenter()
5 | google()
6 | }
7 |
8 | dependencies {
9 | classpath 'com.android.tools.build:gradle:3.0.1'
10 | }
11 | }
12 |
13 | apply plugin: 'com.android.application'
14 |
15 | repositories {
16 | jcenter()
17 | google()
18 | }
19 |
20 | dependencies {
21 | compile "com.android.support:support-v4:27.0.2"
22 | compile "com.android.support:support-v13:27.0.2"
23 | compile "com.android.support:cardview-v7:27.0.2"
24 | compile 'com.android.support:appcompat-v7:27.0.2'
25 | }
26 |
27 | // The sample build uses multiple directories to
28 | // keep boilerplate and common code separate from
29 | // the main sample code.
30 | List dirs = [
31 | 'main', // main sample code; look here for the interesting stuff.
32 | 'common', // components that are reused by multiple samples
33 | 'template'] // boilerplate code that is generated by the sample template process
34 |
35 | android {
36 | compileSdkVersion 27
37 | buildToolsVersion "27.0.3"
38 |
39 | defaultConfig {
40 | minSdkVersion 21
41 | targetSdkVersion 27
42 | }
43 |
44 | compileOptions {
45 | sourceCompatibility JavaVersion.VERSION_1_7
46 | targetCompatibility JavaVersion.VERSION_1_7
47 | }
48 |
49 | sourceSets {
50 | main {
51 | dirs.each { dir ->
52 | java.srcDirs "src/${dir}/java"
53 | res.srcDirs "src/${dir}/res"
54 | }
55 | }
56 | androidTest.setRoot('tests')
57 | androidTest.java.srcDirs = ['tests/src']
58 |
59 | }
60 |
61 | }
62 |
--------------------------------------------------------------------------------
/Application/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
17 |
18 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
30 |
31 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
--------------------------------------------------------------------------------
/Application/src/main/java/com/example/android/camera2basic/AutoFitTextureView.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2014 The Android Open Source Project
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package com.example.android.camera2basic;
18 |
19 | import android.content.Context;
20 | import android.util.AttributeSet;
21 | import android.view.TextureView;
22 |
23 | /**
24 | * A {@link TextureView} that can be adjusted to a specified aspect ratio.
25 | */
26 | public class AutoFitTextureView extends TextureView {
27 |
28 | private int mRatioWidth = 0;
29 | private int mRatioHeight = 0;
30 |
31 | public AutoFitTextureView(Context context) {
32 | this(context, null);
33 | }
34 |
35 | public AutoFitTextureView(Context context, AttributeSet attrs) {
36 | this(context, attrs, 0);
37 | }
38 |
39 | public AutoFitTextureView(Context context, AttributeSet attrs, int defStyle) {
40 | super(context, attrs, defStyle);
41 | }
42 |
43 | /**
44 | * Sets the aspect ratio for this view. The size of the view will be measured based on the ratio
45 | * calculated from the parameters. Note that the actual sizes of parameters don't matter, that
46 | * is, calling setAspectRatio(2, 3) and setAspectRatio(4, 6) make the same result.
47 | *
48 | * @param width Relative horizontal size
49 | * @param height Relative vertical size
50 | */
51 | public void setAspectRatio(int width, int height) {
52 | if (width < 0 || height < 0) {
53 | throw new IllegalArgumentException("Size cannot be negative.");
54 | }
55 | mRatioWidth = width;
56 | mRatioHeight = height;
57 | requestLayout();
58 | }
59 |
60 | @Override
61 | protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
62 | super.onMeasure(widthMeasureSpec, heightMeasureSpec);
63 | int width = MeasureSpec.getSize(widthMeasureSpec);
64 | int height = MeasureSpec.getSize(heightMeasureSpec);
65 | if (0 == mRatioWidth || 0 == mRatioHeight) {
66 | setMeasuredDimension(width, height);
67 | } else {
68 | if (width < height * mRatioWidth / mRatioHeight) {
69 | setMeasuredDimension(width, width * mRatioHeight / mRatioWidth);
70 | } else {
71 | setMeasuredDimension(height * mRatioWidth / mRatioHeight, height);
72 | }
73 | }
74 | }
75 |
76 | }
77 |
--------------------------------------------------------------------------------
/Application/src/main/java/com/example/android/camera2basic/Camera2BasicFragment.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2014 The Android Open Source Project
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package com.example.android.camera2basic;
18 |
19 | import android.Manifest;
20 | import android.app.Activity;
21 | import android.app.AlertDialog;
22 | import android.app.Dialog;
23 | import android.app.DialogFragment;
24 | import android.app.Fragment;
25 | import android.content.Context;
26 | import android.content.DialogInterface;
27 | import android.content.pm.PackageManager;
28 | import android.content.res.Configuration;
29 | import android.graphics.ImageFormat;
30 | import android.graphics.Matrix;
31 | import android.graphics.Point;
32 | import android.graphics.Rect;
33 | import android.graphics.RectF;
34 | import android.graphics.SurfaceTexture;
35 | import android.hardware.camera2.CameraAccessException;
36 | import android.hardware.camera2.CameraCaptureSession;
37 | import android.hardware.camera2.CameraCharacteristics;
38 | import android.hardware.camera2.CameraDevice;
39 | import android.hardware.camera2.CameraManager;
40 | import android.hardware.camera2.CameraMetadata;
41 | import android.hardware.camera2.CaptureRequest;
42 | import android.hardware.camera2.CaptureResult;
43 | import android.hardware.camera2.TotalCaptureResult;
44 | import android.hardware.camera2.params.Face;
45 | import android.hardware.camera2.params.StreamConfigurationMap;
46 | import android.media.Image;
47 | import android.media.ImageReader;
48 | import android.os.Bundle;
49 | import android.os.Handler;
50 | import android.os.HandlerThread;
51 | import android.support.annotation.NonNull;
52 | import android.support.v13.app.FragmentCompat;
53 | import android.support.v4.content.ContextCompat;
54 | import android.util.Log;
55 | import android.util.Size;
56 | import android.util.SparseIntArray;
57 | import android.view.LayoutInflater;
58 | import android.view.Surface;
59 | import android.view.TextureView;
60 | import android.view.View;
61 | import android.view.ViewGroup;
62 | import android.widget.Toast;
63 |
64 | import java.io.File;
65 | import java.io.FileOutputStream;
66 | import java.io.IOException;
67 | import java.nio.ByteBuffer;
68 | import java.util.ArrayList;
69 | import java.util.Arrays;
70 | import java.util.Collections;
71 | import java.util.Comparator;
72 | import java.util.List;
73 | import java.util.concurrent.Semaphore;
74 | import java.util.concurrent.TimeUnit;
75 |
76 | public class Camera2BasicFragment extends Fragment
77 | implements View.OnClickListener, FragmentCompat.OnRequestPermissionsResultCallback {
78 |
79 | /**
80 | * Conversion from screen rotation to JPEG orientation.
81 | */
82 | private static final SparseIntArray ORIENTATIONS = new SparseIntArray();
83 | private static final int REQUEST_CAMERA_PERMISSION = 1;
84 | private static final String FRAGMENT_DIALOG = "dialog";
85 |
86 | static {
87 | ORIENTATIONS.append(Surface.ROTATION_0, 90);
88 | ORIENTATIONS.append(Surface.ROTATION_90, 0);
89 | ORIENTATIONS.append(Surface.ROTATION_180, 270);
90 | ORIENTATIONS.append(Surface.ROTATION_270, 180);
91 | }
92 |
93 | /**
94 | * Tag for the {@link Log}.
95 | */
96 | private static final String TAG = "Camera2BasicFragment";
97 |
98 | /**
99 | * Camera state: Showing camera preview.
100 | */
101 | private static final int STATE_PREVIEW = 0;
102 |
103 | /**
104 | * Camera state: Waiting for the focus to be locked.
105 | */
106 | private static final int STATE_WAITING_LOCK = 1;
107 |
108 | /**
109 | * Camera state: Waiting for the exposure to be precapture state.
110 | */
111 | private static final int STATE_WAITING_PRECAPTURE = 2;
112 |
113 | /**
114 | * Camera state: Waiting for the exposure state to be something other than precapture.
115 | */
116 | private static final int STATE_WAITING_NON_PRECAPTURE = 3;
117 |
118 | /**
119 | * Camera state: Picture was taken.
120 | */
121 | private static final int STATE_PICTURE_TAKEN = 4;
122 |
123 | /**
124 | * Max preview width that is guaranteed by Camera2 API
125 | */
126 | private static final int MAX_PREVIEW_WIDTH = 1920;
127 |
128 | /**
129 | * Max preview height that is guaranteed by Camera2 API
130 | */
131 | private static final int MAX_PREVIEW_HEIGHT = 1080;
132 |
133 | /**
134 | * {@link TextureView.SurfaceTextureListener} handles several lifecycle events on a
135 | * {@link TextureView}.
136 | */
137 | private final TextureView.SurfaceTextureListener mSurfaceTextureListener
138 | = new TextureView.SurfaceTextureListener() {
139 |
140 | @Override
141 | public void onSurfaceTextureAvailable(SurfaceTexture texture, int width, int height) {
142 | openCamera(width, height);
143 | }
144 |
145 | @Override
146 | public void onSurfaceTextureSizeChanged(SurfaceTexture texture, int width, int height) {
147 | configureTransform(width, height);
148 | }
149 |
150 | @Override
151 | public boolean onSurfaceTextureDestroyed(SurfaceTexture texture) {
152 | return true;
153 | }
154 |
155 | @Override
156 | public void onSurfaceTextureUpdated(SurfaceTexture texture) {
157 | }
158 |
159 | };
160 |
161 | /**
162 | * ID of the current {@link CameraDevice}.
163 | */
164 | private String mCameraId;
165 |
166 | /**
167 | * An {@link AutoFitTextureView} for camera preview.
168 | */
169 | private AutoFitTextureView mTextureView;
170 | private OverlayView mOverlayView;
171 | private Matrix mFaceDetectionMatrix;
172 | private CameraManager mCameraManager;
173 | private CameraCharacteristics mCameraCharacteristics;
174 | private boolean mSwappedDimensions;
175 |
176 | /**
177 | * A {@link CameraCaptureSession } for camera preview.
178 | */
179 | private CameraCaptureSession mCaptureSession;
180 |
181 | /**
182 | * A reference to the opened {@link CameraDevice}.
183 | */
184 | private CameraDevice mCameraDevice;
185 |
186 | /**
187 | * The {@link android.util.Size} of camera preview.
188 | */
189 | private Size mPreviewSize;
190 |
191 | /**
192 | * {@link CameraDevice.StateCallback} is called when {@link CameraDevice} changes its state.
193 | */
194 | private final CameraDevice.StateCallback mStateCallback = new CameraDevice.StateCallback() {
195 |
196 | @Override
197 | public void onOpened(@NonNull CameraDevice cameraDevice) {
198 | // This method is called when the camera is opened. We start camera preview here.
199 | mCameraOpenCloseLock.release();
200 | mCameraDevice = cameraDevice;
201 | createCameraPreviewSession();
202 | }
203 |
204 | @Override
205 | public void onDisconnected(@NonNull CameraDevice cameraDevice) {
206 | mCameraOpenCloseLock.release();
207 | cameraDevice.close();
208 | mCameraDevice = null;
209 | }
210 |
211 | @Override
212 | public void onError(@NonNull CameraDevice cameraDevice, int error) {
213 | mCameraOpenCloseLock.release();
214 | cameraDevice.close();
215 | mCameraDevice = null;
216 | Activity activity = getActivity();
217 | if (null != activity) {
218 | activity.finish();
219 | }
220 | }
221 |
222 | };
223 |
224 | /**
225 | * An additional thread for running tasks that shouldn't block the UI.
226 | */
227 | private HandlerThread mBackgroundThread;
228 |
229 | /**
230 | * A {@link Handler} for running tasks in the background.
231 | */
232 | private Handler mBackgroundHandler;
233 |
234 | /**
235 | * An {@link ImageReader} that handles still image capture.
236 | */
237 | private ImageReader mImageReader;
238 |
239 | /**
240 | * This is the output file for our picture.
241 | */
242 | private File mFile;
243 |
244 | /**
245 | * This a callback object for the {@link ImageReader}. "onImageAvailable" will be called when a
246 | * still image is ready to be saved.
247 | */
248 | private final ImageReader.OnImageAvailableListener mOnImageAvailableListener
249 | = new ImageReader.OnImageAvailableListener() {
250 |
251 | @Override
252 | public void onImageAvailable(ImageReader reader) {
253 | mBackgroundHandler.post(new ImageSaver(reader.acquireNextImage(), mFile));
254 | }
255 |
256 | };
257 |
258 | /**
259 | * {@link CaptureRequest.Builder} for the camera preview
260 | */
261 | private CaptureRequest.Builder mPreviewRequestBuilder;
262 |
263 | /**
264 | * {@link CaptureRequest} generated by {@link #mPreviewRequestBuilder}
265 | */
266 | private CaptureRequest mPreviewRequest;
267 |
268 | /**
269 | * The current state of camera state for taking pictures.
270 | *
271 | * @see #mCaptureCallback
272 | */
273 | private int mState = STATE_PREVIEW;
274 |
275 | /**
276 | * A {@link Semaphore} to prevent the app from exiting before closing the camera.
277 | */
278 | private Semaphore mCameraOpenCloseLock = new Semaphore(1);
279 |
280 | /**
281 | * Whether the current camera device supports Flash or not.
282 | */
283 | private boolean mFlashSupported;
284 |
285 | /**
286 | * Orientation of the camera sensor
287 | */
288 | private int mSensorOrientation;
289 |
290 | /**
291 | * A {@link CameraCaptureSession.CaptureCallback} that handles events related to JPEG capture.
292 | */
293 | private CameraCaptureSession.CaptureCallback mCaptureCallback
294 | = new CameraCaptureSession.CaptureCallback() {
295 |
296 | private void process(CaptureResult result) {
297 | Integer mode = result.get(CaptureResult.STATISTICS_FACE_DETECT_MODE);
298 | Face[] faces = result.get(CaptureResult.STATISTICS_FACES);
299 | if (faces != null && mode != null) {
300 | if (faces.length > 0) {
301 | for(int i = 0; i < faces.length; i++) {
302 | if (faces[i].getScore() > 50) {
303 | Log.i("Test", "faces : " + faces.length + " , mode : " + mode);
304 | int left = faces[i].getBounds().left;
305 | int top = faces[i].getBounds().top;
306 | int right = faces[i].getBounds().right;
307 | int bottom = faces[i].getBounds().bottom;
308 | //float points[] = {(float)left, (float)top, (float)right, (float)bottom};
309 |
310 | Rect uRect = new Rect(left, top, right, bottom);
311 | RectF rectF = new RectF(uRect);
312 | mFaceDetectionMatrix.mapRect(rectF);
313 | //mFaceDetectionMatrix.mapPoints(points);
314 | rectF.round(uRect);
315 | //uRect.set((int) rectF.left, (int) rectF.top, (int) rectF.right, (int) rectF.bottom);
316 | Log.i("Test", "Activity rect" + i + " bounds: " + uRect);
317 |
318 | final Rect rect = uRect;
319 | getActivity().runOnUiThread(new Runnable() {
320 | @Override
321 | public void run() {
322 | mOverlayView.setRect(rect);
323 | mOverlayView.requestLayout();
324 | }
325 | });
326 | break;
327 | }
328 | }
329 | }
330 | }
331 |
332 | switch (mState) {
333 | case STATE_PREVIEW: {
334 | // We have nothing to do when the camera preview is working normally.
335 | break;
336 | }
337 | case STATE_WAITING_LOCK: {
338 | Integer afState = result.get(CaptureResult.CONTROL_AF_STATE);
339 | if (afState == null) {
340 | captureStillPicture();
341 | } else if (CaptureResult.CONTROL_AF_STATE_FOCUSED_LOCKED == afState ||
342 | CaptureResult.CONTROL_AF_STATE_NOT_FOCUSED_LOCKED == afState) {
343 | // CONTROL_AE_STATE can be null on some devices
344 | Integer aeState = result.get(CaptureResult.CONTROL_AE_STATE);
345 | if (aeState == null ||
346 | aeState == CaptureResult.CONTROL_AE_STATE_CONVERGED) {
347 | mState = STATE_PICTURE_TAKEN;
348 | captureStillPicture();
349 | } else {
350 | runPrecaptureSequence();
351 | }
352 | }
353 | break;
354 | }
355 | case STATE_WAITING_PRECAPTURE: {
356 | // CONTROL_AE_STATE can be null on some devices
357 | Integer aeState = result.get(CaptureResult.CONTROL_AE_STATE);
358 | if (aeState == null ||
359 | aeState == CaptureResult.CONTROL_AE_STATE_PRECAPTURE ||
360 | aeState == CaptureRequest.CONTROL_AE_STATE_FLASH_REQUIRED) {
361 | mState = STATE_WAITING_NON_PRECAPTURE;
362 | }
363 | break;
364 | }
365 | case STATE_WAITING_NON_PRECAPTURE: {
366 | // CONTROL_AE_STATE can be null on some devices
367 | Integer aeState = result.get(CaptureResult.CONTROL_AE_STATE);
368 | if (aeState == null || aeState != CaptureResult.CONTROL_AE_STATE_PRECAPTURE) {
369 | mState = STATE_PICTURE_TAKEN;
370 | captureStillPicture();
371 | }
372 | break;
373 | }
374 | }
375 | }
376 |
377 | @Override
378 | public void onCaptureProgressed(@NonNull CameraCaptureSession session,
379 | @NonNull CaptureRequest request,
380 | @NonNull CaptureResult partialResult) {
381 | process(partialResult);
382 | }
383 |
384 | @Override
385 | public void onCaptureCompleted(@NonNull CameraCaptureSession session,
386 | @NonNull CaptureRequest request,
387 | @NonNull TotalCaptureResult result) {
388 | process(result);
389 | }
390 |
391 | };
392 |
393 | /**
394 | * Shows a {@link Toast} on the UI thread.
395 | *
396 | * @param text The message to show
397 | */
398 | private void showToast(final String text) {
399 | final Activity activity = getActivity();
400 | if (activity != null) {
401 | activity.runOnUiThread(new Runnable() {
402 | @Override
403 | public void run() {
404 | Toast.makeText(activity, text, Toast.LENGTH_SHORT).show();
405 | }
406 | });
407 | }
408 | }
409 |
410 | /**
411 | * Given {@code choices} of {@code Size}s supported by a camera, choose the smallest one that
412 | * is at least as large as the respective texture view size, and that is at most as large as the
413 | * respective max size, and whose aspect ratio matches with the specified value. If such size
414 | * doesn't exist, choose the largest one that is at most as large as the respective max size,
415 | * and whose aspect ratio matches with the specified value.
416 | *
417 | * @param choices The list of sizes that the camera supports for the intended output
418 | * class
419 | * @param textureViewWidth The width of the texture view relative to sensor coordinate
420 | * @param textureViewHeight The height of the texture view relative to sensor coordinate
421 | * @param maxWidth The maximum width that can be chosen
422 | * @param maxHeight The maximum height that can be chosen
423 | * @param aspectRatio The aspect ratio
424 | * @return The optimal {@code Size}, or an arbitrary one if none were big enough
425 | */
426 | private static Size chooseOptimalSize(Size[] choices, int textureViewWidth,
427 | int textureViewHeight, int maxWidth, int maxHeight, Size aspectRatio) {
428 |
429 | // Collect the supported resolutions that are at least as big as the preview Surface
430 | List bigEnough = new ArrayList<>();
431 | // Collect the supported resolutions that are smaller than the preview Surface
432 | List notBigEnough = new ArrayList<>();
433 | int w = aspectRatio.getWidth();
434 | int h = aspectRatio.getHeight();
435 | for (Size option : choices) {
436 | if (option.getWidth() <= maxWidth && option.getHeight() <= maxHeight &&
437 | option.getHeight() == option.getWidth() * h / w) {
438 | if (option.getWidth() >= textureViewWidth &&
439 | option.getHeight() >= textureViewHeight) {
440 | bigEnough.add(option);
441 | } else {
442 | notBigEnough.add(option);
443 | }
444 | }
445 | }
446 |
447 | // Pick the smallest of those big enough. If there is no one big enough, pick the
448 | // largest of those not big enough.
449 | if (bigEnough.size() > 0) {
450 | return Collections.min(bigEnough, new CompareSizesByArea());
451 | } else if (notBigEnough.size() > 0) {
452 | return Collections.max(notBigEnough, new CompareSizesByArea());
453 | } else {
454 | Log.e(TAG, "Couldn't find any suitable preview size");
455 | return choices[0];
456 | }
457 | }
458 |
459 | public static Camera2BasicFragment newInstance() {
460 | return new Camera2BasicFragment();
461 | }
462 |
463 | @Override
464 | public View onCreateView(LayoutInflater inflater, ViewGroup container,
465 | Bundle savedInstanceState) {
466 | return inflater.inflate(R.layout.fragment_camera2_basic, container, false);
467 | }
468 |
469 | @Override
470 | public void onViewCreated(final View view, Bundle savedInstanceState) {
471 | view.findViewById(R.id.picture).setOnClickListener(this);
472 | view.findViewById(R.id.info).setOnClickListener(this);
473 | mTextureView = (AutoFitTextureView) view.findViewById(R.id.texture);
474 | mOverlayView = (OverlayView) view.findViewById(R.id.overlay_view);
475 | }
476 |
477 | @Override
478 | public void onActivityCreated(Bundle savedInstanceState) {
479 | super.onActivityCreated(savedInstanceState);
480 | mFile = new File(getActivity().getExternalFilesDir(null), "pic.jpg");
481 | }
482 |
483 | @Override
484 | public void onResume() {
485 | super.onResume();
486 | startBackgroundThread();
487 |
488 | // When the screen is turned off and turned back on, the SurfaceTexture is already
489 | // available, and "onSurfaceTextureAvailable" will not be called. In that case, we can open
490 | // a camera and start preview from here (otherwise, we wait until the surface is ready in
491 | // the SurfaceTextureListener).
492 | if (mTextureView.isAvailable()) {
493 | openCamera(mTextureView.getWidth(), mTextureView.getHeight());
494 | } else {
495 | mTextureView.setSurfaceTextureListener(mSurfaceTextureListener);
496 | }
497 | }
498 |
499 | @Override
500 | public void onPause() {
501 | closeCamera();
502 | stopBackgroundThread();
503 | super.onPause();
504 | }
505 |
506 | private void requestCameraPermission() {
507 | if (FragmentCompat.shouldShowRequestPermissionRationale(this, Manifest.permission.CAMERA)) {
508 | new ConfirmationDialog().show(getChildFragmentManager(), FRAGMENT_DIALOG);
509 | } else {
510 | FragmentCompat.requestPermissions(this, new String[]{Manifest.permission.CAMERA},
511 | REQUEST_CAMERA_PERMISSION);
512 | }
513 | }
514 |
515 | @Override
516 | public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions,
517 | @NonNull int[] grantResults) {
518 | if (requestCode == REQUEST_CAMERA_PERMISSION) {
519 | if (grantResults.length != 1 || grantResults[0] != PackageManager.PERMISSION_GRANTED) {
520 | ErrorDialog.newInstance(getString(R.string.request_permission))
521 | .show(getChildFragmentManager(), FRAGMENT_DIALOG);
522 | }
523 | } else {
524 | super.onRequestPermissionsResult(requestCode, permissions, grantResults);
525 | }
526 | }
527 |
528 | /**
529 | * Sets up member variables related to camera.
530 | *
531 | * @param width The width of available size for camera preview
532 | * @param height The height of available size for camera preview
533 | */
534 | private void setUpCameraOutputs(int width, int height) {
535 | Activity activity = getActivity();
536 | mCameraManager = (CameraManager) activity.getSystemService(Context.CAMERA_SERVICE);
537 | try {
538 | /* for(final String cameraId : manager.getCameraIdList()){
539 | CameraCharacteristics characteristics = manager.getCameraCharacteristics(cameraId);
540 | int cOrientation = characteristics.get(CameraCharacteristics.LENS_FACING);
541 | if(cOrientation == CameraCharacteristics.LENS_FACING_FRONT)
542 | {
543 | System.out.println("cam id f"+cameraId);
544 |
545 | }
546 | System.out.println("cam id "+cameraId);
547 |
548 | }*/
549 | for (String cameraId : mCameraManager.getCameraIdList()) {
550 | mCameraCharacteristics
551 | = mCameraManager.getCameraCharacteristics(cameraId);
552 | System.out.println("cam id " + cameraId);
553 | // We don't use a front facing camera in this sample.
554 | int facing = mCameraCharacteristics.get(CameraCharacteristics.LENS_FACING);
555 | if (facing == CameraCharacteristics.LENS_FACING_FRONT) {
556 |
557 |
558 | StreamConfigurationMap map = mCameraCharacteristics.get(
559 | CameraCharacteristics.SCALER_STREAM_CONFIGURATION_MAP);
560 | if (map == null) {
561 | continue;
562 | }
563 |
564 | // For still image captures, we use the largest available size.
565 | Size largest = Collections.max(
566 | Arrays.asList(map.getOutputSizes(ImageFormat.JPEG)),
567 | new CompareSizesByArea());
568 | mImageReader = ImageReader.newInstance(largest.getWidth(), largest.getHeight(),
569 | ImageFormat.JPEG, /*maxImages*/2);
570 | mImageReader.setOnImageAvailableListener(
571 | mOnImageAvailableListener, mBackgroundHandler);
572 |
573 | // Find out if we need to swap dimension to get the preview size relative to sensor
574 | // coordinate.
575 | int displayRotation = activity.getWindowManager().getDefaultDisplay().getRotation();
576 | //noinspection ConstantConditions
577 | mSensorOrientation = mCameraCharacteristics.get(CameraCharacteristics.SENSOR_ORIENTATION);
578 | mSwappedDimensions = false;
579 |
580 | switch (displayRotation) {
581 | case Surface.ROTATION_0:
582 | case Surface.ROTATION_180:
583 | if (mSensorOrientation == 90 || mSensorOrientation == 270) {
584 | mSwappedDimensions = true;
585 | }
586 | break;
587 | case Surface.ROTATION_90:
588 | case Surface.ROTATION_270:
589 | if (mSensorOrientation == 0 || mSensorOrientation == 180) {
590 | mSwappedDimensions = true;
591 | }
592 | break;
593 | default:
594 | Log.e(TAG, "Display rotation is invalid: " + displayRotation);
595 | }
596 |
597 | Point displaySize = new Point();
598 | activity.getWindowManager().getDefaultDisplay().getSize(displaySize);
599 | int rotatedPreviewWidth = width;
600 | int rotatedPreviewHeight = height;
601 | int maxPreviewWidth = displaySize.x;
602 | int maxPreviewHeight = displaySize.y;
603 |
604 | if (mSwappedDimensions) {
605 | rotatedPreviewWidth = height;
606 | rotatedPreviewHeight = width;
607 | maxPreviewWidth = displaySize.y;
608 | maxPreviewHeight = displaySize.x;
609 | }
610 |
611 | if (maxPreviewWidth > MAX_PREVIEW_WIDTH) {
612 | maxPreviewWidth = MAX_PREVIEW_WIDTH;
613 | }
614 |
615 | if (maxPreviewHeight > MAX_PREVIEW_HEIGHT) {
616 | maxPreviewHeight = MAX_PREVIEW_HEIGHT;
617 | }
618 |
619 | // Danger, W.R.! Attempting to use too large a preview size could exceed the camera
620 | // bus' bandwidth limitation, resulting in gorgeous previews but the storage of
621 | // garbage capture data.
622 | mPreviewSize = chooseOptimalSize(map.getOutputSizes(SurfaceTexture.class),
623 | rotatedPreviewWidth, rotatedPreviewHeight, maxPreviewWidth,
624 | maxPreviewHeight, largest);
625 |
626 | // We fit the aspect ratio of TextureView to the size of preview we picked.
627 | int orientation = getResources().getConfiguration().orientation;
628 | if (orientation == Configuration.ORIENTATION_LANDSCAPE) {
629 | mTextureView.setAspectRatio(
630 | mPreviewSize.getWidth(), mPreviewSize.getHeight());
631 | } else {
632 | mTextureView.setAspectRatio(
633 | mPreviewSize.getHeight(), mPreviewSize.getWidth());
634 | }
635 |
636 | // Check if the flash is supported.
637 | Boolean available = mCameraCharacteristics.get(CameraCharacteristics.FLASH_INFO_AVAILABLE);
638 | mFlashSupported = available == null ? false : available;
639 |
640 | mCameraId = cameraId;
641 |
642 | int orientationOffset = mCameraCharacteristics.get(CameraCharacteristics.SENSOR_ORIENTATION);
643 | Rect activeArraySizeRect = mCameraCharacteristics.get(CameraCharacteristics.SENSOR_INFO_ACTIVE_ARRAY_SIZE);
644 |
645 | // Face Detection Matrix
646 | mFaceDetectionMatrix = new Matrix();
647 | // TODO - I guess that is not enough if we have a landscape layout too...
648 | mFaceDetectionMatrix.setRotate(orientationOffset);
649 |
650 | Log.i("Test", "activeArraySizeRect1: (" + activeArraySizeRect + ") -> " + activeArraySizeRect.width() + ", " + activeArraySizeRect.height());
651 | Log.i("Test", "activeArraySizeRect2: " + mPreviewSize.getWidth() + ", " + mPreviewSize.getHeight());
652 | float s1 = mPreviewSize.getWidth() / (float)activeArraySizeRect.width();
653 | float s2 = mPreviewSize.getHeight() / (float)activeArraySizeRect.height();
654 | //float s1 = mOverlayView.getWidth();
655 | //float s2 = mOverlayView.getHeight();
656 | boolean mirror = true; // we always use front face camera
657 | boolean weAreinPortrait = true;
658 | mFaceDetectionMatrix.postScale(mirror ? -s1 : s1, s2);
659 | if (mSwappedDimensions) {
660 | mFaceDetectionMatrix.postTranslate(mPreviewSize.getHeight(), mPreviewSize.getWidth());
661 | } else {
662 | // TODO - ...
663 | }
664 |
665 | }
666 | // return;
667 | }
668 | } catch (CameraAccessException e) {
669 | e.printStackTrace();
670 | } catch (NullPointerException e) {
671 | // Currently an NPE is thrown when the Camera2API is used but not supported on the
672 | // device this code runs.
673 | ErrorDialog.newInstance(getString(R.string.camera_error))
674 | .show(getChildFragmentManager(), FRAGMENT_DIALOG);
675 | }
676 | }
677 |
678 | /**
679 | * Opens the camera specified by {@link Camera2BasicFragment#mCameraId}.
680 | */
681 | private void openCamera(int width, int height) {
682 | if (ContextCompat.checkSelfPermission(getActivity(), Manifest.permission.CAMERA)
683 | != PackageManager.PERMISSION_GRANTED) {
684 | requestCameraPermission();
685 | return;
686 | }
687 | setUpCameraOutputs(width, height);
688 | configureTransform(width, height);
689 | Activity activity = getActivity();
690 | CameraManager manager = (CameraManager) activity.getSystemService(Context.CAMERA_SERVICE);
691 | try {
692 | if (!mCameraOpenCloseLock.tryAcquire(2500, TimeUnit.MILLISECONDS)) {
693 | throw new RuntimeException("Time out waiting to lock camera opening.");
694 | }
695 | manager.openCamera(mCameraId, mStateCallback, mBackgroundHandler);
696 | } catch (CameraAccessException e) {
697 | e.printStackTrace();
698 | } catch (InterruptedException e) {
699 | throw new RuntimeException("Interrupted while trying to lock camera opening.", e);
700 | }
701 | }
702 |
703 | /**
704 | * Closes the current {@link CameraDevice}.
705 | */
706 | private void closeCamera() {
707 | try {
708 | mCameraOpenCloseLock.acquire();
709 | if (null != mCaptureSession) {
710 | mCaptureSession.close();
711 | mCaptureSession = null;
712 | }
713 | if (null != mCameraDevice) {
714 | mCameraDevice.close();
715 | mCameraDevice = null;
716 | }
717 | if (null != mImageReader) {
718 | mImageReader.close();
719 | mImageReader = null;
720 | }
721 | } catch (InterruptedException e) {
722 | throw new RuntimeException("Interrupted while trying to lock camera closing.", e);
723 | } finally {
724 | mCameraOpenCloseLock.release();
725 | }
726 | }
727 |
728 | /**
729 | * Starts a background thread and its {@link Handler}.
730 | */
731 | private void startBackgroundThread() {
732 | mBackgroundThread = new HandlerThread("CameraBackground");
733 | mBackgroundThread.start();
734 | mBackgroundHandler = new Handler(mBackgroundThread.getLooper());
735 | }
736 |
737 | /**
738 | * Stops the background thread and its {@link Handler}.
739 | */
740 | private void stopBackgroundThread() {
741 | mBackgroundThread.quitSafely();
742 | try {
743 | mBackgroundThread.join();
744 | mBackgroundThread = null;
745 | mBackgroundHandler = null;
746 | } catch (InterruptedException e) {
747 | e.printStackTrace();
748 | }
749 | }
750 |
751 | /**
752 | * Creates a new {@link CameraCaptureSession} for camera preview.
753 | */
754 | private void createCameraPreviewSession() {
755 | try {
756 | SurfaceTexture texture = mTextureView.getSurfaceTexture();
757 | assert texture != null;
758 |
759 | // We configure the size of default buffer to be the size of camera preview we want.
760 | texture.setDefaultBufferSize(mPreviewSize.getWidth(), mPreviewSize.getHeight());
761 |
762 | // This is the output Surface we need to start preview.
763 | Surface surface = new Surface(texture);
764 |
765 | // We set up a CaptureRequest.Builder with the output Surface.
766 | mPreviewRequestBuilder
767 | = mCameraDevice.createCaptureRequest(CameraDevice.TEMPLATE_PREVIEW);
768 | mPreviewRequestBuilder.addTarget(surface);
769 |
770 | // Here, we create a CameraCaptureSession for camera preview.
771 | mCameraDevice.createCaptureSession(Arrays.asList(surface, mImageReader.getSurface()),
772 | new CameraCaptureSession.StateCallback() {
773 |
774 | @Override
775 | public void onConfigured(@NonNull CameraCaptureSession cameraCaptureSession) {
776 | // The camera is already closed
777 | if (null == mCameraDevice) {
778 | return;
779 | }
780 |
781 | // When the session is ready, we start displaying the preview.
782 | mCaptureSession = cameraCaptureSession;
783 | try {
784 | // Auto focus should be continuous for camera preview.
785 | mPreviewRequestBuilder.set(CaptureRequest.STATISTICS_FACE_DETECT_MODE,
786 | CameraMetadata.STATISTICS_FACE_DETECT_MODE_FULL);
787 | // Flash is automatically enabled when necessary.
788 | setAutoFlash(mPreviewRequestBuilder);
789 |
790 | // Finally, we start displaying the camera preview.
791 | mPreviewRequest = mPreviewRequestBuilder.build();
792 | mCaptureSession.setRepeatingRequest(mPreviewRequest,
793 | mCaptureCallback, mBackgroundHandler);
794 | } catch (CameraAccessException e) {
795 | e.printStackTrace();
796 | }
797 | }
798 |
799 | @Override
800 | public void onConfigureFailed(
801 | @NonNull CameraCaptureSession cameraCaptureSession) {
802 | showToast("Failed");
803 | }
804 | }, null
805 | );
806 | } catch (CameraAccessException e) {
807 | e.printStackTrace();
808 | }
809 | }
810 |
811 | /**
812 | * Configures the necessary {@link android.graphics.Matrix} transformation to `mTextureView`.
813 | * This method should be called after the camera preview size is determined in
814 | * setUpCameraOutputs and also the size of `mTextureView` is fixed.
815 | *
816 | * @param viewWidth The width of `mTextureView`
817 | * @param viewHeight The height of `mTextureView`
818 | */
819 | private void configureTransform(int viewWidth, int viewHeight) {
820 | Activity activity = getActivity();
821 | if (null == mTextureView || null == mPreviewSize || null == activity) {
822 | return;
823 | }
824 | int rotation = activity.getWindowManager().getDefaultDisplay().getRotation();
825 | Matrix matrix = new Matrix();
826 | RectF viewRect = new RectF(0, 0, viewWidth, viewHeight);
827 | RectF bufferRect = new RectF(0, 0, mPreviewSize.getHeight(), mPreviewSize.getWidth());
828 | float centerX = viewRect.centerX();
829 | float centerY = viewRect.centerY();
830 | if (Surface.ROTATION_90 == rotation || Surface.ROTATION_270 == rotation) {
831 | bufferRect.offset(centerX - bufferRect.centerX(), centerY - bufferRect.centerY());
832 | matrix.setRectToRect(viewRect, bufferRect, Matrix.ScaleToFit.FILL);
833 | float scale = Math.max(
834 | (float) viewHeight / mPreviewSize.getHeight(),
835 | (float) viewWidth / mPreviewSize.getWidth());
836 | matrix.postScale(scale, scale, centerX, centerY);
837 | matrix.postRotate(90 * (rotation - 2), centerX, centerY);
838 | } else if (Surface.ROTATION_180 == rotation) {
839 | matrix.postRotate(180, centerX, centerY);
840 | }
841 | mTextureView.setTransform(matrix);
842 | }
843 |
844 | /**
845 | * Initiate a still image capture.
846 | */
847 | private void takePicture() {
848 | lockFocus();
849 | }
850 |
851 | /**
852 | * Lock the focus as the first step for a still image capture.
853 | */
854 | private void lockFocus() {
855 | try {
856 | // This is how to tell the camera to lock focus.
857 | mPreviewRequestBuilder.set(CaptureRequest.CONTROL_AF_TRIGGER,
858 | CameraMetadata.CONTROL_AF_TRIGGER_START);
859 | // Tell #mCaptureCallback to wait for the lock.
860 | mState = STATE_WAITING_LOCK;
861 | mCaptureSession.capture(mPreviewRequestBuilder.build(), mCaptureCallback,
862 | mBackgroundHandler);
863 | } catch (CameraAccessException e) {
864 | e.printStackTrace();
865 | }
866 | }
867 |
868 | /**
869 | * Run the precapture sequence for capturing a still image. This method should be called when
870 | * we get a response in {@link #mCaptureCallback} from {@link #lockFocus()}.
871 | */
872 | private void runPrecaptureSequence() {
873 | try {
874 | // This is how to tell the camera to trigger.
875 | mPreviewRequestBuilder.set(CaptureRequest.CONTROL_AE_PRECAPTURE_TRIGGER,
876 | CaptureRequest.CONTROL_AE_PRECAPTURE_TRIGGER_START);
877 | // Tell #mCaptureCallback to wait for the precapture sequence to be set.
878 | mState = STATE_WAITING_PRECAPTURE;
879 | mCaptureSession.capture(mPreviewRequestBuilder.build(), mCaptureCallback,
880 | mBackgroundHandler);
881 | } catch (CameraAccessException e) {
882 | e.printStackTrace();
883 | }
884 | }
885 |
886 | /**
887 | * Capture a still picture. This method should be called when we get a response in
888 | * {@link #mCaptureCallback} from both {@link #lockFocus()}.
889 | */
890 | private void captureStillPicture() {
891 | try {
892 | final Activity activity = getActivity();
893 | if (null == activity || null == mCameraDevice) {
894 | return;
895 | }
896 | // This is the CaptureRequest.Builder that we use to take a picture.
897 | final CaptureRequest.Builder captureBuilder =
898 | mCameraDevice.createCaptureRequest(CameraDevice.TEMPLATE_STILL_CAPTURE);
899 | captureBuilder.addTarget(mImageReader.getSurface());
900 |
901 | // Use the same AE and AF modes as the preview.
902 | captureBuilder.set(CaptureRequest.CONTROL_AF_MODE,
903 | CaptureRequest.CONTROL_AF_MODE_CONTINUOUS_PICTURE);
904 | setAutoFlash(captureBuilder);
905 |
906 | // Orientation
907 | int rotation = activity.getWindowManager().getDefaultDisplay().getRotation();
908 | captureBuilder.set(CaptureRequest.JPEG_ORIENTATION, getOrientation(rotation));
909 |
910 | CameraCaptureSession.CaptureCallback CaptureCallback
911 | = new CameraCaptureSession.CaptureCallback() {
912 |
913 | @Override
914 | public void onCaptureCompleted(@NonNull CameraCaptureSession session,
915 | @NonNull CaptureRequest request,
916 | @NonNull TotalCaptureResult result) {
917 | showToast("Saved: " + mFile);
918 | Log.d(TAG, mFile.toString());
919 | unlockFocus();
920 | }
921 | };
922 |
923 | mCaptureSession.stopRepeating();
924 | mCaptureSession.capture(captureBuilder.build(), CaptureCallback, null);
925 | } catch (CameraAccessException e) {
926 | e.printStackTrace();
927 | }
928 | }
929 |
930 | /**
931 | * Retrieves the JPEG orientation from the specified screen rotation.
932 | *
933 | * @param rotation The screen rotation.
934 | * @return The JPEG orientation (one of 0, 90, 270, and 360)
935 | */
936 | private int getOrientation(int rotation) {
937 | // Sensor orientation is 90 for most devices, or 270 for some devices (eg. Nexus 5X)
938 | // We have to take that into account and rotate JPEG properly.
939 | // For devices with orientation of 90, we simply return our mapping from ORIENTATIONS.
940 | // For devices with orientation of 270, we need to rotate the JPEG 180 degrees.
941 | return (ORIENTATIONS.get(rotation) + mSensorOrientation + 270) % 360;
942 | }
943 |
944 | /**
945 | * Unlock the focus. This method should be called when still image capture sequence is
946 | * finished.
947 | */
948 | private void unlockFocus() {
949 | try {
950 | // Reset the auto-focus trigger
951 | mPreviewRequestBuilder.set(CaptureRequest.CONTROL_AF_TRIGGER,
952 | CameraMetadata.CONTROL_AF_TRIGGER_CANCEL);
953 | setAutoFlash(mPreviewRequestBuilder);
954 | mCaptureSession.capture(mPreviewRequestBuilder.build(), mCaptureCallback,
955 | mBackgroundHandler);
956 | // After this, the camera will go back to the normal state of preview.
957 | mState = STATE_PREVIEW;
958 | mCaptureSession.setRepeatingRequest(mPreviewRequest, mCaptureCallback,
959 | mBackgroundHandler);
960 | } catch (CameraAccessException e) {
961 | e.printStackTrace();
962 | }
963 | }
964 |
965 | @Override
966 | public void onClick(View view) {
967 | switch (view.getId()) {
968 | case R.id.picture: {
969 | takePicture();
970 | break;
971 | }
972 | case R.id.info: {
973 | Activity activity = getActivity();
974 | if (null != activity) {
975 | new AlertDialog.Builder(activity)
976 | .setMessage(R.string.intro_message)
977 | .setPositiveButton(android.R.string.ok, null)
978 | .show();
979 | }
980 | break;
981 | }
982 | }
983 | }
984 |
985 | private void setAutoFlash(CaptureRequest.Builder requestBuilder) {
986 | if (mFlashSupported) {
987 | requestBuilder.set(CaptureRequest.CONTROL_AE_MODE,
988 | CaptureRequest.CONTROL_AE_MODE_ON_AUTO_FLASH);
989 | }
990 | }
991 |
992 | /**
993 | * Saves a JPEG {@link Image} into the specified {@link File}.
994 | */
995 | private static class ImageSaver implements Runnable {
996 |
997 | /**
998 | * The JPEG image
999 | */
1000 | private final Image mImage;
1001 | /**
1002 | * The file we save the image into.
1003 | */
1004 | private final File mFile;
1005 |
1006 | public ImageSaver(Image image, File file) {
1007 | mImage = image;
1008 | mFile = file;
1009 | }
1010 |
1011 | @Override
1012 | public void run() {
1013 | ByteBuffer buffer = mImage.getPlanes()[0].getBuffer();
1014 | byte[] bytes = new byte[buffer.remaining()];
1015 | buffer.get(bytes);
1016 | FileOutputStream output = null;
1017 | try {
1018 | output = new FileOutputStream(mFile);
1019 | output.write(bytes);
1020 | } catch (IOException e) {
1021 | e.printStackTrace();
1022 | } finally {
1023 | mImage.close();
1024 | if (null != output) {
1025 | try {
1026 | output.close();
1027 | } catch (IOException e) {
1028 | e.printStackTrace();
1029 | }
1030 | }
1031 | }
1032 | }
1033 |
1034 | }
1035 |
1036 | /**
1037 | * Compares two {@code Size}s based on their areas.
1038 | */
1039 | static class CompareSizesByArea implements Comparator {
1040 |
1041 | @Override
1042 | public int compare(Size lhs, Size rhs) {
1043 | // We cast here to ensure the multiplications won't overflow
1044 | return Long.signum((long) lhs.getWidth() * lhs.getHeight() -
1045 | (long) rhs.getWidth() * rhs.getHeight());
1046 | }
1047 |
1048 | }
1049 |
1050 | /**
1051 | * Shows an error message dialog.
1052 | */
1053 | public static class ErrorDialog extends DialogFragment {
1054 |
1055 | private static final String ARG_MESSAGE = "message";
1056 |
1057 | public static ErrorDialog newInstance(String message) {
1058 | ErrorDialog dialog = new ErrorDialog();
1059 | Bundle args = new Bundle();
1060 | args.putString(ARG_MESSAGE, message);
1061 | dialog.setArguments(args);
1062 | return dialog;
1063 | }
1064 |
1065 | @Override
1066 | public Dialog onCreateDialog(Bundle savedInstanceState) {
1067 | final Activity activity = getActivity();
1068 | return new AlertDialog.Builder(activity)
1069 | .setMessage(getArguments().getString(ARG_MESSAGE))
1070 | .setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() {
1071 | @Override
1072 | public void onClick(DialogInterface dialogInterface, int i) {
1073 | activity.finish();
1074 | }
1075 | })
1076 | .create();
1077 | }
1078 |
1079 | }
1080 |
1081 | /**
1082 | * Shows OK/Cancel confirmation dialog about camera permission.
1083 | */
1084 | public static class ConfirmationDialog extends DialogFragment {
1085 |
1086 | @Override
1087 | public Dialog onCreateDialog(Bundle savedInstanceState) {
1088 | final Fragment parent = getParentFragment();
1089 | return new AlertDialog.Builder(getActivity())
1090 | .setMessage(R.string.request_permission)
1091 | .setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() {
1092 | @Override
1093 | public void onClick(DialogInterface dialog, int which) {
1094 | FragmentCompat.requestPermissions(parent,
1095 | new String[]{Manifest.permission.CAMERA},
1096 | REQUEST_CAMERA_PERMISSION);
1097 | }
1098 | })
1099 | .setNegativeButton(android.R.string.cancel,
1100 | new DialogInterface.OnClickListener() {
1101 | @Override
1102 | public void onClick(DialogInterface dialog, int which) {
1103 | Activity activity = parent.getActivity();
1104 | if (activity != null) {
1105 | activity.finish();
1106 | }
1107 | }
1108 | })
1109 | .create();
1110 | }
1111 | }
1112 | }
1113 |
--------------------------------------------------------------------------------
/Application/src/main/java/com/example/android/camera2basic/CameraActivity.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2014 The Android Open Source Project
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package com.example.android.camera2basic;
18 |
19 | import android.app.Activity;
20 | import android.os.Bundle;
21 |
22 | public class CameraActivity extends Activity {
23 |
24 | @Override
25 | protected void onCreate(Bundle savedInstanceState) {
26 | super.onCreate(savedInstanceState);
27 | setContentView(R.layout.activity_camera);
28 | if (null == savedInstanceState) {
29 | getFragmentManager().beginTransaction()
30 | .replace(R.id.container, Camera2BasicFragment.newInstance())
31 | .commit();
32 | }
33 | }
34 |
35 | }
36 |
--------------------------------------------------------------------------------
/Application/src/main/java/com/example/android/camera2basic/OverlayView.java:
--------------------------------------------------------------------------------
1 | package com.example.android.camera2basic;
2 |
3 | import android.content.Context;
4 | import android.content.res.Resources;
5 | import android.graphics.Bitmap;
6 | import android.graphics.Canvas;
7 | import android.graphics.Color;
8 | import android.graphics.Paint;
9 | import android.graphics.Path;
10 | import android.graphics.Point;
11 | import android.graphics.Rect;
12 | import android.util.AttributeSet;
13 | import android.util.TypedValue;
14 | import android.view.MotionEvent;
15 | import android.view.View;
16 |
17 | import java.util.List;
18 |
19 | public class OverlayView extends View {
20 |
21 | private Bitmap mBitmap;
22 | private Canvas mCanvas;
23 | private Paint mPaint;
24 | private Rect mRect;
25 | private static final int TOUCH_TOLERANCE_DP = 24;
26 | private static final int BACKGROUND = Color.TRANSPARENT;
27 | private int mTouchTolerance;
28 |
29 | public OverlayView(Context context) {
30 | this(context, null);
31 | }
32 |
33 | public OverlayView(Context context, AttributeSet attrs) {
34 | this(context, attrs, 0);
35 | }
36 |
37 | public OverlayView(Context context, AttributeSet attrs, int defStyle) {
38 | super(context, attrs, defStyle);
39 | mCanvas = new Canvas();
40 | //mRect = new Rect(10,10, 200, 200);
41 | initPaint();
42 | }
43 |
44 | public void clear() {
45 | mBitmap = Bitmap.createBitmap(getWidth(), getHeight(), Bitmap.Config.ARGB_8888);
46 | mBitmap.eraseColor(BACKGROUND);
47 | mCanvas.setBitmap(mBitmap);
48 | invalidate();
49 | }
50 |
51 | @Override
52 | protected void onSizeChanged(int width, int height, int oldWidth, int oldHeight) {
53 | super.onSizeChanged(width, height, oldWidth, oldHeight);
54 | clear();
55 |
56 | }
57 |
58 | @Override
59 | protected void onDraw(Canvas canvas) {
60 | canvas.drawColor(BACKGROUND);
61 | canvas.drawBitmap(mBitmap, 0, 0, null);
62 |
63 | mPaint.setColor(Color.YELLOW);
64 | if (null != mRect) {
65 | canvas.drawRect(mRect, mPaint);
66 | }
67 | }
68 |
69 | /**
70 | * Sets up paint attributes.
71 | */
72 | private void initPaint() {
73 | mPaint = new Paint();
74 | mPaint.setAntiAlias(true);
75 | mPaint.setDither(true);
76 | mPaint.setColor(Color.BLACK);
77 | mPaint.setStyle(Paint.Style.STROKE);
78 | mPaint.setStrokeJoin(Paint.Join.ROUND);
79 | mPaint.setStrokeCap(Paint.Cap.ROUND);
80 | mPaint.setStrokeWidth(12);
81 | mTouchTolerance = dp2px(TOUCH_TOLERANCE_DP);
82 | }
83 |
84 | /**
85 | * Converts dpi units to px
86 | *
87 | * @param dp
88 | * @return
89 | */
90 | private int dp2px(int dp) {
91 | Resources r = getContext().getResources();
92 | float px = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, dp, r.getDisplayMetrics());
93 | return (int) px;
94 | }
95 |
96 | public void setPaint(Paint paint) {
97 | this.mPaint = paint;
98 | }
99 |
100 | public Bitmap getBitmap() {
101 | return mBitmap;
102 | }
103 |
104 | public Rect getRect() {
105 | return mRect;
106 | }
107 |
108 | public void setRect(Rect rect) {
109 | this.mRect = rect;
110 | this.clear();
111 | }
112 | }
113 |
--------------------------------------------------------------------------------
/Application/src/main/res/drawable-hdpi/ic_action_info.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/shadowsheep1/android-camera2-api-face-recon/4b0cb97dc49e4cbaf5f85be7d327e44d48671d13/Application/src/main/res/drawable-hdpi/ic_action_info.png
--------------------------------------------------------------------------------
/Application/src/main/res/drawable-hdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/shadowsheep1/android-camera2-api-face-recon/4b0cb97dc49e4cbaf5f85be7d327e44d48671d13/Application/src/main/res/drawable-hdpi/ic_launcher.png
--------------------------------------------------------------------------------
/Application/src/main/res/drawable-hdpi/tile.9.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/shadowsheep1/android-camera2-api-face-recon/4b0cb97dc49e4cbaf5f85be7d327e44d48671d13/Application/src/main/res/drawable-hdpi/tile.9.png
--------------------------------------------------------------------------------
/Application/src/main/res/drawable-mdpi/ic_action_info.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/shadowsheep1/android-camera2-api-face-recon/4b0cb97dc49e4cbaf5f85be7d327e44d48671d13/Application/src/main/res/drawable-mdpi/ic_action_info.png
--------------------------------------------------------------------------------
/Application/src/main/res/drawable-mdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/shadowsheep1/android-camera2-api-face-recon/4b0cb97dc49e4cbaf5f85be7d327e44d48671d13/Application/src/main/res/drawable-mdpi/ic_launcher.png
--------------------------------------------------------------------------------
/Application/src/main/res/drawable-xhdpi/ic_action_info.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/shadowsheep1/android-camera2-api-face-recon/4b0cb97dc49e4cbaf5f85be7d327e44d48671d13/Application/src/main/res/drawable-xhdpi/ic_action_info.png
--------------------------------------------------------------------------------
/Application/src/main/res/drawable-xhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/shadowsheep1/android-camera2-api-face-recon/4b0cb97dc49e4cbaf5f85be7d327e44d48671d13/Application/src/main/res/drawable-xhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/Application/src/main/res/drawable-xxhdpi/ic_action_info.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/shadowsheep1/android-camera2-api-face-recon/4b0cb97dc49e4cbaf5f85be7d327e44d48671d13/Application/src/main/res/drawable-xxhdpi/ic_action_info.png
--------------------------------------------------------------------------------
/Application/src/main/res/drawable-xxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/shadowsheep1/android-camera2-api-face-recon/4b0cb97dc49e4cbaf5f85be7d327e44d48671d13/Application/src/main/res/drawable-xxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/Application/src/main/res/layout-land/fragment_camera2_basic.xml:
--------------------------------------------------------------------------------
1 |
16 |
19 |
20 |
27 |
28 |
34 |
35 |
45 |
46 |
52 |
53 |
62 |
63 |
64 |
65 |
66 |
67 |
--------------------------------------------------------------------------------
/Application/src/main/res/layout/activity_camera.xml:
--------------------------------------------------------------------------------
1 |
16 |
23 |
--------------------------------------------------------------------------------
/Application/src/main/res/layout/fragment_camera2_basic.xml:
--------------------------------------------------------------------------------
1 |
16 |
19 |
20 |
26 |
27 |
33 |
34 |
41 |
42 |
48 |
49 |
58 |
59 |
60 |
61 |
62 |
--------------------------------------------------------------------------------
/Application/src/main/res/values-sw600dp/template-dimens.xml:
--------------------------------------------------------------------------------
1 |
16 |
17 |
18 |
19 |
20 |
21 | @dimen/margin_huge
22 | @dimen/margin_medium
23 |
24 |
25 |
--------------------------------------------------------------------------------
/Application/src/main/res/values-sw600dp/template-styles.xml:
--------------------------------------------------------------------------------
1 |
16 |
17 |
18 |
19 |
24 |
25 |
26 |
--------------------------------------------------------------------------------
/Application/src/main/res/values-v11/template-styles.xml:
--------------------------------------------------------------------------------
1 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
--------------------------------------------------------------------------------
/Application/src/main/res/values-v21/base-colors.xml:
--------------------------------------------------------------------------------
1 |
2 |
17 |
18 |
19 |
20 |
21 |
22 |
--------------------------------------------------------------------------------
/Application/src/main/res/values-v21/base-template-styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
17 |
18 |
19 |
20 |
21 |
23 |
24 |
25 |
--------------------------------------------------------------------------------
/Application/src/main/res/values/base-strings.xml:
--------------------------------------------------------------------------------
1 |
2 |
17 |
18 |
19 | Camera2Basic
20 |
21 |
29 |
30 |
31 |
--------------------------------------------------------------------------------
/Application/src/main/res/values/colors.xml:
--------------------------------------------------------------------------------
1 |
2 |
17 |
18 | #cc4285f4
19 |
20 |
--------------------------------------------------------------------------------
/Application/src/main/res/values/strings.xml:
--------------------------------------------------------------------------------
1 |
16 |
17 | Picture
18 | Info
19 | This sample needs camera permission.
20 | This device doesn\'t support Camera2 API.
21 |
22 |
--------------------------------------------------------------------------------
/Application/src/main/res/values/styles.xml:
--------------------------------------------------------------------------------
1 |
16 |
17 |
18 |
19 |
--------------------------------------------------------------------------------
/Application/src/main/res/values/template-dimens.xml:
--------------------------------------------------------------------------------
1 |
16 |
17 |
18 |
19 |
20 |
21 | 4dp
22 | 8dp
23 | 16dp
24 | 32dp
25 | 64dp
26 |
27 |
28 |
29 | @dimen/margin_medium
30 | @dimen/margin_medium
31 |
32 |
33 |
--------------------------------------------------------------------------------
/Application/src/main/res/values/template-styles.xml:
--------------------------------------------------------------------------------
1 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
34 |
35 |
41 |
42 |
43 |
--------------------------------------------------------------------------------
/Application/tests/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
17 |
18 |
22 |
23 |
24 |
25 |
28 |
29 |
30 |
31 |
32 |
35 |
39 |
40 |
41 |
--------------------------------------------------------------------------------
/Application/tests/src/com/example/android/camera2basic/tests/SampleTests.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2013 The Android Open Source Project
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package com.example.android.camera2basic.tests;
17 |
18 | import com.example.android.camera2basic.*;
19 |
20 | import android.test.ActivityInstrumentationTestCase2;
21 |
22 | /**
23 | * Tests for Camera2Basic sample.
24 | */
25 | public class SampleTests extends ActivityInstrumentationTestCase2 {
26 |
27 | private CameraActivity mTestActivity;
28 |
29 | public SampleTests() {
30 | super(CameraActivity.class);
31 | }
32 |
33 | @Override
34 | protected void setUp() throws Exception {
35 | super.setUp();
36 |
37 | // Starts the activity under test using the default Intent with:
38 | // action = {@link Intent#ACTION_MAIN}
39 | // flags = {@link Intent#FLAG_ACTIVITY_NEW_TASK}
40 | // All other fields are null or empty.
41 | mTestActivity = getActivity();
42 | }
43 |
44 | /**
45 | * Test if the test fixture has been set up correctly.
46 | */
47 | public void testPreconditions() {
48 | //Try to add a message to add context to your assertions. These messages will be shown if
49 | //a tests fails and make it easy to understand why a test failed
50 | assertNotNull("mTestActivity is null", mTestActivity);
51 | }
52 |
53 | /**
54 | * Add more tests below.
55 | */
56 |
57 | }
58 |
--------------------------------------------------------------------------------
/CONTRIB.md:
--------------------------------------------------------------------------------
1 | # How to become a contributor and submit your own code
2 |
3 | ## Contributor License Agreements
4 |
5 | We'd love to accept your sample apps and patches! Before we can take them, we
6 | have to jump a couple of legal hurdles.
7 |
8 | Please fill out either the individual or corporate Contributor License Agreement (CLA).
9 |
10 | * If you are an individual writing original source code and you're sure you
11 | own the intellectual property, then you'll need to sign an [individual CLA]
12 | (https://developers.google.com/open-source/cla/individual).
13 | * If you work for a company that wants to allow you to contribute your work,
14 | then you'll need to sign a [corporate CLA]
15 | (https://developers.google.com/open-source/cla/corporate).
16 |
17 | Follow either of the two links above to access the appropriate CLA and
18 | instructions for how to sign and return it. Once we receive it, we'll be able to
19 | accept your pull requests.
20 |
21 | ## Contributing A Patch
22 |
23 | 1. Submit an issue describing your proposed change to the repo in question.
24 | 1. The repo owner will respond to your issue promptly.
25 | 1. If your proposed change is accepted, and you haven't already done so, sign a
26 | Contributor License Agreement (see details above).
27 | 1. Fork the desired repo, develop and test your code changes.
28 | 1. Ensure that your code adheres to the existing style in the sample to which
29 | you are contributing. Refer to the
30 | [Android Code Style Guide]
31 | (https://source.android.com/source/code-style.html) for the
32 | recommended coding standards for this organization.
33 | 1. Ensure that your code has an appropriate set of unit tests which all pass.
34 | 1. Submit a pull request.
35 |
36 |
--------------------------------------------------------------------------------
/CONTRIBUTING.md:
--------------------------------------------------------------------------------
1 | # How to become a contributor and submit your own code
2 |
3 | ## Contributor License Agreements
4 |
5 | We'd love to accept your sample apps and patches! Before we can take them, we
6 | have to jump a couple of legal hurdles.
7 |
8 | Please fill out either the individual or corporate Contributor License Agreement (CLA).
9 |
10 | * If you are an individual writing original source code and you're sure you
11 | own the intellectual property, then you'll need to sign an [individual CLA]
12 | (https://cla.developers.google.com).
13 | * If you work for a company that wants to allow you to contribute your work,
14 | then you'll need to sign a [corporate CLA]
15 | (https://cla.developers.google.com).
16 |
17 | Follow either of the two links above to access the appropriate CLA and
18 | instructions for how to sign and return it. Once we receive it, we'll be able to
19 | accept your pull requests.
20 |
21 | ## Contributing A Patch
22 |
23 | 1. Submit an issue describing your proposed change to the repo in question.
24 | 1. The repo owner will respond to your issue promptly.
25 | 1. If your proposed change is accepted, and you haven't already done so, sign a
26 | Contributor License Agreement (see details above).
27 | 1. Fork the desired repo, develop and test your code changes.
28 | 1. Ensure that your code adheres to the existing style in the sample to which
29 | you are contributing. Refer to the
30 | [Android Code Style Guide]
31 | (https://source.android.com/source/code-style.html) for the
32 | recommended coding standards for this organization.
33 | 1. Ensure that your code has an appropriate set of unit tests which all pass.
34 | 1. Submit a pull request.
35 |
36 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | Apache License
2 | --------------
3 |
4 | Version 2.0, January 2004
5 | http://www.apache.org/licenses/
6 |
7 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
8 |
9 | 1. Definitions.
10 |
11 | "License" shall mean the terms and conditions for use, reproduction,
12 | and distribution as defined by Sections 1 through 9 of this document.
13 |
14 | "Licensor" shall mean the copyright owner or entity authorized by
15 | the copyright owner that is granting the License.
16 |
17 | "Legal Entity" shall mean the union of the acting entity and all
18 | other entities that control, are controlled by, or are under common
19 | control with that entity. For the purposes of this definition,
20 | "control" means (i) the power, direct or indirect, to cause the
21 | direction or management of such entity, whether by contract or
22 | otherwise, or (ii) ownership of fifty percent (50%) or more of the
23 | outstanding shares, or (iii) beneficial ownership of such entity.
24 |
25 | "You" (or "Your") shall mean an individual or Legal Entity
26 | exercising permissions granted by this License.
27 |
28 | "Source" form shall mean the preferred form for making modifications,
29 | including but not limited to software source code, documentation
30 | source, and configuration files.
31 |
32 | "Object" form shall mean any form resulting from mechanical
33 | transformation or translation of a Source form, including but
34 | not limited to compiled object code, generated documentation,
35 | and conversions to other media types.
36 |
37 | "Work" shall mean the work of authorship, whether in Source or
38 | Object form, made available under the License, as indicated by a
39 | copyright notice that is included in or attached to the work
40 | (an example is provided in the Appendix below).
41 |
42 | "Derivative Works" shall mean any work, whether in Source or Object
43 | form, that is based on (or derived from) the Work and for which the
44 | editorial revisions, annotations, elaborations, or other modifications
45 | represent, as a whole, an original work of authorship. For the purposes
46 | of this License, Derivative Works shall not include works that remain
47 | separable from, or merely link (or bind by name) to the interfaces of,
48 | the Work and Derivative Works thereof.
49 |
50 | "Contribution" shall mean any work of authorship, including
51 | the original version of the Work and any modifications or additions
52 | to that Work or Derivative Works thereof, that is intentionally
53 | submitted to Licensor for inclusion in the Work by the copyright owner
54 | or by an individual or Legal Entity authorized to submit on behalf of
55 | the copyright owner. For the purposes of this definition, "submitted"
56 | means any form of electronic, verbal, or written communication sent
57 | to the Licensor or its representatives, including but not limited to
58 | communication on electronic mailing lists, source code control systems,
59 | and issue tracking systems that are managed by, or on behalf of, the
60 | Licensor for the purpose of discussing and improving the Work, but
61 | excluding communication that is conspicuously marked or otherwise
62 | designated in writing by the copyright owner as "Not a Contribution."
63 |
64 | "Contributor" shall mean Licensor and any individual or Legal Entity
65 | on behalf of whom a Contribution has been received by Licensor and
66 | subsequently incorporated within the Work.
67 |
68 | 2. Grant of Copyright License. Subject to the terms and conditions of
69 | this License, each Contributor hereby grants to You a perpetual,
70 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable
71 | copyright license to reproduce, prepare Derivative Works of,
72 | publicly display, publicly perform, sublicense, and distribute the
73 | Work and such Derivative Works in Source or Object form.
74 |
75 | 3. Grant of Patent License. Subject to the terms and conditions of
76 | this License, each Contributor hereby grants to You a perpetual,
77 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable
78 | (except as stated in this section) patent license to make, have made,
79 | use, offer to sell, sell, import, and otherwise transfer the Work,
80 | where such license applies only to those patent claims licensable
81 | by such Contributor that are necessarily infringed by their
82 | Contribution(s) alone or by combination of their Contribution(s)
83 | with the Work to which such Contribution(s) was submitted. If You
84 | institute patent litigation against any entity (including a
85 | cross-claim or counterclaim in a lawsuit) alleging that the Work
86 | or a Contribution incorporated within the Work constitutes direct
87 | or contributory patent infringement, then any patent licenses
88 | granted to You under this License for that Work shall terminate
89 | as of the date such litigation is filed.
90 |
91 | 4. Redistribution. You may reproduce and distribute copies of the
92 | Work or Derivative Works thereof in any medium, with or without
93 | modifications, and in Source or Object form, provided that You
94 | meet the following conditions:
95 |
96 | (a) You must give any other recipients of the Work or
97 | Derivative Works a copy of this License; and
98 |
99 | (b) You must cause any modified files to carry prominent notices
100 | stating that You changed the files; and
101 |
102 | (c) You must retain, in the Source form of any Derivative Works
103 | that You distribute, all copyright, patent, trademark, and
104 | attribution notices from the Source form of the Work,
105 | excluding those notices that do not pertain to any part of
106 | the Derivative Works; and
107 |
108 | (d) If the Work includes a "NOTICE" text file as part of its
109 | distribution, then any Derivative Works that You distribute must
110 | include a readable copy of the attribution notices contained
111 | within such NOTICE file, excluding those notices that do not
112 | pertain to any part of the Derivative Works, in at least one
113 | of the following places: within a NOTICE text file distributed
114 | as part of the Derivative Works; within the Source form or
115 | documentation, if provided along with the Derivative Works; or,
116 | within a display generated by the Derivative Works, if and
117 | wherever such third-party notices normally appear. The contents
118 | of the NOTICE file are for informational purposes only and
119 | do not modify the License. You may add Your own attribution
120 | notices within Derivative Works that You distribute, alongside
121 | or as an addendum to the NOTICE text from the Work, provided
122 | that such additional attribution notices cannot be construed
123 | as modifying the License.
124 |
125 | You may add Your own copyright statement to Your modifications and
126 | may provide additional or different license terms and conditions
127 | for use, reproduction, or distribution of Your modifications, or
128 | for any such Derivative Works as a whole, provided Your use,
129 | reproduction, and distribution of the Work otherwise complies with
130 | the conditions stated in this License.
131 |
132 | 5. Submission of Contributions. Unless You explicitly state otherwise,
133 | any Contribution intentionally submitted for inclusion in the Work
134 | by You to the Licensor shall be under the terms and conditions of
135 | this License, without any additional terms or conditions.
136 | Notwithstanding the above, nothing herein shall supersede or modify
137 | the terms of any separate license agreement you may have executed
138 | with Licensor regarding such Contributions.
139 |
140 | 6. Trademarks. This License does not grant permission to use the trade
141 | names, trademarks, service marks, or product names of the Licensor,
142 | except as required for reasonable and customary use in describing the
143 | origin of the Work and reproducing the content of the NOTICE file.
144 |
145 | 7. Disclaimer of Warranty. Unless required by applicable law or
146 | agreed to in writing, Licensor provides the Work (and each
147 | Contributor provides its Contributions) on an "AS IS" BASIS,
148 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
149 | implied, including, without limitation, any warranties or conditions
150 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
151 | PARTICULAR PURPOSE. You are solely responsible for determining the
152 | appropriateness of using or redistributing the Work and assume any
153 | risks associated with Your exercise of permissions under this License.
154 |
155 | 8. Limitation of Liability. In no event and under no legal theory,
156 | whether in tort (including negligence), contract, or otherwise,
157 | unless required by applicable law (such as deliberate and grossly
158 | negligent acts) or agreed to in writing, shall any Contributor be
159 | liable to You for damages, including any direct, indirect, special,
160 | incidental, or consequential damages of any character arising as a
161 | result of this License or out of the use or inability to use the
162 | Work (including but not limited to damages for loss of goodwill,
163 | work stoppage, computer failure or malfunction, or any and all
164 | other commercial damages or losses), even if such Contributor
165 | has been advised of the possibility of such damages.
166 |
167 | 9. Accepting Warranty or Additional Liability. While redistributing
168 | the Work or Derivative Works thereof, You may choose to offer,
169 | and charge a fee for, acceptance of support, warranty, indemnity,
170 | or other liability obligations and/or rights consistent with this
171 | License. However, in accepting such obligations, You may act only
172 | on Your own behalf and on Your sole responsibility, not on behalf
173 | of any other Contributor, and only if You agree to indemnify,
174 | defend, and hold each Contributor harmless for any liability
175 | incurred by, or claims asserted against, such Contributor by reason
176 | of your accepting any such warranty or additional liability.
177 |
178 | END OF TERMS AND CONDITIONS
179 |
180 | APPENDIX: How to apply the Apache License to your work.
181 |
182 | To apply the Apache License to your work, attach the following
183 | boilerplate notice, with the fields enclosed by brackets "{}"
184 | replaced with your own identifying information. (Don't include
185 | the brackets!) The text should be enclosed in the appropriate
186 | comment syntax for the file format. We also recommend that a
187 | file or class name and description of purpose be included on the
188 | same "printed page" as the copyright notice for easier
189 | identification within third-party archives.
190 |
191 | Copyright {yyyy} {name of copyright owner}
192 |
193 | Licensed under the Apache License, Version 2.0 (the "License");
194 | you may not use this file except in compliance with the License.
195 | You may obtain a copy of the License at
196 |
197 | http://www.apache.org/licenses/LICENSE-2.0
198 |
199 | Unless required by applicable law or agreed to in writing, software
200 | distributed under the License is distributed on an "AS IS" BASIS,
201 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
202 | See the License for the specific language governing permissions and
203 | limitations under the License.
204 |
205 | All image and audio files (including *.png, *.jpg, *.svg, *.mp3, *.wav
206 | and *.ogg) are licensed under the CC-BY-NC license. All other files are
207 | licensed under the Apache 2 license.
208 |
209 | CC-BY-NC License
210 | ----------------
211 |
212 | Attribution-NonCommercial-ShareAlike 4.0 International
213 |
214 | =======================================================================
215 |
216 | Creative Commons Corporation ("Creative Commons") is not a law firm and
217 | does not provide legal services or legal advice. Distribution of
218 | Creative Commons public licenses does not create a lawyer-client or
219 | other relationship. Creative Commons makes its licenses and related
220 | information available on an "as-is" basis. Creative Commons gives no
221 | warranties regarding its licenses, any material licensed under their
222 | terms and conditions, or any related information. Creative Commons
223 | disclaims all liability for damages resulting from their use to the
224 | fullest extent possible.
225 |
226 | Using Creative Commons Public Licenses
227 |
228 | Creative Commons public licenses provide a standard set of terms and
229 | conditions that creators and other rights holders may use to share
230 | original works of authorship and other material subject to copyright
231 | and certain other rights specified in the public license below. The
232 | following considerations are for informational purposes only, are not
233 | exhaustive, and do not form part of our licenses.
234 |
235 | Considerations for licensors: Our public licenses are
236 | intended for use by those authorized to give the public
237 | permission to use material in ways otherwise restricted by
238 | copyright and certain other rights. Our licenses are
239 | irrevocable. Licensors should read and understand the terms
240 | and conditions of the license they choose before applying it.
241 | Licensors should also secure all rights necessary before
242 | applying our licenses so that the public can reuse the
243 | material as expected. Licensors should clearly mark any
244 | material not subject to the license. This includes other CC-
245 | licensed material, or material used under an exception or
246 | limitation to copyright. More considerations for licensors:
247 | wiki.creativecommons.org/Considerations_for_licensors
248 |
249 | Considerations for the public: By using one of our public
250 | licenses, a licensor grants the public permission to use the
251 | licensed material under specified terms and conditions. If
252 | the licensor's permission is not necessary for any reason--for
253 | example, because of any applicable exception or limitation to
254 | copyright--then that use is not regulated by the license. Our
255 | licenses grant only permissions under copyright and certain
256 | other rights that a licensor has authority to grant. Use of
257 | the licensed material may still be restricted for other
258 | reasons, including because others have copyright or other
259 | rights in the material. A licensor may make special requests,
260 | such as asking that all changes be marked or described.
261 | Although not required by our licenses, you are encouraged to
262 | respect those requests where reasonable. More_considerations
263 | for the public:
264 | wiki.creativecommons.org/Considerations_for_licensees
265 |
266 | =======================================================================
267 |
268 | Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International
269 | Public License
270 |
271 | By exercising the Licensed Rights (defined below), You accept and agree
272 | to be bound by the terms and conditions of this Creative Commons
273 | Attribution-NonCommercial-ShareAlike 4.0 International Public License
274 | ("Public License"). To the extent this Public License may be
275 | interpreted as a contract, You are granted the Licensed Rights in
276 | consideration of Your acceptance of these terms and conditions, and the
277 | Licensor grants You such rights in consideration of benefits the
278 | Licensor receives from making the Licensed Material available under
279 | these terms and conditions.
280 |
281 |
282 | Section 1 -- Definitions.
283 |
284 | a. Adapted Material means material subject to Copyright and Similar
285 | Rights that is derived from or based upon the Licensed Material
286 | and in which the Licensed Material is translated, altered,
287 | arranged, transformed, or otherwise modified in a manner requiring
288 | permission under the Copyright and Similar Rights held by the
289 | Licensor. For purposes of this Public License, where the Licensed
290 | Material is a musical work, performance, or sound recording,
291 | Adapted Material is always produced where the Licensed Material is
292 | synched in timed relation with a moving image.
293 |
294 | b. Adapter's License means the license You apply to Your Copyright
295 | and Similar Rights in Your contributions to Adapted Material in
296 | accordance with the terms and conditions of this Public License.
297 |
298 | c. BY-NC-SA Compatible License means a license listed at
299 | creativecommons.org/compatiblelicenses, approved by Creative
300 | Commons as essentially the equivalent of this Public License.
301 |
302 | d. Copyright and Similar Rights means copyright and/or similar rights
303 | closely related to copyright including, without limitation,
304 | performance, broadcast, sound recording, and Sui Generis Database
305 | Rights, without regard to how the rights are labeled or
306 | categorized. For purposes of this Public License, the rights
307 | specified in Section 2(b)(1)-(2) are not Copyright and Similar
308 | Rights.
309 |
310 | e. Effective Technological Measures means those measures that, in the
311 | absence of proper authority, may not be circumvented under laws
312 | fulfilling obligations under Article 11 of the WIPO Copyright
313 | Treaty adopted on December 20, 1996, and/or similar international
314 | agreements.
315 |
316 | f. Exceptions and Limitations means fair use, fair dealing, and/or
317 | any other exception or limitation to Copyright and Similar Rights
318 | that applies to Your use of the Licensed Material.
319 |
320 | g. License Elements means the license attributes listed in the name
321 | of a Creative Commons Public License. The License Elements of this
322 | Public License are Attribution, NonCommercial, and ShareAlike.
323 |
324 | h. Licensed Material means the artistic or literary work, database,
325 | or other material to which the Licensor applied this Public
326 | License.
327 |
328 | i. Licensed Rights means the rights granted to You subject to the
329 | terms and conditions of this Public License, which are limited to
330 | all Copyright and Similar Rights that apply to Your use of the
331 | Licensed Material and that the Licensor has authority to license.
332 |
333 | j. Licensor means the individual(s) or entity(ies) granting rights
334 | under this Public License.
335 |
336 | k. NonCommercial means not primarily intended for or directed towards
337 | commercial advantage or monetary compensation. For purposes of
338 | this Public License, the exchange of the Licensed Material for
339 | other material subject to Copyright and Similar Rights by digital
340 | file-sharing or similar means is NonCommercial provided there is
341 | no payment of monetary compensation in connection with the
342 | exchange.
343 |
344 | l. Share means to provide material to the public by any means or
345 | process that requires permission under the Licensed Rights, such
346 | as reproduction, public display, public performance, distribution,
347 | dissemination, communication, or importation, and to make material
348 | available to the public including in ways that members of the
349 | public may access the material from a place and at a time
350 | individually chosen by them.
351 |
352 | m. Sui Generis Database Rights means rights other than copyright
353 | resulting from Directive 96/9/EC of the European Parliament and of
354 | the Council of 11 March 1996 on the legal protection of databases,
355 | as amended and/or succeeded, as well as other essentially
356 | equivalent rights anywhere in the world.
357 |
358 | n. You means the individual or entity exercising the Licensed Rights
359 | under this Public License. Your has a corresponding meaning.
360 |
361 |
362 | Section 2 -- Scope.
363 |
364 | a. License grant.
365 |
366 | 1. Subject to the terms and conditions of this Public License,
367 | the Licensor hereby grants You a worldwide, royalty-free,
368 | non-sublicensable, non-exclusive, irrevocable license to
369 | exercise the Licensed Rights in the Licensed Material to:
370 |
371 | a. reproduce and Share the Licensed Material, in whole or
372 | in part, for NonCommercial purposes only; and
373 |
374 | b. produce, reproduce, and Share Adapted Material for
375 | NonCommercial purposes only.
376 |
377 | 2. Exceptions and Limitations. For the avoidance of doubt, where
378 | Exceptions and Limitations apply to Your use, this Public
379 | License does not apply, and You do not need to comply with
380 | its terms and conditions.
381 |
382 | 3. Term. The term of this Public License is specified in Section
383 | 6(a).
384 |
385 | 4. Media and formats; technical modifications allowed. The
386 | Licensor authorizes You to exercise the Licensed Rights in
387 | all media and formats whether now known or hereafter created,
388 | and to make technical modifications necessary to do so. The
389 | Licensor waives and/or agrees not to assert any right or
390 | authority to forbid You from making technical modifications
391 | necessary to exercise the Licensed Rights, including
392 | technical modifications necessary to circumvent Effective
393 | Technological Measures. For purposes of this Public License,
394 | simply making modifications authorized by this Section 2(a)
395 | (4) never produces Adapted Material.
396 |
397 | 5. Downstream recipients.
398 |
399 | a. Offer from the Licensor -- Licensed Material. Every
400 | recipient of the Licensed Material automatically
401 | receives an offer from the Licensor to exercise the
402 | Licensed Rights under the terms and conditions of this
403 | Public License.
404 |
405 | b. Additional offer from the Licensor -- Adapted Material.
406 | Every recipient of Adapted Material from You
407 | automatically receives an offer from the Licensor to
408 | exercise the Licensed Rights in the Adapted Material
409 | under the conditions of the Adapter's License You apply.
410 |
411 | c. No downstream restrictions. You may not offer or impose
412 | any additional or different terms or conditions on, or
413 | apply any Effective Technological Measures to, the
414 | Licensed Material if doing so restricts exercise of the
415 | Licensed Rights by any recipient of the Licensed
416 | Material.
417 |
418 | 6. No endorsement. Nothing in this Public License constitutes or
419 | may be construed as permission to assert or imply that You
420 | are, or that Your use of the Licensed Material is, connected
421 | with, or sponsored, endorsed, or granted official status by,
422 | the Licensor or others designated to receive attribution as
423 | provided in Section 3(a)(1)(A)(i).
424 |
425 | b. Other rights.
426 |
427 | 1. Moral rights, such as the right of integrity, are not
428 | licensed under this Public License, nor are publicity,
429 | privacy, and/or other similar personality rights; however, to
430 | the extent possible, the Licensor waives and/or agrees not to
431 | assert any such rights held by the Licensor to the limited
432 | extent necessary to allow You to exercise the Licensed
433 | Rights, but not otherwise.
434 |
435 | 2. Patent and trademark rights are not licensed under this
436 | Public License.
437 |
438 | 3. To the extent possible, the Licensor waives any right to
439 | collect royalties from You for the exercise of the Licensed
440 | Rights, whether directly or through a collecting society
441 | under any voluntary or waivable statutory or compulsory
442 | licensing scheme. In all other cases the Licensor expressly
443 | reserves any right to collect such royalties, including when
444 | the Licensed Material is used other than for NonCommercial
445 | purposes.
446 |
447 |
448 | Section 3 -- License Conditions.
449 |
450 | Your exercise of the Licensed Rights is expressly made subject to the
451 | following conditions.
452 |
453 | a. Attribution.
454 |
455 | 1. If You Share the Licensed Material (including in modified
456 | form), You must:
457 |
458 | a. retain the following if it is supplied by the Licensor
459 | with the Licensed Material:
460 |
461 | i. identification of the creator(s) of the Licensed
462 | Material and any others designated to receive
463 | attribution, in any reasonable manner requested by
464 | the Licensor (including by pseudonym if
465 | designated);
466 |
467 | ii. a copyright notice;
468 |
469 | iii. a notice that refers to this Public License;
470 |
471 | iv. a notice that refers to the disclaimer of
472 | warranties;
473 |
474 | v. a URI or hyperlink to the Licensed Material to the
475 | extent reasonably practicable;
476 |
477 | b. indicate if You modified the Licensed Material and
478 | retain an indication of any previous modifications; and
479 |
480 | c. indicate the Licensed Material is licensed under this
481 | Public License, and include the text of, or the URI or
482 | hyperlink to, this Public License.
483 |
484 | 2. You may satisfy the conditions in Section 3(a)(1) in any
485 | reasonable manner based on the medium, means, and context in
486 | which You Share the Licensed Material. For example, it may be
487 | reasonable to satisfy the conditions by providing a URI or
488 | hyperlink to a resource that includes the required
489 | information.
490 | 3. If requested by the Licensor, You must remove any of the
491 | information required by Section 3(a)(1)(A) to the extent
492 | reasonably practicable.
493 |
494 | b. ShareAlike.
495 |
496 | In addition to the conditions in Section 3(a), if You Share
497 | Adapted Material You produce, the following conditions also apply.
498 |
499 | 1. The Adapter's License You apply must be a Creative Commons
500 | license with the same License Elements, this version or
501 | later, or a BY-NC-SA Compatible License.
502 |
503 | 2. You must include the text of, or the URI or hyperlink to, the
504 | Adapter's License You apply. You may satisfy this condition
505 | in any reasonable manner based on the medium, means, and
506 | context in which You Share Adapted Material.
507 |
508 | 3. You may not offer or impose any additional or different terms
509 | or conditions on, or apply any Effective Technological
510 | Measures to, Adapted Material that restrict exercise of the
511 | rights granted under the Adapter's License You apply.
512 |
513 |
514 | Section 4 -- Sui Generis Database Rights.
515 |
516 | Where the Licensed Rights include Sui Generis Database Rights that
517 | apply to Your use of the Licensed Material:
518 |
519 | a. for the avoidance of doubt, Section 2(a)(1) grants You the right
520 | to extract, reuse, reproduce, and Share all or a substantial
521 | portion of the contents of the database for NonCommercial purposes
522 | only;
523 |
524 | b. if You include all or a substantial portion of the database
525 | contents in a database in which You have Sui Generis Database
526 | Rights, then the database in which You have Sui Generis Database
527 | Rights (but not its individual contents) is Adapted Material,
528 | including for purposes of Section 3(b); and
529 |
530 | c. You must comply with the conditions in Section 3(a) if You Share
531 | all or a substantial portion of the contents of the database.
532 |
533 | For the avoidance of doubt, this Section 4 supplements and does not
534 | replace Your obligations under this Public License where the Licensed
535 | Rights include other Copyright and Similar Rights.
536 |
537 |
538 | Section 5 -- Disclaimer of Warranties and Limitation of Liability.
539 |
540 | a. UNLESS OTHERWISE SEPARATELY UNDERTAKEN BY THE LICENSOR, TO THE
541 | EXTENT POSSIBLE, THE LICENSOR OFFERS THE LICENSED MATERIAL AS-IS
542 | AND AS-AVAILABLE, AND MAKES NO REPRESENTATIONS OR WARRANTIES OF
543 | ANY KIND CONCERNING THE LICENSED MATERIAL, WHETHER EXPRESS,
544 | IMPLIED, STATUTORY, OR OTHER. THIS INCLUDES, WITHOUT LIMITATION,
545 | WARRANTIES OF TITLE, MERCHANTABILITY, FITNESS FOR A PARTICULAR
546 | PURPOSE, NON-INFRINGEMENT, ABSENCE OF LATENT OR OTHER DEFECTS,
547 | ACCURACY, OR THE PRESENCE OR ABSENCE OF ERRORS, WHETHER OR NOT
548 | KNOWN OR DISCOVERABLE. WHERE DISCLAIMERS OF WARRANTIES ARE NOT
549 | ALLOWED IN FULL OR IN PART, THIS DISCLAIMER MAY NOT APPLY TO YOU.
550 |
551 | b. TO THE EXTENT POSSIBLE, IN NO EVENT WILL THE LICENSOR BE LIABLE
552 | TO YOU ON ANY LEGAL THEORY (INCLUDING, WITHOUT LIMITATION,
553 | NEGLIGENCE) OR OTHERWISE FOR ANY DIRECT, SPECIAL, INDIRECT,
554 | INCIDENTAL, CONSEQUENTIAL, PUNITIVE, EXEMPLARY, OR OTHER LOSSES,
555 | COSTS, EXPENSES, OR DAMAGES ARISING OUT OF THIS PUBLIC LICENSE OR
556 | USE OF THE LICENSED MATERIAL, EVEN IF THE LICENSOR HAS BEEN
557 | ADVISED OF THE POSSIBILITY OF SUCH LOSSES, COSTS, EXPENSES, OR
558 | DAMAGES. WHERE A LIMITATION OF LIABILITY IS NOT ALLOWED IN FULL OR
559 | IN PART, THIS LIMITATION MAY NOT APPLY TO YOU.
560 |
561 | c. The disclaimer of warranties and limitation of liability provided
562 | above shall be interpreted in a manner that, to the extent
563 | possible, most closely approximates an absolute disclaimer and
564 | waiver of all liability.
565 |
566 |
567 | Section 6 -- Term and Termination.
568 |
569 | a. This Public License applies for the term of the Copyright and
570 | Similar Rights licensed here. However, if You fail to comply with
571 | this Public License, then Your rights under this Public License
572 | terminate automatically.
573 |
574 | b. Where Your right to use the Licensed Material has terminated under
575 | Section 6(a), it reinstates:
576 |
577 | 1. automatically as of the date the violation is cured, provided
578 | it is cured within 30 days of Your discovery of the
579 | violation; or
580 |
581 | 2. upon express reinstatement by the Licensor.
582 |
583 | For the avoidance of doubt, this Section 6(b) does not affect any
584 | right the Licensor may have to seek remedies for Your violations
585 | of this Public License.
586 |
587 | c. For the avoidance of doubt, the Licensor may also offer the
588 | Licensed Material under separate terms or conditions or stop
589 | distributing the Licensed Material at any time; however, doing so
590 | will not terminate this Public License.
591 |
592 | d. Sections 1, 5, 6, 7, and 8 survive termination of this Public
593 | License.
594 |
595 |
596 | Section 7 -- Other Terms and Conditions.
597 |
598 | a. The Licensor shall not be bound by any additional or different
599 | terms or conditions communicated by You unless expressly agreed.
600 |
601 | b. Any arrangements, understandings, or agreements regarding the
602 | Licensed Material not stated herein are separate from and
603 | independent of the terms and conditions of this Public License.
604 |
605 |
606 | Section 8 -- Interpretation.
607 |
608 | a. For the avoidance of doubt, this Public License does not, and
609 | shall not be interpreted to, reduce, limit, restrict, or impose
610 | conditions on any use of the Licensed Material that could lawfully
611 | be made without permission under this Public License.
612 |
613 | b. To the extent possible, if any provision of this Public License is
614 | deemed unenforceable, it shall be automatically reformed to the
615 | minimum extent necessary to make it enforceable. If the provision
616 | cannot be reformed, it shall be severed from this Public License
617 | without affecting the enforceability of the remaining terms and
618 | conditions.
619 |
620 | c. No term or condition of this Public License will be waived and no
621 | failure to comply consented to unless expressly agreed to by the
622 | Licensor.
623 |
624 | d. Nothing in this Public License constitutes or may be interpreted
625 | as a limitation upon, or waiver of, any privileges and immunities
626 | that apply to the Licensor or You, including from the legal
627 | processes of any jurisdiction or authority.
628 |
629 | =======================================================================
630 |
631 | Creative Commons is not a party to its public licenses.
632 | Notwithstanding, Creative Commons may elect to apply one of its public
633 | licenses to material it publishes and in those instances will be
634 | considered the "Licensor." Except for the limited purpose of indicating
635 | that material is shared under a Creative Commons public license or as
636 | otherwise permitted by the Creative Commons policies published at
637 | creativecommons.org/policies, Creative Commons does not authorize the
638 | use of the trademark "Creative Commons" or any other trademark or logo
639 | of Creative Commons without its prior written consent including,
640 | without limitation, in connection with any unauthorized modifications
641 | to any of its public licenses or any other arrangements,
642 | understandings, or agreements concerning use of licensed material. For
643 | the avoidance of doubt, this paragraph does not form part of the public
644 | licenses.
645 |
646 | Creative Commons may be contacted at creativecommons.org.
647 |
648 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 |
2 | Android Camera2Basic Sample
3 | ===================================
4 |
5 | This sample demonstrates how to use basic functionalities of Camera2
6 | API. You can learn how to iterate through characteristics of all the
7 | cameras attached to the device, display a camera preview, and take
8 | pictures.
9 |
10 | Introduction
11 | ------------
12 |
13 | The [Camera2 API][1] provides an interface to individual camera
14 | devices connected to an Android device. It replaces the deprecated
15 | Camera class.
16 |
17 | Use [getCameraIdList][2] to get a list of all the available
18 | cameras. You can then use [getCameraCharacteristics][3] and find the
19 | best camera that suits your need (front/rear facing, resolution etc).
20 |
21 | Create an instance of [CameraDevice.StateCallback][4] and open a
22 | camera. It is ready to start camera preview when the camera is opened.
23 |
24 | This sample uses TextureView to show the camera preview. Create a
25 | [CameraCaptureSession][5] and set a repeating [CaptureRequest][6] to it.
26 |
27 | Still image capture takes several steps. First, you need to lock the
28 | focus of the camera by updating the CaptureRequest for the camera
29 | preview. Then, in a similar way, you need to run a precapture
30 | sequence. After that, it is ready to capture a picture. Create a new
31 | CaptureRequest and call [capture][7]. Don't forget to unlock the focus
32 | when you are done.
33 |
34 | [1]: https://developer.android.com/reference/android/hardware/camera2/package-summary.html
35 | [2]: https://developer.android.com/reference/android/hardware/camera2/CameraManager.html#getCameraIdList()
36 | [3]: https://developer.android.com/reference/android/hardware/camera2/CameraManager.html#getCameraCharacteristics(java.lang.String)
37 | [4]: https://developer.android.com/reference/android/hardware/camera2/CameraDevice.StateCallback.html
38 | [5]: https://developer.android.com/reference/android/hardware/camera2/CameraCaptureSession.html
39 | [6]: https://developer.android.com/reference/android/hardware/camera2/CaptureRequest.html
40 | [7]: https://developer.android.com/reference/android/hardware/camera2/CameraCaptureSession.html#capture(android.hardware.camera2.CaptureRequest, android.hardware.camera2.CameraCaptureSession.CaptureCallback, android.os.Handler)
41 |
42 | Pre-requisites
43 | --------------
44 |
45 | - Android SDK v23
46 | - Android Build Tools v23.0.3
47 | - Android Support Repository
48 |
49 | Getting Started
50 | ---------------
51 |
52 | This sample uses the Gradle build system. To build this project, use the
53 | "gradlew build" command or use "Import Project" in Android Studio.
54 |
55 | Support
56 | -------
57 |
58 | - Google+ Community: https://plus.google.com/communities/105153134372062985968
59 | - Stack Overflow: http://stackoverflow.com/questions/tagged/android
60 |
61 | If you've found an error in this sample, please file an issue:
62 | https://github.com/googlesamples/android-Camera2Basic
63 |
64 | Patches are encouraged, and may be submitted by forking this project and
65 | submitting a pull request through GitHub. Please see CONTRIBUTING.md for more details.
66 |
67 | License
68 | -------
69 |
70 | Copyright 2014 The Android Open Source Project, Inc.
71 |
72 | Licensed to the Apache Software Foundation (ASF) under one or more contributor
73 | license agreements. See the NOTICE file distributed with this work for
74 | additional information regarding copyright ownership. The ASF licenses this
75 | file to you under the Apache License, Version 2.0 (the "License"); you may not
76 | use this file except in compliance with the License. You may obtain a copy of
77 | the License at
78 |
79 | http://www.apache.org/licenses/LICENSE-2.0
80 |
81 | Unless required by applicable law or agreed to in writing, software
82 | distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
83 | WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
84 | License for the specific language governing permissions and limitations under
85 | the License.
86 |
--------------------------------------------------------------------------------
/build.gradle:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
--------------------------------------------------------------------------------
/gradle/wrapper/gradle-wrapper.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/shadowsheep1/android-camera2-api-face-recon/4b0cb97dc49e4cbaf5f85be7d327e44d48671d13/gradle/wrapper/gradle-wrapper.jar
--------------------------------------------------------------------------------
/gradle/wrapper/gradle-wrapper.properties:
--------------------------------------------------------------------------------
1 | #Fri Feb 09 11:22:40 CET 2018
2 | distributionBase=GRADLE_USER_HOME
3 | distributionPath=wrapper/dists
4 | zipStoreBase=GRADLE_USER_HOME
5 | zipStorePath=wrapper/dists
6 | distributionUrl=https\://services.gradle.org/distributions/gradle-4.1-all.zip
7 |
--------------------------------------------------------------------------------
/gradlew:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 |
3 | ##############################################################################
4 | ##
5 | ## Gradle start up script for UN*X
6 | ##
7 | ##############################################################################
8 |
9 | # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
10 | DEFAULT_JVM_OPTS=""
11 |
12 | APP_NAME="Gradle"
13 | APP_BASE_NAME=`basename "$0"`
14 |
15 | # Use the maximum available, or set MAX_FD != -1 to use that value.
16 | MAX_FD="maximum"
17 |
18 | warn ( ) {
19 | echo "$*"
20 | }
21 |
22 | die ( ) {
23 | echo
24 | echo "$*"
25 | echo
26 | exit 1
27 | }
28 |
29 | # OS specific support (must be 'true' or 'false').
30 | cygwin=false
31 | msys=false
32 | darwin=false
33 | case "`uname`" in
34 | CYGWIN* )
35 | cygwin=true
36 | ;;
37 | Darwin* )
38 | darwin=true
39 | ;;
40 | MINGW* )
41 | msys=true
42 | ;;
43 | esac
44 |
45 | # For Cygwin, ensure paths are in UNIX format before anything is touched.
46 | if $cygwin ; then
47 | [ -n "$JAVA_HOME" ] && JAVA_HOME=`cygpath --unix "$JAVA_HOME"`
48 | fi
49 |
50 | # Attempt to set APP_HOME
51 | # Resolve links: $0 may be a link
52 | PRG="$0"
53 | # Need this for relative symlinks.
54 | while [ -h "$PRG" ] ; do
55 | ls=`ls -ld "$PRG"`
56 | link=`expr "$ls" : '.*-> \(.*\)$'`
57 | if expr "$link" : '/.*' > /dev/null; then
58 | PRG="$link"
59 | else
60 | PRG=`dirname "$PRG"`"/$link"
61 | fi
62 | done
63 | SAVED="`pwd`"
64 | cd "`dirname \"$PRG\"`/" >&-
65 | APP_HOME="`pwd -P`"
66 | cd "$SAVED" >&-
67 |
68 | CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
69 |
70 | # Determine the Java command to use to start the JVM.
71 | if [ -n "$JAVA_HOME" ] ; then
72 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
73 | # IBM's JDK on AIX uses strange locations for the executables
74 | JAVACMD="$JAVA_HOME/jre/sh/java"
75 | else
76 | JAVACMD="$JAVA_HOME/bin/java"
77 | fi
78 | if [ ! -x "$JAVACMD" ] ; then
79 | die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
80 |
81 | Please set the JAVA_HOME variable in your environment to match the
82 | location of your Java installation."
83 | fi
84 | else
85 | JAVACMD="java"
86 | which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
87 |
88 | Please set the JAVA_HOME variable in your environment to match the
89 | location of your Java installation."
90 | fi
91 |
92 | # Increase the maximum file descriptors if we can.
93 | if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then
94 | MAX_FD_LIMIT=`ulimit -H -n`
95 | if [ $? -eq 0 ] ; then
96 | if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
97 | MAX_FD="$MAX_FD_LIMIT"
98 | fi
99 | ulimit -n $MAX_FD
100 | if [ $? -ne 0 ] ; then
101 | warn "Could not set maximum file descriptor limit: $MAX_FD"
102 | fi
103 | else
104 | warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
105 | fi
106 | fi
107 |
108 | # For Darwin, add options to specify how the application appears in the dock
109 | if $darwin; then
110 | GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
111 | fi
112 |
113 | # For Cygwin, switch paths to Windows format before running java
114 | if $cygwin ; then
115 | APP_HOME=`cygpath --path --mixed "$APP_HOME"`
116 | CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
117 |
118 | # We build the pattern for arguments to be converted via cygpath
119 | ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
120 | SEP=""
121 | for dir in $ROOTDIRSRAW ; do
122 | ROOTDIRS="$ROOTDIRS$SEP$dir"
123 | SEP="|"
124 | done
125 | OURCYGPATTERN="(^($ROOTDIRS))"
126 | # Add a user-defined pattern to the cygpath arguments
127 | if [ "$GRADLE_CYGPATTERN" != "" ] ; then
128 | OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
129 | fi
130 | # Now convert the arguments - kludge to limit ourselves to /bin/sh
131 | i=0
132 | for arg in "$@" ; do
133 | CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
134 | CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
135 |
136 | if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
137 | eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
138 | else
139 | eval `echo args$i`="\"$arg\""
140 | fi
141 | i=$((i+1))
142 | done
143 | case $i in
144 | (0) set -- ;;
145 | (1) set -- "$args0" ;;
146 | (2) set -- "$args0" "$args1" ;;
147 | (3) set -- "$args0" "$args1" "$args2" ;;
148 | (4) set -- "$args0" "$args1" "$args2" "$args3" ;;
149 | (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
150 | (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
151 | (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
152 | (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
153 | (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
154 | esac
155 | fi
156 |
157 | # Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules
158 | function splitJvmOpts() {
159 | JVM_OPTS=("$@")
160 | }
161 | eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS
162 | JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME"
163 |
164 | exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@"
165 |
--------------------------------------------------------------------------------
/gradlew.bat:
--------------------------------------------------------------------------------
1 | @if "%DEBUG%" == "" @echo off
2 | @rem ##########################################################################
3 | @rem
4 | @rem Gradle startup script for Windows
5 | @rem
6 | @rem ##########################################################################
7 |
8 | @rem Set local scope for the variables with windows NT shell
9 | if "%OS%"=="Windows_NT" setlocal
10 |
11 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
12 | set DEFAULT_JVM_OPTS=
13 |
14 | set DIRNAME=%~dp0
15 | if "%DIRNAME%" == "" set DIRNAME=.
16 | set APP_BASE_NAME=%~n0
17 | set APP_HOME=%DIRNAME%
18 |
19 | @rem Find java.exe
20 | if defined JAVA_HOME goto findJavaFromJavaHome
21 |
22 | set JAVA_EXE=java.exe
23 | %JAVA_EXE% -version >NUL 2>&1
24 | if "%ERRORLEVEL%" == "0" goto init
25 |
26 | echo.
27 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
28 | echo.
29 | echo Please set the JAVA_HOME variable in your environment to match the
30 | echo location of your Java installation.
31 |
32 | goto fail
33 |
34 | :findJavaFromJavaHome
35 | set JAVA_HOME=%JAVA_HOME:"=%
36 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe
37 |
38 | if exist "%JAVA_EXE%" goto init
39 |
40 | echo.
41 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
42 | echo.
43 | echo Please set the JAVA_HOME variable in your environment to match the
44 | echo location of your Java installation.
45 |
46 | goto fail
47 |
48 | :init
49 | @rem Get command-line arguments, handling Windowz variants
50 |
51 | if not "%OS%" == "Windows_NT" goto win9xME_args
52 | if "%@eval[2+2]" == "4" goto 4NT_args
53 |
54 | :win9xME_args
55 | @rem Slurp the command line arguments.
56 | set CMD_LINE_ARGS=
57 | set _SKIP=2
58 |
59 | :win9xME_args_slurp
60 | if "x%~1" == "x" goto execute
61 |
62 | set CMD_LINE_ARGS=%*
63 | goto execute
64 |
65 | :4NT_args
66 | @rem Get arguments from the 4NT Shell from JP Software
67 | set CMD_LINE_ARGS=%$
68 |
69 | :execute
70 | @rem Setup the command line
71 |
72 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
73 |
74 | @rem Execute Gradle
75 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
76 |
77 | :end
78 | @rem End local scope for the variables with windows NT shell
79 | if "%ERRORLEVEL%"=="0" goto mainEnd
80 |
81 | :fail
82 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
83 | rem the _cmd.exe /c_ return code!
84 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
85 | exit /b 1
86 |
87 | :mainEnd
88 | if "%OS%"=="Windows_NT" endlocal
89 |
90 | :omega
91 |
--------------------------------------------------------------------------------
/packaging.yaml:
--------------------------------------------------------------------------------
1 | # GOOGLE SAMPLE PACKAGING DATA
2 | #
3 | # This file is used by Google as part of our samples packaging process.
4 | # End users may safely ignore this file. It has no relevance to other systems.
5 | ---
6 |
7 | status: PUBLISHED
8 | technologies: [Android]
9 | categories: [Media]
10 | languages: [Java]
11 | solutions: [Mobile]
12 | github: googlesamples/android-Camera2Basic
13 | level: BEGINNER
14 | icon: Camera2BasicSample/src/main/res/drawable-xxhdpi/ic_launcher.png
15 | license: apache2
16 |
--------------------------------------------------------------------------------
/settings.gradle:
--------------------------------------------------------------------------------
1 | include 'Application'
2 |
--------------------------------------------------------------------------------