Convert Figma logo to code with AI

tbruyelle logoRxPermissions

Android runtime permissions powered by RxJava2

10,481
1,310
10,481
101

Top Related Projects

5,232

Android library that simplifies the process of requesting permissions at runtime.

A declarative API to handle Android runtime permissions.

Simplify Android M system permissions

Easy check permission library for Android Marshmallow

Quick Overview

RxPermissions is an Android library that simplifies the process of requesting runtime permissions using RxJava. It provides a reactive approach to handling Android's permission system, making it easier to manage complex permission scenarios and reducing boilerplate code.

Pros

  • Simplifies permission handling with a reactive programming approach
  • Reduces boilerplate code compared to traditional permission requests
  • Supports chaining multiple permission requests
  • Integrates well with RxJava-based Android applications

Cons

  • Requires knowledge of RxJava, which may have a learning curve for some developers
  • Adds an additional dependency to the project
  • May be overkill for simple permission scenarios
  • Limited to Android projects using RxJava

Code Examples

  1. Requesting a single permission:
RxPermissions(this)
    .request(Manifest.permission.CAMERA)
    .subscribe { granted ->
        if (granted) {
            // Permission granted, proceed with camera operation
        } else {
            // Permission denied, handle accordingly
        }
    }
  1. Requesting multiple permissions:
RxPermissions(this)
    .request(
        Manifest.permission.CAMERA,
        Manifest.permission.READ_EXTERNAL_STORAGE
    )
    .subscribe { allGranted ->
        if (allGranted) {
            // All permissions granted
        } else {
            // At least one permission denied
        }
    }
  1. Ensuring permissions before performing an action:
RxPermissions(this)
    .ensure(Manifest.permission.CAMERA)
    .andThen(Observable.just(true))
    .subscribe(
        { // Permission granted, perform action },
        { // Permission denied or error occurred }
    )

Getting Started

  1. Add the dependency to your app's build.gradle:
dependencies {
    implementation 'com.github.tbruyelle:rxpermissions:0.12'
}
  1. Initialize RxPermissions in your Activity or Fragment:
private lateinit var rxPermissions: RxPermissions

override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    rxPermissions = RxPermissions(this)
}
  1. Use RxPermissions to request permissions as shown in the code examples above.

Competitor Comparisons

5,232

Android library that simplifies the process of requesting permissions at runtime.

Pros of Dexter

  • Simpler API with a more intuitive interface for handling multiple permissions
  • Built-in support for handling rationale and permanently denied cases
  • Easier to integrate into existing projects without RxJava dependency

Cons of Dexter

  • Less flexible for complex permission scenarios
  • Not as well-suited for projects already using RxJava
  • Slightly more verbose for single permission requests

Code Comparison

Dexter:

Dexter.withActivity(this)
    .withPermission(Manifest.permission.CAMERA)
    .withListener(new PermissionListener() {
        @Override public void onPermissionGranted(PermissionGrantedResponse response) { /* ... */ }
        @Override public void onPermissionDenied(PermissionDeniedResponse response) { /* ... */ }
        @Override public void onPermissionRationaleShouldBeShown(PermissionRequest permission, PermissionToken token) { /* ... */ }
    }).check();

RxPermissions:

RxPermissions rxPermissions = new RxPermissions(this);
rxPermissions
    .request(Manifest.permission.CAMERA)
    .subscribe(granted -> {
        if (granted) { /* ... */ } else { /* ... */ }
    });

Both libraries simplify Android runtime permissions, but Dexter offers a more straightforward API for handling complex permission scenarios, while RxPermissions integrates seamlessly with RxJava workflows. Choose based on your project's existing architecture and specific permission handling needs.

A declarative API to handle Android runtime permissions.

Pros of PermissionsDispatcher

  • Uses annotation processing, which can lead to cleaner and more maintainable code
  • Provides a more declarative approach to handling permissions
  • Offers built-in support for handling permission rationale

Cons of PermissionsDispatcher

  • Requires additional setup and configuration compared to RxPermissions
  • May have a steeper learning curve for developers unfamiliar with annotation processing
  • Can increase build times due to the annotation processing step

Code Comparison

PermissionsDispatcher:

@RuntimePermissions
public class MainActivity extends AppCompatActivity {
    @NeedsPermission(Manifest.permission.CAMERA)
    void showCamera() {
        // Camera permission granted
    }
}

RxPermissions:

RxPermissions rxPermissions = new RxPermissions(this);
rxPermissions
    .request(Manifest.permission.CAMERA)
    .subscribe(granted -> {
        if (granted) {
            // Camera permission granted
        }
    });

PermissionsDispatcher uses annotations to define permission requirements and callbacks, while RxPermissions employs a more reactive approach with RxJava. PermissionsDispatcher's code is more declarative, but RxPermissions offers a more flexible and composable solution, especially when dealing with multiple permissions or complex permission flows.

Simplify Android M system permissions

Pros of EasyPermissions

  • Simpler API and easier to use for basic permission handling
  • Supports both Activity and Fragment contexts
  • Includes built-in rationale handling and UI for permission requests

Cons of EasyPermissions

  • Less flexible for complex permission scenarios
  • Not based on reactive programming paradigms
  • May require more boilerplate code for advanced use cases

Code Comparison

EasyPermissions:

@AfterPermissionGranted(RC_CAMERA_AND_LOCATION)
private void methodRequiresTwoPermission() {
    String[] perms = {Manifest.permission.CAMERA, Manifest.permission.ACCESS_FINE_LOCATION};
    if (EasyPermissions.hasPermissions(this, perms)) {
        // Already have permission, do the thing
    } else {
        // Do not have permissions, request them now
        EasyPermissions.requestPermissions(this, getString(R.string.camera_and_location_rationale),
                RC_CAMERA_AND_LOCATION, perms);
    }
}

RxPermissions:

RxPermissions rxPermissions = new RxPermissions(this);
rxPermissions
    .request(Manifest.permission.CAMERA, Manifest.permission.ACCESS_FINE_LOCATION)
    .subscribe(granted -> {
        if (granted) {
            // All requested permissions are granted
        } else {
            // At least one permission is denied
        }
    });

Easy check permission library for Android Marshmallow

Pros of TedPermission

  • Simpler API with less boilerplate code
  • Supports both Kotlin and Java
  • Includes a built-in rationale dialog for explaining permissions

Cons of TedPermission

  • Less flexible for complex permission scenarios
  • May not integrate as well with RxJava-based projects
  • Fewer customization options for permission request flow

Code Comparison

TedPermission:

TedPermission.create()
    .setPermissions(Manifest.permission.CAMERA)
    .check()

RxPermissions:

rxPermissions
    .request(Manifest.permission.CAMERA)
    .subscribe { granted ->
        if (granted) {
            // Permission granted
        } else {
            // Permission denied
        }
    }

TedPermission offers a more straightforward approach with less code, while RxPermissions provides better integration with reactive programming paradigms. TedPermission is easier to use for simple permission requests, but RxPermissions offers more flexibility for complex scenarios and better fits into RxJava-based architectures.

Both libraries aim to simplify Android runtime permissions, but they cater to different development styles and project requirements. The choice between them depends on the specific needs of the project and the developer's familiarity with reactive programming concepts.

Convert Figma logo designs to code with AI

Visual Copilot

Introducing Visual Copilot: A new AI model to turn Figma designs to high quality code using your components.

Try Visual Copilot

README

RxPermissions

BuildVersion Build Status

This library allows the usage of RxJava with the new Android M permission model.

Setup

To use this library your minSdkVersion must be >= 14.

allprojects {
    repositories {
        ...
        maven { url 'https://jitpack.io' }
    }
}

dependencies {
    implementation 'com.github.tbruyelle:rxpermissions:0.12'
}

Usage

Create a RxPermissions instance :

final RxPermissions rxPermissions = new RxPermissions(this); // where this is an Activity or Fragment instance

NOTE: new RxPermissions(this) the this parameter can be a FragmentActivity or a Fragment. If you are using RxPermissions inside of a fragment you should pass the fragment instance(new RxPermissions(this)) as constructor parameter rather than new RxPermissions(fragment.getActivity()) or you could face a java.lang.IllegalStateException: FragmentManager is already executing transactions.

Example : request the CAMERA permission (with Retrolambda for brevity, but not required)

// Must be done during an initialization phase like onCreate
rxPermissions
    .request(Manifest.permission.CAMERA)
    .subscribe(granted -> {
        if (granted) { // Always true pre-M
           // I can control the camera now
        } else {
           // Oups permission denied
        }
    });

If you need to trigger the permission request from a specific event, you need to setup your event as an observable inside an initialization phase.

You can use JakeWharton/RxBinding to turn your view to an observable (not included in the library).

Example :

// Must be done during an initialization phase like onCreate
RxView.clicks(findViewById(R.id.enableCamera))
    .compose(rxPermissions.ensure(Manifest.permission.CAMERA))
    .subscribe(granted -> {
        // R.id.enableCamera has been clicked
    });

If multiple permissions at the same time, the result is combined :

rxPermissions
    .request(Manifest.permission.CAMERA,
             Manifest.permission.READ_PHONE_STATE)
    .subscribe(granted -> {
        if (granted) {
           // All requested permissions are granted
        } else {
           // At least one permission is denied
        }
    });

You can also observe a detailed result with requestEach or ensureEach :

rxPermissions
    .requestEach(Manifest.permission.CAMERA,
             Manifest.permission.READ_PHONE_STATE)
    .subscribe(permission -> { // will emit 2 Permission objects
        if (permission.granted) {
           // `permission.name` is granted !
        } else if (permission.shouldShowRequestPermissionRationale) {
           // Denied permission without ask never again
        } else {
           // Denied permission with ask never again
           // Need to go to the settings
        }
    });

You can also get combined detailed result with requestEachCombined or ensureEachCombined :

rxPermissions
    .requestEachCombined(Manifest.permission.CAMERA,
             Manifest.permission.READ_PHONE_STATE)
    .subscribe(permission -> { // will emit 1 Permission object
        if (permission.granted) {
           // All permissions are granted !
        } else if (permission.shouldShowRequestPermissionRationale)
           // At least one denied permission without ask never again
        } else {
           // At least one denied permission with ask never again
           // Need to go to the settings
        }
    });

Look at the sample app for more.

Important read

As mentioned above, because your app may be restarted during the permission request, the request must be done during an initialization phase. This may be Activity.onCreate, or View.onFinishInflate, but not pausing methods like onResume, because you'll potentially create an infinite request loop, as your requesting activity is paused by the framework during the permission request.

If not, and if your app is restarted during the permission request (because of a configuration change for instance), the user's answer will never be emitted to the subscriber.

You can find more details about that here.

Status

This library is still beta, so contributions are welcome. I'm currently using it in production since months without issue.

Benefits

  • Avoid worrying about the framework version. If the sdk is pre-M, the observer will automatically receive a granted result.

  • Prevents you to split your code between the permission request and the result handling. Currently without this library you have to request the permission in one place and handle the result in Activity.onRequestPermissionsResult().

  • All what RX provides about transformation, filter, chaining...

License

Copyright (C) 2015 Thomas Bruyelle

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

   http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.