diff options
author | Trevor Johns <trevorjohns@google.com> | 2015-08-17 09:37:47 -0700 |
---|---|---|
committer | Trevor Johns <trevorjohns@google.com> | 2015-08-17 09:37:47 -0700 |
commit | c8e94bf583adc38c36e968eb00f21a8b8ca70257 (patch) | |
tree | 656dbba0acaec6717b138e9c6f06c30a89e96521 /samples/browseable/RuntimePermissions/src/com.example.android.system.runtimepermissions | |
parent | a56a6341669e1402c23c9d4e1c24337525189c65 (diff) | |
download | android_development-c8e94bf583adc38c36e968eb00f21a8b8ca70257.tar.gz android_development-c8e94bf583adc38c36e968eb00f21a8b8ca70257.tar.bz2 android_development-c8e94bf583adc38c36e968eb00f21a8b8ca70257.zip |
Sync mnc-dev sample prebuilts
Syncing to //developers/samples/android commmit 2be5f5ca32.
Change-Id: Ia08c63655bd122c7fbb0cc3a50eec95d8edcb3f1
Diffstat (limited to 'samples/browseable/RuntimePermissions/src/com.example.android.system.runtimepermissions')
3 files changed, 135 insertions, 92 deletions
diff --git a/samples/browseable/RuntimePermissions/src/com.example.android.system.runtimepermissions/MainActivity.java b/samples/browseable/RuntimePermissions/src/com.example.android.system.runtimepermissions/MainActivity.java index 5f38bad8d..7abc538cf 100644 --- a/samples/browseable/RuntimePermissions/src/com.example.android.system.runtimepermissions/MainActivity.java +++ b/samples/browseable/RuntimePermissions/src/com.example.android.system.runtimepermissions/MainActivity.java @@ -16,7 +16,6 @@ package com.example.android.system.runtimepermissions; -import com.example.android.common.activities.SampleActivityBase; import com.example.android.common.logger.Log; import com.example.android.common.logger.LogFragment; import com.example.android.common.logger.LogWrapper; @@ -26,15 +25,20 @@ import com.example.android.system.runtimepermissions.contacts.ContactsFragment; import android.Manifest; import android.app.Activity; +import android.content.Context; import android.content.pm.PackageManager; import android.os.Bundle; +import android.support.annotation.NonNull; +import android.support.design.widget.Snackbar; +import android.support.v4.app.ActivityCompat; import android.support.v4.app.FragmentTransaction; import android.view.Menu; import android.view.MenuItem; import android.view.View; -import android.widget.Toast; import android.widget.ViewAnimator; +import common.activities.SampleActivityBase; + /** * Launcher Activity that demonstrates the use of runtime permissions for Android M. * It contains a summary sample description, sample log and a Fragment that calls callbacks on this @@ -46,15 +50,18 @@ import android.widget.ViewAnimator; * android.Manifest.permission#WRITE_CONTACTS})) are requested when the 'Show and Add Contacts' * button is * clicked to display the first contact in the contacts database and to add a dummy contact - * directly - * to it. First, permissions are checked if they have already been granted through {@link - * android.app.Activity#checkSelfPermission(String)} (wrapped in {@link - * PermissionUtil#hasSelfPermission(Activity, String)} and {@link PermissionUtil#hasSelfPermission(Activity, - * String[])} for compatibility). If permissions have not been granted, they are requested through - * {@link Activity#requestPermissions(String[], int)} and the return value checked in {@link - * Activity#onRequestPermissionsResult(int, String[], int[])}. + * directly to it. Permissions are verified and requested through compat helpers in the support v4 + * library, in this Activity using {@link ActivityCompat}. + * First, permissions are checked if they have already been granted through {@link + * ActivityCompat#checkSelfPermission(Context, String)}. + * If permissions have not been granted, they are requested through + * {@link ActivityCompat#requestPermissions(Activity, String[], int)} and the return value checked + * in + * a callback to the {@link android.support.v4.app.ActivityCompat.OnRequestPermissionsResultCallback} + * interface. * <p> - * Before requesting permissions, {@link Activity#shouldShowRequestPermissionRationale(String)} + * Before requesting permissions, {@link ActivityCompat#shouldShowRequestPermissionRationale(Activity, + * String)} * should be called to provide the user with additional context for the use of permissions if they * have been denied previously. * <p> @@ -73,7 +80,8 @@ import android.widget.ViewAnimator; * <p> * (This class is based on the MainActivity used in the SimpleFragment sample template.) */ -public class MainActivity extends SampleActivityBase { +public class MainActivity extends SampleActivityBase + implements ActivityCompat.OnRequestPermissionsResultCallback { public static final String TAG = "MainActivity"; @@ -96,6 +104,10 @@ public class MainActivity extends SampleActivityBase { // Whether the Log Fragment is currently shown. private boolean mLogShown; + /** + * Root of the layout of this Activity. + */ + private View mLayout; /** * Called when the 'show camera' button is clicked. @@ -105,30 +117,57 @@ public class MainActivity extends SampleActivityBase { Log.i(TAG, "Show camera button pressed. Checking permission."); // BEGIN_INCLUDE(camera_permission) // Check if the Camera permission is already available. - if (PermissionUtil.hasSelfPermission(this, Manifest.permission.CAMERA)) { + if (ActivityCompat.checkSelfPermission(this, Manifest.permission.CAMERA) + != PackageManager.PERMISSION_GRANTED) { + // Camera permission has not been granted. + + requestCameraPermission(); + + } else { + // Camera permissions is already available, show the camera preview. Log.i(TAG, "CAMERA permission has already been granted. Displaying camera preview."); showCameraPreview(); - } else { - // Camera permission has not been granted. - Log.i(TAG, "CAMERA permission has NOT been granted. Requesting permission."); + } + // END_INCLUDE(camera_permission) + } + + /** + * Requests the Camera permission. + * If the permission has been denied previously, a SnackBar will prompt the user to grant the + * permission, otherwise it is requested directly. + */ + private void requestCameraPermission() { + Log.i(TAG, "CAMERA permission has NOT been granted. Requesting permission."); + + // BEGIN_INCLUDE(camera_permission_request) + if (ActivityCompat.shouldShowRequestPermissionRationale(this, + Manifest.permission.CAMERA)) { // Provide an additional rationale to the user if the permission was not granted // and the user would benefit from additional context for the use of the permission. - if (shouldShowRequestPermissionRationale(Manifest.permission.CAMERA)) { - Log.i(TAG, - "Displaying camera permission rationale to provide additional context."); - Toast.makeText(this, R.string.permission_camera_rationale, Toast.LENGTH_SHORT) - .show(); - } + // For example if the user has previously denied the permission. + Log.i(TAG, + "Displaying camera permission rationale to provide additional context."); + Snackbar.make(mLayout, R.string.permission_camera_rationale, + Snackbar.LENGTH_INDEFINITE) + .setAction(R.string.ok, new View.OnClickListener() { + @Override + public void onClick(View view) { + ActivityCompat.requestPermissions(MainActivity.this, + new String[]{Manifest.permission.CAMERA}, + REQUEST_CAMERA); + } + }) + .show(); + } else { - // Request Camera permission - requestPermissions(new String[]{Manifest.permission.CAMERA}, + // Camera permission has not been granted yet. Request it directly. + ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.CAMERA}, REQUEST_CAMERA); } - // END_INCLUDE(camera_permission) - + // END_INCLUDE(camera_permission_request) } /** @@ -137,30 +176,63 @@ public class MainActivity extends SampleActivityBase { */ public void showContacts(View v) { Log.i(TAG, "Show contacts button pressed. Checking permissions."); + // Verify that all required contact permissions have been granted. - if (PermissionUtil.hasSelfPermission(this, PERMISSIONS_CONTACT)) { + if (ActivityCompat.checkSelfPermission(this, Manifest.permission.READ_CONTACTS) + != PackageManager.PERMISSION_GRANTED + || ActivityCompat.checkSelfPermission(this, Manifest.permission.WRITE_CONTACTS) + != PackageManager.PERMISSION_GRANTED) { + // Contacts permissions have not been granted. + Log.i(TAG, "Contact permissions has NOT been granted. Requesting permissions."); + requestContactsPermissions(); + + } else { + + // Contact permissions have been granted. Show the contacts fragment. Log.i(TAG, "Contact permissions have already been granted. Displaying contact details."); - // Contact permissions have been granted. Show the contacts fragment. showContactDetails(); - } else { - // Contacts permissions have not been granted. - Log.i(TAG, "Contact permissions has NOT been granted. Requesting permission."); + } + } + + /** + * Requests the Contacts permissions. + * If the permission has been denied previously, a SnackBar will prompt the user to grant the + * permission, otherwise it is requested directly. + */ + private void requestContactsPermissions() { + // BEGIN_INCLUDE(contacts_permission_request) + if (ActivityCompat.shouldShowRequestPermissionRationale(this, + Manifest.permission.READ_CONTACTS) + || ActivityCompat.shouldShowRequestPermissionRationale(this, + Manifest.permission.WRITE_CONTACTS)) { // Provide an additional rationale to the user if the permission was not granted // and the user would benefit from additional context for the use of the permission. - if (shouldShowRequestPermissionRationale(Manifest.permission.CAMERA)) { - Log.i(TAG, - "Displaying contacts permission rationale to provide additional context."); - Toast.makeText(this, R.string.permission_contacts_rationale, Toast.LENGTH_SHORT) - .show(); - } - - // contact permissions has not been granted (read and write contacts). Request them. - requestPermissions(PERMISSIONS_CONTACT, REQUEST_CONTACTS); + // For example, if the request has been denied previously. + Log.i(TAG, + "Displaying contacts permission rationale to provide additional context."); + + // Display a SnackBar with an explanation and a button to trigger the request. + Snackbar.make(mLayout, R.string.permission_contacts_rationale, + Snackbar.LENGTH_INDEFINITE) + .setAction(R.string.ok, new View.OnClickListener() { + @Override + public void onClick(View view) { + ActivityCompat + .requestPermissions(MainActivity.this, PERMISSIONS_CONTACT, + REQUEST_CONTACTS); + } + }) + .show(); + } else { + // Contact permissions have not been granted yet. Request them directly. + ActivityCompat.requestPermissions(this, PERMISSIONS_CONTACT, REQUEST_CONTACTS); } + // END_INCLUDE(contacts_permission_request) } + /** * Display the {@link CameraPreviewFragment} in the content area if the required Camera * permission has been granted. @@ -189,8 +261,8 @@ public class MainActivity extends SampleActivityBase { * Callback received when a permissions request has been completed. */ @Override - public void onRequestPermissionsResult(int requestCode, String[] permissions, - int[] grantResults) { + public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, + @NonNull int[] grantResults) { if (requestCode == REQUEST_CAMERA) { // BEGIN_INCLUDE(permission_result) @@ -198,14 +270,15 @@ public class MainActivity extends SampleActivityBase { Log.i(TAG, "Received response for Camera permission request."); // Check if the only required permission has been granted - if (grantResults[0] == PackageManager.PERMISSION_GRANTED) { + if (grantResults.length == 1 && grantResults[0] == PackageManager.PERMISSION_GRANTED) { // Camera permission has been granted, preview can be displayed Log.i(TAG, "CAMERA permission has now been granted. Showing preview."); - Toast.makeText(this, R.string.permision_available_camera, Toast.LENGTH_SHORT) - .show(); + Snackbar.make(mLayout, R.string.permision_available_camera, + Snackbar.LENGTH_SHORT).show(); } else { Log.i(TAG, "CAMERA permission was NOT granted."); - Toast.makeText(this, R.string.permissions_not_granted, Toast.LENGTH_SHORT).show(); + Snackbar.make(mLayout, R.string.permissions_not_granted, + Snackbar.LENGTH_SHORT).show(); } // END_INCLUDE(permission_result) @@ -217,11 +290,14 @@ public class MainActivity extends SampleActivityBase { // checked. if (PermissionUtil.verifyPermissions(grantResults)) { // All required permissions have been granted, display contacts fragment. - Toast.makeText(this, R.string.permision_available_contacts, Toast.LENGTH_SHORT) + Snackbar.make(mLayout, R.string.permision_available_contacts, + Snackbar.LENGTH_SHORT) .show(); } else { Log.i(TAG, "Contacts permissions were NOT granted."); - Toast.makeText(this, R.string.permissions_not_granted, Toast.LENGTH_SHORT).show(); + Snackbar.make(mLayout, R.string.permissions_not_granted, + Snackbar.LENGTH_SHORT) + .show(); } } else { @@ -291,6 +367,7 @@ public class MainActivity extends SampleActivityBase { protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); + mLayout = findViewById(R.id.sample_main_layout); if (savedInstanceState == null) { FragmentTransaction transaction = getSupportFragmentManager().beginTransaction(); diff --git a/samples/browseable/RuntimePermissions/src/com.example.android.system.runtimepermissions/PermissionUtil.java b/samples/browseable/RuntimePermissions/src/com.example.android.system.runtimepermissions/PermissionUtil.java index d0742ead9..b9be6258e 100644 --- a/samples/browseable/RuntimePermissions/src/com.example.android.system.runtimepermissions/PermissionUtil.java +++ b/samples/browseable/RuntimePermissions/src/com.example.android.system.runtimepermissions/PermissionUtil.java @@ -18,7 +18,6 @@ package com.example.android.system.runtimepermissions; import android.app.Activity; import android.content.pm.PackageManager; -import android.os.Build; /** * Utility class that wraps access to the runtime permissions API in M and provides basic helper @@ -33,6 +32,11 @@ public abstract class PermissionUtil { * @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) { @@ -42,43 +46,4 @@ public abstract class PermissionUtil { return true; } - /** - * Returns true if the Activity has access to all given permissions. - * Always returns true on platforms below M. - * - * @see Activity#checkSelfPermission(String) - */ - public static boolean hasSelfPermission(Activity activity, String[] permissions) { - // Below Android M all permissions are granted at install time and are already available. - if (!isMNC()) { - return true; - } - - // Verify that all required permissions have been granted - for (String permission : permissions) { - if (activity.checkSelfPermission(permission) != PackageManager.PERMISSION_GRANTED) { - return false; - } - } - return true; - } - - /** - * Returns true if the Activity has access to a given permission. - * Always returns true on platforms below M. - * - * @see Activity#checkSelfPermission(String) - */ - public static boolean hasSelfPermission(Activity activity, String permission) { - // Below Android M all permissions are granted at install time and are already available. - if (!isMNC()) { - return true; - } - - return activity.checkSelfPermission(permission) == PackageManager.PERMISSION_GRANTED; - } - - public static boolean isMNC() { - return Build.VERSION.SDK_INT >= Build.VERSION_CODES.M; - } } diff --git a/samples/browseable/RuntimePermissions/src/com.example.android.system.runtimepermissions/RuntimePermissionsFragment.java b/samples/browseable/RuntimePermissions/src/com.example.android.system.runtimepermissions/RuntimePermissionsFragment.java index b35bfebc0..d38195f57 100644 --- a/samples/browseable/RuntimePermissions/src/com.example.android.system.runtimepermissions/RuntimePermissionsFragment.java +++ b/samples/browseable/RuntimePermissions/src/com.example.android.system.runtimepermissions/RuntimePermissionsFragment.java @@ -16,6 +16,7 @@ package com.example.android.system.runtimepermissions; +import android.os.Build; import android.os.Bundle; import android.support.annotation.Nullable; import android.support.v4.app.Fragment; @@ -32,16 +33,16 @@ public class RuntimePermissionsFragment extends Fragment { View root = inflater.inflate(R.layout.fragment_main, null); // BEGIN_INCLUDE(m_only_permission) - if (!PermissionUtil.isMNC()) { + if (Build.VERSION.SDK_INT < 23) { /* - The contacts permissions have been declared in the AndroidManifest for Android M only. - They are not available on older platforms, so we are hiding the button to access the - contacts database. + The contacts permissions have been declared in the AndroidManifest for Android M and + above only. They are not available on older platforms, so we are hiding the button to + access the contacts database. This shows how new runtime-only permissions can be added, that do not apply to older platform versions. This can be useful for automated updates where additional permissions might prompt the user on upgrade. */ - root.findViewById(R.id.button_camera).setVisibility(View.GONE); + root.findViewById(R.id.button_contacts).setVisibility(View.GONE); } // END_INCLUDE(m_only_permission) |