Skip to content Skip to sidebar Skip to footer

Grant Permission Read Call Log Permission Android

Android G's name was just announced officially days ago. The final version is near in that location and would be released not so long.

Although Android is existence proceed adult but the latest update to Android M is totally different since there is some major modify that would change everything like new Runtime Permission. Surprisingly information technology is not much talked nigh in Android Developer community even though it is extremely of import and may cause some big trouble in the about future.

That's the reason why I decide to blog most this topic today. Everything y'all need to know most this new Runtime Permission including how to implement information technology in your code. Let's do it earlier it's too belatedly.

The New Runtime Permission

Android's permission system is one of the biggest security business concern all along since those permissions are asked for at install fourth dimension. In one case installed, the application will be able to access all of things granted without any user's acknowledgement what exactly application does with the permission.

No surprise why there are and so many bad guys trying to collect user's personal data through this security weakness and apply information technology in the bad way.

Android team also know this concern. 7 twelvemonth passed, finally permission arrangement is redesigned. In Android 6.0 Marshmallow, application will not be granted any permission at installation time. Instead, application has to enquire user for a permission one-by-one at runtime.

Please note that permission request dialog shown above volition non launch automatically. Developer has to call for it manually. In the instance that developer try to phone call some function that requires a permission which user has not granted still, the office volition suddenly throw an Exception which will atomic number 82 to the application crashing.

Besides, user is too able to revoke the granted permission someday through phone'south Settings application.

You might already feel similar there is some cold wind bravado through your arms ... If you are an Android Programmer, you volition suddenly know that programming logic is totally changed. Y'all cannot simply call a function to practice the chore like previous just yous accept to check for the permission for every unmarried feature or your application will just simply crash !

Correct. I would non spoil you that it is like shooting fish in a barrel. Although information technology is a great affair for user but it is truly nightmare for u.s. developer. We take to take coding to the next level or it will surely have a problem in both brusk-term and long-term.

Anyway this new Runtime Permission will work like described but when we set up the application's targetSdkVersion to 23 which hateful it is declared that awarding has already been tested on API Level 23. And this feature will piece of work only on Android half-dozen.0 Marshmallow. The same app will run with same old behavior on pre-Marshmallow device.

What happened to the application that has already been launched?

This new permission system may crusade y'all some panic right now. "Hey ! What'due south almost my application that launched 3 years ago. If it is installed on Android 6.0 device, does this behavior likewise applied? Will my application also crash?!?"

Don't worry. Android team has already idea about it. If the awarding'southward targetSdkVersion is set to less than 23. Information technology will be assumed that application is non tested with new permission system all the same and will switch to the same old behavior: user has to accept every single permission at install time and they will be all granted once installed !

As a result, application will run perfectly similar previous. Anyway please note that user still can revoke a permission after that ! Although Android half-dozen.0 warn the user when they try to do that but they tin revoke anyway.

Next question in your head right now. And then volition my application crash?

Such a kindness sent from god delivered through the Android squad. When we call a function that requires a permission user revoked on awarding with targetSdkVersion less than 23, no whatever Exception volition be thrown. Instead it will just only do zippo. For the function that return value, it volition return either cypher or 0 depends on the case.

But don't be too happy. Although application would non be crashed from calling a role. It may still can crash from what that application does next with those returned value.

Proficient news (at to the lowest degree for now) is these cases may rarely occur since this permission revoking feature is quite new and I believe that but few user will do it. In case they practice, they accept to accept the result.

Only in the long run, I believe that there volition be millions of users who turn some permission off. Letting our application non to work perfectly on new device is non adequate.

To brand it work perfectly, you meliorate modify your application to support this new permission system and I propose you to outset doing it right at present !

For that application which source code is not successfully modified to support Runtime Permission, Exercise NOT release information technology with targetSdkVersion 23 or it volition cause you a trouble. Movement the targetSdkVersion to 23 only when y'all laissez passer all the test.

Alert: Right now when you create a new project in Android Studio. targetSdkVersion volition exist automatically ready to the latest version, 23. If you are not set to make your application fully back up the Runtime Permission, I suggest you to step downwards the targetSdkVersion to 22 offset.

Automatically granted permissions

There is some permission that will be automatically granted at install time and will not be able to revoke. Nosotros call it Normal Permission (PROTECTION_NORMAL). Here is the total list of them:

