### Build and Run AGDK Mainloop Example Source: https://github.com/rust-mobile/android-activity/blob/main/examples/agdk-mainloop/README.md Set up environment variables, install necessary tools, build the Rust code for Android, and then build, install, and launch the application on a device. ```bash export ANDROID_NDK_HOME="path/to/ndk" export ANDROID_HOME="path/to/sdk" rustup target add aarch64-linux-android cargo install cargo-ndk cargo ndk -t arm64-v8a -o app/src/main/jniLibs/ build ./gradlew build ./gradlew installDebug ``` ```bash adb shell am start -n com.github.rust_mobile.agdkmainloop/.MainActivity ``` -------------------------------- ### Gradle Build Setup and Execution Source: https://github.com/rust-mobile/android-activity/blob/main/examples/na-mainloop/README.md Set up NDK and SDK paths, add the Android target, install cargo-ndk, and build, install, and run the application using Gradle. ```bash export ANDROID_NDK_HOME="path/to/ndk" export ANDROID_HOME="path/to/sdk" rustup target add aarch64-linux-android cargo install cargo-ndk cargo ndk -t arm64-v8a -o app/src/main/jniLibs/ build ./gradlew build ./gradlew installDebug ``` -------------------------------- ### Cargo APK Build Setup and Execution Source: https://github.com/rust-mobile/android-activity/blob/main/examples/na-mainloop/README.md Set up NDK and SDK paths, add the Android target, install cargo-apk, and build and run the application using Cargo APK. ```bash export ANDROID_NDK_HOME="path/to/ndk" export ANDROID_SDK_HOME="path/to/sdk" rustup target add aarch64-linux-android cargo install cargo-apk cargo apk build cargo apk run ``` -------------------------------- ### Complete Example Source: https://github.com/rust-mobile/android-activity/blob/main/_autodocs/api-reference/MotionEvent.md A comprehensive example demonstrating how to handle motion events, including detecting touch actions like Down, Move, and Up, and processing pointer data. ```APIDOC ## Complete Example ```rust use android_activity::{AndroidApp, InputEvent, InputStatus, input::{InputEvent, MotionEvent}}; fn handle_motion_event(event: &MotionEvent) -> InputStatus { match event.action() { MotionAction::Down => { println!("Touch began"); for pointer in event.pointers() { let x = pointer.axis_value(Axis::X); let y = pointer.axis_value(Axis::Y); let pressure = pointer.axis_value(Axis::Pressure); println!(" Pointer {}: ({}, {}), pressure: {}", pointer.pointer_id(), x, y, pressure); } InputStatus::Handled } MotionAction::Move => { println!("Touch moved"); for pointer in event.pointers() { let x = pointer.axis_value(Axis::X); let y = pointer.axis_value(Axis::Y); // Update position in your application } InputStatus::Handled } MotionAction::Up => { println!("Touch ended"); InputStatus::Handled } MotionAction::Cancel => { println!("Touch cancelled"); InputStatus::Handled } _ => InputStatus::Unhandled, } } fn process_input(app: &AndroidApp) { if let Ok(mut iter) = app.input_events_iter() { loop { let read_input = iter.next(|event| { match event { InputEvent::MotionEvent(motion_event) => { handle_motion_event(motion_event) } _ => InputStatus::Unhandled, } }); if !read_input { break; } } } } ``` ``` -------------------------------- ### Start Event Source: https://github.com/rust-mobile/android-activity/blob/main/_autodocs/api-reference/MainEvent.md The application's Activity has been started. ```rust Start ``` -------------------------------- ### Complete Input Handling Example Source: https://github.com/rust-mobile/android-activity/blob/main/_autodocs/api-reference/KeyEvent.md This example demonstrates the full lifecycle of input event handling, including polling for events, processing key presses with character mapping, and handling touch motion events. It shows how to use the android-activity crate to interact with Android's input system. ```rust use android_activity::{AndroidApp, InputEvent, InputStatus, input::*}; fn android_main(app: AndroidApp) { let mut combining_accent: Option = None; loop { app.poll_events(Some(std::time::Duration::from_millis(500)), |event| { match event { PollEvent::Main(MainEvent::Destroy) => return, PollEvent::Main(MainEvent::InputAvailable) => { // Process input if let Ok(mut iter) = app.input_events_iter() { loop { let read_input = iter.next(|event| { match event { InputEvent::KeyEvent(key_event) => { if key_event.action() == KeyAction::Down { handle_key_input(&app, &key_event, &mut combining_accent) } else { InputStatus::Unhandled } } InputEvent::MotionEvent(motion_event) => { handle_motion_input(motion_event) } _ => InputStatus::Unhandled, } }); if !read_input { break; } } } } _ => {} } }); } } fn handle_key_input( app: &AndroidApp, key_event: &KeyEvent, combining_accent: &mut Option, ) -> InputStatus { match app.device_key_character_map(key_event.device_id()) { Ok(map) => { match map.get(key_event.key_code(), key_event.meta_state()) { Ok(KeyMapChar::Unicode(unicode)) => { let final_char = if let Some(accent) = *combining_accent { match map.get_dead_char(accent, unicode) { Ok(Some(combined)) => { log::info!("Combined '{}' with accent '{}' to give '{}'", unicode, accent, combined); combined } _ => unicode, } } else { unicode }; log::info!("Character typed: {}", final_char); *combining_accent = None; InputStatus::Handled } Ok(KeyMapChar::CombiningAccent(accent)) => { log::info!("Dead key combining accent: {}", accent); *combining_accent = Some(accent); InputStatus::Handled } Ok(KeyMapChar::None) => { *combining_accent = None; InputStatus::Unhandled } Err(err) => { log::error!("Error getting character: {err:?}"); *combining_accent = None; InputStatus::Unhandled } } } Err(err) => { log::error!("Error getting key character map: {err:?}"); *combining_accent = None; InputStatus::Unhandled } } } fn handle_motion_input(motion_event: &MotionEvent) -> InputStatus { match motion_event.action() { MotionAction::Down => { log::info!("Touch began"); InputStatus::Handled } MotionAction::Move => { let pointer_count = motion_event.pointer_count(); for i in 0..pointer_count { let pointer = motion_event.pointer_at_index(i); let x = pointer.axis_value(Axis::X); let y = pointer.axis_value(Axis::Y); log::info!("Touch {} at ({}, {})", pointer.pointer_id(), x, y); } InputStatus::Handled } MotionAction::Up => { log::info!("Touch ended"); InputStatus::Handled } _ => InputStatus::Unhandled, } } ``` -------------------------------- ### Android OnCreate Initialization Example Source: https://github.com/rust-mobile/android-activity/blob/main/_autodocs/api-reference/OnCreateState.md This snippet shows a complete example of using `android_on_create` for application initialization. It demonstrates how to use `OnceLock` to ensure initialization happens only once, set up logging, retrieve the Java VM and Activity, restore saved state, and attach to the current thread for JNI operations. It also includes error handling for JNI attachment. ```rust use std::sync::OnceLock; use jni::{JavaVM, objects::JObject}; use android_activity::OnCreateState; #[unsafe(no_mangle)] fn android_on_create(state: &OnCreateState) { // Ensure initialization happens only once static APP_ONCE: OnceLock<()> = OnceLock::new(); APP_ONCE.get_or_init(|| { // Initialize logging (must be done on main thread or early) android_logger::init_once( android_logger::Config::default() .with_min_level(log::Level::Info) ); log::info!("android_on_create called"); }); // Get the Java VM and Activity while on the main thread let vm = unsafe { JavaVM::from_raw(state.vm_as_ptr().cast()) }; // Restore saved state if available let saved_state = state.saved_state(); if !saved_state.is_empty() { log::info!("Restoring {} bytes of saved state", saved_state.len()); // Deserialize and use saved state } // Perform main-thread-only initialization let activity = state.activity_as_ptr() as jni::sys::jobject; if let Err(err) = vm.attach_current_thread(|env| -> jni::errors::Result<()> { // We're already attached (we're in a native JNI callback) // but this call will give us an &Env reference and catch Java exceptions // SAFETY: The Activity reference is valid until we return let activity_obj = unsafe { env.as_cast_raw::(&activity)? }; // Example: Call a method on the Activity // ... Ok(()) }) { eprintln!("Failed to initialize on Java main thread: {err:?}"); } } #[unsafe(no_mangle)] fn android_main(app: android_activity::AndroidApp) { // Logging and JNI are already initialized from android_on_create log::info!("android_main started"); loop { app.poll_events(Some(std::time::Duration::from_millis(500)), |event| { // Handle events }); } } ``` -------------------------------- ### Complete Text Input Handling Example Source: https://github.com/rust-mobile/android-activity/blob/main/_autodocs/api-reference/KeyCharacterMap.md This example demonstrates a full implementation of text input handling for an Android application written in Rust. It shows how to poll for input events, process key events using the device's key character map, and manage combining accents for characters. ```rust use android_activity::{AndroidApp, InputEvent, InputStatus, input::*}; use std::collections::VecDeque; struct TextInputHandler { combining_accent: Option, text: String, } impl TextInputHandler { fn new() -> Self { Self { combining_accent: None, text: String::new(), } } fn handle_key_event( &mut self, app: &AndroidApp, key_event: &KeyEvent, ) -> InputStatus { if key_event.action() != KeyAction::Down { return InputStatus::Unhandled; } match app.device_key_character_map(key_event.device_id()) { Ok(map) => { match map.get(key_event.key_code(), key_event.meta_state()) { Ok(KeyMapChar::Unicode(unicode)) => { let final_char = if let Some(accent) = self.combining_accent { match map.get_dead_char(accent, unicode) { Ok(Some(combined)) => { log::info!("Combined '{}' with accent '{}' to give '{}'", unicode, accent, combined); combined } _ => { // No valid combination, output both separately self.text.push(accent); unicode } } } else { unicode }; self.text.push(final_char); self.combining_accent = None; log::info!("Text input: {}", self.text); InputStatus::Handled } Ok(KeyMapChar::CombiningAccent(accent)) => { // Store the accent for the next character log::info!("Dead key combining accent: {}", accent); self.combining_accent = Some(accent); InputStatus::Handled } Ok(KeyMapChar::None) => { // Non-printable key self.combining_accent = None; InputStatus::Unhandled } Err(err) => { log::error!("Error getting character: {err:?}"); self.combining_accent = None; InputStatus::Unhandled } } } Err(err) => { log::error!("Error getting key character map: {err:?}"); self.combining_accent = None; InputStatus::Unhandled } } } fn on_backspace(&mut self) { self.text.pop(); self.combining_accent = None; } fn on_clear(&mut self) { self.text.clear(); self.combining_accent = None; } } fn android_main(app: AndroidApp) { let mut text_handler = TextInputHandler::new(); loop { app.poll_events(Some(std::time::Duration::from_millis(500)), |event| { match event { PollEvent::Main(MainEvent::Destroy) => return, PollEvent::Main(MainEvent::InputAvailable) => { if let Ok(mut iter) = app.input_events_iter() { loop { let read_input = iter.next(|event| { match event { InputEvent::KeyEvent(key_event) => { // Handle special keys match key_event.key_code() { Keycode::Back => { text_handler.on_backspace(); InputStatus::Handled } Keycode::DelDel => { text_handler.on_clear(); InputStatus::Handled } _ => { text_handler.handle_key_event(&app, &key_event) } } } _ => InputStatus::Unhandled, } }); if !read_input { break; } } } } _ => {} } }); } } ``` -------------------------------- ### Destroy Event Example Source: https://github.com/rust-mobile/android-activity/blob/main/_autodocs/api-reference/MainEvent.md Example of handling the Destroy event to log a message and exit the main loop, as the Activity is being destroyed. ```rust MainEvent::Destroy => { log::info!("Activity destroyed, exiting main loop"); return; } ``` -------------------------------- ### SaveState Event Example Source: https://github.com/rust-mobile/android-activity/blob/main/_autodocs/api-reference/MainEvent.md Example of how to handle the SaveState event to save application state using the provided saver interface. ```rust MainEvent::SaveState { saver } => { let state_data = b"my application state"; saver.save(state_data); } ``` -------------------------------- ### Get Application Configuration Source: https://github.com/rust-mobile/android-activity/blob/main/_autodocs/api-reference/AndroidApp.md Retrieves a reference to the application's configuration. Note that this reference can change with configuration events. ```rust pub fn config(&self) -> ConfigurationRef ``` -------------------------------- ### Get Screen Density Source: https://github.com/rust-mobile/android-activity/blob/main/_autodocs/configuration.md Returns the screen density in DPI. On some devices it can return values outside of standard density enums. Example values: 160, 240, 320, 480. ```rust pub fn density(&self) -> Option ``` -------------------------------- ### Basic lib.rs Setup for Android Activity Source: https://github.com/rust-mobile/android-activity/blob/main/_autodocs/OVERVIEW.md Sets up logging and the main application loop for an Android Rust application. It initializes logging and polls for events, handling destruction and input availability. ```rust use std::sync::OnceLock; use android_activity::{AndroidApp, InputStatus, MainEvent, PollEvent}; #[unsafe(no_mangle)] fn android_on_create(state: &android_activity::OnCreateState) { static APP_ONCE: OnceLock<()> = OnceLock::new(); APP_ONCE.get_or_init(|| { android_logger::init_once( android_logger::Config::default() .with_min_level(log::Level::Info) ); }); } #[unsafe(no_mangle)] fn android_main(app: AndroidApp) { log::info!("Application started"); loop { app.poll_events(Some(std::time::Duration::from_millis(500)), |event| { match event { PollEvent::Main(MainEvent::Destroy) => { log::info!("Activity destroyed"); return; } PollEvent::Main(MainEvent::InputAvailable) => { // Process input } PollEvent::Timeout => { // Render frame or do periodic work } _ => {} } }); } } ``` -------------------------------- ### Get UI Mode Type Source: https://github.com/rust-mobile/android-activity/blob/main/_autodocs/configuration.md Returns the UI mode type. ```rust pub fn ui_mode_type(&self) -> UiModeType ``` -------------------------------- ### Optional android_on_create Entry Point Source: https://github.com/rust-mobile/android-activity/blob/main/README.md Demonstrates the usage of the `android_on_create` function, which is called from the Activity.onCreate() callback before `android_main()`. It's suitable for setup work that must be done on the Java main thread, using `OnceLock` to prevent multiple initializations. ```rust use std::sync::OnceLock; use jni::{JavaVM, objects::JObject}; #[unsafe(no_mangle)] fn android_on_create(state: &android_activity::OnCreateState) { // `android_on_create` is tied to your `Activity` lifecycle, not your application lifecycle // and so it may be called multiple times if your activity is destroyed and recreated. // // Use a `OnceLock` or similar to ensure that you don't attempt to initialize global state // multiple times. static APP_ONCE: OnceLock<()> = OnceLock::new(); APP_ONCE.get_or_init(|| { // Initialize logging... }); let vm = unsafe { JavaVM::from_raw(state.vm_as_ptr().cast()) }; let activity = state.activity_as_ptr() as jni::sys::jobject; // Do some other setup work on the Java main thread before `android_main` starts running } ``` -------------------------------- ### Android Activity Entry Points Source: https://github.com/rust-mobile/android-activity/blob/main/_autodocs/OVERVIEW.md Defines the required entry points for an Android application using the android-activity crate. `android_on_create` is optional for setup, while `android_main` is the main application loop. ```rust #[unsafe(no_mangle)] fn android_on_create(state: &OnCreateState) { // Optional: Called on Java main thread before android_main // Good place for logging and JNI setup } #[unsafe(no_mangle)] fn android_main(app: AndroidApp) { // Required: Main application loop // Called on dedicated thread; must call app.poll_events() regularly } ``` -------------------------------- ### Get Language Code Source: https://github.com/rust-mobile/android-activity/blob/main/_autodocs/configuration.md Returns the language as a two-character String, if set. Example values: "en", "es", "fr", "ja". ```rust pub fn language(&self) -> Option ``` -------------------------------- ### Get SDK Version Source: https://github.com/rust-mobile/android-activity/blob/main/_autodocs/configuration.md Returns the SDK version, which is the same as `AndroidApp::sdk_version()`. ```rust pub fn sdk_version(&self) -> i32 ``` -------------------------------- ### Get Navigation Method Source: https://github.com/rust-mobile/android-activity/blob/main/_autodocs/configuration.md Returns the navigation method. Possible variants include `Undefined`, `Nonav`, `Dpad`, `Trackball`, and `Wheel`. ```rust pub fn navigation(&self) -> Navigation ``` -------------------------------- ### Rust Input Processing Example Source: https://github.com/rust-mobile/android-activity/blob/main/_autodocs/INDEX.md This code shows how to iterate over input events and process them. It handles key and motion events, returning an InputStatus. The loop breaks if no more input is available. ```Rust if let Ok(mut iter) = app.input_events_iter() { loop { let read = iter.next(|event| { match event { InputEvent::KeyEvent(key) => handle_key(key), InputEvent::MotionEvent(motion) => handle_motion(motion), _ => InputStatus::Unhandled, } }); if !read { break; } } } ``` -------------------------------- ### Handle Motion Events in Rust Source: https://github.com/rust-mobile/android-activity/blob/main/_autodocs/api-reference/MotionEvent.md A complete example demonstrating how to process motion events within an Android application using the `android-activity` crate. It shows how to match different motion actions like Down, Move, and Up, and extract pointer data. ```rust use android_activity::{AndroidApp, InputEvent, InputStatus, input::{InputEvent, MotionEvent}}; fn handle_motion_event(event: &MotionEvent) -> InputStatus { match event.action() { MotionAction::Down => { println!("Touch began"); for pointer in event.pointers() { let x = pointer.axis_value(Axis::X); let y = pointer.axis_value(Axis::Y); let pressure = pointer.axis_value(Axis::Pressure); println!(" Pointer {}: ({}, {}), pressure: {}", pointer.pointer_id(), x, y, pressure); } InputStatus::Handled } MotionAction::Move => { println!("Touch moved"); for pointer in event.pointers() { let x = pointer.axis_value(Axis::X); let y = pointer.axis_value(Axis::Y); // Update position in your application } InputStatus::Handled } MotionAction::Up => { println!("Touch ended"); InputStatus::Handled } MotionAction::Cancel => { println!("Touch cancelled"); InputStatus::Handled } _ => InputStatus::Unhandled, } } fn process_input(app: &AndroidApp) { if let Ok(mut iter) = app.input_events_iter() { loop { let read_input = iter.next(|event| { match event { InputEvent::MotionEvent(motion_event) => { handle_motion_event(motion_event) } _ => InputStatus::Unhandled, } }); if !read_input { break; } } } } ``` -------------------------------- ### Get Keyboard Visibility Source: https://github.com/rust-mobile/android-activity/blob/main/_autodocs/configuration.md Returns keyboard visibility/availability. Possible variants include `Undefined`, `No`, `Yes`, and `Soft`. ```rust pub fn keys_hidden(&self) -> KeysHidden ``` -------------------------------- ### Complete Android App Waker Usage Example Source: https://github.com/rust-mobile/android-activity/blob/main/_autodocs/api-reference/AndroidAppWaker.md Demonstrates a full application lifecycle with a worker thread simulating async work and using a waker to notify the main thread upon completion. The main thread then processes the completed work. ```rust use android_activity::{AndroidApp, MainEvent, PollEvent}; use std::sync::{Arc, Mutex}; use std::thread; use std::time::Duration; struct AppState { work_done: bool, } fn android_main(app: AndroidApp) { let app_state = Arc::new(Mutex::new(AppState { work_done: false })); let waker = app.create_waker(); // Spawn a worker thread that does async work let state_clone = app_state.clone(); let waker_clone = waker.clone(); thread::spawn(move || { // Simulate some async work thread::sleep(Duration::from_secs(3)); // Mark work as done { let mut state = state_clone.lock().unwrap(); state.work_done = true; } // Wake the main thread to process the result log::info!("Worker thread: waking up main thread"); waker_clone.wake(); }); // Main event loop loop { app.poll_events( Some(Duration::from_millis(500)), |event| { match event { PollEvent::Wake => { log::info!("Main thread woken up"); // Check if work is done let mut state = app_state.lock().unwrap(); if state.work_done { log::info!("Worker thread finished its work"); state.work_done = false; // Process the result } } PollEvent::Timeout => { log::info!("Timeout - checking for work..."); } PollEvent::Main(MainEvent::Destroy) => { log::info!("Activity destroyed"); return; } _ => {} } } ); } } ``` -------------------------------- ### Getting Screen Dimensions Source: https://github.com/rust-mobile/android-activity/blob/main/_autodocs/configuration.md Retrieves the screen dimensions in density-independent pixels (dp) and its size category using `ConfigurationRef`. ```APIDOC ## Getting Screen Dimensions ```rust fn get_screen_info(config: &ConfigurationRef) { let width_dp = config.screen_width_dp(); let height_dp = config.screen_height_dp(); let size = config.screen_size(); println!( "Screen: {}x{} dp, size: {:?}", width_dp.unwrap_or(-1), height_dp.unwrap_or(-1), size ); } ``` ``` -------------------------------- ### Get OBB Path Source: https://github.com/rust-mobile/android-activity/blob/main/_autodocs/configuration.md Returns the path to the directory containing OBB files. This path is read-only for the application. ```rust pub fn obb_path(&self) -> Option ``` -------------------------------- ### Get Native Window Source: https://github.com/rust-mobile/android-activity/blob/main/_autodocs/api-reference/AndroidApp.md Retrieves the current NativeWindow for drawing graphics. Returns Some(window) only between InitWindow and TerminateWindow events. ```rust if let Some(window) = app.native_window() { // Use the NativeWindow to render graphics } ``` -------------------------------- ### Rust Event Loop Example Source: https://github.com/rust-mobile/android-activity/blob/main/_autodocs/INDEX.md This snippet demonstrates a basic event loop for an application. It continuously polls for events and handles different event types like application destruction, input availability, and timeouts for rendering. ```Rust loop { app.poll_events(timeout, |event| { match event { PollEvent::Main(MainEvent::Destroy) => return, PollEvent::Main(MainEvent::InputAvailable) => { // Process input } PollEvent::Timeout => { // Render frame } _ => {} } }); } ``` -------------------------------- ### Get Window Content Rectangle Source: https://github.com/rust-mobile/android-activity/blob/main/_autodocs/api-reference/AndroidApp.md Queries the current content rectangle of the window, which defines the area where content is visible. ```rust pub fn content_rect(&self) -> Rect ``` -------------------------------- ### Get Navigation Button Visibility Source: https://github.com/rust-mobile/android-activity/blob/main/_autodocs/configuration.md Returns navigation button visibility. Possible variants include `Undefined`, `No`, and `Yes`. ```rust pub fn nav_hidden(&self) -> NavHidden ``` -------------------------------- ### Get Internal Data Path Source: https://github.com/rust-mobile/android-activity/blob/main/_autodocs/configuration.md Returns the path to the application's private internal data directory. Contents are deleted on uninstall. ```rust pub fn internal_data_path(&self) -> Option ``` -------------------------------- ### Get Android SDK Version Source: https://github.com/rust-mobile/android-activity/blob/main/_autodocs/api-reference/AndroidApp.md Returns the user-visible SDK version of the Android framework, equivalent to `Build.VERSION_CODES`. This function may panic if the system property cannot be read. ```rust pub fn sdk_version() -> i32 ``` -------------------------------- ### Rust State Saving and Restoration Source: https://github.com/rust-mobile/android-activity/blob/main/_autodocs/OVERVIEW.md This example illustrates saving and restoring application state in an Android Activity using Rust. State is deserialized when the activity is created if saved state exists, and serialized and saved when requested during the `SaveState` event. ```rust // In android_on_create: restore state let saved = state.saved_state(); if !saved.is_empty() { app_state = deserialize(saved); } // In poll_events: save state MainEvent::SaveState { saver } => { let serialized = serialize(&app_state); saver.save(&serialized); } ``` -------------------------------- ### Get External Data Path Source: https://github.com/rust-mobile/android-activity/blob/main/_autodocs/configuration.md Returns the path to the application's external data directory. May require storage permissions and contents can be deleted by the user. ```rust pub fn external_data_path(&self) -> Option ``` -------------------------------- ### Get Country Code Source: https://github.com/rust-mobile/android-activity/blob/main/_autodocs/configuration.md Returns the country code as a two-character String, if set. Example values: "US", "GB", "JP". ```rust pub fn country(&self) -> Option ``` -------------------------------- ### Running the NativeActivity Application Source: https://github.com/rust-mobile/android-activity/blob/main/examples/na-mainloop/README.md Launch the NativeActivity application on an Android device using ADB. ```bash adb shell am start -n com.github.realfit_mobile.namainloop/android.app.NativeActivity ``` -------------------------------- ### MotionEvent::down_time Source: https://github.com/rust-mobile/android-activity/blob/main/_autodocs/api-reference/MotionEvent.md Returns the timestamp, in nanoseconds, of when the current gesture started. ```APIDOC ## MotionEvent::down_time ### Description Returns the time of the start of this gesture in `java.lang.System.nanoTime()` time base. ### Method `pub fn down_time(&self) -> i64` ### Return Type `i64` - Nanoseconds ``` -------------------------------- ### Define android_on_create Entry Point Source: https://github.com/rust-mobile/android-activity/blob/main/_autodocs/api-reference/OnCreateState.md Implement the android_on_create function to handle initialization on the Java main thread using the provided OnCreateState. ```rust #[unsafe(no_mangle)] fn android_on_create(state: &OnCreateState) { // Use state to initialize on the Java main thread } ``` -------------------------------- ### copy() Source: https://github.com/rust-mobile/android-activity/blob/main/_autodocs/configuration.md Returns a deep copy of the full application configuration. Use this if you need an independent copy that won't change with `MainEvent::ConfigChanged` events. ```APIDOC ## copy() ### Description Returns a deep copy of the full application configuration. This is useful for obtaining an independent copy that is not affected by subsequent configuration changes. ### Method `copy` ### Return Type `ndk::configuration::Configuration` ``` -------------------------------- ### Get Mobile Country Code Source: https://github.com/rust-mobile/android-activity/blob/main/_autodocs/configuration.md Returns the mobile country code. ```rust pub fn mcc(&self) -> i32 ``` -------------------------------- ### Build and Run Android Activity App Source: https://github.com/rust-mobile/android-activity/blob/main/_autodocs/OVERVIEW.md Commands to set up the Rust toolchain for Android development, build the application using cargo-apk, run it on a device, and view logs. ```bash rustup target add aarch64-linux-android cargo install cargo-apk cargo apk run adb logcat example:V *:S ``` -------------------------------- ### Build and Run Android Application Source: https://github.com/rust-mobile/android-activity/blob/main/README.md Commands to set up the Rust toolchain for Android, build the application using cargo-apk, and run it on a device. ADB is used to view logs. ```sh rustup target add aarch64-linux-android cargo install cargo-apk cargo apk run adb logcat example:V *:S ``` -------------------------------- ### InitWindow Event Source: https://github.com/rust-mobile/android-activity/blob/main/_autodocs/api-reference/MainEvent.md Signals that a new NativeWindow is ready. After this event, AndroidApp::native_window() will return the new window. ```rust InitWindow {} ``` -------------------------------- ### Get Screen Width in DP Source: https://github.com/rust-mobile/android-activity/blob/main/_autodocs/configuration.md Returns the screen width in device-independent pixels (dp). ```rust pub fn screen_width_dp(&self) -> Option ``` -------------------------------- ### Get Screen Height in DP Source: https://github.com/rust-mobile/android-activity/blob/main/_autodocs/configuration.md Returns the screen height in device-independent pixels (dp). ```rust pub fn screen_height_dp(&self) -> Option ``` -------------------------------- ### Get Mobile Network Code Source: https://github.com/rust-mobile/android-activity/blob/main/_autodocs/configuration.md Returns the mobile network code, if one is defined. ```rust pub fn mnc(&self) -> Option ``` -------------------------------- ### Get Smallest Screen Width in DP Source: https://github.com/rust-mobile/android-activity/blob/main/_autodocs/configuration.md Returns the smallest screen dimension in device-independent pixels. ```rust pub fn smallest_screen_width_dp(&self) -> Option ``` -------------------------------- ### Get Screen Dimensions Source: https://github.com/rust-mobile/android-activity/blob/main/_autodocs/configuration.md Retrieves screen dimensions in density-independent pixels (dp) and its general size category. ```rust fn get_screen_info(config: &ConfigurationRef) { let width_dp = config.screen_width_dp(); let height_dp = config.screen_height_dp(); let size = config.screen_size(); println!( "Screen: {}x{} dp, size: {:?}", width_dp.unwrap_or(-1), height_dp.unwrap_or(-1), size ); } ``` -------------------------------- ### Create and Use AndroidAppWaker Source: https://github.com/rust-mobile/android-activity/blob/main/_autodocs/api-reference/AndroidAppWaker.md Demonstrates how to create an AndroidAppWaker and use it from a worker thread to wake up the main loop. ```rust fn android_main(app: AndroidApp) { let waker = app.create_waker(); // Send waker to another thread let waker_clone = waker.clone(); std::thread::spawn(move || { // From worker thread, wake up the main loop waker_clone.wake(); }); } ``` -------------------------------- ### navigation() Source: https://github.com/rust-mobile/android-activity/blob/main/_autodocs/configuration.md Returns the navigation method. ```APIDOC ## navigation() ### Description Retrieves the type of navigation method used by the device. ### Method `navigation` ### Return Type `ndk::configuration::Navigation` ### Variants - `Undefined` - `Nonav` - `Dpad` - `Trackball` - `Wheel` ``` -------------------------------- ### orientation() Source: https://github.com/rust-mobile/android-activity/blob/main/_autodocs/configuration.md Returns the device orientation. ```APIDOC ## orientation() ### Description Retrieves the current orientation of the device. ### Method `orientation` ### Return Type `ndk::configuration::Orientation` ### Variants - `Undefined` - `Portrait` - `Landscape` - `PortraitReverse` - `LandscapeReverse` ``` -------------------------------- ### Handle Key Action Source: https://github.com/rust-mobile/android-activity/blob/main/_autodocs/api-reference/KeyEvent.md This snippet helps differentiate between key presses, releases, and repetitions. ```rust match key_event.action() { KeyAction::Down => println!("Key pressed"), KeyAction::Up => println!("Key released"), KeyAction::Multiple => println!("Key repeated {} times", key_event.repeat_count()), _ => {} } ``` -------------------------------- ### sdk_version() Source: https://github.com/rust-mobile/android-activity/blob/main/_autodocs/configuration.md Returns the SDK version. ```APIDOC ## sdk_version() ### Description Retrieves the SDK version of the Android system. ### Method `sdk_version` ### Return Type `i32` (same as `AndroidApp::sdk_version()`) ``` -------------------------------- ### config Source: https://github.com/rust-mobile/android-activity/blob/main/_autodocs/api-reference/AndroidApp.md Returns a reference to the application's Configuration, which changes with every MainEvent::ConfigChanged event. ```APIDOC ## config ### Description Returns a reference to the application's `Configuration`, which changes with every `MainEvent::ConfigChanged` event. ### Method `config` ### Parameters #### Path Parameters - **—** (—) - — - — ### Return Type `ConfigurationRef` - Reference to device configuration (language, orientation, etc.) ### Warning The returned reference **will change** with every `MainEvent::ConfigChanged` event. Do not clone to compare against a "new" value. ``` -------------------------------- ### Get Touchscreen Type Source: https://github.com/rust-mobile/android-activity/blob/main/_autodocs/configuration.md Returns the touchscreen type. Possible variants include `Undefined`, `Notouch`, `Stylus`, and `Finger`. ```rust pub fn touchscreen(&self) -> Touchscreen ``` -------------------------------- ### Copy Application Configuration Source: https://github.com/rust-mobile/android-activity/blob/main/_autodocs/configuration.md Returns a deep copy of the full application configuration. Use this if you need an independent copy that won't change with `MainEvent::ConfigChanged` events. ```rust pub fn copy(&self) -> Configuration ``` -------------------------------- ### Get Layout Direction Source: https://github.com/rust-mobile/android-activity/blob/main/_autodocs/configuration.md Returns the layout direction. Possible variants are `Undefined`, `Ltr` (Left-to-right), and `Rtl` (Right-to-left). ```rust pub fn layout_direction(&self) -> LayoutDir ``` -------------------------------- ### native_window Source: https://github.com/rust-mobile/android-activity/blob/main/_autodocs/api-reference/AndroidApp.md Queries the current `NativeWindow` for the application. Returns `Some(window)` only between `MainEvent::InitWindow` and `MainEvent::TerminateWindow` events. ```APIDOC ## native_window ### Description Queries the current `NativeWindow` for the application. Returns `Some(window)` only between `MainEvent::InitWindow` and `MainEvent::TerminateWindow` events. ### Method `native_window` ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body None ### Parameters Table | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | — | — | — | — | — | ### Return Type `Option` - Native drawing surface, or `None` if no window is active ### Example ```rust if let Some(window) = app.native_window() { // Use the NativeWindow to render graphics } ``` ``` -------------------------------- ### Get Keyboard Type Source: https://github.com/rust-mobile/android-activity/blob/main/_autodocs/configuration.md Returns the keyboard type. Possible variants include `Undefined`, `NoKeys`, `Qwerty`, and `12Key`. ```rust pub fn keyboard(&self) -> Keyboard ``` -------------------------------- ### Android App Entry Point Source: https://github.com/rust-mobile/android-activity/blob/main/_autodocs/api-reference/AndroidApp.md The entry point for a native Rust application on Android. The AndroidApp handle is passed to this function. ```rust #[unsafe(no_mangle)] fn android_main(app: android_activity::AndroidApp) { // app is your handle to the Activity } ``` -------------------------------- ### Get Screen Long Format Source: https://github.com/rust-mobile/android-activity/blob/main/_autodocs/configuration.md Returns whether the screen is in long format. Possible variants include `Undefined`, `No`, and `Yes`. ```rust pub fn screen_long(&self) -> ScreenLong ``` -------------------------------- ### ConfigurationRef Source: https://github.com/rust-mobile/android-activity/blob/main/_autodocs/types.md A runtime-replacable reference to configuration settings. Methods delegate to the underlying configuration object. ```APIDOC ## ConfigurationRef ### Description A runtime-replacable reference to `ndk::configuration::Configuration`. Methods delegate to the underlying configuration object. ### Methods - `country() -> Option` - `density() -> Option` - `keyboard() -> Keyboard` - `language() -> Option` - `orientation() -> Orientation` - `screen_height_dp() -> Option` - `screen_width_dp() -> Option` - `screen_size() -> ScreenSize` - `sdk_version() -> i32` - `touchscreen() -> Touchscreen` - `ui_mode_type() -> UiModeType` - `ui_mode_night() -> UiModeNight` **Important:** The value held by this reference changes with every `MainEvent::ConfigChanged` event. Do not clone to compare against a new value. ``` -------------------------------- ### Get Device Orientation Source: https://github.com/rust-mobile/android-activity/blob/main/_autodocs/configuration.md Returns the device orientation. Possible variants include `Undefined`, `Portrait`, `Landscape`, `PortraitReverse`, and `LandscapeReverse`. ```rust pub fn orientation(&self) -> Orientation ``` -------------------------------- ### Handle KeyEvent in Rust Source: https://github.com/rust-mobile/android-activity/blob/main/_autodocs/api-reference/InputEvent.md This snippet demonstrates how to pattern match on an InputEvent to handle KeyEvent variants. It shows how to retrieve key code, action, and meta state from a KeyEvent. ```rust InputEvent::KeyEvent(key_event) => { let key_code = key_event.key_code(); let action = key_event.action(); let meta_state = key_event.meta_state(); } ``` -------------------------------- ### input_events_iter Source: https://github.com/rust-mobile/android-activity/blob/main/_autodocs/api-reference/AndroidApp.md Gets an exclusive, lending iterator over buffered input events. Applications should call this in sync with rendering or in response to `MainEvent::InputAvailable`. ```APIDOC ## input_events_iter ### Description Gets an exclusive, lending iterator over buffered input events. Applications should call this in sync with rendering or in response to `MainEvent::InputAvailable`. ### Method `&self` (Implicitly GET-like) ### Parameters None ### Response #### Success Response - **Return Type:** `Result>` - Iterator over pending input events #### Error Handling - **Throws:** `AppError::InputUnavailable` if no input is currently available ### Example ```rust match app.input_events_iter() { Ok(mut iter) => { loop { let read_input = iter.next(|event| { match event { InputEvent::KeyEvent(key_event) => InputStatus::Handled, InputEvent::MotionEvent(motion_event) => InputStatus::Unhandled, _ => InputStatus::Unhandled, } }); if !read_input { break; } } } Err(err) => log::error!("Failed to get input events: {err:?}"), } ``` ``` -------------------------------- ### Get Java VM Pointer for JNI Source: https://github.com/rust-mobile/android-activity/blob/main/_autodocs/api-reference/AndroidApp.md Obtains a pointer to the Java Virtual Machine, which can be cast to JavaVM for making JNI calls. ```rust let vm = unsafe { JavaVM::from_raw(app.vm_as_ptr().cast()) }; ``` -------------------------------- ### source Source: https://github.com/rust-mobile/android-activity/blob/main/_autodocs/api-reference/KeyEvent.md Identifies the source of the input event, such as a physical keyboard or a gamepad. ```APIDOC ## source ### Description Get the source of the event (keyboard, dpad, etc.). ### Method `source(&self) -> Source` ### Return Type `Source` ### Example ```rust match key_event.source() { Source::Keyboard => println!("Physical keyboard"), Source::Dpad => println!("D-pad navigation"), Source::Gamepad => println!("Game controller"), _ => {} } ``` ``` -------------------------------- ### Rust Text Input Management Source: https://github.com/rust-mobile/android-activity/blob/main/_autodocs/OVERVIEW.md This snippet shows how to enable the soft keyboard and configure text input for an Android Activity using Rust. It sets the input type, action, and options, then displays the keyboard. It also includes handling for received text events and cursor information. ```rust // Enable soft keyboard and set input type app.set_ime_editor_info( input::InputType::Text, input::TextInputAction::Send, input::ImeOptions::empty(), ); app.show_soft_input(true); // Handle text events InputEvent::TextEvent(state) => { println!("Text: {}", state.text); println!("Cursor: {}", state.selection_start); } ``` -------------------------------- ### Pattern Matching MainEvent Variants Source: https://github.com/rust-mobile/android-activity/blob/main/_autodocs/api-reference/MainEvent.md Demonstrates how to use pattern matching to handle different MainEvent variants, including a fallback for unknown or unhandled variants. This approach ensures compatibility with future SDK and crate versions. ```rust match event { MainEvent::Destroy => { /* handle */ }, MainEvent::Resume { .. } => { /* handle */ }, MainEvent::InitWindow {} => { /* handle */ }, _ => { /* unknown or unhandled variant */ } } ``` -------------------------------- ### Get Motion Event Flags Source: https://github.com/rust-mobile/android-activity/blob/main/_autodocs/api-reference/MotionEvent.md Retrieves the flags associated with a motion event. This can be used to check for conditions like the window being obscured. ```rust let flags = motion_event.flags(); if flags.window_is_obscured() { println!("Window is partially obscured"); } ``` -------------------------------- ### Get Pointer at Index Source: https://github.com/rust-mobile/android-activity/blob/main/_autodocs/api-reference/MotionEvent.md Retrieves a specific pointer from the motion event using its index. Ensure the index is within bounds before calling. ```rust if motion_event.pointer_count() > 0 { let first = motion_event.pointer_at_index(0); println!("First pointer ID: {}", first.pointer_id()); } ``` -------------------------------- ### Pointer Methods Source: https://github.com/rust-mobile/android-activity/blob/main/_autodocs/api-reference/MotionEvent.md Details methods available for each pointer within a motion event, including index, ID, axis values, raw coordinates, and tool type. ```APIDOC ## Pointer Methods Each pointer in a motion event provides: - `pointer_index() -> usize` - Index in this event - `pointer_id() -> i32` - Stable identifier across events - `axis_value(axis: Axis) -> f32` - Value on a specific axis - `raw_x() -> f32` - Unscaled X coordinate - `raw_y() -> f32` - Unscaled Y coordinate - `tool_type() -> ToolType` - Type of pointing tool (finger, stylus, etc.) ``` -------------------------------- ### Input Event Handling Source: https://github.com/rust-mobile/android-activity/blob/main/_autodocs/INDEX.md Provides detailed information about handling various input events, including motion, keyboard, and text input, along with their associated data and properties. ```APIDOC ## InputEvent, MotionEvent, and KeyEvent ### Description These types define the structure and handling of input events. `InputEvent` is an enumeration of different input types. `MotionEvent` captures touch and pointer events, while `KeyEvent` captures keyboard events. ### InputEvent Variants - `MotionEvent`: Touch/pointer events. - `KeyEvent`: Keyboard events. - `TextEvent`: IME text updates. - `TextAction`: IME actions. ### MotionEvent Properties - `source()`: Input source (touchscreen, mouse, etc.). - `action()`: Event action (down, up, move, etc.). - `pointer_count()`: Number of simultaneous pointers. - `pointers()`: Iterator over pointer data. - `meta_state()`: Modifier keys (shift, ctrl, alt). - `button_state()`: Button states. - `event_time()`: Event timestamp. - Includes pressure, size, tool type, and orientation data. ### KeyEvent Properties - `key_code()`: Which key was pressed. - `action()`: Down, up, or multiple. - `repeat_count()`: Number of repeats. - `meta_state()`: Modifier keys. - `device_id()`: Source device identifier. - `source()`: Input source type. ``` -------------------------------- ### Get MotionEvent Source Source: https://github.com/rust-mobile/android-activity/blob/main/_autodocs/api-reference/MotionEvent.md Retrieves the input source of the motion event, such as touchscreen, mouse, or stylus. Use this to differentiate input types. ```rust match motion_event.source() { Source::Touchscreen => println!("Touch input"), Source::Mouse => println!("Mouse input"), Source::Stylus => println!("Stylus input"), _ => {} } ``` -------------------------------- ### Checking for Specific Features Source: https://github.com/rust-mobile/android-activity/blob/main/_autodocs/configuration.md Checks for specific device features like touchscreen availability and navigation hardware (D-pad, trackball, etc.) using `ConfigurationRef`. ```APIDOC ## Checking for Specific Features ```rust fn check_device_features(config: &ConfigurationRef) { if config.touchscreen() == ndk::configuration::Touchscreen::Finger { println!("Device has touchscreen"); } match config.navigation() { ndk::configuration::Navigation::Dpad => println!("Has D-pad"), ndk::configuration::Navigation::Trackball => println!("Has trackball"), ndk::configuration::Navigation::Wheel => println!("Has scroll wheel"), _ => println!("No navigation hardware"), } } ``` ``` -------------------------------- ### Get Keyboard Type Source: https://github.com/rust-mobile/android-activity/blob/main/_autodocs/api-reference/KeyCharacterMap.md Retrieves the type of the keyboard associated with the device. Useful for understanding input methods like multi-tap or predictive text. ```rust match map.get_keyboard_type() { Ok(KeyboardType::Full) => { println!("Full QWERTY keyboard - direct symbol access"); } Ok(KeyboardType::Numeric) => { println!("Numeric keyboard - multi-tap for symbols"); } Ok(KeyboardType::SpecialFunction) => { println!("Special function keys only"); } _ => {} } ``` -------------------------------- ### Log Errors and Continue Execution Source: https://github.com/rust-mobile/android-activity/blob/main/_autodocs/errors.md This pattern demonstrates how to log an error using the `log` crate and continue execution without crashing. Useful for non-critical operations where failure doesn't halt the application. ```rust fn try_get_input(app: &AndroidApp) { match app.input_events_iter() { Ok(mut iter) => { // Process input } Err(err) => { log::error!("Failed to get input events: {:?}", err); // Continue without processing input } } } ``` -------------------------------- ### Handling Configuration Changes Source: https://github.com/rust-mobile/android-activity/blob/main/_autodocs/configuration.md Configuration changes are delivered via `MainEvent::ConfigChanged`. After receiving this event, call `AndroidApp::config()` to get the updated `ConfigurationRef`. ```APIDOC ## Handling Configuration Changes Configuration changes are delivered as `MainEvent::ConfigChanged`. 1. Call `AndroidApp::config()` to get the updated `ConfigurationRef`. 2. The old `ConfigurationRef` will automatically contain the new values (it shares internal state). 3. All methods will return the new configuration values. **Example:** ```rust use android_activity::MainEvent; app.poll_events(Some(Duration::from_secs(1)), |event| { match event { PollEvent::Main(MainEvent::ConfigChanged {}) => { // Configuration changed (orientation, language, etc.) let config = app.config(); let orientation = config.orientation(); let language = config.language(); log::info!("New orientation: {:?}", orientation); log::info!("New language: {:?}", language); } _ => {} } }); ``` ``` -------------------------------- ### Get Android SDK Version Source: https://github.com/rust-mobile/android-activity/blob/main/_autodocs/configuration.md Retrieves the user-visible SDK version of the Android framework. Useful for conditional API usage based on Android version. ```rust pub fn sdk_version() -> i32 ``` ```rust let sdk = AndroidApp::sdk_version(); if sdk >= 30 { // Use APIs only available in Android 11+ } ``` -------------------------------- ### ConfigurationRef Struct Source: https://github.com/rust-mobile/android-activity/blob/main/_autodocs/types.md A reference to the application's configuration, allowing access to settings like country, density, language, and screen dimensions. The configuration can change dynamically. ```rust pub struct ConfigurationRef { config: Arc>, } ``` -------------------------------- ### Get Number of Pointers Source: https://github.com/rust-mobile/android-activity/blob/main/_autodocs/api-reference/MotionEvent.md Retrieves the total number of active pointers (e.g., touch points) involved in the motion event. Useful for multi-touch scenarios. ```rust let count = motion_event.pointer_count(); println!("Touch points: {}", count); ``` -------------------------------- ### touchscreen() Source: https://github.com/rust-mobile/android-activity/blob/main/_autodocs/configuration.md Returns the touchscreen type. ```APIDOC ## touchscreen() ### Description Retrieves the type of touchscreen available on the device. ### Method `touchscreen` ### Return Type `ndk::configuration::Touchscreen` ### Variants - `Undefined` - `Notouch` - `Stylus` - `Finger` ```