Skip to content

Commit 6d4d017

Browse files
committed
Updating samples to handle the new permissions model in M.
Change-Id: I78ca92adf755a8f4cafd86740c38c338765c60f9
1 parent 3cafe19 commit 6d4d017

File tree

8 files changed

+318
-36
lines changed

8 files changed

+318
-36
lines changed

visionSamples/FaceTracker/app/build.gradle

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,13 @@
11
apply plugin: 'com.android.application'
22

33
android {
4-
compileSdkVersion 22
4+
compileSdkVersion 23
55
buildToolsVersion "22.0.1"
66

77
defaultConfig {
88
applicationId "com.google.android.gms.samples.vision.face.facetracker"
99
minSdkVersion 9
10-
targetSdkVersion 22
10+
targetSdkVersion 23
1111
versionCode 1
1212
versionName "1.0"
1313
}
@@ -21,6 +21,7 @@ android {
2121

2222
dependencies {
2323
compile fileTree(dir: 'libs', include: ['*.jar'])
24-
compile 'com.android.support:appcompat-v7:22.2.0'
24+
compile 'com.android.support:support-v4:23+'
2525
compile 'com.google.android.gms:play-services:7.8.+'
26+
compile 'com.android.support:design:23.0.0'
2627
}

visionSamples/FaceTracker/app/src/main/AndroidManifest.xml

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,14 +11,18 @@
1111

1212
<uses-sdk
1313
android:minSdkVersion="9"
14-
android:targetSdkVersion="21" />
14+
android:targetSdkVersion="23" />
1515

1616
<application
1717
android:allowBackup="true"
1818
android:hardwareAccelerated="true"
1919
android:icon="@drawable/icon"
20+
android:theme="@style/Theme.AppCompat"
2021
android:label="FaceTracker">
2122

23+
<meta-data android:name="com.google.android.gms.version"
24+
android:value="@integer/google_play_services_version"/>
25+
2226
<meta-data
2327
android:name="com.google.android.gms.vision.DEPENDENCIES"
2428
android:value="face" />
@@ -27,7 +31,7 @@
2731
android:name="com.google.android.gms.samples.vision.face.facetracker.FaceTrackerActivity"
2832
android:icon="@drawable/icon"
2933
android:label="Face Tracker"
30-
android:theme="@android:style/Theme.Black.NoTitleBar"
34+
android:theme="@style/Theme.AppCompat.NoActionBar"
3135
android:screenOrientation="fullSensor">
3236
<intent-filter>
3337
<action android:name="android.intent.action.MAIN" />
@@ -37,4 +41,4 @@
3741
</activity>
3842
</application>
3943

40-
</manifest>
44+
</manifest>

visionSamples/FaceTracker/app/src/main/java/com/google/android/gms/samples/vision/face/facetracker/FaceTrackerActivity.java

Lines changed: 142 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -15,11 +15,22 @@
1515
*/
1616
package com.google.android.gms.samples.vision.face.facetracker;
1717

18+
import android.Manifest;
1819
import android.app.Activity;
20+
import android.app.AlertDialog;
21+
import android.app.Dialog;
1922
import android.content.Context;
23+
import android.content.DialogInterface;
24+
import android.content.pm.PackageManager;
2025
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;
2129
import android.util.Log;
30+
import android.view.View;
2231

32+
import com.google.android.gms.common.ConnectionResult;
33+
import com.google.android.gms.common.GoogleApiAvailability;
2334
import com.google.android.gms.vision.CameraSource;
2435
import com.google.android.gms.vision.MultiProcessor;
2536
import com.google.android.gms.vision.Tracker;
@@ -34,13 +45,18 @@
3445
* Activity for the face tracker app. This app detects faces with the rear facing camera, and draws
3546
* overlay graphics to indicate the position, size, and ID of each face.
3647
*/
37-
public final class FaceTrackerActivity extends Activity {
48+
public final class FaceTrackerActivity extends AppCompatActivity {
3849
private static final String TAG = "FaceTracker";
3950

40-
private CameraSource mCameraSource;
51+
private CameraSource mCameraSource = null;
52+
4153
private CameraSourcePreview mPreview;
4254
private GraphicOverlay mGraphicOverlay;
4355

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+
4460
//==============================================================================================
4561
// Activity Methods
4662
//==============================================================================================
@@ -56,12 +72,63 @@ public void onCreate(Bundle icicle) {
5672
mPreview = (CameraSourcePreview) findViewById(R.id.preview);
5773
mGraphicOverlay = (GraphicOverlay) findViewById(R.id.faceOverlay);
5874

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+
59124
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+
63129
detector.setProcessor(
64-
new MultiProcessor.Builder<>(new GraphicFaceTrackerFactory()).build());
130+
new MultiProcessor.Builder<>(new GraphicFaceTrackerFactory())
131+
.build());
65132

66133
if (!detector.isOperational()) {
67134
// 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) {
88155
@Override
89156
protected void onResume() {
90157
super.onResume();
158+
91159
startCameraSource();
92160
}
93161

@@ -107,7 +175,56 @@ protected void onPause() {
107175
@Override
108176
protected void onDestroy() {
109177
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();
111228
}
112229

113230
//==============================================================================================
@@ -120,12 +237,24 @@ protected void onDestroy() {
120237
* again when the camera source is created.
121238
*/
122239
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+
}
129258
}
130259
}
131260

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
<?xml version="1.0" encoding="utf-8"?>
2+
<resources>
3+
<string name="ok">OK</string>
4+
<string name="permission_camera_rationale">Access to the camera is needed for detection</string>
5+
<string name="no_camera_permission">This application cannot run because it does not have the camera permission. The application will now exit.</string>
6+
</resources>

visionSamples/multi-tracker/app/build.gradle

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,13 @@
11
apply plugin: 'com.android.application'
22

33
android {
4-
compileSdkVersion 22
4+
compileSdkVersion 23
55
buildToolsVersion "22.0.1"
66

77
defaultConfig {
88
applicationId "com.google.android.gms.samples.vision.face.multitracker"
9-
minSdkVersion 21
10-
targetSdkVersion 22
9+
minSdkVersion 9
10+
targetSdkVersion 23
1111
versionCode 1
1212
versionName "1.0"
1313
}
@@ -21,6 +21,7 @@ android {
2121

2222
dependencies {
2323
compile fileTree(dir: 'libs', include: ['*.jar'])
24-
compile 'com.android.support:appcompat-v7:22.2.0'
24+
compile 'com.android.support:support-v4:23+'
2525
compile 'com.google.android.gms:play-services:7.8.+'
26+
compile 'com.android.support:design:23.0.0'
2627
}

visionSamples/multi-tracker/app/src/main/AndroidManifest.xml

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,15 +10,19 @@
1010
<uses-permission android:name="android.permission.CAMERA" />
1111

1212
<uses-sdk
13-
android:minSdkVersion="21"
14-
android:targetSdkVersion="21" />
13+
android:minSdkVersion="9"
14+
android:targetSdkVersion="23" />
1515

1616
<application
1717
android:allowBackup="true"
1818
android:hardwareAccelerated="true"
1919
android:icon="@drawable/icon"
20+
android:theme="@style/Theme.AppCompat"
2021
android:label="MultiTrackerApp">
2122

23+
<meta-data android:name="com.google.android.gms.version"
24+
android:value="@integer/google_play_services_version"/>
25+
2226
<meta-data
2327
android:name="com.google.android.gms.vision.DEPENDENCIES"
2428
android:value="barcode,face" />
@@ -27,7 +31,7 @@
2731
android:name="com.google.android.gms.samples.vision.face.multitracker.MultiTrackerActivity"
2832
android:icon="@drawable/icon"
2933
android:label="Multi-Tracker"
30-
android:theme="@android:style/Theme.Black.NoTitleBar"
34+
android:theme="@style/Theme.AppCompat.NoActionBar"
3135
android:screenOrientation="fullSensor">
3236
<intent-filter>
3337
<action android:name="android.intent.action.MAIN" />

0 commit comments

Comments
 (0)