15
15
*/
16
16
package com .google .android .gms .samples .vision .face .facetracker ;
17
17
18
+ import android .Manifest ;
18
19
import android .app .Activity ;
20
+ import android .app .AlertDialog ;
21
+ import android .app .Dialog ;
19
22
import android .content .Context ;
23
+ import android .content .DialogInterface ;
24
+ import android .content .pm .PackageManager ;
20
25
import android .os .Bundle ;
26
+ import android .support .design .widget .Snackbar ;
27
+ import android .support .v4 .app .ActivityCompat ;
28
+ import android .support .v7 .app .AppCompatActivity ;
21
29
import android .util .Log ;
30
+ import android .view .View ;
22
31
32
+ import com .google .android .gms .common .ConnectionResult ;
33
+ import com .google .android .gms .common .GoogleApiAvailability ;
23
34
import com .google .android .gms .vision .CameraSource ;
24
35
import com .google .android .gms .vision .MultiProcessor ;
25
36
import com .google .android .gms .vision .Tracker ;
34
45
* Activity for the face tracker app. This app detects faces with the rear facing camera, and draws
35
46
* overlay graphics to indicate the position, size, and ID of each face.
36
47
*/
37
- public final class FaceTrackerActivity extends Activity {
48
+ public final class FaceTrackerActivity extends AppCompatActivity {
38
49
private static final String TAG = "FaceTracker" ;
39
50
40
- private CameraSource mCameraSource ;
51
+ private CameraSource mCameraSource = null ;
52
+
41
53
private CameraSourcePreview mPreview ;
42
54
private GraphicOverlay mGraphicOverlay ;
43
55
56
+ private static final int RC_HANDLE_GMS = 9001 ;
57
+ // permission request codes need to be < 256
58
+ private static final int RC_HANDLE_CAMERA_PERM = 2 ;
59
+
44
60
//==============================================================================================
45
61
// Activity Methods
46
62
//==============================================================================================
@@ -56,12 +72,63 @@ public void onCreate(Bundle icicle) {
56
72
mPreview = (CameraSourcePreview ) findViewById (R .id .preview );
57
73
mGraphicOverlay = (GraphicOverlay ) findViewById (R .id .faceOverlay );
58
74
75
+ // Check for the camera permission before accessing the camera. If the
76
+ // permission is not granted yet, request permission.
77
+ int rc = ActivityCompat .checkSelfPermission (this , Manifest .permission .CAMERA );
78
+ if (rc == PackageManager .PERMISSION_GRANTED ) {
79
+ createCameraSource ();
80
+ } else {
81
+ requestCameraPermission ();
82
+ }
83
+ }
84
+
85
+ /**
86
+ * Handles the requesting of the camera permission. This includes
87
+ * showing a "Snackbar" message of why the permission is needed then
88
+ * sending the request.
89
+ */
90
+ private void requestCameraPermission () {
91
+ Log .w (TAG , "Camera permission is not granted. Requesting permission" );
92
+
93
+ final String [] permissions = new String []{Manifest .permission .CAMERA };
94
+
95
+ if (!ActivityCompat .shouldShowRequestPermissionRationale (this ,
96
+ Manifest .permission .CAMERA )) {
97
+ ActivityCompat .requestPermissions (this , permissions , RC_HANDLE_CAMERA_PERM );
98
+ return ;
99
+ }
100
+
101
+ final Activity thisActivity = this ;
102
+
103
+ View .OnClickListener listener = new View .OnClickListener () {
104
+ @ Override
105
+ public void onClick (View view ) {
106
+ ActivityCompat .requestPermissions (thisActivity , permissions ,
107
+ RC_HANDLE_CAMERA_PERM );
108
+ }
109
+ };
110
+
111
+ Snackbar .make (mGraphicOverlay , R .string .permission_camera_rationale ,
112
+ Snackbar .LENGTH_INDEFINITE )
113
+ .setAction (R .string .ok , listener )
114
+ .show ();
115
+ }
116
+
117
+ /**
118
+ * Creates and starts the camera. Note that this uses a higher resolution in comparison
119
+ * to other detection examples to enable the barcode detector to detect small barcodes
120
+ * at long distances.
121
+ */
122
+ private void createCameraSource () {
123
+
59
124
Context context = getApplicationContext ();
60
- FaceDetector .Builder detectorBuilder = new FaceDetector .Builder (context );
61
- detectorBuilder .setClassificationType (FaceDetector .ALL_CLASSIFICATIONS );
62
- FaceDetector detector = detectorBuilder .build ();
125
+ FaceDetector detector = new FaceDetector .Builder (context )
126
+ .setClassificationType (FaceDetector .ALL_CLASSIFICATIONS )
127
+ .build ();
128
+
63
129
detector .setProcessor (
64
- new MultiProcessor .Builder <>(new GraphicFaceTrackerFactory ()).build ());
130
+ new MultiProcessor .Builder <>(new GraphicFaceTrackerFactory ())
131
+ .build ());
65
132
66
133
if (!detector .isOperational ()) {
67
134
// Note: The first time that an app using face API is installed on a device, GMS will
@@ -88,6 +155,7 @@ public void onCreate(Bundle icicle) {
88
155
@ Override
89
156
protected void onResume () {
90
157
super .onResume ();
158
+
91
159
startCameraSource ();
92
160
}
93
161
@@ -107,7 +175,56 @@ protected void onPause() {
107
175
@ Override
108
176
protected void onDestroy () {
109
177
super .onDestroy ();
110
- mCameraSource .release ();
178
+ if (mCameraSource != null ) {
179
+ mCameraSource .release ();
180
+ }
181
+ }
182
+
183
+ /**
184
+ * Callback for the result from requesting permissions. This method
185
+ * is invoked for every call on {@link #requestPermissions(String[], int)}.
186
+ * <p>
187
+ * <strong>Note:</strong> It is possible that the permissions request interaction
188
+ * with the user is interrupted. In this case you will receive empty permissions
189
+ * and results arrays which should be treated as a cancellation.
190
+ * </p>
191
+ *
192
+ * @param requestCode The request code passed in {@link #requestPermissions(String[], int)}.
193
+ * @param permissions The requested permissions. Never null.
194
+ * @param grantResults The grant results for the corresponding permissions
195
+ * which is either {@link PackageManager#PERMISSION_GRANTED}
196
+ * or {@link PackageManager#PERMISSION_DENIED}. Never null.
197
+ * @see #requestPermissions(String[], int)
198
+ */
199
+ @ Override
200
+ public void onRequestPermissionsResult (int requestCode , String [] permissions , int [] grantResults ) {
201
+ if (requestCode != RC_HANDLE_CAMERA_PERM ) {
202
+ Log .d (TAG , "Got unexpected permission result: " + requestCode );
203
+ super .onRequestPermissionsResult (requestCode , permissions , grantResults );
204
+ return ;
205
+ }
206
+
207
+ if (grantResults .length != 0 && grantResults [0 ] == PackageManager .PERMISSION_GRANTED ) {
208
+ Log .d (TAG , "Camera permission granted - initialize the camera source" );
209
+ // we have permission, so create the camerasource
210
+ createCameraSource ();
211
+ return ;
212
+ }
213
+
214
+ Log .e (TAG , "Permission not granted: results len = " + grantResults .length +
215
+ " Result code = " + (grantResults .length > 0 ? grantResults [0 ] : "(empty)" ));
216
+
217
+ DialogInterface .OnClickListener listener = new DialogInterface .OnClickListener () {
218
+ public void onClick (DialogInterface dialog , int id ) {
219
+ finish ();
220
+ }
221
+ };
222
+
223
+ AlertDialog .Builder builder = new AlertDialog .Builder (this );
224
+ builder .setTitle ("Face Tracker sample" )
225
+ .setMessage (R .string .no_camera_permission )
226
+ .setPositiveButton (R .string .ok , listener )
227
+ .show ();
111
228
}
112
229
113
230
//==============================================================================================
@@ -120,12 +237,24 @@ protected void onDestroy() {
120
237
* again when the camera source is created.
121
238
*/
122
239
private void startCameraSource () {
123
- try {
124
- mPreview .start (mCameraSource , mGraphicOverlay );
125
- } catch (IOException e ) {
126
- Log .e (TAG , "Unable to start camera source." , e );
127
- mCameraSource .release ();
128
- mCameraSource = null ;
240
+
241
+ // check that the device has play services available.
242
+ int code = GoogleApiAvailability .getInstance ().isGooglePlayServicesAvailable (
243
+ getApplicationContext ());
244
+ if (code != ConnectionResult .SUCCESS ) {
245
+ Dialog dlg =
246
+ GoogleApiAvailability .getInstance ().getErrorDialog (this , code , RC_HANDLE_GMS );
247
+ dlg .show ();
248
+ }
249
+
250
+ if (mCameraSource != null ) {
251
+ try {
252
+ mPreview .start (mCameraSource , mGraphicOverlay );
253
+ } catch (IOException e ) {
254
+ Log .e (TAG , "Unable to start camera source." , e );
255
+ mCameraSource .release ();
256
+ mCameraSource = null ;
257
+ }
129
258
}
130
259
}
131
260
0 commit comments