As We have the basic understanding of RxJava features and function from the last post of basic of RxJava and RxJava2 Part-1 and basic of RxJava and RxBinding part-2. Rx is getting popular in Android application development because it gives the best result of reactive nature. In this series, we will learn some of new Rx feature is called RxPermission.
Earlier we have practiced that the user can be seen the permission detail at while installing the app. But in marshmallow device version 6.0 it has changed. Now application will not be granted the permission while installing the application. It will ask users at runtime. Why is this required?
In the previous below the marshmallow versions like the lollipop and other lower version devices, User was felt like obvious to see the permission details while installing that, They might be thinking that why can I shared my confidential information without asking that permission. The application should be asked me, hey if you want to access those then please grant me permission to access. For example, if any other app wants to get access the phone contacts then user feel obvious to give access those. That why it comes runtime permission. If the other application wants to access phone contacts of users then its all depend on the user if they granted the permission or not. If the user has not granted then other application will not be allowed to access that information.
One common question of every developer that how Android take care our old application launch on marshmallow device. So I would say do not panic be relaxed android take care that issue very smartly. If your application has built on targeted SDK version is less than 23 then it should not be crashed on Android M. It will work fine without any issue. Runtime permission will only ask users if you build the app on target SDK version 23 or higher.
This really sounds good for the users to feel confident that my phone is secure if I used to install any other application without any issue. Android take care security point of view at the top priority. Awesome:)
Okay, Let’s see what are those permissions are granted while installing the application. These permissions called protection-level permission. It will not ask the user at runtime.
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.INTERNET 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.alarm.permission.SET_ALARM com.android.launcher.permission.INSTALL_SHORTCUT com.android.launcher.permission.UNINSTALL_SHORTCUT
Great. This permission is required to add in Android manifest file then it works fine without any crash. Now let’s check what is required to check the permission of my target SDK version and compile SDK version is 23 or higher.
A developer needs to follow three basic methods.
1. checkSelfPermission(Permission) – to check the permission is already granted or not.
2. requestPermissions(String [] permissions, int requestCode) – if not then request for permission
3. onRequestPermissionsResult(int premsRequestCode, String [] permissions, int [] grantResults) – to check the result whether permission is granted or not.
Let’s see one example I am building an app which targets SDK version is 23 or higher. I want location access in one of my application. First of all, you need to know what are permission is required for access the Location. Okay, How do I make sure? Let’s check in framework level what Gooogle has defined for location access?
When I look this file DefaultPermissionGrantPolicy.java in framework module.
I found this permission is required to access the location.
private static final Set<String> LOCATION_PERMISSIONS = new ArraySet<>(); static { LOCATION_PERMISSIONS.add(Manifest.permission.ACCESS_FINE_LOCATION); LOCATION_PERMISSIONS.add(Manifest.permission.ACCESS_COARSE_LOCATION); }
So basically these two permission is required to access Location. Ok, Let’s check while clicking on a button I want to access the location.
@OnClick(R.id.RuntimeButton) public void RunTimeClick(){ if (android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { if (ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED) { //Location Permission already granted or not tryToGetLocationValue(); } else { //Request Location Permission askLocationPermission(); } } else { // not required any runtime permission for below M tryToGetLocationValue(); } }
Here we are checking the build SDK version is marshmallow then request for permission else not required permission.
public static final int MY_PERMISSIONS_REQUEST_LOCATION = 99; private void askLocationPermission() { if (ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED) { // Should we show an explanation? if (ActivityCompat.shouldShowRequestPermissionRationale(this, Manifest.permission.ACCESS_FINE_LOCATION)) { // Show an explanation to the user *asynchronously* -- don't block // this thread waiting for the user's response! After the user // sees the explanation, try again to request the permission. This info convince to users to allow // Show alert message to users to need location access allpw location permission showAlert(); } else { // No explanation needed, we can request the permission. ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.ACCESS_FINE_LOCATION}, MY_PERMISSIONS_REQUEST_LOCATION ); } } }
private void showAlert(){ new AlertDialog.Builder(this) .setTitle("Location Permission Needed") .setMessage("This app needs the Location permission, please accept to use location functionality") .setPositiveButton("OK", new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialogInterface, int i) { //Prompt the user once explanation has been shown to ask for permission again ActivityCompat.requestPermissions(RunTimePermissionTestActivity.this, new String[]{Manifest.permission.ACCESS_FINE_LOCATION}, MY_PERMISSIONS_REQUEST_LOCATION ); } }) .create() .show(); }
To access the runtime permission it is mandatory that permission also registered in AndroidManifest.xml file.
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"> <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION">
Once the user will be allowed to granting this permission it will trigger the result in onRequestPermissionResult ().
@Override public void onRequestPermissionsResult(int requestCode, String permissions[], int[] grantResults) { switch (requestCode) { case MY_PERMISSIONS_REQUEST_LOCATION: { // If request is cancelled, the result arrays are empty. if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) { // permission is granted // location-related task you need to do. if (ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED) { tryToGetLocationValue(); } } else { // permission denied Toast.makeText(this, "permission denied", Toast.LENGTH_LONG).show(); } return; } } }
So this is the basic Runtime permission in Android application development. But now the time is the Reactive, So we should be thinking about the reactive that removed all the boilerplate code. RxPermissions is the library allows the usage of RxJava with the new Android M permission model.
To access the reactive permission very first thing we need to add the relevant dependency in android gradle file.
compile 'com.tbruyelle.rxpermissions:rxpermissions:0.9.4@aar'
for RxJava2 it has modified
compile 'com.tbruyelle.rxpermissions2:rxpermissions:0.9.4@aar'
It has removed all the boilerplate code and make our life pretty easy and simple. It is not required to check the permission result that particular permission is granted or not. Every thing is handling at single place.
@OnClick(R.id.RuntimeButton) public void RunTimeClick() { RxPermissions rxPermissions = new RxPermissions(this); // where this is an Activity instance // Must be done during an initialization phase like onCreate rxPermissions .requestEach(Manifest.permission.ACCESS_FINE_LOCATION, Manifest.permission.ACCESS_COARSE_LOCATION) .subscribe(permission -> { // will emit 2 Permission objects if (permission.granted) { // `permission.name` is granted ! tryToGetLocationValue(); } else if (permission.shouldShowRequestPermissionRationale) { // Denied permission without ask never again Toast.makeText(RunTimePermissionTestActivity.this, "Denied permission without ask never again", Toast.LENGTH_SHORT).show(); } else { // Denied permission with ask never again // Need to go to the settings Toast.makeText(RunTimePermissionTestActivity.this, "Permission denied, can't enable the Location", Toast.LENGTH_SHORT).show(); } }, new Consumer<Throwable>() { @Override public void accept(@NonNull Throwable throwable) throws Exception { Log.e("TAG", "onError,"+throwable.getMessage()); } }); }
RxPermission is awesome for runtime permission prompt. In my next tutorial of this Rx series, we will learn new reactive feature and functions. If you wondering Kotlin for android then I would be recommended to check all this post of Kotlin Category.
Please do subscribe your email to get every newsletter from this blog and if you feel that this post helps you then do not forget to share and comment below.
I used my old reference to this post which is written here.
Happy coding 🙂
I am a very enthusiastic Android developer to build solid Android apps. I have a keen interest in developing for Android and have published apps to the Google Play Store. I always open to learning new technologies. For any help drop us a line anytime at contact@mobologicplus.com
Hi everyone, In this article, we are going to learn how to hide the production… Read More
Hello everyone, Today in this article, we are going to learn about localisation to support… Read More
Hello everyone, In this article, we are going to learn something to handle the callback… Read More
In this article, we are learning about the run time permissions for request permission launchers.… Read More
Hello everyone. In my last tutorial, we learned about the Jetpack Compose introduction and about applying the… Read More
Hello everyone, In this article, we are going to learn about the Jetpack Compose with… Read More