Skip to content

Most visited

Recently visited

navigation
RuntimePermissions / src / com.example.android.system.runtimepermissions /

MainActivity.java

1
/*
2
* Copyright 2015 The Android Open Source Project
3
*
4
* Licensed under the Apache License, Version 2.0 (the "License");
5
* you may not use this file except in compliance with the License.
6
* You may obtain a copy of the License at
7
*
8
*     http://www.apache.org/licenses/LICENSE-2.0
9
*
10
* Unless required by applicable law or agreed to in writing, software
11
* distributed under the License is distributed on an "AS IS" BASIS,
12
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
* See the License for the specific language governing permissions and
14
* limitations under the License.
15
*/
16
 
17
package com.example.android.system.runtimepermissions;
18
 
19
import com.example.android.common.logger.Log;
20
import com.example.android.common.logger.LogFragment;
21
import com.example.android.common.logger.LogWrapper;
22
import com.example.android.common.logger.MessageOnlyLogFilter;
23
import com.example.android.system.runtimepermissions.camera.CameraPreviewFragment;
24
import com.example.android.system.runtimepermissions.contacts.ContactsFragment;
25
 
26
import android.Manifest;
27
import android.app.Activity;
28
import android.content.Context;
29
import android.content.pm.PackageManager;
30
import android.os.Bundle;
31
import android.support.annotation.NonNull;
32
import android.support.design.widget.Snackbar;
33
import android.support.v4.app.ActivityCompat;
34
import android.support.v4.app.FragmentTransaction;
35
import android.view.Menu;
36
import android.view.MenuItem;
37
import android.view.View;
38
import android.widget.ViewAnimator;
39
 
40
import common.activities.SampleActivityBase;
41
 
42
/**
43
 * Launcher Activity that demonstrates the use of runtime permissions for Android M.
44
 * It contains a summary sample description, sample log and a Fragment that calls callbacks on this
45
 * Activity to illustrate parts of the runtime permissions API.
46
 * <p>
47
 * This Activity requests permissions to access the camera ({@link android.Manifest.permission#CAMERA})
48
 * when the 'Show Camera' button is clicked to display the camera preview.
49
 * Contacts permissions (({@link android.Manifest.permission#READ_CONTACTS} and ({@link
50
 * android.Manifest.permission#WRITE_CONTACTS})) are requested when the 'Show and Add Contacts'
51
 * button is
52
 * clicked to display the first contact in the contacts database and to add a dummy contact
53
 * directly to it. Permissions are verified and requested through compat helpers in the support v4
54
 * library, in this Activity using {@link ActivityCompat}.
55
 * First, permissions are checked if they have already been granted through {@link
56
 * ActivityCompat#checkSelfPermission(Context, String)}.
57
 * If permissions have not been granted, they are requested through
58
 * {@link ActivityCompat#requestPermissions(Activity, String[], int)} and the return value checked
59
 * in
60
 * a callback to the {@link android.support.v4.app.ActivityCompat.OnRequestPermissionsResultCallback}
61
 * interface.
62
 * <p>
63
 * Before requesting permissions, {@link ActivityCompat#shouldShowRequestPermissionRationale(Activity,
64
 * String)}
65
 * should be called to provide the user with additional context for the use of permissions if they
66
 * have been denied previously.
67
 * <p>
68
 * If this sample is executed on a device running a platform version below M, all permissions
69
 * declared
70
 * in the Android manifest file are always granted at install time and cannot be requested at run
71
 * time.
72
 * <p>
73
 * This sample targets the M platform and must therefore request permissions at runtime. Change the
74
 * targetSdk in the file 'Application/build.gradle' to 22 to run the application in compatibility
75
 * mode.
76
 * Now, if a permission has been disable by the system through the application settings, disabled
77
 * APIs provide compatibility data.
78
 * For example the camera cannot be opened or an empty list of contacts is returned. No special
79
 * action is required in this case.
80
 * <p>
81
 * (This class is based on the MainActivity used in the SimpleFragment sample template.)
82
 */
