cargo-apk

repository·main·Indexed 41 days ago

https://github.com/rust-mobile/cargo-apk

A tool for creating Android packages (APKs) from native Rust crates with minimal setup, specifically designed for applications providing a NativeActivity via the ndk crate. Version 0.10.0 provides subcommands to build, run, and debug APKs, as well as programmatic construction via the ApkBuilder struct. It supports Android Manifest configuration through Cargo metadata in Cargo.toml, including SDK versions, permissions, and signing profiles.

Tokens
9.6K
Snippets
42
Records
55
Agent score
52%

What's inside cargo-apk

  1. View logs for sample apps using adb logcat

    main

    To view the logs of sample applications in your console, use the adb logcat command with a filter for RustStdoutStderr:D and suppress other logs using *:S. This allows you to see the output from the Rust code running on the device.

    $ adb logcat RustStdoutStderr:D '*:S'
  2. Configure Android permissions and features

    main

    Use uses_feature and uses_permission to declare requirements in the manifest.

    • [[package.metadata.android.uses_feature]]: Defines hardware or software features (e.g., Vulkan).
    • [[package.metadata.android.uses_permission]]: Defines required Android permissions.
    [[package.metadata.android.uses_feature]]
    name = "android.hardware.vulkan.level"
    required = true
    version = 1
    
    [[package.metadata.android.uses_permission]]
    name = "android.permission.WRITE_EXTERNAL_STORAGE"
    max_sdk_version = 18
  3. Configure debug symbol stripping

    main

    The strip option in [package.metadata.android] controls how debug symbols are handled in the shared libraries (.so files) included in the APK.

    Options:

    • default: Debug symbols are not treated specially.
    • strip: Debug symbols are stripped from the shared libraries before being copied into the APK.
    • split: Functions like strip, but debug symbols are written to the APK output directory alongside the stripped libraries with a .dwarf extension.

    Note: These options only work if debug symbols are present in the .so files. You may need to configure your Cargo profile using strip or split-debuginfo to ensure symbols are available for cargo apk to process.

    [package.metadata.android]
    strip = "strip"
  4. Configure Android Activity settings

    main

    The [package.metadata.android.application.activity] table configures the main activity, including its launch mode, orientation, and intent filters.

    [package.metadata.android.application.activity]
    config_changes = "orientation"
    label = "Activity Name"
    launch_mode = "singleTop"
    orientation = "landscape"
    exported = true
    resizeable_activity = false
    always_retain_task_state = true
    
    [[package.metadata.android.application.activity.meta_data]]
    name = "com.oculus.vr.focusaware"
    value = "true"
    
    [[package.metadata.android.application.activity.intent_filter]]
    actions = ["android.intent.action.VIEW", "android.intent.action.WEB_SEARCH"]
    categories = ["android.intent.category.DEFAULT", "android.intent.category.BROWSABLE"]
    
    [[package.metadata.android.application.activity.intent_filter.data]]
    scheme = "https"
    host = "github.com"
    port = "8080"
    path = "/rust-windowing/android-ndk-rs/tree/master/cargo-apk"
    path_prefix = "/rust-windowing/"
    mime_type = "image/jpeg"
  5. Configure APK signing and keystores

    main

    Signing configuration is handled under [package.metadata.android.signing.<profile>].

    • For the dev profile, cargo apk defaults to $HOME/.android/debug.keystore and will only generate a new one if it doesn't exist.
    • For other profiles, you must specify the path and password.
    • Environment Variables: You can override manifest settings using CARGO_APK_<PROFILE>_KEYSTORE and CARGO_APK_<PROFILE>_KEYSTORE_PASSWORD. The <PROFILE> part is the uppercased profile name with hyphens replaced by underscores (e.g., release becomes RELEASE).
    • Environment variables take precedence over the Cargo.toml settings.
    [package.metadata.android.signing.release]
    path = "relative/or/absolute/path/to/my.keystore"
    keystore_password = "android"
  6. Configure Android Application settings

    main

    The [package.metadata.android.application] table allows you to configure global application properties such as the icon, label, theme, and debuggability.

    [package.metadata.android.application]
    debuggable = false
    theme = "@android:style/Theme.DeviceDefault.NoActionBar.Fullscreen"
    icon = "@mipmap/ic_launcher"
    label = "Application Name"
    extract_native_libs = true
    uses_cleartext_traffic = true
    
    [[package.metadata.android.application.meta_data]]
    name = "com.samsung.android.vr.application.mode"
    value = "vr_only"
  7. Configure the Activity element

    main

    The Activity struct defines the behavior of an Android Activity. By default, cargo-apk provides a default activity name of android.app.NativeActivity and default config_changes of orientation|keyboardHidden|screenSize.

    Available configuration options:

    • name: The class name of the activity (defaults to android.app.NativeActivity).
    • label: The activity's user-facing label.
    • launch_mode: The launch mode (e.g., singleTop, singleTask).
    • orientation: The screen orientation (e.g., portrait, landscape).
    • exported: Whether the activity can be started by other apps.
    • resizeable_activity: Whether the activity can be resized.
    • always_retain_task_state: Whether the task state is always retained.
    • config_changes: A string of configuration changes the activity handles (defaults to orientation|keyboardHidden|screenSize).
    • intent_filter: A list of IntentFilter elements to define how the activity responds to intents.
  8. Structure of the AndroidManifest

    main

    The AndroidManifest struct represents the root of an Android manifest file. It contains essential application metadata, including the package name, versioning, SDK requirements, permissions, and the Application element.

    Key fields include:

    • package: The unique package identifier for the application.
    • version_code: An integer used for version tracking.
    • version_name: A string representing the user-visible version.
    • sdk: Defines minSdkVersion, targetSdkVersion, and maxSdkVersion.
    • uses_permission: A list of requested permissions.
    • uses_feature: A list of required hardware or software features.
    • application: The core Application configuration.
    let manifest = AndroidManifest {
        package: "com.example.myapp".to_string(),
        version_code: Some(1),
        version_name: Some("1.0.0".to_string()),
        ..Default::default()
    };
  9. Configure Android SDK versions

    main

    Define the SDK requirements for your application under [package.metadata.android.sdk]. If not specified, it defaults to min_sdk_version = 23 and target_sdk_version = 35 (or the highest supported by your NDK).

    [package.metadata.android.sdk]
    min_sdk_version = 23
    target_sdk_version = 30
    max_sdk_version = 29
  10. Configure Android Manifest via Cargo metadata

    main

    You can configure the Android Manifest for your APK by adding a [package.metadata.android] table to your Cargo.toml. This allows you to define package properties, build targets, resources, assets, and signing information directly within your Rust project configuration.

    [package.metadata.android]
    package = "com.foo.bar"
    build_targets = [ "armv7-linux-androideabi", "aarch64-linux-android" ]
    resources = "path/to/resources_folder"
    assets = "path/to/assets_folder"
    apk_name = "myapp"