From 4ed03b29cd53f0c9f430a4177248dd887808d724 Mon Sep 17 00:00:00 2001 From: Ibrahim Ulukaya Date: Mon, 24 Aug 2015 14:19:17 -0400 Subject: [PATCH] Adding permissions for Android M Release --- app/build.gradle | 15 ++-- app/src/main/AndroidManifest.xml | 13 +--- .../apps/watchme/EventsListFragment.java | 9 +-- .../apps/watchme/StreamerActivity.java | 73 ++++++++++++++++++- .../android/apps/watchme/StreamerService.java | 17 +++-- .../android/apps/watchme/util/Utils.java | 22 ++++++ app/src/main/res/values/strings.xml | 3 + build.gradle | 2 +- gradle/wrapper/gradle-wrapper.properties | 4 +- yt-watchme.iml | 19 +++++ 10 files changed, 145 insertions(+), 32 deletions(-) create mode 100644 yt-watchme.iml diff --git a/app/build.gradle b/app/build.gradle index 62e1c48..783ecee 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -1,20 +1,20 @@ apply plugin: 'com.android.application' android { - compileSdkVersion 19 - buildToolsVersion "19.1" + compileSdkVersion 23 + buildToolsVersion "23.0.0" defaultConfig { applicationId "com.google.android.apps.watchme" minSdkVersion 16 - targetSdkVersion 19 + targetSdkVersion 23 versionCode 1 versionName "1.0" } buildTypes { release { - runProguard false + minifyEnabled false proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' } } @@ -22,11 +22,12 @@ android { dependencies { compile fileTree(dir: 'libs', include: ['*.jar']) - compile 'com.google.android.gms:play-services:+' - compile 'com.android.support:support-v13:20.0.0' + compile 'com.google.android.gms:play-services-plus:7.8.0' + compile 'com.android.support:support-v4:23.0.0' + compile 'com.android.support:design:23.0.0' compile 'com.google.apis:google-api-services-youtube:v3-rev120-1.19.0' compile 'com.google.http-client:google-http-client-android:+' compile 'com.google.api-client:google-api-client-android:+' compile 'com.google.api-client:google-api-client-gson:+' - compile 'com.google.code.gson:gson:2.2.4' + compile 'com.google.code.gson:gson:2.3' } diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index be389a4..b8763b4 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -18,17 +18,14 @@ package="com.google.android.apps.watchme"> - - - - - @@ -57,11 +50,11 @@ - + \ No newline at end of file diff --git a/app/src/main/java/com/google/android/apps/watchme/EventsListFragment.java b/app/src/main/java/com/google/android/apps/watchme/EventsListFragment.java index bdcc27a..0c2632d 100644 --- a/app/src/main/java/com/google/android/apps/watchme/EventsListFragment.java +++ b/app/src/main/java/com/google/android/apps/watchme/EventsListFragment.java @@ -32,7 +32,8 @@ import com.google.android.apps.watchme.util.ImageFetcher; import com.google.android.apps.watchme.util.ImageWorker; import com.google.android.gms.common.ConnectionResult; -import com.google.android.gms.common.GooglePlayServicesClient.ConnectionCallbacks; +import com.google.android.gms.common.api.GoogleApiClient.ConnectionCallbacks; +import com.google.android.gms.common.api.GoogleApiClient.ConnectionCallbacks; import com.google.android.gms.common.api.GoogleApiClient; import com.google.android.gms.plus.Plus; import com.google.android.gms.plus.PlusOneButton; @@ -46,7 +47,7 @@ * Left side fragment showing user's uploaded YouTube videos. */ public class EventsListFragment extends Fragment implements - ConnectionCallbacks, GoogleApiClient.OnConnectionFailedListener, GoogleApiClient.ConnectionCallbacks { + ConnectionCallbacks, GoogleApiClient.OnConnectionFailedListener { private static final String TAG = EventsListFragment.class.getName(); private Callbacks mCallbacks; @@ -142,10 +143,6 @@ public void onConnectionSuspended(int i) { } - @Override - public void onDisconnected() { - } - @Override public void onConnectionFailed(ConnectionResult connectionResult) { if (connectionResult.hasResolution()) { diff --git a/app/src/main/java/com/google/android/apps/watchme/StreamerActivity.java b/app/src/main/java/com/google/android/apps/watchme/StreamerActivity.java index 5d2aa29..cc3bda2 100644 --- a/app/src/main/java/com/google/android/apps/watchme/StreamerActivity.java +++ b/app/src/main/java/com/google/android/apps/watchme/StreamerActivity.java @@ -14,15 +14,19 @@ package com.google.android.apps.watchme; +import android.Manifest; import android.app.Activity; import android.content.ComponentName; import android.content.Context; import android.content.Intent; import android.content.ServiceConnection; +import android.content.pm.PackageManager; import android.hardware.Camera; import android.os.Bundle; import android.os.IBinder; import android.os.PowerManager; +import android.support.design.widget.Snackbar; +import android.support.v4.app.ActivityCompat; import android.util.Log; import android.view.View; import android.view.View.OnClickListener; @@ -31,6 +35,9 @@ import com.google.android.apps.watchme.util.Utils; import com.google.android.apps.watchme.util.YouTubeApi; +import java.util.ArrayList; +import java.util.List; + /** * @author Ibrahim Ulukaya *

@@ -41,6 +48,8 @@ public class StreamerActivity extends Activity { // TODO: Stop hardcoding this and read values from the camera's supported sizes. public static final int CAMERA_WIDTH = 640; public static final int CAMERA_HEIGHT = 480; + private static final int REQUEST_CAMERA_MICROPHONE = 0; + // Member variables private StreamerService streamerService; @@ -160,10 +169,72 @@ private void startStreaming() { wakeLock.acquire(); if (!streamerService.isStreaming()) { - streamerService.startStreaming(rtmpUrl); + + String cameraPermission = Manifest.permission.CAMERA; + String microphonePermission = Manifest.permission.RECORD_AUDIO; + int hasCamPermission = checkSelfPermission(cameraPermission); + int hasMicPermission = checkSelfPermission(microphonePermission); + List permissions = new ArrayList(); + if (hasCamPermission != PackageManager.PERMISSION_GRANTED) { + permissions.add(cameraPermission); + if (ActivityCompat.shouldShowRequestPermissionRationale(this, + Manifest.permission.CAMERA)) { + // Provide rationale in Snackbar with button to request permission + Snackbar.make(preview, R.string.permission_camera_rationale, + Snackbar.LENGTH_INDEFINITE).show(); + } + } + if (hasMicPermission != PackageManager.PERMISSION_GRANTED) { + permissions.add(microphonePermission); + if (ActivityCompat.shouldShowRequestPermissionRationale(this, + Manifest.permission.RECORD_AUDIO)) { + // Provide rationale in Snackbar with button to request permission + Snackbar.make(preview, R.string.permission_microphone_rationale, + Snackbar.LENGTH_INDEFINITE).show(); + } + } + if (!permissions.isEmpty()) { + String[] params = permissions.toArray(new String[permissions.size()]); + ActivityCompat.requestPermissions(this, params, REQUEST_CAMERA_MICROPHONE); + } else { + // We already have permission, so handle as normal + streamerService.startStreaming(rtmpUrl); + } + } + } + + /** + * Callback received when a permissions request has been completed. + */ + @Override + public void onRequestPermissionsResult(int requestCode, + String permissions[], int[] grantResults) { + switch (requestCode) { + case REQUEST_CAMERA_MICROPHONE: { + Log.i(MainActivity.APP_NAME, "Received response for camera with mic permissions request."); + + // We have requested multiple permissions for contacts, so all of them need to be + // checked. + if (Utils.verifyPermissions(grantResults)) { + // permissions were granted, yay! do the + // streamer task you need to do. + streamerService.startStreaming(rtmpUrl); + } else { + Log.i(MainActivity.APP_NAME, "Camera with mic permissions were NOT granted."); + Snackbar.make(preview, R.string.permissions_not_granted, + Snackbar.LENGTH_SHORT) + .show(); + } + break; + } + + // other 'switch' lines to check for other + // permissions this app might request } + return; } + private void stopStreaming() { Log.d(MainActivity.APP_NAME, "stopStreaming"); diff --git a/app/src/main/java/com/google/android/apps/watchme/StreamerService.java b/app/src/main/java/com/google/android/apps/watchme/StreamerService.java index 2aebf5c..f8b7daa 100644 --- a/app/src/main/java/com/google/android/apps/watchme/StreamerService.java +++ b/app/src/main/java/com/google/android/apps/watchme/StreamerService.java @@ -14,20 +14,28 @@ package com.google.android.apps.watchme; +import android.Manifest; import android.app.Notification; import android.app.NotificationManager; import android.app.PendingIntent; import android.app.Service; import android.content.Context; import android.content.Intent; +import android.content.pm.PackageManager; import android.hardware.Camera; import android.hardware.Camera.CameraInfo; import android.os.Binder; import android.os.IBinder; +import android.support.design.widget.Snackbar; +import android.support.v4.app.ActivityCompat; import android.util.Log; +import android.view.View; import com.google.android.apps.watchme.util.Utils; +import java.util.ArrayList; +import java.util.List; + /** * @author Ibrahim Ulukaya *

@@ -66,11 +74,10 @@ public boolean onUnbind(Intent intent) { public void startStreaming(String streamUrl) { Log.d(MainActivity.APP_NAME, "startStreaming"); - - showForegroundNotification(); - connection = new VideoStreamingConnection(); - // TODO Pass an actual preview surface. - connection.open(streamUrl, camera, null); + showForegroundNotification(); + connection = new VideoStreamingConnection(); + // TODO Pass an actual preview surface. + connection.open(streamUrl, camera, null); } public void stopStreaming() { diff --git a/app/src/main/java/com/google/android/apps/watchme/util/Utils.java b/app/src/main/java/com/google/android/apps/watchme/util/Utils.java index 54c6f26..5edd0a4 100644 --- a/app/src/main/java/com/google/android/apps/watchme/util/Utils.java +++ b/app/src/main/java/com/google/android/apps/watchme/util/Utils.java @@ -16,6 +16,7 @@ package com.google.android.apps.watchme.util; import android.app.Activity; +import android.content.pm.PackageManager; import android.content.res.Resources; import android.hardware.Camera; import android.os.Build; @@ -149,4 +150,25 @@ private static String getErrorMessage(Activity activity, String message) { } return resources.getString(R.string.error_format, message); } + + /** + * Check that all given permissions have been granted by verifying that each entry in the + * given array is of the value {@link PackageManager#PERMISSION_GRANTED}. + * + * @see Activity#onRequestPermissionsResult(int, String[], int[]) + */ + public static boolean verifyPermissions(int[] grantResults) { + // At least one result must be checked. + if(grantResults.length < 1){ + return false; + } + + // Verify that each required permission has been granted, otherwise return false. + for (int result : grantResults) { + if (result != PackageManager.PERMISSION_GRANTED) { + return false; + } + } + return true; + } } diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index e340ee3..fb627e6 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -38,4 +38,7 @@ Starting event. Please wait… Ending event. Please wait… video thumbnail + App needs camera for video stream. + App needs microphone for audio stream. + Streaming service won\'t be able to work without camera and microphone permissions. \ No newline at end of file diff --git a/build.gradle b/build.gradle index 782b676..71d2fd6 100644 --- a/build.gradle +++ b/build.gradle @@ -5,7 +5,7 @@ buildscript { jcenter() } dependencies { - classpath 'com.android.tools.build:gradle:0.12.2' + classpath 'com.android.tools.build:gradle:1.3.0' } } diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index 1e61d1f..5d492af 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ -#Wed Apr 10 15:27:10 PDT 2013 +#Thu Aug 20 11:12:54 EDT 2015 distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists -distributionUrl=http\://services.gradle.org/distributions/gradle-1.12-all.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-2.4-all.zip diff --git a/yt-watchme.iml b/yt-watchme.iml new file mode 100644 index 0000000..94b12df --- /dev/null +++ b/yt-watchme.iml @@ -0,0 +1,19 @@ + + + + + + + + + + + + + + + + + \ No newline at end of file