83
public class MainActivity extends SampleActivityBase
84
        implements ActivityCompat.OnRequestPermissionsResultCallback {
85
 
86
    public static final String TAG = "MainActivity";
87
 
88
    /**
89
     * Id to identify a camera permission request.
90
     */
91
    private static final int REQUEST_CAMERA = 0;
92
 
93
    /**
94
     * Id to identify a contacts permission request.
95
     */
96
    private static final int REQUEST_CONTACTS = 1;
97
 
98
    /**
99
     * Permissions required to read and write contacts. Used by the {@link ContactsFragment}.
100
     */
101
    private static String[] PERMISSIONS_CONTACT = {Manifest.permission.READ_CONTACTS,
102
            Manifest.permission.WRITE_CONTACTS};
103
 
104
    // Whether the Log Fragment is currently shown.
105
    private boolean mLogShown;
106
 
107
    /**
108
     * Root of the layout of this Activity.
109
     */
110
    private View mLayout;
111
 
112
    /**
113
     * Called when the 'show camera' button is clicked.
114
     * Callback is defined in resource layout definition.
115
     */
116
    public void showCamera(View view) {
117
        Log.i(TAG, "Show camera button pressed. Checking permission.");
119
        // Check if the Camera permission is already available.
120
        if (ActivityCompat.checkSelfPermission(this, Manifest.permission.CAMERA)
121
                != PackageManager.PERMISSION_GRANTED) {
122
            // Camera permission has not been granted.
123
 
124
            requestCameraPermission();
125
 
126
        } else {
127
 
128
            // Camera permissions is already available, show the camera preview.
129
            Log.i(TAG,
130
                    "CAMERA permission has already been granted. Displaying camera preview.");
131
            showCameraPreview();
132
        }
134
 
135
    }
136
 
137
    /**
138
     * Requests the Camera permission.
139
     * If the permission has been denied previously, a SnackBar will prompt the user to grant the
140
     * permission, otherwise it is requested directly.
141
     */
142
    private void requestCameraPermission() {
143
        Log.i(TAG, "CAMERA permission has NOT been granted. Requesting permission.");
144
 
146
        if (ActivityCompat.shouldShowRequestPermissionRationale(this,
147
                Manifest.permission.CAMERA)) {
148
            // Provide an additional rationale to the user if the permission was not granted
149
            // and the user would benefit from additional context for the use of the permission.
150
            // For example if the user has previously denied the permission.
151
            Log.i(TAG,
152
                    "Displaying camera permission rationale to provide additional context.");
153
            Snackbar.make(mLayout, R.string.permission_camera_rationale,
154
                    Snackbar.LENGTH_INDEFINITE)
155
                    .setAction(R.string.ok, new View.OnClickListener() {
156
                        @Override
157
                        public void onClick(View view) {
158
                            ActivityCompat.requestPermissions(MainActivity.this,
159
                                    new String[]{Manifest.permission.CAMERA},
160
                                    REQUEST_CAMERA);
161
                        }
162
                    })
163
                    .show();
164
        } else {
165
 
166
            // Camera permission has not been granted yet. Request it directly.
167
            ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.CAMERA},
168
                    REQUEST_CAMERA);
169
        }
171
    }
172
 
173
    /**
174
     * Called when the 'show camera' button is clicked.
175
     * Callback is defined in resource layout definition.
176
     */
177
    public void showContacts(View v) {
178
        Log.i(TAG, "Show contacts button pressed. Checking permissions.");
179
 
180
        // Verify that all required contact permissions have been granted.
181
        if (ActivityCompat.checkSelfPermission(this, Manifest.permission.READ_CONTACTS)
182
                != PackageManager.PERMISSION_GRANTED
183
                || ActivityCompat.checkSelfPermission(this, Manifest.permission.WRITE_CONTACTS)
184
                != PackageManager.PERMISSION_GRANTED) {
185
            // Contacts permissions have not been granted.
186
            Log.i(TAG, "Contact permissions has NOT been granted. Requesting permissions.");
187
            requestContactsPermissions();
188
 
189
        } else {
190
 
191
            // Contact permissions have been granted. Show the contacts fragment.
192
            Log.i(TAG,
193
                    "Contact permissions have already been granted. Displaying contact details.");
194
            showContactDetails();
195
        }
196
    }
