├── .gitignore ├── .idea ├── .name ├── compiler.xml ├── copyright │ └── profiles_settings.xml ├── dbnavigator.xml ├── encodings.xml ├── gradle.xml ├── misc.xml ├── modules.xml ├── runConfigurations.xml └── vcs.xml ├── README.md ├── app ├── .gitignore ├── build.gradle ├── proguard-rules.pro └── src │ ├── androidTest │ └── java │ │ └── droidmentor │ │ └── permissionexample │ │ └── ApplicationTest.java │ ├── main │ ├── AndroidManifest.xml │ ├── java │ │ └── droidmentor │ │ │ └── permissionexample │ │ │ ├── PermissionActivity.java │ │ │ ├── PermissionResultCallback.java │ │ │ └── PermissionUtils.java │ └── res │ │ ├── layout │ │ └── activity_permission.xml │ │ ├── mipmap-hdpi │ │ └── ic_launcher.png │ │ ├── mipmap-mdpi │ │ └── ic_launcher.png │ │ ├── mipmap-xhdpi │ │ └── ic_launcher.png │ │ ├── mipmap-xxhdpi │ │ └── ic_launcher.png │ │ ├── mipmap-xxxhdpi │ │ └── ic_launcher.png │ │ ├── values-w820dp │ │ └── dimens.xml │ │ └── values │ │ ├── colors.xml │ │ ├── dimens.xml │ │ ├── strings.xml │ │ └── styles.xml │ └── test │ └── java │ └── droidmentor │ └── permissionexample │ └── ExampleUnitTest.java ├── build.gradle ├── gradle.properties ├── gradle └── wrapper │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── gradlew ├── gradlew.bat └── settings.gradle /.gitignore: -------------------------------------------------------------------------------- 1 | *.iml 2 | .gradle 3 | /local.properties 4 | /.idea/workspace.xml 5 | /.idea/libraries 6 | .DS_Store 7 | /build 8 | /captures 9 | -------------------------------------------------------------------------------- /.idea/.name: -------------------------------------------------------------------------------- 1 | PermissionExample -------------------------------------------------------------------------------- /.idea/compiler.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /.idea/copyright/profiles_settings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | -------------------------------------------------------------------------------- /.idea/dbnavigator.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | 134 | 135 | 136 | 137 | 138 | 139 | 140 | 141 | 142 | 143 | 144 | 145 | 146 | 147 | 148 | 149 | 150 | 151 | 152 | 153 | 154 | 155 | 156 | 157 | 158 | 159 | 160 | 161 | 162 | 163 | 164 | 165 | 166 | 167 | 168 | 169 | 170 | 171 | 172 | 173 | 174 | 175 | 176 | 177 | 178 | 179 | 180 | 181 | 182 | 183 | 184 | 185 | 186 | 187 | 188 | 189 | 190 | 191 | 192 | 193 | 194 | 195 | 196 | 197 | 198 | 199 | 200 | 201 | 202 | 203 | 204 | 205 | 206 | 207 | 208 | 209 | 210 | 211 | 212 | 213 | 214 | 215 | 216 | 217 | 218 | 219 | 220 | 221 | 222 | 223 | 224 | 225 | 226 | 227 | 228 | 229 | 230 | 231 | 232 | 233 | 234 | 235 | 236 | 237 | 238 | 239 | 240 | 241 | 242 | 243 | 244 | 245 | 246 | 247 | 248 | 249 | 250 | 251 | 252 | 253 | 254 | 255 | 256 | 257 | 258 | 259 | 260 | 261 | 262 | 263 | 264 | 265 | 266 | 267 | 268 | 269 | 270 | 271 | 272 | 273 | 274 | 275 | 276 | 277 | 278 | 279 | 280 | 281 | 282 | 283 | 284 | 285 | 286 | 287 | 288 | 289 | 290 | 291 | 292 | 293 | 294 | 295 | 296 | 297 | 298 | 299 | 300 | 301 | 302 | 303 | 304 | 305 | 306 | 307 | 308 | 309 | 310 | 311 | 312 | 313 | 314 | 315 | 316 | 317 | 318 | 319 | 320 | 321 | 322 | 323 | 324 | 325 | 326 | 327 | 328 | 329 | 330 | 331 | 332 | 333 | 334 | 335 | 336 | 337 | 338 | 339 | 340 | 341 | 342 | 343 | 344 | 345 | 346 | 347 | 348 | 349 | 350 | 351 | 352 | 353 | 354 | 355 | 356 | 357 | 358 | 359 | 360 | 361 | 362 | 363 | 364 | 365 | 366 | 367 | 368 | 369 | 370 | 371 | 372 | 373 | 374 | 375 | 376 | 377 | 378 | 379 | 380 | 381 | 382 | 383 | 384 | 385 | 386 | 387 | 388 | 389 | 390 | 391 | 392 | 393 | 394 | 395 | 396 | 397 | 398 | 399 | 400 | 401 | 402 | 403 | 404 | 405 | 406 | 407 | 408 | 409 | 410 | 411 | 412 | 413 | 414 | 415 | 416 | 417 | 418 | 419 | 420 | 421 | 422 | 423 | 424 | 425 | 426 | 427 | 428 | 429 | 430 | 431 | 432 | 433 | 434 | 435 | 436 | 437 | 438 | 439 | 440 | 441 | 442 | 443 | 444 | 445 | 446 | 447 | 448 | 449 | -------------------------------------------------------------------------------- /.idea/encodings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /.idea/gradle.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 22 | 23 | -------------------------------------------------------------------------------- /.idea/misc.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 12 | 13 | 14 | 26 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 53 | 54 | 55 | 56 | 57 | 1.8 58 | 59 | 64 | 65 | 66 | 67 | 68 | 69 | -------------------------------------------------------------------------------- /.idea/modules.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /.idea/runConfigurations.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 11 | 12 | -------------------------------------------------------------------------------- /.idea/vcs.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | 2 | This is a sample Android application to show how to get Multiple Permissions in one Go in Android M 3 | 4 | Basically two files are needed to get permissions. One file is used to check and request the needed permission 5 | and the other one to send the callback. 6 | 7 | PermissionUtils.java