android.permission.ACCESS_LOCATION_EXTRA_COMMANDS
android.permission.ACCESS_NETWORK_STATE
android.permission.ACCESS_NOTIFICATION_POLICY
android.permission.ACCESS_WIFI_STATE
android.permission.ACCESS_WIMAX_STATE
android.permission.BLUETOOTH
android.permission.BLUETOOTH_ADMIN
android.permission.BROADCAST_STICKY
android.permission.CHANGE_NETWORK_STATE
android.permission.CHANGE_WIFI_MULTICAST_STATE
android.permission.CHANGE_WIFI_STATE
android.permission.CHANGE_WIMAX_STATE
android.permission.DISABLE_KEYGUARD
android.permission.EXPAND_STATUS_BAR
android.permission.FLASHLIGHT
android.permission.GET_ACCOUNTS
android.permission.GET_PACKAGE_SIZE
android.permission.Cyberspace
android.permission.KILL_BACKGROUND_PROCESSES
android.permission.MODIFY_AUDIO_SETTINGS
android.permission.NFC
android.permission.READ_SYNC_SETTINGS
android.permission.READ_SYNC_STATS
android.permission.RECEIVE_BOOT_COMPLETED
android.permission.REORDER_TASKS
android.permission.REQUEST_INSTALL_PACKAGES
android.permission.SET_TIME_ZONE
android.permission.SET_WALLPAPER
android.permission.SET_WALLPAPER_HINTS
android.permission.SUBSCRIBED_FEEDS_READ
android.permission.TRANSMIT_IR
android.permission.USE_FINGERPRINT
android.permission.VIBRATE
android.permission.WAKE_LOCK
android.permission.WRITE_SYNC_SETTINGS
com.android.alert.permission.SET_ALARM
com.android.launcher.permission.INSTALL_SHORTCUT
com.android.launcher.permission.UNINSTALL_SHORTCUT

Just simply declare those permissions in AndroidManifest.xml and information technology will work just fine. No need to check for the permission listed above since it couldn't be revoked.

Brand your awarding back up new Runtime Permission