197
 
198
    /**
199
     * Requests the Contacts permissions.
200
     * If the permission has been denied previously, a SnackBar will prompt the user to grant the
201
     * permission, otherwise it is requested directly.
202
     */
203
    private void requestContactsPermissions() {
205
        if (ActivityCompat.shouldShowRequestPermissionRationale(this,
206
                Manifest.permission.READ_CONTACTS)
207
                || ActivityCompat.shouldShowRequestPermissionRationale(this,
208
                Manifest.permission.WRITE_CONTACTS)) {
209
 
210
            // Provide an additional rationale to the user if the permission was not granted
211
            // and the user would benefit from additional context for the use of the permission.
212
            // For example, if the request has been denied previously.
213
            Log.i(TAG,
214
                    "Displaying contacts permission rationale to provide additional context.");
215
 
216
            // Display a SnackBar with an explanation and a button to trigger the request.
217
            Snackbar.make(mLayout, R.string.permission_contacts_rationale,
218
                    Snackbar.LENGTH_INDEFINITE)
219
                    .setAction(R.string.ok, new View.OnClickListener() {
220
                        @Override
221
                        public void onClick(View view) {
222
                            ActivityCompat
223
                                    .requestPermissions(MainActivity.this, PERMISSIONS_CONTACT,
224
                                            REQUEST_CONTACTS);
225
                        }
226
                    })
227
                    .show();
228
        } else {
229
            // Contact permissions have not been granted yet. Request them directly.
230
            ActivityCompat.requestPermissions(this, PERMISSIONS_CONTACT, REQUEST_CONTACTS);
231
        }
233
    }
234
 
235
 
236
    /**
237
     * Display the {@link CameraPreviewFragment} in the content area if the required Camera
238
     * permission has been granted.
239
     */
240
    private void showCameraPreview() {
241
        getSupportFragmentManager().beginTransaction()
242
                .replace(R.id.sample_content_fragment, CameraPreviewFragment.newInstance())
243
                .addToBackStack("contacts")
244
                .commit();
245
    }
246
 
247
    /**
248
     * Display the {@link ContactsFragment} in the content area if the required contacts
249
     * permissions
250
     * have been granted.
251
     */
252
    private void showContactDetails() {
253
        getSupportFragmentManager().beginTransaction()
254
                .replace(R.id.sample_content_fragment, ContactsFragment.newInstance())
255
                .addToBackStack("contacts")
256
                .commit();
257
    }
258
 
259
 
260
    /**
261
     * Callback received when a permissions request has been completed.
262
     */
263
    @Override
264
    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions,
265
            @NonNull int[] grantResults) {
266
 
267
        if (requestCode == REQUEST_CAMERA) {
269
            // Received permission result for camera permission.
270
            Log.i(TAG, "Received response for Camera permission request.");
271
 
272
            // Check if the only required permission has been granted
273
            if (grantResults.length == 1 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
274
                // Camera permission has been granted, preview can be displayed
275
                Log.i(TAG, "CAMERA permission has now been granted. Showing preview.");
276
                Snackbar.make(mLayout, R.string.permision_available_camera,
277
                        Snackbar.LENGTH_SHORT).show();
278
            } else {
279
                Log.i(TAG, "CAMERA permission was NOT granted.");
280
                Snackbar.make(mLayout, R.string.permissions_not_granted,
281
                        Snackbar.LENGTH_SHORT).show();
282
 
283
            }
285
 
286
        } else if (requestCode == REQUEST_CONTACTS) {
287
            Log.i(TAG, "Received response for contact permissions request.");
288
 
289
            // We have requested multiple permissions for contacts, so all of them need to be
290
            // checked.
291
            if (PermissionUtil.verifyPermissions(grantResults)) {
292
                // All required permissions have been granted, display contacts fragment.
293
                Snackbar.make(mLayout, R.string.permision_available_contacts,
294
                        Snackbar.LENGTH_SHORT)
295
                        .show();
296
            } else {
297
                Log.i(TAG, "Contacts permissions were NOT granted.");
298
                Snackbar.make(mLayout, R.string.permissions_not_granted,