# apk-rs
> This independent crate is derived from the `apk` package in
[rust-mobile/xbuild](https://github.com/rust-mobile/xbuild), commit
`e67b501cbe0e9ca5436c223aa7ec0fe5e27544d1` (`apk` 0.4.0).
Welcome to apk-rs.
you can build, sign, verfify, read, etc. Android APKs. Pure rust.
you can probably get the rest from the code apis at docs.rs
## Building a native app
```rust,no_run
use apk::prelude::*;
let mut app = ApkBuilder::native_activity("org.example.game".parse()?, "game".parse()?);
app.label("Game")
.version(VersionCode::try_new(7)?, "1.0.7")
.localized_string("app_name", "fr".parse()?, "Jeu")?
.icon(Density::XXXHDPI, std::fs::read("icon.png")?)?
.native_library(Abi::Arm64V8a, "target/aarch64-linux-android/release/libgame.so")?
.sign_with(Signer::new(SigningIdentity::from_pem_file("release.pem")?));
app.write("game.apk")?;
# Ok::<(), Box<dyn std::error::Error>>(())
```
```rust,no_run
# use apk::prelude::*;
# let mut app = ApkBuilder::native_activity("org.example.game".parse()?, "game".parse()?);
let activity = app.manifest_mut().application_mut().element_mut("activity").unwrap();
activity.set_attr(attr::SCREEN_ORIENTATION, attr::SCREEN_ORIENTATION.parse("sensorLandscape")?);
# Ok::<(), Box<dyn std::error::Error>>(())
```
`Manifest::parse` accepts a hand-written `AndroidManifest.xml` instead.
## Signing and verifying
```rust,no_run
use apk::sign::{Keystore, Signer, verify};
let identity = Keystore::open("release.p12", "store password")?.identity("upload", None)?;
Signer::new(identity).sign_file("app.apk")?;
let verification = verify("app.apk")?;
println!("{:?} by {}", verification.schemes, verification.certificate().subject());
# Ok::<(), apk::Error>(())
```
## Reading
```rust,no_run
use apk::Apk;
use apk::res::ResourceTable;
let mut apk = Apk::open("app.apk")?;
println!("{}", apk.manifest()?);
let bytes = apk.read("resources.arsc")?;
print!("{}", ResourceTable::parse(&bytes)?);
# Ok::<(), apk::Error>(())
```
## Scope
It does *mostly everything* except for
- ZIP64 archives, which APK signature schemes cannot cover.
- Signing key rotation: v3.1 blocks and proof-of-rotation lineages are
rejected rather than trusted unverified. APK Signature Scheme v4 and DSA
signatures and verity digests are not supported. RSA, P-256, and P-384
keys are supported.
- Bag resources (styles, arrays, plurals, attributes) and nine-patch images
are not compiled; ONLY simple values, files, and XML documents are. Reading
supports simple values and bags; styled string spans are not exposed. I would probably take this as a PR though!
Verification establishes signature integrity and SDK scheme coverage. But certainly does
not establish certificate trust or guarantee installation: DEX validity,
device policy, and native symbol availability still depend on the app and device.
Framework attribute and resource IDs come from API 35 (`src/android/framework.txt`).
To update them, run `tools/gen-framework` against a newer SDK platform:
```sh
cd tools/gen-framework && cargo run -- $ANDROID_HOME/platforms/android-36
```
## License
Licensed under either of Apache License, Version 2.0 or MIT license at your
option.