Permissions In Kotlin

Introduction

 
While developing an application, the most important process is to secure sensitive data. Permissions add security to system data and features and use predefined permissions.
 

Permission Types

 
Normal
 
It is low-level security-sensitive information. The system will grant the permissions automatically without asking the user, but permission is listed in the application package description.
 
Dangerous
 
This is high-level security-sensitive information. The permission is asked to the user and if the user grants permission, the permission will not be asked anymore until the application is reinstalled.
 
Signature
 
It is extremely high-level security-sensitive information. Apps signed with the same certificate as app defining the permissions can acquire it. If signature matches, it automatically grants the permission.
 
Special
 
The system grant access to system resources only by the off-band acquisition method. The app must use two if necessary.
 
Privileged
 
These are for system image apps. It should not have to use them. 
 

Defining Permissions

 
Defining own permissions are used for secure apps. For built-in permissions, the permissions are defined by the system and own permissions are used when application are exposed sensitive information. Own permissions are set inside the AndroidMainfest.xml. 
  1. <permission android:description = "string resource"    
  2.   android:icon = "drawable resource"    
  3.   android:label = "string resource"    
  4.   android:name = "string"    
  5.   android:permissionGroup = "string"    
  6.   android:protectionLevel = ["normal" | "dangerous" | "signature" | "signatureOrsystem"]  />    
For grouping the permissions, there are two ways: Use the <permission-group> element and add permissionGroup attributes to <permission>; the section "Manifest Top Level Entries" in the text companion. Use the <permission-tree> element and name permission basis of "Manifest Top Level Entries" in text companion.
 
Using Permissions
  1. <uses-permission android :name = "String"    
  2.    android:maxSdkVerion = "integer" />   
The name attribute specifies the permission name and to connect the permission to all components at a time on a per-component base. In such case the below code can be used inside the permission attribute.
  1. <activity android:name = "com.example.myapp.ExampleActivity"    
  2. android :permission = "com.example.myapp.abcPermission" />    

Acquiring permission

 
Permissions enquiry happens at the runtime of an application. This made the psermission system more flexible. The below runtime permission inquiry must be included in the code.
  1. val activity = this  
  2. val perm = Manifest.permission.CAMERA  
  3. val cameraPermReturnId = 7239  
  4. val permissionCheck = ContextComat.checkSelfPermission(activity, perm)  
  5. if (permissionCheck != Package.Permission_Granted) {  
  6.     if (ActivityCompat.shouldRequestPermissionRationale(activity, perm)) {  
  7.         //shows the explanation to user    
  8.         //the permission    
  9.         val dialog = AlertDialog.Builder(activity).Create()  
  10.         dialog.show()  
  11.     } else {  
  12.         //the permission    
  13.         ActivityCompat.requestPermision(activity, arrayOf(perm), cameraPermReturnId)  
  14.         // the result of the request    
  15.     }  
  16. }  
The code checks whether the permission is granted already or the permission got revoked explicitly. The method checks a rationale should be shown to the user. Another method performs the permission enquiry. It occurs asynchronously, so the call returns immediately.The result that show asynchronous callback method as follows:
  1. override  
  2. fun onRequestPermissionResult(requestCode: Int, permissions: Array < String > , grantResults: IntArray) {  
  3.     when(requestCode) {  
  4.         cameraPermREturnId - > {  
  5.             if ((grantResults.isNotempty() && grantResults[0] == PackageManager.Permission_GRANTED)) {  
  6.                 //permission granted    
  7.             } else {  
  8.                 //permission denied    
  9.             }  
  10.             return  
  11.         }  
  12.         else - > {  
  13.             Ignores all request  
  14.         }  
  15.     }  
  16. }  
The above method must be implemeted inside the android.content.Activity class.
 

Special Permission

 
In a situation such as using a ActivityCompat.requestPermissions() is not enough to acquire permissions SYSTEM_ALERT_WINDOW and WRIE_SETTINGS. In requirement of two permission the special permission is used.
  1. val backFromSettingPerm = 6183  
  2. if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {  
  3.     val activity = this  
  4.     if (!Settings.system.canWrite(activity)) {  
  5.         AlertDialog dialog = new AlertDialog.Builder(activity).setTitle(..).setmessage(..).setPositiveButton("OK", {  
  6.             doalog,  
  7.             id - > val intent = Intent(Settings.ACTION_MANAGE_WRITE_SETTINGS)  
  8.             intent.data = Iri.parse("package:" + getPackageName())  
  9.             activity.startActivityForResult(intent, backFromSettingPerm)  
  10.         }).setNegativeButton("Cancel,{ dialog ,id - >")  
  11.     })  
  12.    create();  
  13.    dialog.show();  
  14.    systemWillAsk = true;  
  15.  }  
  16. }  
  17. else {  
  18.     //other permissions    
  19. }  

Permissions handled in teminal

 
To view permissions on the device, Scanning through the apps list in the system settings app, use the ADB shell to acquire various permissions related information in the terminal. Inside the shell there are a pair of commands to get the permission information. To view the permission state for certain package or to grant or revoke permissions, the below code is used:
  1. cmd package list permissions -d -g    
  2. dumpsys package <PACKAGE-NAME>    
  3. pm [grant][revoke] <PERMISSION-NAME>