PackageTrack
Sign in Get early access

android-activity

Glue for building Rust applications on Android with NativeActivity or GameActivity

0.6.1 24M downloads/mo #1902 most downloaded on crates.io rust-mobile/android-activity

What this package is like to depend on

Last release 5 months ago

24 Mar 2026

Ships unpredictably

gaps range from 2 weeks to 1.9 years

Nearly every release is documented

notes for 13 of 13 stable releases

Nothing withdrawn

no release was ever pulled

4 years old

17 releases · first in 2022

1 release in the last 12 months

see the full history below

Release timeline

17 releases · Jul 2022 to Mar 2026
2023 2024 2025 2026
Release Pre-release

Releases

latest 17
  1. 0.6.1 24 Mar 2026
    Release notes

    Added

    • input: TextInputAction enum representing action button types on soft keyboards. (#216)
    • input: InputEvent::TextAction event for handling action button presses from soft keyboards. (#216)
    • The ndk and ndk-sys crates are now re-exported under android_activity::ndk and android_activity::ndk_sys (#194)
    • AndroidApp::java_main_looper() gives access to the ALooper for the Java main / UI thread (#198)
    • AndroidApp::run_on_java_main_thread() can be used to run boxed closures on the Java main / UI thread (#232)
    • Support for an optional android_on_create entry point that gets called from the Activity.onCreate() callback before android_main() is called, allowing for doing some setup work on the Java main / UI thread before the android_main Rust code starts running.

    For example:

    use std::sync::OnceLock;
    use android_activity::OnCreateState;
    use jni::{JavaVM, refs::Global, objects::JObject};
    
    #[unsafe(no_mangle)]
    fn android_on_create(state: &OnCreateState) {
        static APP_ONCE: OnceLock<()> = OnceLock::new();
        APP_ONCE.get_or_init(|| {
            // Initialize logging...
            //
            // Remember, `android_on_create` may be called multiple times but some
            // logger crates will panic if initialized multiple times.
        });
        let vm = unsafe { JavaVM::from_raw(state.vm_as_ptr().cast()) };
        let activity = state.activity_as_ptr() as jni::sys::jobject;
        // Although the thread is implicitly already attached (we are inside an onCreate native method)
        // using `vm.attach_current_thread` here will use the existing attachment, give us an `&Env`
        // reference and also catch Java exceptions.
        if let Err(err) = vm.attach_current_thread(|env| -> jni::errors::Result<()> {
            // SAFETY:
            // - The `Activity` reference / pointer is at least valid until we return
            // - By creating a `Cast` we ensure we can't accidentally delete the reference
            let activity = unsafe { env.as_cast_raw::<JObject>(&activity)? };
    
            // Do something with the activity on the Java main thread...
            Ok(())
        }) {
           eprintln!("Failed to interact with Android SDK on Java main thread: {err:?}");
        }
    }
    • Support for MotionEvent history, providing higher fidelity input data for things like stylus input (native-activity + game-activity backends). (#218)

    Changed

    • rust-version bumped to 1.85.0 (#193, #219)
    • GameActivity updated to 4.4.0 (#191, #240)
    • ndk-context is initialized with an Application context instead of an Activity context (#229)

    GameActivity 4.4.0 Update

    Important: This release is no longer compatible with GameActivity 2.0.2

    Android Packaging: Your Android application must be packaged with the corresponding androidX, GameActivity 4.x.x library from Google.

    This release has been tested with the androidx.games:games-activity:4.4.0 stable
    release
    , and is backwards
    compatible with the 4.0.0 stable release.

    If you use Gradle to build your Android application, you can depend on the 4.4.0 release of the GameActivity library via:

    dependencies {
        implementation 'androidx.appcompat:appcompat:1.7.1'
    
        // To use the Games Activity library
        implementation "androidx.games:games-activity:4.4.0"
        // Note: don't include game-text-input separately, since it's integrated into game-activity
    }

    Note: there is no guarantee that later 4.x.x releases of GameActivity will be compatible with this release of
    android-activity, so please refer to the android-activity release notes for any future updates regarding
    GameActivity compatibility.

    Initializing ndk-context with an Application Context

    ndk-context is a separate, framework-independent crate that provides a way for library crates to access a Java VM pointer and an android.content.Context JNI reference without needing to depend on android-activity directly.

    ndk-context may be initialized by various framework crates, including android-activity, on behalf of library crates.

    Historically android-activity has initialized ndk-context with an Activity context since that was the simplest choice considering that the entrypoint for android-activity comes from an Activity onCreate callback.

    However, in retrospect it was realized that this was a short-sighted mistake when considering that:

    1. ndk-context only provides a single, global context reference for the entire application that can't be updated
    2. An Android application can have multiple Activity instances over its lifetime (and at times could have no Activity instances at all, e.g. if the app is running a background Service)
    3. Whatever is put into ndk-context needs to leak a corresponding global reference to ensure it remains valid to access safely. This is inappropriate for an Activity reference since it can be destroyed and recreated multiple times over the lifetime of the application.

    A far better choice, that aligns with the global nature of the ndk-context API is to initialize it with an Application context which is valid for the entire lifetime of the application.

    Note: Although the ndk-context API only promises to provide an android.content.Context and specifically warns that user's should not assume the context is an Activity, there is still some risk that some users of ndk-context could be affected by the change made in #229.

    For example, until recently the webbrowser crate (for opening URLs) was assuming it could access an Activity context via ndk-context. In preparation for making this change, webbrowser was updated to ensure it is agnostic to the type of context provided by ndk-context, see: amodm/webbrowser-rs#111

    Other notable library crates that support Android (such as app_dirs2) are expected to be unaffected by this, since they already operate in terms of the android.content.Context API, not the Activity API.

    _Note:: if some crate really needs an Activity reference then they should ideally be able to get one via the
    AndroidApp::activity_as_ptr() API. They may need to add some Android-specific initialization API, similar to how Winit has a dedicated .with_android_app() API. An Android-specific init API that could accept a JNI reference to an Activity could avoid needing to specifically depend on android-activity.

    Fixed

    • Safety AndroidApp::asset_manager() returns an AssetManager that has a safe 'static lifetime that's not invalidated when android_main() returns (#233)
    • Safety The native-activity backend clears its ANativeActivity ptr after onDestroy and AndroidApp remains safe to access after android_main() returns (#234)
    • Safety AndroidApp::activity_as_ptr() returns a pointer to a global reference that remains valid until AndroidApp is dropped, instead of the ANativeActivity's clazz pointer which is only guaranteed to be valid until onDestroy returns (native-activity backend) (#234)
    • Safety The game-activity backend clears its android_app ptr after onDestroy and AndroidApp remains safe to access after android_main() returns (#236)
    • Support for AndroidApp::show/hide_soft_input() APIs in the native-activity backend (#178)

    Overall, some effort was made to ensure that android-activity can gracefully and safely handle cases where the Activity gets repeatedly created, destroyed and recreated (e.g due to configuration changes). Theoretically it should even be possible to run multiple Activity instances (although that's not really something that NativeActivity or GameActivity are designed for).

    New Contributors

    Full Changelog: v0.6.0...v0.6.1

    Open source →
    Release notes

    Added

    • input: TextInputAction enum representing action button types on soft keyboards. (#216)
    • input: InputEvent::TextAction event for handling action button presses from soft keyboards. (#216)
    • The ndk and ndk-sys crates are now re-exported under android_activity::ndk and android_activity::ndk_sys (#194)
    • AndroidApp::java_main_looper() gives access to the ALooper for the Java main / UI thread (#198)
    • AndroidApp::run_on_java_main_thread() can be used to run boxed closures on the Java main / UI thread (#232)
    • Support for an optional android_on_create entry point that gets called from the Activity.onCreate() callback before android_main() is called, allowing for doing some setup work on the Java main / UI thread before the android_main Rust code starts running.

    For example:

    use std::sync::OnceLock;
    use android_activity::OnCreateState;
    use jni::{JavaVM, refs::Global, objects::JObject};
    
    #[unsafe(no_mangle)]
    fn android_on_create(state: &OnCreateState) {
        static APP_ONCE: OnceLock<()> = OnceLock::new();
        APP_ONCE.get_or_init(|| {
            // Initialize logging...
            //
            // Remember, `android_on_create` may be called multiple times but some
            // logger crates will panic if initialized multiple times.
        });
        let vm = unsafe { JavaVM::from_raw(state.vm_as_ptr().cast()) };
        let activity = state.activity_as_ptr() as jni::sys::jobject;
        // Although the thread is implicitly already attached (we are inside an onCreate native method)
        // using `vm.attach_current_thread` here will use the existing attachment, give us an `&Env`
        // reference and also catch Java exceptions.
        if let Err(err) = vm.attach_current_thread(|env| -> jni::errors::Result<()> {
            // SAFETY:
            // - The `Activity` reference / pointer is at least valid until we return
            // - By creating a `Cast` we ensure we can't accidentally delete the reference
            let activity = unsafe { env.as_cast_raw::<JObject>(&activity)? };
    
            // Do something with the activity on the Java main thread...
            Ok(())
        }) {
           eprintln!("Failed to interact with Android SDK on Java main thread: {err:?}");
        }
    }
    
    • Support for MotionEvent history, providing higher fidelity input data for things like stylus input (native-activity + game-activity backends). (#218)

    Changed

    • rust-version bumped to 1.85.0 (#193, #219)
    • GameActivity updated to 4.4.0 (#191, #240)
    • ndk-context is initialized with an Application context instead of an Activity context (#229)

    GameActivity 4.4.0 Update

    Important: This release is no longer compatible with GameActivity 2.0.2

    Android Packaging: Your Android application must be packaged with the corresponding androidX, GameActivity 4.x.x library from Google.

    This release has been tested with the androidx.games:games-activity:4.4.0 stable release, and is backwards compatible with the 4.0.0 stable release.

    If you use Gradle to build your Android application, you can depend on the 4.4.0 release of the GameActivity library via:

    dependencies {
        implementation 'androidx.appcompat:appcompat:1.7.1'
    
        // To use the Games Activity library
        implementation "androidx.games:games-activity:4.4.0"
        // Note: don't include game-text-input separately, since it's integrated into game-activity
    }
    

    Note: there is no guarantee that later 4.x.x releases of GameActivity will be compatible with this release of android-activity, so please refer to the android-activity release notes for any future updates regarding GameActivity compatibility.

    Initializing ndk-context with an Application Context

    ndk-context is a separate, framework-independent crate that provides a way for library crates to access a Java VM pointer and an android.content.Context JNI reference without needing to depend on android-activity directly.

    ndk-context may be initialized by various framework crates, including android-activity, on behalf of library crates.

    Historically android-activity has initialized ndk-context with an Activity context since that was the simplest choice considering that the entrypoint for android-activity comes from an Activity onCreate callback.

    However, in retrospect it was realized that this was a short-sighted mistake when considering that:

    1. ndk-context only provides a single, global context reference for the entire application that can't be updated
    2. An Android application can have multiple Activity instances over its lifetime (and at times could have no Activity instances at all, e.g. if the app is running a background Service)
    3. Whatever is put into ndk-context needs to leak a corresponding global reference to ensure it remains valid to access safely. This is inappropriate for an Activity reference since it can be destroyed and recreated multiple times over the lifetime of the application.

    A far better choice, that aligns with the global nature of the ndk-context API is to initialize it with an Application context which is valid for the entire lifetime of the application.

    Note: Although the ndk-context API only promises to provide an android.content.Context and specifically warns that user's should not assume the context is an Activity, there is still some risk that some users of ndk-context could be affected by the change made in #229.

    For example, until recently the webbrowser crate (for opening URLs) was assuming it could access an Activity context via ndk-context. In preparation for making this change, webbrowser was updated to ensure it is agnostic to the type of context provided by ndk-context, see: https://github.com/amodm/webbrowser-rs/pull/111

    Other notable library crates that support Android (such as app_dirs2) are expected to be unaffected by this, since they already operate in terms of the android.content.Context API, not the Activity API.

    _Note:: if some crate really needs an Activity reference then they should ideally be able to get one via the AndroidApp::activity_as_ptr() API. They may need to add some Android-specific initialization API, similar to how Winit has a dedicated .with_android_app() API. An Android-specific init API that could accept a JNI reference to an Activity could avoid needing to specifically depend on android-activity.

    Fixed

    • Safety AndroidApp::asset_manager() returns an AssetManager that has a safe 'static lifetime that's not invalidated when android_main() returns (#233)
    • Safety The native-activity backend clears its ANativeActivity ptr after onDestroy and AndroidApp remains safe to access after android_main() returns (#234)
    • Safety AndroidApp::activity_as_ptr() returns a pointer to a global reference that remains valid until AndroidApp is dropped, instead of the ANativeActivity's clazz pointer which is only guaranteed to be valid until onDestroy returns (native-activity backend) (#234)
    • Safety The game-activity backend clears its android_app ptr after onDestroy and AndroidApp remains safe to access after android_main() returns (#236)
    • Support for AndroidApp::show/hide_soft_input() APIs in the native-activity backend (#178)

    Overall, some effort was made to ensure that android-activity can gracefully and safely handle cases where the Activity gets repeatedly created, destroyed and recreated (e.g due to configuration changes). Theoretically it should even be possible to run multiple Activity instances (although that's not really something that NativeActivity or GameActivity are designed for).

    Open source →
  2. 0.6.0 26 Apr 2024
    Release notes

    What's Changed

    • Bump MSRV to 1.69.0 considering we can't build cargo ndk with 1.68 by @rib in #156
    • Upgrade to ndk-sys 0.6.0 and ndk 0.9.0 by @MarijnS95 in #155
    • native-activity: Check for null saved_state_in pointer by @skibon02 in #157
    • Release 0.6.0 by @rib in #158

    New Contributors

    Full Changelog: v0.5.2...v0.6.0

    Open source →
    Release notes

    Changed

    • rust-version bumped to 1.69.0 (#156)
    • Upgrade to ndk-sys 0.6.0 and ndk 0.9.0 (#155)

    Fixed

    • Check for null saved_state_in pointer from NativeActivity
    Open source →
  3. 0.5.2 30 Jan 2024
    Release notes

    What's Changed

    • native-activity/input: AND with EVENT_ACTION_MASK when extracting MotionEvent action by @ArthurCose in #147

    New Contributors

    Full Changelog: v0.5.1...v0.5.2

    Open source →
    Release notes

    Fixed

    • NativeActivity: OR with EVENT_ACTION_MASK when extracting action from MotionEvent - fixing multi-touch input (#146, #147)
    Open source →
  4. 0.5.1 20 Dec 2023
    Release notes

    Changed

    • Avoids depending on default features for ndk crate to avoid pulling in any raw-window-handle dependencies (#142)

      Note: Technically, this could be observed as a breaking change in case you were depending on the rwh_06 feature that was enabled by default in the ndk crate. This could be observed via the NativeWindow type (exposed via AndroidApp::native_window()) no longer implementing rwh_06::HasWindowHandle.

      In the unlikely case that you were depending on the ndk's rwh_06 API being enabled by default via android-activity's ndk dependency, your crate should explicitly enable the rwh_06 feature for the ndk crate.

      As far as could be seen though, it's not expected that anything was depending on this (e.g. anything based on Winit enables the ndk feature based on an equivalent winit feature).

      The benefit of the change is that it can help avoid a redundant raw-window-handle 0.6 dependency in projects that still need to use older (non-default) raw-window-handle versions. (Though note that this may be awkward to achieve in practice since other crates that depend on the ndk are still likely to use default features and also pull in raw-window-handles 0.6)

    • The IO thread now gets named stdio-to-logcat and main thread is named android_main (#145)

    • Improved IO error handling in stdio-to-logcat IO loop. (#133)

    New Contributors

    Full Changelog: v0.5.0...v0.5.1

    Open source →
    Release notes

    Changed

    • Avoids depending on default features for ndk crate to avoid pulling in any raw-window-handle dependencies (#142)

      Note: Technically, this could be observed as a breaking change in case you were depending on the rwh_06 feature that was enabled by default in the ndk crate. This could be observed via the NativeWindow type (exposed via AndroidApp::native_window()) no longer implementing rwh_06::HasWindowHandle.

      In the unlikely case that you were depending on the ndk's rwh_06 API being enabled by default via android-activity's ndk dependency, your crate should explicitly enable the rwh_06 feature for the ndk crate.

      As far as could be seen though, it's not expected that anything was depending on this (e.g. anything based on Winit enables the ndk feature based on an equivalent winit feature).

      The benefit of the change is that it can help avoid a redundant raw-window-handle 0.6 dependency in projects that still need to use older (non-default) raw-window-handle versions. (Though note that this may be awkward to achieve in practice since other crates that depend on the ndk are still likely to use default features and also pull in raw-window-handles 0.6)

    • The IO thread now gets named stdio-to-logcat and main thread is named android_main (#145)

    • Improved IO error handling in stdio-to-logcat IO loop. (#133)

    Open source →
  5. 0.5.0 16 Oct 2023
    Release notes

    Probably the most notable (breaking) change in this release is the updated API for reading input events to better support being able to use other AndroidApp APIs while iterating input events, to support unicode character mapping for Keycodes.

    The other big change with this release is the update of the game-activity backend, updating to GameActivity 2.0.2. Applications using the game-activity backend will need to ensure they pull in the corresponding 2.0.2 .aar from Google (For example, see https://github.com/rust-mobile/android-activity/blob/main/examples/agdk-mainloop/app/build.gradle)

    Added

    • Added KeyEvent::meta_state() for being able to query the state of meta keys, needed for character mapping (#102)

    • Added KeyCharacterMap JNI bindings to the corresponding Android SDK API (#102)

    • Added AndroidApp::device_key_character_map() for being able to get a KeyCharacterMap for a given device_id for unicode character mapping (#102)

      Click here for an example of how to handle unicode character mapping:
      let mut combining_accent = None;
      // Snip
      
      
      let combined_key_char = if let Ok(map) = app.device_key_character_map(device_id) {
          match map.get(key_event.key_code(), key_event.meta_state()) {
              Ok(KeyMapChar::Unicode(unicode)) => {
                  let combined_unicode = if let Some(accent) = combining_accent {
                      match map.get_dead_char(accent, unicode) {
                          Ok(Some(key)) => {
                              info!("KeyEvent: Combined '{unicode}' with accent '{accent}' to give '{key}'");
                              Some(key)
                          }
                          Ok(None) => None,
                          Err(err) => {
                              log::error!("KeyEvent: Failed to combine 'dead key' accent '{accent}' with '{unicode}': {err:?}");
                              None
                          }
                      }
                  } else {
                      info!("KeyEvent: Pressed '{unicode}'");
                      Some(unicode)
                  };
                  combining_accent = None;
                  combined_unicode.map(|unicode| KeyMapChar::Unicode(unicode))
              }
              Ok(KeyMapChar::CombiningAccent(accent)) => {
                  info!("KeyEvent: Pressed 'dead key' combining accent '{accent}'");
                  combining_accent = Some(accent);
                  Some(KeyMapChar::CombiningAccent(accent))
              }
              Ok(KeyMapChar::None) => {
                  info!("KeyEvent: Pressed non-unicode key");
                  combining_accent = None;
                  None
              }
              Err(err) => {
                  log::error!("KeyEvent: Failed to get key map character: {err:?}");
                  combining_accent = None;
                  None
              }
          }
      } else {
          None
      };
    • Added TextEvent Input Method event for supporting text editing via virtual keyboards (#24)

    • Added MotionEvent::action_button() exposing the button associated with button press/release actions (#138)

    Changed

    • rust-version bumped to 0.68 (#123)

    • Breaking: update to ndk 0.8 and ndk-sys 0.5 (#128)

    • GameActivity updated to 2.0.2 (requires the corresponding 2.0.2 .aar release from Google) (#88)

    • AndroidApp::input_events() is replaced by AndroidApp::input_events_iter() (#102)

      Click here for an example of how to use `input_events_iter()`:
      match app.input_events_iter() {
          Ok(mut iter) => {
              loop {
                  let read_input = iter.next(|event| {
                      let handled = match event {
                          InputEvent::KeyEvent(key_event) => {
                              // Snip
                          }
                          InputEvent::MotionEvent(motion_event) => {
                              // Snip
                          }
                          event => {
                              // Snip
                          }
                      };
      
                      handled
                  });
      
                  if !read_input {
                      break;
                  }
              }
          }
          Err(err) => {
              log::error!("Failed to get input events iterator: {err:?}");
          }
      }
    • The Pointer and PointerIter types from the ndk crate are no longer directly exposed in the public API (#122)

    • All input API enums based on Android SDK enums have been made runtime extensible via hidden __Unknown(u32) variants (#131)

    New Contributors

    Full Changelog: v0.4.3...v0.5.0

    Open source →
    Release notes

    Added

    • Added MotionEvent::action_button() exposing the button associated with button press/release actions (#138)

    Changed

    • rust-version bumped to 0.68 (#123)
    • Breaking: updates to ndk 0.8 and ndk-sys 0.5 (#128)
    • The Pointer and PointerIter types from the ndk crate are no longer directly exposed in the public API (#122)
    • All input API enums based on Android SDK enums have been made runtime extensible via hidden __Unknown(u32) variants (#131)
    Open source →
  6. 0.5.0-beta.1 15 Aug 2023 pre-release
    Release notes

    This only updates the ndk and ndk-sys dependencies to pull in ndk 0.8.0-beta.0 and ndk-sys 0.5.0-beta.0

    Open source →
    Release notes

    Changed

    • Pulled in ndk-sys 0.5.0-beta.0 and ndk 0.8.0-beta.0 (#113)
    Open source →
  7. 0.5.0-beta.0 15 Aug 2023 pre-release
    Release notes

    This is the first 0.5.0 beta that's aiming to be ready for the upcoming Winit 0.29 release

    The main reason that a (breaking) semver bump was required was so we could update the API for reading input events to better support being able to use other AndroidApp APIs while iterating input events, to support unicode character mapping for Keycodes.

    A big change with this release is the update of the game-activity backend, updating to GameActivity 2.0.2. Applications using the game-activity backend will need to ensure they pull in the corresponding 2.0.2 .aar from Google (For example, see https://github.com/rust-mobile/android-activity/blob/main/examples/agdk-mainloop/app/build.gradle)

    Added

    • Added KeyEvent::meta_state() for being able to query the state of meta keys, needed for character mapping (#102)

    • Added KeyCharacterMap JNI bindings to the corresponding Android SDK API (#102)

    • Added AndroidApp::device_key_character_map() for being able to get a KeyCharacterMap for a given device_id for unicode character mapping (#102)

      Click here for an example of how to handle unicode character mapping:
      let mut combining_accent = None;
      // Snip
      
      
      let combined_key_char = if let Ok(map) = app.device_key_character_map(device_id) {
          match map.get(key_event.key_code(), key_event.meta_state()) {
              Ok(KeyMapChar::Unicode(unicode)) => {
                  let combined_unicode = if let Some(accent) = combining_accent {
                      match map.get_dead_char(accent, unicode) {
                          Ok(Some(key)) => {
                              info!("KeyEvent: Combined '{unicode}' with accent '{accent}' to give '{key}'");
                              Some(key)
                          }
                          Ok(None) => None,
                          Err(err) => {
                              log::error!("KeyEvent: Failed to combine 'dead key' accent '{accent}' with '{unicode}': {err:?}");
                              None
                          }
                      }
                  } else {
                      info!("KeyEvent: Pressed '{unicode}'");
                      Some(unicode)
                  };
                  combining_accent = None;
                  combined_unicode.map(|unicode| KeyMapChar::Unicode(unicode))
              }
              Ok(KeyMapChar::CombiningAccent(accent)) => {
                  info!("KeyEvent: Pressed 'dead key' combining accent '{accent}'");
                  combining_accent = Some(accent);
                  Some(KeyMapChar::CombiningAccent(accent))
              }
              Ok(KeyMapChar::None) => {
                  info!("KeyEvent: Pressed non-unicode key");
                  combining_accent = None;
                  None
              }
              Err(err) => {
                  log::error!("KeyEvent: Failed to get key map character: {err:?}");
                  combining_accent = None;
                  None
              }
          }
      } else {
          None
      };
    • Added TextEvent Input Method event for supporting text editing via virtual keyboards (#24)

    Changed

    • GameActivity updated to 2.0.2 (requires the corresponding 2.0.2 .aar release from Google) (#88)

    • AndroidApp::input_events() is replaced by AndroidApp::input_events_iter() (#102)

      Click here for an example of how to use `input_events_iter()`:
      match app.input_events_iter() {
          Ok(mut iter) => {
              loop {
                  let read_input = iter.next(|event| {
                      let handled = match event {
                          InputEvent::KeyEvent(key_event) => {
                              // Snip
                          }
                          InputEvent::MotionEvent(motion_event) => {
                              // Snip
                          }
                          event => {
                              // Snip
                          }
                      };
      
                      handled
                  });
      
                  if !read_input {
                      break;
                  }
              }
          }
          Err(err) => {
              log::error!("Failed to get input events iterator: {err:?}");
          }
      }

    New Contributors

    Full Changelog: v0.4.3...v0.5.0-beta.0

    Open source →
    Release notes

    Added

    • Added KeyEvent::meta_state() for being able to query the state of meta keys, needed for character mapping (#102)

    • Added KeyCharacterMap JNI bindings to the corresponding Android SDK API (#102)

    • Added AndroidApp::device_key_character_map() for being able to get a KeyCharacterMap for a given device_id for unicode character mapping (#102)

      <details> <summary>Click here for an example of how to handle unicode character mapping:</summary>

      let mut combining_accent = None;
      // Snip
      
      
      let combined_key_char = if let Ok(map) = app.device_key_character_map(device_id) {
          match map.get(key_event.key_code(), key_event.meta_state()) {
              Ok(KeyMapChar::Unicode(unicode)) => {
                  let combined_unicode = if let Some(accent) = combining_accent {
                      match map.get_dead_char(accent, unicode) {
                          Ok(Some(key)) => {
                              info!("KeyEvent: Combined '{unicode}' with accent '{accent}' to give '{key}'");
                              Some(key)
                          }
                          Ok(None) => None,
                          Err(err) => {
                              log::error!("KeyEvent: Failed to combine 'dead key' accent '{accent}' with '{unicode}': {err:?}");
                              None
                          }
                      }
                  } else {
                      info!("KeyEvent: Pressed '{unicode}'");
                      Some(unicode)
                  };
                  combining_accent = None;
                  combined_unicode.map(|unicode| KeyMapChar::Unicode(unicode))
              }
              Ok(KeyMapChar::CombiningAccent(accent)) => {
                  info!("KeyEvent: Pressed 'dead key' combining accent '{accent}'");
                  combining_accent = Some(accent);
                  Some(KeyMapChar::CombiningAccent(accent))
              }
              Ok(KeyMapChar::None) => {
                  info!("KeyEvent: Pressed non-unicode key");
                  combining_accent = None;
                  None
              }
              Err(err) => {
                  log::error!("KeyEvent: Failed to get key map character: {err:?}");
                  combining_accent = None;
                  None
              }
          }
      } else {
          None
      };
      

      </details>

    • Added TextEvent Input Method event for supporting text editing via virtual keyboards (#24)

    Changed

    • GameActivity updated to 2.0.2 (requires the corresponding 2.0.2 .aar release from Google) (#88)

    • AndroidApp::input_events() is replaced by AndroidApp::input_events_iter() (#102)

      <details> <summary>Click here for an example of how to use input_events_iter():</summary>

      match app.input_events_iter() {
          Ok(mut iter) => {
              loop {
                  let read_input = iter.next(|event| {
                      let handled = match event {
                          InputEvent::KeyEvent(key_event) => {
                              // Snip
                          }
                          InputEvent::MotionEvent(motion_event) => {
                              // Snip
                          }
                          event => {
                              // Snip
                          }
                      };
      
                      handled
                  });
      
                  if !read_input {
                      break;
                  }
              }
          }
          Err(err) => {
              log::error!("Failed to get input events iterator: {err:?}");
          }
      }
      

      </details>

    Open source →
  8. 0.4.3 30 Jul 2023
    Release notes

    What's Changed

    • Fix deadlock on activity onDestroy by @sagebind in #94
    • GameActivity PATCH: fix deadlocks in java callbacks after app destroyed by @rib in #98

    New Contributors

    Full Changelog: v0.4.2...v0.4.3

    Open source →
    Release notes

    Fixed

    • Fixed a deadlock in the native-activity backend while waiting for the native thread after getting an onDestroy callback from Java (#94)
    • Fixed numerous deadlocks in the game-activity backend with how it would wait for the native thread in various Java callbacks, after the app has returned from android_main (#98)
    Open source →
  9. 0.4.2 27 Jun 2023
    Release notes

    What's Changed

    • Add dependabot support by @notgull in #72
    • native-activity: Propagate NativeWindow redraw/resize and ContentRectChanged callbacks to main loop by @MarijnS95 in #70
    • Add MSRV policy to README and bump rust_version to 1.64, due to ndk -> raw_window_handle dependency by @rib in #76
    • build(deps): update num_enum requirement from 0.5 to 0.6 by @dependabot in #74
    • build(deps): bump actions/checkout from 2 to 3 by @dependabot in #73
    • Fix rust_version typo s/0.64/1.64/ by @rib in #77
    • Add panic guards to extern "C" functions by @notgull in #68
    • game_activity: Fix pointer_index() always returning 0 by @yunsash in #84
    • README: Add badges to CI, crates.io, docs.rs and show the MSRV by @MarijnS95 in #86
    • Call Activity.finish() when android_main returns by @rib in #81
    • cargo: Fix rust_version -> rust-version property typo by @MarijnS95 in #87
    • Release 0.4.2 by @rib in #90

    New Contributors

    • @notgull made their first contribution in #72
    • @dependabot made their first contribution in #74 - good bot 🤖
    • @yunsash made their first contribution in #84

    Full Changelog: v0.4.1...v0.4.2

    Open source →
    Release notes

    Changed

    • The Activity.finish() method is now called when android_main returns so the Activity will be destroyed (#67)
    • The native-activity backend now propagates NativeWindow redraw/resize and ContentRectChanged callbacks to main loop (#70)
    • The game-activity implementation of pointer_index() was fixed to not always return 0 (#80)
    • Added panic guards around application's android_main() and native code that could potentially unwind across a Java FFI boundary (#68)
    Open source →
  10. 0.4.1 15 Feb 2023
    Release notes

    What's Changed

    Added

    • Added AndroidApp::vm_as_ptr() to expose JNI JavaVM pointer (#60)
    • Added AndroidApp::activity_as_ptr() to expose Android Activity JNI reference as pointer (#60)

    Changed

    • Removed some overly-verbose logging in the native-activity backend (#49)

    Removed

    New Contributors

    Full Changelog: v0.4.0...v0.4.1

    Open source →
    Release notes

    Added

    • Added AndroidApp::vm_as_ptr() to expose JNI JavaVM pointer (#60)
    • Added AndroidApp::activity_as_ptr() to expose Android Activity JNI reference as pointer (#60)

    Changed

    • Removed some overly-verbose logging in the native-activity backend (#49)

    Removed

    Open source →
  11. 0.4.0 14 Nov 2022
    Release notes

    Changed

    • Breaking: input_events callback now return whether an event was handled or not to allow for fallback handling (#31)
    • The native-activity backend is now implemented in Rust only, without building on android_native_app_glue.c (#35)

    Added

    • Added Pointer::tool_type() API to GameActivity backend for compatibility with ndk events API (#38)
    Open source →
  12. 0.4.0-beta.1 11 Oct 2022 pre-release

    Nothing published for this version

  13. 0.4.0-beta 20 Sep 2022 pre-release

    Nothing published for this version

  14. 0.3.0 17 Sep 2022
    Release notes

    Added

    • show/hide_sot_input API for being able to show/hide a soft keyboard (other IME still pending)
    • set_window_flags() API for setting WindowManager params

    Changed

    • Breaking: Created extensible, #[non_exhaustive] InputEvent wrapper enum instead of exposing ndk type directly
    Open source →
  15. 0.2.0 25 Aug 2022
    Release notes

    Added

    • Emit an InputAvailable event for new input with NativeActivity and GameActivity enabling gui apps that don't render continuously
    • Oboe and Cpal audio examples added
    • AndroidApp is now Send + Sync

    Changed

    • Breaking: updates to ndk 0.7 and ndk-sys 0.4
    • Breaking: AndroidApp::config() now returns a clonable ConfigurationRef instead of a deep Configuration copy

    Removed

    • The NativeWindowRef wrapper struct was removed since NativeWindow now implements Clone and Drop in ndk 0.7
    • Breaking: The FdEvent and Error enum values were removed from PollEvents
    Open source →
  16. 0.1.1 04 Jul 2022
    Release notes

    Changed

    • Documentation fixes
    Open source →
  17. 0.1.0 03 Jul 2022
    Release notes

    Added

    • Initial release
    Open source →

Every package, every release, already written down.

The archive is open and free. Watching your own project is what we are building next.

Browse the archive