Now it's time to make our application back up new Runtime Permission perfectly. Showtime with setting compileSdkVersion andtargetSdkVersion to 23.

          android {     compileSdkVersion 23     ...      defaultConfig {         ...         targetSdkVersion 23         ...     }        

In this example, we attempt to add together a contact with a function below.

                      private static concluding Cord TAG = "Contacts";     private void insertDummyContact() {         // Ii operations are needed to insert a new contact.         ArrayList<ContentProviderOperation> operations = new ArrayList<ContentProviderOperation>(2);          // First, set up upwards a new raw contact.         ContentProviderOperation.Builder op =                 ContentProviderOperation.newInsert(ContactsContract.RawContacts.CONTENT_URI)                         .withValue(ContactsContract.RawContacts.ACCOUNT_TYPE, zero)                         .withValue(ContactsContract.RawContacts.ACCOUNT_NAME, naught);         operations.add(op.build());          // Adjacent, set the name for the contact.         op = ContentProviderOperation.newInsert(ContactsContract.Data.CONTENT_URI)                 .withValueBackReference(ContactsContract.Data.RAW_CONTACT_ID, 0)                 .withValue(ContactsContract.Data.MIMETYPE,                         ContactsContract.CommonDataKinds.StructuredName.CONTENT_ITEM_TYPE)                 .withValue(ContactsContract.CommonDataKinds.StructuredName.DISPLAY_NAME,                         "__DUMMY CONTACT from runtime permissions sample");         operations.add(op.build());          // Utilise the operations.         ContentResolver resolver = getContentResolver();         try {             resolver.applyBatch(ContactsContract.Authorization, operations);         } catch (RemoteException eastward) {             Log.d(TAG, "Could not add together a new contact: " + eastward.getMessage());         } catch (OperationApplicationException east) {             Log.d(TAG, "Could not add a new contact: " + due east.getMessage());         }     }        

The higher up code requires WRITE_CONTACTS permission. If it is called without this permission granted, application will suddenly crash.

Next step is to add a permission intoAndroidManifest.xml with same old method.

          <uses-permission android:name="android.permission.WRITE_CONTACTS"/>        

Adjacent step is nosotros accept to create some other function to check that permission is granted or not. If it isn't and so phone call a dialog to ask user for a permission. Otherwise, you lot tin proceed the side by side footstep, creating a new contact.

Permissions are grouped into Permission Grouping like table below.

If any permission in a Permission Group is granted. Another permission in the same group will be automatically granted as well. In this case, once WRITE_CONTACTS is granted, application will also grant READ_CONTACTS and GET_ACCOUNTS.

Source code used to check and ask for permission is Activity'southward checkSelfPermission and requestPermissions respectively. These methods are added in API Level 23.

                      last private int REQUEST_CODE_ASK_PERMISSIONS = 123;      private void insertDummyContactWrapper() {         int hasWriteContactsPermission = checkSelfPermission(Manifest.permission.WRITE_CONTACTS);         if (hasWriteContactsPermission != PackageManager.PERMISSION_GRANTED) {             requestPermissions(new String[] {Manifest.permission.WRITE_CONTACTS},                     REQUEST_CODE_ASK_PERMISSIONS);             return;         }         insertDummyContact();     }        

If permission has already been granted, insertDummyContact() will be suddenly called. Otherwise, requestPermissions will be chosen to launch a permission request dialog like below.

No matter Let or Deny is chosen, Action'due south onRequestPermissionsResult will always be chosen to inform a result which we can bank check from the 3rd parameter, grantResults, similar this:

                      @Override     public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {         switch (requestCode) {             case REQUEST_CODE_ASK_PERMISSIONS:                 if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {                     // Permission Granted                     insertDummyContact();                 } else {                     // Permission Denied                     Toast.makeText(MainActivity.this, "WRITE_CONTACTS Denied", Toast.LENGTH_SHORT)                             .show();                 }                 suspension;             default:                 super.onRequestPermissionsResult(requestCode, permissions, grantResults);         }     }                  

This is how Runtime Permission works. Code is quite complicated but be used to it ... To make you application works perfectly with Runtime Permission, you have to handle all the example with the aforementioned method shown to a higher place.

If y'all desire to dial some wall, it is a skillful fourth dimension now ...

Handle "Never Ask Again"

If user denied a permission. In the second launch, user will get a "Never ask again" option to forbid application from request this permission in the time to come.

If this option is checked earlier denying. Next time we call requestPermissions, this dialog will not be appeared for this kind of permission anymore. Instead, it just does nothing.

However it is quite bad in term of UX if user does something just there is cypher interact back. This instance has to be handled as well. Earlier calling requestPermissions, we demand to check that should nosotros show a rationale about why application needs the being-requested permission through Activity'sshouldShowRequestPermissionRationale method. Source code will now look similar this:

                      last private int REQUEST_CODE_ASK_PERMISSIONS = 123;      private void insertDummyContactWrapper() {         int hasWriteContactsPermission = checkSelfPermission(Manifest.permission.WRITE_CONTACTS);         if (hasWriteContactsPermission != PackageManager.PERMISSION_GRANTED) {                 if (!shouldShowRequestPermissionRationale(Manifest.permission.WRITE_CONTACTS)) {                     showMessageOKCancel("You need to allow admission to Contacts",                             new DialogInterface.OnClickListener() {                                 @Override                                 public void onClick(DialogInterface dialog, int which) {                                     requestPermissions(new String[] {Manifest.permission.WRITE_CONTACTS},                                             REQUEST_CODE_ASK_PERMISSIONS);                                 }                             });                     return;                 }             requestPermissions(new String[] {Manifest.permission.WRITE_CONTACTS},                     REQUEST_CODE_ASK_PERMISSIONS);             render;         }         insertDummyContact();     }      private void showMessageOKCancel(Cord message, DialogInterface.OnClickListener okListener) {         new AlertDialog.Architect(MainActivity.this)                 .setMessage(bulletin)                 .setPositiveButton("OK", okListener)                 .setNegativeButton("Cancel", nothing)                 .create()                 .testify();     }        

The result are rational dialog volition be shown when this permission is requested for the first fourth dimension and also be shown if user has ever marked that permission as Never ask again. For the latter case, onRequestPermissionsResult will be chosen with PERMISSION_DENIED without any permission grant dialog.

Done !

Asking for multiple permissions at a time

There is definitely some characteristic that requires more than one permission. You could request for multiple permissions at a time with same method as above. Anyway don't forget to check the 'Never enquire once more' case for every unmarried permission too.

Here is the revised code.

                      final private int REQUEST_CODE_ASK_MULTIPLE_PERMISSIONS = 124;      private void insertDummyContactWrapper() {         List<Cord> permissionsNeeded = new ArrayList<String>();          concluding Listing<String> permissionsList = new ArrayList<String>();         if (!addPermission(permissionsList, Manifest.permission.ACCESS_FINE_LOCATION))             permissionsNeeded.add("GPS");         if (!addPermission(permissionsList, Manifest.permission.READ_CONTACTS))             permissionsNeeded.add together("Read Contacts");         if (!addPermission(permissionsList, Manifest.permission.WRITE_CONTACTS))             permissionsNeeded.add("Write Contacts");          if (permissionsList.size() > 0) {             if (permissionsNeeded.size() > 0) {                 // Need Rationale                 Cord message = "You need to grant admission to " + permissionsNeeded.go(0);                 for (int i = i; i < permissionsNeeded.size(); i++)                     message = message + ", " + permissionsNeeded.get(i);                 showMessageOKCancel(message,                         new DialogInterface.OnClickListener() {                             @Override                             public void onClick(DialogInterface dialog, int which) {                                 requestPermissions(permissionsList.toArray(new String[permissionsList.size()]),                                         REQUEST_CODE_ASK_MULTIPLE_PERMISSIONS);                             }                         });                 return;             }             requestPermissions(permissionsList.toArray(new String[permissionsList.size()]),                     REQUEST_CODE_ASK_MULTIPLE_PERMISSIONS);             return;         }          insertDummyContact();     }      private boolean addPermission(List<String> permissionsList, String permission) {         if (checkSelfPermission(permission) != PackageManager.PERMISSION_GRANTED) {             permissionsList.add(permission);             // Check for Rationale Option             if (!shouldShowRequestPermissionRationale(permission))                 return fake;         }         render truthful;     }                  

When every single permission got its grant result, the effect will be sent to the same callback method,onRequestPermissionsResult. I use HashMap to brand source code looks cleaner and more readable.

                      @Override     public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {         switch (requestCode) {             case REQUEST_CODE_ASK_MULTIPLE_PERMISSIONS:                 {                 Map<String, Integer> perms = new HashMap<String, Integer>();                 // Initial                 perms.put(Manifest.permission.ACCESS_FINE_LOCATION, PackageManager.PERMISSION_GRANTED);                 perms.put(Manifest.permission.READ_CONTACTS, PackageManager.PERMISSION_GRANTED);                 perms.put(Manifest.permission.WRITE_CONTACTS, PackageManager.PERMISSION_GRANTED);                 // Fill with results                 for (int i = 0; i < permissions.length; i++)                     perms.put(permissions[i], grantResults[i]);                 // Check for ACCESS_FINE_LOCATION                 if (perms.get(Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED                         && perms.become(Manifest.permission.READ_CONTACTS) == PackageManager.PERMISSION_GRANTED                         && perms.go(Manifest.permission.WRITE_CONTACTS) == PackageManager.PERMISSION_GRANTED) {                     // All Permissions Granted                     insertDummyContact();                 } else {                     // Permission Denied                     Toast.makeText(MainActivity.this, "Some Permission is Denied", Toast.LENGTH_SHORT)                             .show();                 }                 }                 suspension;             default:                 super.onRequestPermissionsResult(requestCode, permissions, grantResults);         }     }                  

The condition is flexible. You lot have to set it by your own. In some instance, if fifty-fifty one permission is not granted, that feature will exist just but disabled. But in some case, it volition still work but with express characteristic. There is no suggestion from me. Information technology is all by your design.

Utilise Support Library to make lawmaking frontwards-uniform

Although the code in a higher place works perfectly on Android 6.0 Marshmallow. Unfortunate that it will crash on Android pre-Marshmallow since those functions called are added in API Level 23.

The straight way is you can check Build Version with code beneath.

                      if (Build.VERSION.SDK_INT >= 23) {             // Marshmallow+         } else {             // Pre-Marshmallow         }                  

Merely code will be even more than complicated. So I propose you to use some help from Support Library v4 which is already prepared for this affair. Supplant those functions with these:

- ContextCompat.checkSelfPermission()

No matter application is run on M or not. This office will correctly render PERMISSION_GRANTED if the permission is granted. OtherwisePERMISSION_DENIED will exist returned.

- ActivityCompat.requestPermissions()

If this office is chosen on pre-Yard, OnRequestPermissionsResultCallback will be suddenly called with rightPERMISSION_GRANTED orPERMISSION_DENIED upshot.

- ActivityCompat.shouldShowRequestPermissionRationale()

If this role is chosen on pre-Grand, it will always return false.

Ever replace Activity'scheckSelfPermission, requestPermissions andshouldShowRequestPermissionRationale with these functions from Support Library v4.  And your application will work perfectly detect on any Android version with aforementioned code logic. Please note that these functions require some additional parameter: Context or Activeness. Zilch special to do, merely pass what it wants correctly. Hither is what source lawmaking will wait like.

                      individual void insertDummyContactWrapper() {         int hasWriteContactsPermission = ContextCompat.checkSelfPermission(MainActivity.this,                 Manifest.permission.WRITE_CONTACTS);         if (hasWriteContactsPermission != PackageManager.PERMISSION_GRANTED) {             if (!ActivityCompat.shouldShowRequestPermissionRationale(MainActivity.this,                     Manifest.permission.WRITE_CONTACTS)) {                 showMessageOKCancel("You need to allow access to Contacts",                         new DialogInterface.OnClickListener() {                             @Override                             public void onClick(DialogInterface dialog, int which) {                                 ActivityCompat.requestPermissions(MainActivity.this,                                         new String[] {Manifest.permission.WRITE_CONTACTS},                                         REQUEST_CODE_ASK_PERMISSIONS);                             }                         });                 return;             }             ActivityCompat.requestPermissions(MainActivity.this,                     new Cord[] {Manifest.permission.WRITE_CONTACTS},                     REQUEST_CODE_ASK_PERMISSIONS);             render;         }         insertDummyContact();     }                  

These methods are besides available in Fragment from Android Support Library v4. And then please feel complimentary to motion these logics into the Fragment.

Shorten source code with tertiary Party Library

You lot will observe that code is quite complicated. No surprise, there are quite many of 3rd party libraries out at that place trying to solve this big matter. I gave a endeavor with quite a lot of them and finally constitute one that satisfy me. It is hotchemi's PermissionsDispatcher.

What is does it exactly the same as I described above only just with shorter and cleaner lawmaking. Surely with some trade-off with flexibility. Delight give it a endeavor and see if information technology could be practical in your application. If it couldn't, you tin get on the direct way which is as well my selection right at present.

What will happen if permission is revoked while awarding is opened?

As mentioned above, a permission can be revoked anytime through phone'due south Settings.

And then what will happen if permission is revoked when application is opened? I take already given information technology a try and institute that application'south procedure is suddenly terminated. Everything inside application only just stopped (since it is already terminated ...). It sounds make sense to me anyway since if OS allows the application to become on its process, it may summon Freddy to my nightmare. I mean fifty-fifty worse nightmare than currently is ...

Decision and Suggestion

I believe that yous see the large picture of this new permission system quite clear right at present. And I believe that you besides see how big issue it is.

Withal you accept no selection. Runtime Permission is already used in Android Marshmallow. We are at the point of no return. Only affair we could do right now is to make our application fully back up this new permission system.

Skilful news is at that place are simply few permission that requires Runtime Permission flow. Most of the often-used permissions, for example, INTERNET, are in Normal Permission are automatically granted and you have no need to do anything with them. In decision, there are just few part of code that you need to modify.

At that place are two suggestions to y'all all:

1) Make Runtime Permission back up an urgent result

2) Don't set awarding's targetSdkVersion to 23 if your code is not still supported Runtime Permission. Especially when you create a new project from Android Studio, don't forget to take a expect at build.gradle everytime for targetSdkVersion !

Talk about source code modification, I must admit that it is quite a big thing. If code structure is not designed good enough, y'all may need some serious reconstruction which will surely have some time. Or at least I believe that source code need to be refactored for every single application. Anyhow like I said above, we have no selection ...

In the man time, since permission concept is turned upside downwards. Right at present if some permission is not granted, your awarding demand to still be able to work with limited characteristic. So I advise yous to list all the feature that related to permission you requested. And write down all the example possible, if permission A is granted but permission B is denied, what volition happen. Blah blah blah.

Good luck with your code refactoring. Mark it as urgent in your to-do list and start practice it today so it will contains no problem on the day Android Yard is publicly launched.

Hope yous find this article helpful and Happy Coding !

More details are available here.

Author: nuuneoi (Android GDE, CTO & CEO at The Cheese Factory)

A total-stack developer with more than six years feel on Android Application Development and more than 12 years in Mobile Application Development industry. Also has skill in Infrastucture, Service Side, Design, UI&UX, Hardware, Optimization, Cooking, Photographing, Blogging, Grooming, Public Speaking and exercise love to share things to people in the world!

funkariestabox.blogspot.com

Source: https://inthecheesefactory.com/blog/things-you-need-to-know-about-android-m-permission-developer-edition/en

Postar um comentário for "Grant Permission Read Call Log Permission Android"