Used to check and request the needed permission from the user.

8 | 9 | PermissionResultCallback.java

It's an interface,which gives the status of the request. 10 | 11 |
12 | interface PermissionResultCallback
13 | {
14 |     void PermissionGranted(int request_code);
15 |     void PartialPermissionGranted(int request_code, ArrayList granted_permissions);
16 |     void PermissionDenied(int request_code);
17 |     void NeverAskAgain(int request_code);
18 | }
19 | 
20 | 21 | Getting permissions from the user is simple,First add all the needed permissions in a list 22 | 23 |
24 | 
25 |  ArrayList permissions=new ArrayList<>();
26 | 
27 |  permissions.add(Manifest.permission.ACCESS_FINE_LOCATION);
28 |  permissions.add(Manifest.permission.WRITE_EXTERNAL_STORAGE);
29 |  
30 | 
31 | 32 | Create an instance for the class "PermissionUtils", and call the function check_permission by passing the 33 | permission list,why we need those permission explanation and the request code. 34 | 35 |
36 | 
37 |  permissionUtils=new PermissionUtils(getApplicationContext());
38 |  permissionUtils.check_permission(permissions,"Explain here why the app needs permissions",1);
39 |  
40 | 
41 | 42 | Then redirect the onRequestPermissionsResult to permissionUtils.onRequestPermissionsResult 43 | 44 |
45 | 
46 |   @Override
47 |   public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions,
48 |                                            @NonNull int[] grantResults) {
49 | 
50 |         // redirects to utils
51 | 
52 |         permissionUtils.onRequestPermissionsResult(requestCode,permissions,grantResults);
53 | 
54 |     }
55 | 
56 | 
57 | 58 | For getting the callbacks you need to include PermissionResultCallback interface into your activity, 59 | and also implement the needed methods. 60 | 61 |
62 | 
63 | public class PermissionActivity extends AppCompatActivity implements
64 |         OnRequestPermissionsResultCallback,PermissionResultCallback
65 | 
66 | 
67 |  // Callback functions
68 | 
69 | 
70 |     @Override
71 |     public void PermissionGranted(int request_code) {
72 |         Log.i("PERMISSION","GRANTED");
73 |     }
74 | 
75 |     @Override
76 |     public void PartialPermissionGranted(int request_code, ArrayList granted_permissions) {
77 |         Log.i("PERMISSION PARTIALLY","GRANTED");
78 |     }
79 | 
80 |     @Override
81 |     public void PermissionDenied(int request_code) {
82 |         Log.i("PERMISSION","DENIED");
83 |     }
84 | 
85 |     @Override
86 |     public void NeverAskAgain(int request_code) {
87 |         Log.i("PERMISSION","NEVER ASK AGAIN");
88 |     }
89 |     
90 | 
91 | 92 | In AndroidManifest.xml
93 | 94 | Specify all the needed permissions. If you don't, permission requests fail silently. That's an Android thing. 95 | 96 | For more information, check out my detailed guide here : http://droidmentor.com/multiple-permissions-in-one-go 97 | 98 | -------------------------------------------------------------------------------- /app/.gitignore: -------------------------------------------------------------------------------- 1 | /build 2 | -------------------------------------------------------------------------------- /app/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'com.android.application' 2 | 3 | android { 4 | compileSdkVersion 23 5 | buildToolsVersion "24.0.1" 6 | 7 | defaultConfig { 8 | applicationId "droidmentor.permissionexample" 9 | minSdkVersion 15 10 | targetSdkVersion 23 11 | versionCode 1 12 | versionName "1.0" 13 | } 14 | buildTypes { 15 | release { 16 | minifyEnabled false 17 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' 18 | } 19 | } 20 | } 21 | 22 | dependencies { 23 | compile fileTree(dir: 'libs', include: ['*.jar']) 24 | testCompile 'junit:junit:4.12' 25 | compile 'com.android.support:appcompat-v7:23.4.0' 26 | } 27 | -------------------------------------------------------------------------------- /app/proguard-rules.pro: -------------------------------------------------------------------------------- 1 | # Add project specific ProGuard rules here. 2 | # By default, the flags in this file are appended to flags specified 3 | # in /Users/Jaison/Library/Android/sdk/tools/proguard/proguard-android.txt 4 | # You can edit the include path and order by changing the proguardFiles 5 | # directive in build.gradle. 6 | # 7 | # For more details, see 8 | # http://developer.android.com/guide/developing/tools/proguard.html 9 | 10 | # Add any project specific keep options here: 11 | 12 | # If your project uses WebView with JS, uncomment the following 13 | # and specify the fully qualified class name to the JavaScript interface 14 | # class: 15 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview { 16 | # public *; 17 | #} 18 | -------------------------------------------------------------------------------- /app/src/androidTest/java/droidmentor/permissionexample/ApplicationTest.java: -------------------------------------------------------------------------------- 1 | package droidmentor.permissionexample; 2 | 3 | import android.app.Application; 4 | import android.test.ApplicationTestCase; 5 | 6 | /** 7 | * Testing Fundamentals 8 | */ 9 | public class ApplicationTest extends ApplicationTestCase { 10 | public ApplicationTest() { 11 | super(Application.class); 12 | } 13 | } -------------------------------------------------------------------------------- /app/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 7 | 8 | 9 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | -------------------------------------------------------------------------------- /app/src/main/java/droidmentor/permissionexample/PermissionActivity.java: -------------------------------------------------------------------------------- 1 | package droidmentor.permissionexample; 2 | 3 | import android.Manifest; 4 | import android.os.Bundle; 5 | import android.support.annotation.NonNull; 6 | import android.support.v4.app.ActivityCompat.OnRequestPermissionsResultCallback; 7 | import android.support.v7.app.AppCompatActivity; 8 | import android.util.Log; 9 | import android.view.View; 10 | import android.widget.Button; 11 | 12 | import java.util.ArrayList; 13 | 14 | public class PermissionActivity extends AppCompatActivity implements 15 | OnRequestPermissionsResultCallback,PermissionResultCallback{ 16 | 17 | Button btn_check; 18 | 19 | 20 | // list of permissions 21 | 22 | ArrayList permissions=new ArrayList<>(); 23 | 24 | PermissionUtils permissionUtils; 25 | 26 | 27 | @Override 28 | protected void onCreate(Bundle savedInstanceState) { 29 | super.onCreate(savedInstanceState); 30 | setContentView(R.layout.activity_permission); 31 | 32 | permissionUtils=new PermissionUtils(getApplicationContext()); 33 | 34 | permissions.add(Manifest.permission.ACCESS_FINE_LOCATION); 35 | permissions.add(Manifest.permission.WRITE_EXTERNAL_STORAGE); 36 | 37 | btn_check= (Button) findViewById(R.id.btn_check); 38 | btn_check.setOnClickListener(new View.OnClickListener() { 39 | @Override 40 | public void onClick(View v) { 41 | permissionUtils.check_permission(permissions,"Explain here why the app needs permissions",1); 42 | 43 | } 44 | }); 45 | } 46 | 47 | @Override 48 | public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, 49 | @NonNull int[] grantResults) { 50 | 51 | // redirects to utils 52 | 53 | permissionUtils.onRequestPermissionsResult(requestCode,permissions,grantResults); 54 | 55 | } 56 | 57 | // Callback functions 58 | 59 | 60 | @Override 61 | public void PermissionGranted(int request_code) { 62 | Log.i("PERMISSION","GRANTED"); 63 | } 64 | 65 | @Override 66 | public void PartialPermissionGranted(int request_code, ArrayList granted_permissions) { 67 | Log.i("PERMISSION PARTIALLY","GRANTED"); 68 | } 69 | 70 | @Override 71 | public void PermissionDenied(int request_code) { 72 | Log.i("PERMISSION","DENIED"); 73 | } 74 | 75 | @Override 76 | public void NeverAskAgain(int request_code) { 77 | Log.i("PERMISSION","NEVER ASK AGAIN"); 78 | } 79 | } 80 | -------------------------------------------------------------------------------- /app/src/main/java/droidmentor/permissionexample/PermissionResultCallback.java: -------------------------------------------------------------------------------- 1 | package droidmentor.permissionexample; 2 | 3 | import java.util.ArrayList; 4 | 5 | /** 6 | * Created by Jaison on 25/08/16. 7 | */ 8 | 9 | 10 | interface PermissionResultCallback 11 | { 12 | void PermissionGranted(int request_code); 13 | void PartialPermissionGranted(int request_code, ArrayList granted_permissions); 14 | void PermissionDenied(int request_code); 15 | void NeverAskAgain(int request_code); 16 | } 17 | -------------------------------------------------------------------------------- /app/src/main/java/droidmentor/permissionexample/PermissionUtils.java: -------------------------------------------------------------------------------- 1 | package droidmentor.permissionexample; 2 | 3 | import android.app.Activity; 4 | import android.content.Context; 5 | import android.content.DialogInterface; 6 | import android.content.pm.PackageManager; 7 | import android.os.Build; 8 | import android.support.v4.app.ActivityCompat; 9 | import android.support.v4.content.ContextCompat; 10 | import android.support.v7.app.AlertDialog; 11 | import android.util.Log; 12 | import android.widget.Toast; 13 | 14 | import java.util.ArrayList; 15 | import java.util.HashMap; 16 | import java.util.Map; 17 | 18 | /** 19 | * Created by Jaison on 25/08/16. 20 | */ 21 | 22 | 23 | public class PermissionUtils 24 | { 25 | 26 | Context context; 27 | Activity current_activity; 28 | 29 | PermissionResultCallback permissionResultCallback; 30 | 31 | 32 | ArrayList permission_list=new ArrayList<>(); 33 | ArrayList listPermissionsNeeded=new ArrayList<>(); 34 | String dialog_content=""; 35 | int req_code; 36 | 37 | public PermissionUtils(Context context) 38 | { 39 | this.context=context; 40 | this.current_activity= (Activity) context; 41 | 42 | permissionResultCallback= (PermissionResultCallback) context; 43 | } 44 | 45 | 46 | /** 47 | * Check the API Level & Permission 48 | * 49 | * @param permissions 50 | * @param dialog_content 51 | * @param request_code 52 | */ 53 | 54 | public void check_permission(ArrayList permissions, String dialog_content, int request_code) 55 | { 56 | this.permission_list=permissions; 57 | this.dialog_content=dialog_content; 58 | this.req_code=request_code; 59 | 60 | if(Build.VERSION.SDK_INT >= 23) 61 | { 62 | if (checkAndRequestPermissions(permissions, request_code)) 63 | { 64 | permissionResultCallback.PermissionGranted(request_code); 65 | Log.i("all permissions", "granted"); 66 | Log.i("proceed", "to callback"); 67 | } 68 | } 69 | else 70 | { 71 | permissionResultCallback.PermissionGranted(request_code); 72 | 73 | Log.i("all permissions", "granted"); 74 | Log.i("proceed", "to callback"); 75 | } 76 | 77 | } 78 | 79 | 80 | /** 81 | * Check and request the Permissions 82 | * 83 | * @param permissions 84 | * @param request_code 85 | * @return 86 | */ 87 | 88 | private boolean checkAndRequestPermissions(ArrayList permissions,int request_code) { 89 | 90 | if(permissions.size()>0) 91 | { 92 | listPermissionsNeeded = new ArrayList<>(); 93 | 94 | for(int i=0;i0) 127 | { 128 | Map perms = new HashMap<>(); 129 | 130 | for (int i = 0; i < permissions.length; i++) 131 | { 132 | perms.put(permissions[i], grantResults[i]); 133 | } 134 | 135 | final ArrayList pending_permissions=new ArrayList<>(); 136 | 137 | for (int i = 0; i < listPermissionsNeeded.size(); i++) 138 | { 139 | if (perms.get(listPermissionsNeeded.get(i)) != PackageManager.PERMISSION_GRANTED) 140 | { 141 | if(ActivityCompat.shouldShowRequestPermissionRationale(current_activity,listPermissionsNeeded.get(i))) 142 | pending_permissions.add(listPermissionsNeeded.get(i)); 143 | else 144 | { 145 | Log.i("Go to settings","and enable permissions"); 146 | permissionResultCallback.NeverAskAgain(req_code); 147 | Toast.makeText(current_activity, "Go to settings and enable permissions", Toast.LENGTH_LONG).show(); 148 | return; 149 | } 150 | } 151 | 152 | } 153 | 154 | if(pending_permissions.size()>0) 155 | { 156 | showMessageOKCancel(dialog_content, 157 | new DialogInterface.OnClickListener() { 158 | @Override 159 | public void onClick(DialogInterface dialog, int which) { 160 | 161 | switch (which) { 162 | case DialogInterface.BUTTON_POSITIVE: 163 | check_permission(permission_list,dialog_content,req_code); 164 | break; 165 | case DialogInterface.BUTTON_NEGATIVE: 166 | Log.i("permisson","not fully given"); 167 | if(permission_list.size()==pending_permissions.size()) 168 | permissionResultCallback.PermissionDenied(req_code); 169 | else 170 | permissionResultCallback.PartialPermissionGranted(req_code,pending_permissions); 171 | break; 172 | } 173 | 174 | 175 | } 176 | }); 177 | 178 | } 179 | else 180 | { 181 | Log.i("all","permissions granted"); 182 | Log.i("proceed","to next step"); 183 | permissionResultCallback.PermissionGranted(req_code); 184 | 185 | } 186 | 187 | 188 | 189 | } 190 | break; 191 | } 192 | } 193 | 194 | 195 | /** 196 | * Explain why the app needs permissions 197 | * 198 | * @param message 199 | * @param okListener 200 | */ 201 | private void showMessageOKCancel(String message, DialogInterface.OnClickListener okListener) { 202 | new AlertDialog.Builder(current_activity) 203 | .setMessage(message) 204 | .setPositiveButton("Ok", okListener) 205 | .setNegativeButton("Cancel", okListener) 206 | .create() 207 | .show(); 208 | } 209 | 210 | } 211 | -------------------------------------------------------------------------------- /app/src/main/res/layout/activity_permission.xml: -------------------------------------------------------------------------------- 1 | 2 | 11 | 12 |