android-permissions 0.1.0

Android permissions
docs.rs failed to build android-permissions-0.1.0
Please check the build logs for more information.
See Builds for ideas on how to fix a failed build, or Metadata for how to configure docs.rs builds.
If you believe this is docs.rs' fault, open an issue.

Android Permissions for Rust

A Rust library for handling Android permissions in Android apps written in Rust with the Android NDK. This library provides a simple and idiomatic Rust interface for checking and requesting Android permissions.

Features

  • Check if a permission is granted
  • Request one or multiple permissions asynchronously
  • Predefined constants for common Android permissions
  • Automatic handling of permission request callbacks
  • Seamless integration with Android NDK projects

Installation

Add this to your Cargo.toml:

[dependencies]
android-permissions = "0.1.0"

Setup

1. Add Permissions to AndroidManifest.xml

Add the required permissions to your AndroidManifest.xml:

<uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />

2. Configure Cargo.toml for Cargo APK

In your Cargo.toml, add the permissions metadata:

[[package.metadata.android.uses_permission]]
name = "android.permission.WRITE_EXTERNAL_STORAGE"

[[package.metadata.android.uses_permission]]
name = "android.permission.CAMERA"

Usage

Here's a complete example of how to use the library:

use android_permissions::{self as permissions, Permission, PermissionManager, Result};
use jni::objects::{JObject, JValue};
use log::{error, info};

use std::collections::HashMap;
use std::future::Future;

#[cfg_attr(target_os = "android", ndk_glue::main(backtrace = "on"))]
pub fn main() {
    android_logger::init_once(
        android_logger::Config::default().with_max_level(log::LevelFilter::Trace),
    );

    log::info!("Rust main function started.");

    let native_activity = ndk_glue::native_activity();
    let vm = unsafe { jni::JavaVM::from_raw(native_activity.vm()) }.expect("Failed to get JavaVM");
    let activity_obj = native_activity.activity();

    let runtime = tokio::runtime::Builder::new_multi_thread()
        .enable_all()
        .build()
        .unwrap();

    runtime.block_on(async move {
        info!("Async app main function entered.");
        let manager =
            match permissions::init(vm, unsafe { JObject::from_raw(native_activity.activity()) }) {
                Ok(m) => m,
                Err(e) => {
                    error!("Failed to create PermissionManager: {}", e);
                    return;
                }
            };

        info!("PermissionManager created successfully.");
        if let Err(e) = run_permission_demo(&manager).await {
            error!("An error occurred during permission demo: {}", e);
        }

        info!("Permission demo finished. The app will now idle.");
    });
}

async fn run_permission_demo(manager: &PermissionManager) -> Result<()> {
    info!("Checking for CAMERA permission...");
    match manager.check(&permissions::CAMERA) {
        Ok(has_permission) => info!("Do we have CAMERA permission? -> {}", has_permission),
        Err(e) => error!("Error checking for CAMERA permission: {}", e),
    }

    let permissions_to_request = &[
        &permissions::CAMERA,
        &permissions::WRITE_EXTERNAL_STORAGE,
        &permissions::READ_EXTERNAL_STORAGE,
    ];

    info!(
        "Requesting permissions: {:?}",
        permissions_to_request
            .iter()
            .map(|p| p.as_str())
            .collect::<Vec<_>>()
    );

    let request_future = manager.request(permissions_to_request);
    match request_future.await {
        Ok(grants) => {
            info!("Permission request finished. Results:");
            for (permission, granted) in &grants {
                info!(
                    "  - {}: {}",
                    permission,
                    if *granted { "GRANTED" } else { "DENIED" }
                );
            }
            if grants.values().all(|&g| g) {
                info!("All requested permissions were granted!");
            } else {
                info!("Some permissions were denied.");
            }
        }
        Err(e) => error!("Error requesting permissions: {}", e),
    }

    Ok(())
}

API Reference

init(vm: JavaVM, activity: JObject) -> Result<PermissionManager>

Initialize the permission manager with the JavaVM and Activity references.

PermissionManager.check(permission: &Permission) -> Result<bool>

Check if a specific permission is granted.

PermissionManager.request(permissions: &[&Permission]) -> Future<Result<HashMap<String, bool>>>

Request one or more permissions from the user. Returns a future that resolves with a map of permission names to their granted status.

Predefined Permissions

The library provides constants for common Android permissions:

  • CAMERA
  • READ_EXTERNAL_STORAGE
  • WRITE_EXTERNAL_STORAGE
  • ACCESS_FINE_LOCATION
  • ACCESS_COARSE_LOCATION
  • RECORD_AUDIO
  • POST_NOTIFICATIONS
  • READ_MEDIA_IMAGES
  • READ_MEDIA_VIDEO
  • READ_MEDIA_AUDIO
  • READ_CONTACTS
  • WRITE_CONTACTS
  • GET_ACCOUNTS
  • READ_CALENDAR
  • WRITE_CALENDAR
  • SEND_SMS
  • RECEIVE_SMS
  • READ_SMS
  • CALL_PHONE
  • READ_PHONE_STATE

License

MIT