1*90c8c64dSAndroid Build Coastguard Worker /* 2*90c8c64dSAndroid Build Coastguard Worker * Copyright 2015 The Android Open Source Project 3*90c8c64dSAndroid Build Coastguard Worker * 4*90c8c64dSAndroid Build Coastguard Worker * Licensed under the Apache License, Version 2.0 (the "License"); 5*90c8c64dSAndroid Build Coastguard Worker * you may not use this file except in compliance with the License. 6*90c8c64dSAndroid Build Coastguard Worker * You may obtain a copy of the License at 7*90c8c64dSAndroid Build Coastguard Worker * 8*90c8c64dSAndroid Build Coastguard Worker * http://www.apache.org/licenses/LICENSE-2.0 9*90c8c64dSAndroid Build Coastguard Worker * 10*90c8c64dSAndroid Build Coastguard Worker * Unless required by applicable law or agreed to in writing, software 11*90c8c64dSAndroid Build Coastguard Worker * distributed under the License is distributed on an "AS IS" BASIS, 12*90c8c64dSAndroid Build Coastguard Worker * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13*90c8c64dSAndroid Build Coastguard Worker * See the License for the specific language governing permissions and 14*90c8c64dSAndroid Build Coastguard Worker * limitations under the License. 15*90c8c64dSAndroid Build Coastguard Worker */ 16*90c8c64dSAndroid Build Coastguard Worker 17*90c8c64dSAndroid Build Coastguard Worker package com.example.android.system.runtimepermissions; 18*90c8c64dSAndroid Build Coastguard Worker 19*90c8c64dSAndroid Build Coastguard Worker import com.example.android.common.logger.Log; 20*90c8c64dSAndroid Build Coastguard Worker import com.example.android.common.logger.LogFragment; 21*90c8c64dSAndroid Build Coastguard Worker import com.example.android.common.logger.LogWrapper; 22*90c8c64dSAndroid Build Coastguard Worker import com.example.android.common.logger.MessageOnlyLogFilter; 23*90c8c64dSAndroid Build Coastguard Worker import com.example.android.system.runtimepermissions.camera.CameraPreviewFragment; 24*90c8c64dSAndroid Build Coastguard Worker import com.example.android.system.runtimepermissions.contacts.ContactsFragment; 25*90c8c64dSAndroid Build Coastguard Worker 26*90c8c64dSAndroid Build Coastguard Worker import android.Manifest; 27*90c8c64dSAndroid Build Coastguard Worker import android.app.Activity; 28*90c8c64dSAndroid Build Coastguard Worker import android.content.Context; 29*90c8c64dSAndroid Build Coastguard Worker import android.content.pm.PackageManager; 30*90c8c64dSAndroid Build Coastguard Worker import android.os.Bundle; 31*90c8c64dSAndroid Build Coastguard Worker import android.support.annotation.NonNull; 32*90c8c64dSAndroid Build Coastguard Worker import android.support.design.widget.Snackbar; 33*90c8c64dSAndroid Build Coastguard Worker import android.support.v4.app.ActivityCompat; 34*90c8c64dSAndroid Build Coastguard Worker import android.support.v4.app.FragmentTransaction; 35*90c8c64dSAndroid Build Coastguard Worker import android.view.Menu; 36*90c8c64dSAndroid Build Coastguard Worker import android.view.MenuItem; 37*90c8c64dSAndroid Build Coastguard Worker import android.view.View; 38*90c8c64dSAndroid Build Coastguard Worker import android.widget.ViewAnimator; 39*90c8c64dSAndroid Build Coastguard Worker 40*90c8c64dSAndroid Build Coastguard Worker import common.activities.SampleActivityBase; 41*90c8c64dSAndroid Build Coastguard Worker 42*90c8c64dSAndroid Build Coastguard Worker /** 43*90c8c64dSAndroid Build Coastguard Worker * Launcher Activity that demonstrates the use of runtime permissions for Android M. 44*90c8c64dSAndroid Build Coastguard Worker * It contains a summary sample description, sample log and a Fragment that calls callbacks on this 45*90c8c64dSAndroid Build Coastguard Worker * Activity to illustrate parts of the runtime permissions API. 46*90c8c64dSAndroid Build Coastguard Worker * <p> 47*90c8c64dSAndroid Build Coastguard Worker * This Activity requests permissions to access the camera ({@link android.Manifest.permission#CAMERA}) 48*90c8c64dSAndroid Build Coastguard Worker * when the 'Show Camera' button is clicked to display the camera preview. 49*90c8c64dSAndroid Build Coastguard Worker * Contacts permissions (({@link android.Manifest.permission#READ_CONTACTS} and ({@link 50*90c8c64dSAndroid Build Coastguard Worker * android.Manifest.permission#WRITE_CONTACTS})) are requested when the 'Show and Add Contacts' 51*90c8c64dSAndroid Build Coastguard Worker * button is 52*90c8c64dSAndroid Build Coastguard Worker * clicked to display the first contact in the contacts database and to add a placeholder contact 53*90c8c64dSAndroid Build Coastguard Worker * directly to it. Permissions are verified and requested through compat helpers in the support v4 54*90c8c64dSAndroid Build Coastguard Worker * library, in this Activity using {@link ActivityCompat}. 55*90c8c64dSAndroid Build Coastguard Worker * First, permissions are checked if they have already been granted through {@link 56*90c8c64dSAndroid Build Coastguard Worker * ActivityCompat#checkSelfPermission(Context, String)}. 57*90c8c64dSAndroid Build Coastguard Worker * If permissions have not been granted, they are requested through 58*90c8c64dSAndroid Build Coastguard Worker * {@link ActivityCompat#requestPermissions(Activity, String[], int)} and the return value checked 59*90c8c64dSAndroid Build Coastguard Worker * in 60*90c8c64dSAndroid Build Coastguard Worker * a callback to the {@link android.support.v4.app.ActivityCompat.OnRequestPermissionsResultCallback} 61*90c8c64dSAndroid Build Coastguard Worker * interface. 62*90c8c64dSAndroid Build Coastguard Worker * <p> 63*90c8c64dSAndroid Build Coastguard Worker * Before requesting permissions, {@link ActivityCompat#shouldShowRequestPermissionRationale(Activity, 64*90c8c64dSAndroid Build Coastguard Worker * String)} 65*90c8c64dSAndroid Build Coastguard Worker * should be called to provide the user with additional context for the use of permissions if they 66*90c8c64dSAndroid Build Coastguard Worker * have been denied previously. 67*90c8c64dSAndroid Build Coastguard Worker * <p> 68*90c8c64dSAndroid Build Coastguard Worker * If this sample is executed on a device running a platform version below M, all permissions 69*90c8c64dSAndroid Build Coastguard Worker * declared 70*90c8c64dSAndroid Build Coastguard Worker * in the Android manifest file are always granted at install time and cannot be requested at run 71*90c8c64dSAndroid Build Coastguard Worker * time. 72*90c8c64dSAndroid Build Coastguard Worker * <p> 73*90c8c64dSAndroid Build Coastguard Worker * This sample targets the M platform and must therefore request permissions at runtime. Change the 74*90c8c64dSAndroid Build Coastguard Worker * targetSdk in the file 'Application/build.gradle' to 22 to run the application in compatibility 75*90c8c64dSAndroid Build Coastguard Worker * mode. 76*90c8c64dSAndroid Build Coastguard Worker * Now, if a permission has been disable by the system through the application settings, disabled 77*90c8c64dSAndroid Build Coastguard Worker * APIs provide compatibility data. 78*90c8c64dSAndroid Build Coastguard Worker * For example the camera cannot be opened or an empty list of contacts is returned. No special 79*90c8c64dSAndroid Build Coastguard Worker * action is required in this case. 80*90c8c64dSAndroid Build Coastguard Worker * <p> 81*90c8c64dSAndroid Build Coastguard Worker * (This class is based on the MainActivity used in the SimpleFragment sample template.) 82*90c8c64dSAndroid Build Coastguard Worker */ 83*90c8c64dSAndroid Build Coastguard Worker public class MainActivity extends SampleActivityBase 84*90c8c64dSAndroid Build Coastguard Worker implements ActivityCompat.OnRequestPermissionsResultCallback { 85*90c8c64dSAndroid Build Coastguard Worker 86*90c8c64dSAndroid Build Coastguard Worker public static final String TAG = "MainActivity"; 87*90c8c64dSAndroid Build Coastguard Worker 88*90c8c64dSAndroid Build Coastguard Worker /** 89*90c8c64dSAndroid Build Coastguard Worker * Id to identify a camera permission request. 90*90c8c64dSAndroid Build Coastguard Worker */ 91*90c8c64dSAndroid Build Coastguard Worker private static final int REQUEST_CAMERA = 0; 92*90c8c64dSAndroid Build Coastguard Worker 93*90c8c64dSAndroid Build Coastguard Worker /** 94*90c8c64dSAndroid Build Coastguard Worker * Id to identify a contacts permission request. 95*90c8c64dSAndroid Build Coastguard Worker */ 96*90c8c64dSAndroid Build Coastguard Worker private static final int REQUEST_CONTACTS = 1; 97*90c8c64dSAndroid Build Coastguard Worker 98*90c8c64dSAndroid Build Coastguard Worker /** 99*90c8c64dSAndroid Build Coastguard Worker * Permissions required to read and write contacts. Used by the {@link ContactsFragment}. 100*90c8c64dSAndroid Build Coastguard Worker */ 101*90c8c64dSAndroid Build Coastguard Worker private static String[] PERMISSIONS_CONTACT = {Manifest.permission.READ_CONTACTS, 102*90c8c64dSAndroid Build Coastguard Worker Manifest.permission.WRITE_CONTACTS}; 103*90c8c64dSAndroid Build Coastguard Worker 104*90c8c64dSAndroid Build Coastguard Worker // Whether the Log Fragment is currently shown. 105*90c8c64dSAndroid Build Coastguard Worker private boolean mLogShown; 106*90c8c64dSAndroid Build Coastguard Worker 107*90c8c64dSAndroid Build Coastguard Worker /** 108*90c8c64dSAndroid Build Coastguard Worker * Root of the layout of this Activity. 109*90c8c64dSAndroid Build Coastguard Worker */ 110*90c8c64dSAndroid Build Coastguard Worker private View mLayout; 111*90c8c64dSAndroid Build Coastguard Worker 112*90c8c64dSAndroid Build Coastguard Worker /** 113*90c8c64dSAndroid Build Coastguard Worker * Called when the 'show camera' button is clicked. 114*90c8c64dSAndroid Build Coastguard Worker * Callback is defined in resource layout definition. 115*90c8c64dSAndroid Build Coastguard Worker */ showCamera(View view)116*90c8c64dSAndroid Build Coastguard Worker public void showCamera(View view) { 117*90c8c64dSAndroid Build Coastguard Worker Log.i(TAG, "Show camera button pressed. Checking permission."); 118*90c8c64dSAndroid Build Coastguard Worker // BEGIN_INCLUDE(camera_permission) 119*90c8c64dSAndroid Build Coastguard Worker // Check if the Camera permission is already available. 120*90c8c64dSAndroid Build Coastguard Worker if (ActivityCompat.checkSelfPermission(this, Manifest.permission.CAMERA) 121*90c8c64dSAndroid Build Coastguard Worker != PackageManager.PERMISSION_GRANTED) { 122*90c8c64dSAndroid Build Coastguard Worker // Camera permission has not been granted. 123*90c8c64dSAndroid Build Coastguard Worker 124*90c8c64dSAndroid Build Coastguard Worker requestCameraPermission(); 125*90c8c64dSAndroid Build Coastguard Worker 126*90c8c64dSAndroid Build Coastguard Worker } else { 127*90c8c64dSAndroid Build Coastguard Worker 128*90c8c64dSAndroid Build Coastguard Worker // Camera permissions is already available, show the camera preview. 129*90c8c64dSAndroid Build Coastguard Worker Log.i(TAG, 130*90c8c64dSAndroid Build Coastguard Worker "CAMERA permission has already been granted. Displaying camera preview."); 131*90c8c64dSAndroid Build Coastguard Worker showCameraPreview(); 132*90c8c64dSAndroid Build Coastguard Worker } 133*90c8c64dSAndroid Build Coastguard Worker // END_INCLUDE(camera_permission) 134*90c8c64dSAndroid Build Coastguard Worker 135*90c8c64dSAndroid Build Coastguard Worker } 136*90c8c64dSAndroid Build Coastguard Worker 137*90c8c64dSAndroid Build Coastguard Worker /** 138*90c8c64dSAndroid Build Coastguard Worker * Requests the Camera permission. 139*90c8c64dSAndroid Build Coastguard Worker * If the permission has been denied previously, a SnackBar will prompt the user to grant the 140*90c8c64dSAndroid Build Coastguard Worker * permission, otherwise it is requested directly. 141*90c8c64dSAndroid Build Coastguard Worker */ requestCameraPermission()142*90c8c64dSAndroid Build Coastguard Worker private void requestCameraPermission() { 143*90c8c64dSAndroid Build Coastguard Worker Log.i(TAG, "CAMERA permission has NOT been granted. Requesting permission."); 144*90c8c64dSAndroid Build Coastguard Worker 145*90c8c64dSAndroid Build Coastguard Worker // BEGIN_INCLUDE(camera_permission_request) 146*90c8c64dSAndroid Build Coastguard Worker if (ActivityCompat.shouldShowRequestPermissionRationale(this, 147*90c8c64dSAndroid Build Coastguard Worker Manifest.permission.CAMERA)) { 148*90c8c64dSAndroid Build Coastguard Worker // Provide an additional rationale to the user if the permission was not granted 149*90c8c64dSAndroid Build Coastguard Worker // and the user would benefit from additional context for the use of the permission. 150*90c8c64dSAndroid Build Coastguard Worker // For example if the user has previously denied the permission. 151*90c8c64dSAndroid Build Coastguard Worker Log.i(TAG, 152*90c8c64dSAndroid Build Coastguard Worker "Displaying camera permission rationale to provide additional context."); 153*90c8c64dSAndroid Build Coastguard Worker Snackbar.make(mLayout, R.string.permission_camera_rationale, 154*90c8c64dSAndroid Build Coastguard Worker Snackbar.LENGTH_INDEFINITE) 155*90c8c64dSAndroid Build Coastguard Worker .setAction(R.string.ok, new View.OnClickListener() { 156*90c8c64dSAndroid Build Coastguard Worker @Override 157*90c8c64dSAndroid Build Coastguard Worker public void onClick(View view) { 158*90c8c64dSAndroid Build Coastguard Worker ActivityCompat.requestPermissions(MainActivity.this, 159*90c8c64dSAndroid Build Coastguard Worker new String[]{Manifest.permission.CAMERA}, 160*90c8c64dSAndroid Build Coastguard Worker REQUEST_CAMERA); 161*90c8c64dSAndroid Build Coastguard Worker } 162*90c8c64dSAndroid Build Coastguard Worker }) 163*90c8c64dSAndroid Build Coastguard Worker .show(); 164*90c8c64dSAndroid Build Coastguard Worker } else { 165*90c8c64dSAndroid Build Coastguard Worker 166*90c8c64dSAndroid Build Coastguard Worker // Camera permission has not been granted yet. Request it directly. 167*90c8c64dSAndroid Build Coastguard Worker ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.CAMERA}, 168*90c8c64dSAndroid Build Coastguard Worker REQUEST_CAMERA); 169*90c8c64dSAndroid Build Coastguard Worker } 170*90c8c64dSAndroid Build Coastguard Worker // END_INCLUDE(camera_permission_request) 171*90c8c64dSAndroid Build Coastguard Worker } 172*90c8c64dSAndroid Build Coastguard Worker 173*90c8c64dSAndroid Build Coastguard Worker /** 174*90c8c64dSAndroid Build Coastguard Worker * Called when the 'show camera' button is clicked. 175*90c8c64dSAndroid Build Coastguard Worker * Callback is defined in resource layout definition. 176*90c8c64dSAndroid Build Coastguard Worker */ showContacts(View v)177*90c8c64dSAndroid Build Coastguard Worker public void showContacts(View v) { 178*90c8c64dSAndroid Build Coastguard Worker Log.i(TAG, "Show contacts button pressed. Checking permissions."); 179*90c8c64dSAndroid Build Coastguard Worker 180*90c8c64dSAndroid Build Coastguard Worker // Verify that all required contact permissions have been granted. 181*90c8c64dSAndroid Build Coastguard Worker if (ActivityCompat.checkSelfPermission(this, Manifest.permission.READ_CONTACTS) 182*90c8c64dSAndroid Build Coastguard Worker != PackageManager.PERMISSION_GRANTED 183*90c8c64dSAndroid Build Coastguard Worker || ActivityCompat.checkSelfPermission(this, Manifest.permission.WRITE_CONTACTS) 184*90c8c64dSAndroid Build Coastguard Worker != PackageManager.PERMISSION_GRANTED) { 185*90c8c64dSAndroid Build Coastguard Worker // Contacts permissions have not been granted. 186*90c8c64dSAndroid Build Coastguard Worker Log.i(TAG, "Contact permissions has NOT been granted. Requesting permissions."); 187*90c8c64dSAndroid Build Coastguard Worker requestContactsPermissions(); 188*90c8c64dSAndroid Build Coastguard Worker 189*90c8c64dSAndroid Build Coastguard Worker } else { 190*90c8c64dSAndroid Build Coastguard Worker 191*90c8c64dSAndroid Build Coastguard Worker // Contact permissions have been granted. Show the contacts fragment. 192*90c8c64dSAndroid Build Coastguard Worker Log.i(TAG, 193*90c8c64dSAndroid Build Coastguard Worker "Contact permissions have already been granted. Displaying contact details."); 194*90c8c64dSAndroid Build Coastguard Worker showContactDetails(); 195*90c8c64dSAndroid Build Coastguard Worker } 196*90c8c64dSAndroid Build Coastguard Worker } 197*90c8c64dSAndroid Build Coastguard Worker 198*90c8c64dSAndroid Build Coastguard Worker /** 199*90c8c64dSAndroid Build Coastguard Worker * Requests the Contacts permissions. 200*90c8c64dSAndroid Build Coastguard Worker * If the permission has been denied previously, a SnackBar will prompt the user to grant the 201*90c8c64dSAndroid Build Coastguard Worker * permission, otherwise it is requested directly. 202*90c8c64dSAndroid Build Coastguard Worker */ requestContactsPermissions()203*90c8c64dSAndroid Build Coastguard Worker private void requestContactsPermissions() { 204*90c8c64dSAndroid Build Coastguard Worker // BEGIN_INCLUDE(contacts_permission_request) 205*90c8c64dSAndroid Build Coastguard Worker if (ActivityCompat.shouldShowRequestPermissionRationale(this, 206*90c8c64dSAndroid Build Coastguard Worker Manifest.permission.READ_CONTACTS) 207*90c8c64dSAndroid Build Coastguard Worker || ActivityCompat.shouldShowRequestPermissionRationale(this, 208*90c8c64dSAndroid Build Coastguard Worker Manifest.permission.WRITE_CONTACTS)) { 209*90c8c64dSAndroid Build Coastguard Worker 210*90c8c64dSAndroid Build Coastguard Worker // Provide an additional rationale to the user if the permission was not granted 211*90c8c64dSAndroid Build Coastguard Worker // and the user would benefit from additional context for the use of the permission. 212*90c8c64dSAndroid Build Coastguard Worker // For example, if the request has been denied previously. 213*90c8c64dSAndroid Build Coastguard Worker Log.i(TAG, 214*90c8c64dSAndroid Build Coastguard Worker "Displaying contacts permission rationale to provide additional context."); 215*90c8c64dSAndroid Build Coastguard Worker 216*90c8c64dSAndroid Build Coastguard Worker // Display a SnackBar with an explanation and a button to trigger the request. 217*90c8c64dSAndroid Build Coastguard Worker Snackbar.make(mLayout, R.string.permission_contacts_rationale, 218*90c8c64dSAndroid Build Coastguard Worker Snackbar.LENGTH_INDEFINITE) 219*90c8c64dSAndroid Build Coastguard Worker .setAction(R.string.ok, new View.OnClickListener() { 220*90c8c64dSAndroid Build Coastguard Worker @Override 221*90c8c64dSAndroid Build Coastguard Worker public void onClick(View view) { 222*90c8c64dSAndroid Build Coastguard Worker ActivityCompat 223*90c8c64dSAndroid Build Coastguard Worker .requestPermissions(MainActivity.this, PERMISSIONS_CONTACT, 224*90c8c64dSAndroid Build Coastguard Worker REQUEST_CONTACTS); 225*90c8c64dSAndroid Build Coastguard Worker } 226*90c8c64dSAndroid Build Coastguard Worker }) 227*90c8c64dSAndroid Build Coastguard Worker .show(); 228*90c8c64dSAndroid Build Coastguard Worker } else { 229*90c8c64dSAndroid Build Coastguard Worker // Contact permissions have not been granted yet. Request them directly. 230*90c8c64dSAndroid Build Coastguard Worker ActivityCompat.requestPermissions(this, PERMISSIONS_CONTACT, REQUEST_CONTACTS); 231*90c8c64dSAndroid Build Coastguard Worker } 232*90c8c64dSAndroid Build Coastguard Worker // END_INCLUDE(contacts_permission_request) 233*90c8c64dSAndroid Build Coastguard Worker } 234*90c8c64dSAndroid Build Coastguard Worker 235*90c8c64dSAndroid Build Coastguard Worker 236*90c8c64dSAndroid Build Coastguard Worker /** 237*90c8c64dSAndroid Build Coastguard Worker * Display the {@link CameraPreviewFragment} in the content area if the required Camera 238*90c8c64dSAndroid Build Coastguard Worker * permission has been granted. 239*90c8c64dSAndroid Build Coastguard Worker */ showCameraPreview()240*90c8c64dSAndroid Build Coastguard Worker private void showCameraPreview() { 241*90c8c64dSAndroid Build Coastguard Worker getSupportFragmentManager().beginTransaction() 242*90c8c64dSAndroid Build Coastguard Worker .replace(R.id.sample_content_fragment, CameraPreviewFragment.newInstance()) 243*90c8c64dSAndroid Build Coastguard Worker .addToBackStack("contacts") 244*90c8c64dSAndroid Build Coastguard Worker .commit(); 245*90c8c64dSAndroid Build Coastguard Worker } 246*90c8c64dSAndroid Build Coastguard Worker 247*90c8c64dSAndroid Build Coastguard Worker /** 248*90c8c64dSAndroid Build Coastguard Worker * Display the {@link ContactsFragment} in the content area if the required contacts 249*90c8c64dSAndroid Build Coastguard Worker * permissions 250*90c8c64dSAndroid Build Coastguard Worker * have been granted. 251*90c8c64dSAndroid Build Coastguard Worker */ showContactDetails()252*90c8c64dSAndroid Build Coastguard Worker private void showContactDetails() { 253*90c8c64dSAndroid Build Coastguard Worker getSupportFragmentManager().beginTransaction() 254*90c8c64dSAndroid Build Coastguard Worker .replace(R.id.sample_content_fragment, ContactsFragment.newInstance()) 255*90c8c64dSAndroid Build Coastguard Worker .addToBackStack("contacts") 256*90c8c64dSAndroid Build Coastguard Worker .commit(); 257*90c8c64dSAndroid Build Coastguard Worker } 258*90c8c64dSAndroid Build Coastguard Worker 259*90c8c64dSAndroid Build Coastguard Worker 260*90c8c64dSAndroid Build Coastguard Worker /** 261*90c8c64dSAndroid Build Coastguard Worker * Callback received when a permissions request has been completed. 262*90c8c64dSAndroid Build Coastguard Worker */ 263*90c8c64dSAndroid Build Coastguard Worker @Override onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults)264*90c8c64dSAndroid Build Coastguard Worker public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, 265*90c8c64dSAndroid Build Coastguard Worker @NonNull int[] grantResults) { 266*90c8c64dSAndroid Build Coastguard Worker 267*90c8c64dSAndroid Build Coastguard Worker if (requestCode == REQUEST_CAMERA) { 268*90c8c64dSAndroid Build Coastguard Worker // BEGIN_INCLUDE(permission_result) 269*90c8c64dSAndroid Build Coastguard Worker // Received permission result for camera permission. 270*90c8c64dSAndroid Build Coastguard Worker Log.i(TAG, "Received response for Camera permission request."); 271*90c8c64dSAndroid Build Coastguard Worker 272*90c8c64dSAndroid Build Coastguard Worker // Check if the only required permission has been granted 273*90c8c64dSAndroid Build Coastguard Worker if (grantResults.length == 1 && grantResults[0] == PackageManager.PERMISSION_GRANTED) { 274*90c8c64dSAndroid Build Coastguard Worker // Camera permission has been granted, preview can be displayed 275*90c8c64dSAndroid Build Coastguard Worker Log.i(TAG, "CAMERA permission has now been granted. Showing preview."); 276*90c8c64dSAndroid Build Coastguard Worker Snackbar.make(mLayout, R.string.permision_available_camera, 277*90c8c64dSAndroid Build Coastguard Worker Snackbar.LENGTH_SHORT).show(); 278*90c8c64dSAndroid Build Coastguard Worker } else { 279*90c8c64dSAndroid Build Coastguard Worker Log.i(TAG, "CAMERA permission was NOT granted."); 280*90c8c64dSAndroid Build Coastguard Worker Snackbar.make(mLayout, R.string.permissions_not_granted, 281*90c8c64dSAndroid Build Coastguard Worker Snackbar.LENGTH_SHORT).show(); 282*90c8c64dSAndroid Build Coastguard Worker 283*90c8c64dSAndroid Build Coastguard Worker } 284*90c8c64dSAndroid Build Coastguard Worker // END_INCLUDE(permission_result) 285*90c8c64dSAndroid Build Coastguard Worker 286*90c8c64dSAndroid Build Coastguard Worker } else if (requestCode == REQUEST_CONTACTS) { 287*90c8c64dSAndroid Build Coastguard Worker Log.i(TAG, "Received response for contact permissions request."); 288*90c8c64dSAndroid Build Coastguard Worker 289*90c8c64dSAndroid Build Coastguard Worker // We have requested multiple permissions for contacts, so all of them need to be 290*90c8c64dSAndroid Build Coastguard Worker // checked. 291*90c8c64dSAndroid Build Coastguard Worker if (PermissionUtil.verifyPermissions(grantResults)) { 292*90c8c64dSAndroid Build Coastguard Worker // All required permissions have been granted, display contacts fragment. 293*90c8c64dSAndroid Build Coastguard Worker Snackbar.make(mLayout, R.string.permision_available_contacts, 294*90c8c64dSAndroid Build Coastguard Worker Snackbar.LENGTH_SHORT) 295*90c8c64dSAndroid Build Coastguard Worker .show(); 296*90c8c64dSAndroid Build Coastguard Worker } else { 297*90c8c64dSAndroid Build Coastguard Worker Log.i(TAG, "Contacts permissions were NOT granted."); 298*90c8c64dSAndroid Build Coastguard Worker Snackbar.make(mLayout, R.string.permissions_not_granted, 299*90c8c64dSAndroid Build Coastguard Worker Snackbar.LENGTH_SHORT) 300*90c8c64dSAndroid Build Coastguard Worker .show(); 301*90c8c64dSAndroid Build Coastguard Worker } 302*90c8c64dSAndroid Build Coastguard Worker 303*90c8c64dSAndroid Build Coastguard Worker } else { 304*90c8c64dSAndroid Build Coastguard Worker super.onRequestPermissionsResult(requestCode, permissions, grantResults); 305*90c8c64dSAndroid Build Coastguard Worker } 306*90c8c64dSAndroid Build Coastguard Worker } 307*90c8c64dSAndroid Build Coastguard Worker 308*90c8c64dSAndroid Build Coastguard Worker /* Note: Methods and definitions below are only used to provide the UI for this sample and are 309*90c8c64dSAndroid Build Coastguard Worker not relevant for the execution of the runtime permissions API. */ 310*90c8c64dSAndroid Build Coastguard Worker 311*90c8c64dSAndroid Build Coastguard Worker 312*90c8c64dSAndroid Build Coastguard Worker @Override onCreateOptionsMenu(Menu menu)313*90c8c64dSAndroid Build Coastguard Worker public boolean onCreateOptionsMenu(Menu menu) { 314*90c8c64dSAndroid Build Coastguard Worker getMenuInflater().inflate(R.menu.main, menu); 315*90c8c64dSAndroid Build Coastguard Worker return true; 316*90c8c64dSAndroid Build Coastguard Worker } 317*90c8c64dSAndroid Build Coastguard Worker 318*90c8c64dSAndroid Build Coastguard Worker @Override onPrepareOptionsMenu(Menu menu)319*90c8c64dSAndroid Build Coastguard Worker public boolean onPrepareOptionsMenu(Menu menu) { 320*90c8c64dSAndroid Build Coastguard Worker MenuItem logToggle = menu.findItem(R.id.menu_toggle_log); 321*90c8c64dSAndroid Build Coastguard Worker logToggle.setVisible(findViewById(R.id.sample_output) instanceof ViewAnimator); 322*90c8c64dSAndroid Build Coastguard Worker logToggle.setTitle(mLogShown ? R.string.sample_hide_log : R.string.sample_show_log); 323*90c8c64dSAndroid Build Coastguard Worker 324*90c8c64dSAndroid Build Coastguard Worker return super.onPrepareOptionsMenu(menu); 325*90c8c64dSAndroid Build Coastguard Worker } 326*90c8c64dSAndroid Build Coastguard Worker 327*90c8c64dSAndroid Build Coastguard Worker @Override onOptionsItemSelected(MenuItem item)328*90c8c64dSAndroid Build Coastguard Worker public boolean onOptionsItemSelected(MenuItem item) { 329*90c8c64dSAndroid Build Coastguard Worker switch (item.getItemId()) { 330*90c8c64dSAndroid Build Coastguard Worker case R.id.menu_toggle_log: 331*90c8c64dSAndroid Build Coastguard Worker mLogShown = !mLogShown; 332*90c8c64dSAndroid Build Coastguard Worker ViewAnimator output = (ViewAnimator) findViewById(R.id.sample_output); 333*90c8c64dSAndroid Build Coastguard Worker if (mLogShown) { 334*90c8c64dSAndroid Build Coastguard Worker output.setDisplayedChild(1); 335*90c8c64dSAndroid Build Coastguard Worker } else { 336*90c8c64dSAndroid Build Coastguard Worker output.setDisplayedChild(0); 337*90c8c64dSAndroid Build Coastguard Worker } 338*90c8c64dSAndroid Build Coastguard Worker supportInvalidateOptionsMenu(); 339*90c8c64dSAndroid Build Coastguard Worker return true; 340*90c8c64dSAndroid Build Coastguard Worker } 341*90c8c64dSAndroid Build Coastguard Worker return super.onOptionsItemSelected(item); 342*90c8c64dSAndroid Build Coastguard Worker } 343*90c8c64dSAndroid Build Coastguard Worker 344*90c8c64dSAndroid Build Coastguard Worker /** Create a chain of targets that will receive log data */ 345*90c8c64dSAndroid Build Coastguard Worker @Override initializeLogging()346*90c8c64dSAndroid Build Coastguard Worker public void initializeLogging() { 347*90c8c64dSAndroid Build Coastguard Worker // Wraps Android's native log framework. 348*90c8c64dSAndroid Build Coastguard Worker LogWrapper logWrapper = new LogWrapper(); 349*90c8c64dSAndroid Build Coastguard Worker // Using Log, front-end to the logging chain, emulates android.util.log method signatures. 350*90c8c64dSAndroid Build Coastguard Worker Log.setLogNode(logWrapper); 351*90c8c64dSAndroid Build Coastguard Worker 352*90c8c64dSAndroid Build Coastguard Worker // Filter strips out everything except the message text. 353*90c8c64dSAndroid Build Coastguard Worker MessageOnlyLogFilter msgFilter = new MessageOnlyLogFilter(); 354*90c8c64dSAndroid Build Coastguard Worker logWrapper.setNext(msgFilter); 355*90c8c64dSAndroid Build Coastguard Worker 356*90c8c64dSAndroid Build Coastguard Worker // On screen logging via a fragment with a TextView. 357*90c8c64dSAndroid Build Coastguard Worker LogFragment logFragment = (LogFragment) getSupportFragmentManager() 358*90c8c64dSAndroid Build Coastguard Worker .findFragmentById(R.id.log_fragment); 359*90c8c64dSAndroid Build Coastguard Worker msgFilter.setNext(logFragment.getLogView()); 360*90c8c64dSAndroid Build Coastguard Worker } 361*90c8c64dSAndroid Build Coastguard Worker onBackClick(View view)362*90c8c64dSAndroid Build Coastguard Worker public void onBackClick(View view) { 363*90c8c64dSAndroid Build Coastguard Worker getSupportFragmentManager().popBackStack(); 364*90c8c64dSAndroid Build Coastguard Worker } 365*90c8c64dSAndroid Build Coastguard Worker 366*90c8c64dSAndroid Build Coastguard Worker @Override onCreate(Bundle savedInstanceState)367*90c8c64dSAndroid Build Coastguard Worker protected void onCreate(Bundle savedInstanceState) { 368*90c8c64dSAndroid Build Coastguard Worker super.onCreate(savedInstanceState); 369*90c8c64dSAndroid Build Coastguard Worker setContentView(R.layout.activity_main); 370*90c8c64dSAndroid Build Coastguard Worker mLayout = findViewById(R.id.sample_main_layout); 371*90c8c64dSAndroid Build Coastguard Worker 372*90c8c64dSAndroid Build Coastguard Worker if (savedInstanceState == null) { 373*90c8c64dSAndroid Build Coastguard Worker FragmentTransaction transaction = getSupportFragmentManager().beginTransaction(); 374*90c8c64dSAndroid Build Coastguard Worker RuntimePermissionsFragment fragment = new RuntimePermissionsFragment(); 375*90c8c64dSAndroid Build Coastguard Worker transaction.replace(R.id.sample_content_fragment, fragment); 376*90c8c64dSAndroid Build Coastguard Worker transaction.commit(); 377*90c8c64dSAndroid Build Coastguard Worker } 378*90c8c64dSAndroid Build Coastguard Worker 379*90c8c64dSAndroid Build Coastguard Worker // This method sets up our custom logger, which will print all log messages to the device 380*90c8c64dSAndroid Build Coastguard Worker // screen, as well as to adb logcat. 381*90c8c64dSAndroid Build Coastguard Worker initializeLogging(); 382*90c8c64dSAndroid Build Coastguard Worker } 383*90c8c64dSAndroid Build Coastguard Worker } 384