Skip to content
Draft
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions website/docs/.vitepress/config.mts
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ export default defineConfig({
text: "What is Axeron Manager?",
link: "/guide/what-is-axeron-manager",
},
{ text: "API Integration", link: "/guide/api-integration" },
{ text: "User Manual", link: "/guide/user-manual" },
{ text: "FAQ", link: "/guide/faq" },
],
Expand Down Expand Up @@ -70,6 +71,7 @@ export default defineConfig({
text: "什么是 Axeron Manager?",
link: "/zh/guide/what-is-axeron-manager",
},
{ text: "API 集成", link: "/zh/guide/api-integration" },
{ text: "用户手册", link: "/zh/guide/user-manual" },
{ text: "常见问题", link: "/zh/guide/faq" },
],
Expand Down
119 changes: 119 additions & 0 deletions website/docs/guide/api-integration.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,119 @@
# API Integration

AxManager allows third-party client applications to execute shell commands with elevated privileges (ADB or Root) using the **Axeron API**.

There are two primary methods for integrating AxManager into your app:
1. **Using Axerish with libsu** (Recommended for most apps that already use `libsu`)
2. **Using the Direct Axeron API** (Lower level, no `libsu` dependency)

---

## 1. Using Axerish + libsu

Axerish is a shell wrapper provided by AxManager that seamlessly integrates with the popular `libsu` library by topjohnwu. It allows your app to use AxManager's execution context transparently.

### Step 1: Add Dependencies

Add `libsu` and the Axeron API to your `build.gradle.kts`:

```kotlin
dependencies {
implementation("com.github.topjohnwu.libsu:core:<latest_version>")
// Make sure to check GitHub releases for the latest version
implementation("com.github.fahrez182.AxManager:api:<latest_version>")
}
```

### Step 2: Initialize in Application

In your custom `Application` class, initialize `Axerish` and set it as the default shell builder for `libsu`:

```kotlin
import android.app.Application
import com.topjohnwu.superuser.Shell
import frb.axeron.Axerish

class MyApplication : Application() {
override fun onCreate() {
super.onCreate()

// 1. Initialize Axerish by passing your application's package name
Axerish.initialize(packageName)

// 2. Configure libsu to use Axerish as its shell
Shell.setDefaultBuilder(
Shell.Builder.create()
.setCommands("sh", Axerish.axrun_path.absolutePath)
)
}
}
```

### Step 3: Execute Commands

Now you can use `Shell.cmd()` normally. The execution is automatically routed to AxManager's elevated environment!

```kotlin
import com.topjohnwu.superuser.Shell

// Run any command with elevated privileges
val result = Shell.cmd("uname -r").exec()

if (result.isSuccess) {
println("Kernel version: ${result.out.joinToString("\n")}")
}
```

---

## 2. Using Direct Axeron API

If your app requires lower-level integration or you prefer not to include the `libsu` library, you can bind directly to the Axeron service.

### Step 1: Add Dependencies

Add the Axeron API and Provider to your `build.gradle.kts`:

```kotlin
dependencies {
implementation("com.github.fahrez182.AxManager:api:<latest_version>")
implementation("com.github.fahrez182.AxManager:provider:<latest_version>")
}
```

### Step 2: Declare the Provider

Add the `AxeronProvider` to your app's `AndroidManifest.xml`. This enables AxManager to send the IPC binder to your application.

```xml
<provider
android:name="frb.axeron.provider.AxeronProvider"
android:authorities="${applicationId}.axeron"

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

high

The authority specified here (${applicationId}.axeron) does not match the authority the server expects. According to the server implementation in AxeronService.kt (line 188), it looks for a provider with the authority ${packageName}.shizuku. Using the wrong authority will prevent the server from successfully connecting to your application.

Suggested change
android:authorities="${applicationId}.axeron"
android:authorities="${applicationId}.shizuku"

android:exported="true"
android:multiprocess="false" />
```

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

high

The documentation is missing the requirement to declare the necessary permission in the AndroidManifest.xml. The Axeron server (see AxeronService.kt, line 130) iterates through installed packages and only sends the binder to those that have requested the specific API permission. Without this declaration, the addBinderReceivedListenerSticky callback will never be triggered. Please add a <uses-permission> tag to the example.


### Step 3: Listen for Binder & Execute

Wait for the AxManager service to connect using `Axeron.addBinderReceivedListenerSticky`, and then use `Axeron.newProcess` to run commands.

```kotlin
import frb.axeron.api.Axeron

// Listen for the connection to the AxManager service
Axeron.addBinderReceivedListenerSticky {
// We are now connected to AxManager!

// Execute a command directly
val process = Axeron.newProcess("uname -r")

// Read the output
process.inputStream.bufferedReader().useLines { lines ->
lines.forEach { println("Output: $it") }
}

// Wait for the command to finish
val exitCode = process.waitFor()
println("Command finished with exit code: $exitCode")
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

The example code performs blocking operations (reading from an input stream and calling process.waitFor()) directly inside the addBinderReceivedListenerSticky callback. If this listener is executed on the main thread (which is common for default Android listeners), it will lead to an Application Not Responding (ANR) error. It is recommended to perform these operations on a background thread or using coroutines.

```
119 changes: 119 additions & 0 deletions website/docs/zh/guide/api-integration.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,119 @@
# API 集成

AxManager 允许第三方客户端应用程序使用 **Axeron API** 在提权环境(ADB 或 Root)下执行 Shell 命令。

目前有两种主要方法将 AxManager 集成到您的应用中:
1. **使用 Axerish 与 libsu**(推荐,适用于大多数已使用 `libsu` 的应用)
2. **直接使用 Axeron API**(底层方法,无需依赖 `libsu`)

---

## 1. 使用 Axerish + libsu

Axerish 是 AxManager 提供的一个 Shell 包装器,它可以无缝集成到流行的 `libsu` 库中。这使得您的应用可以透明地使用 AxManager 的执行环境。

### 第一步:添加依赖

在您的 `build.gradle.kts` 中添加 `libsu` 和 Axeron API:

```kotlin
dependencies {
implementation("com.github.topjohnwu.libsu:core:<最新版本>")
// 请在 GitHub Releases 页面查看最新版本
implementation("com.github.fahrez182.AxManager:api:<最新版本>")
}
```

### 第二步:在 Application 中初始化

在您自定义的 `Application` 类中,初始化 `Axerish` 并将其设置为 `libsu` 的默认 Shell 构建器:

```kotlin
import android.app.Application
import com.topjohnwu.superuser.Shell
import frb.axeron.Axerish

class MyApplication : Application() {
override fun onCreate() {
super.onCreate()

// 1. 传入您的应用包名来初始化 Axerish
Axerish.initialize(packageName)

// 2. 配置 libsu 以使用 Axerish 作为其 Shell
Shell.setDefaultBuilder(
Shell.Builder.create()
.setCommands("sh", Axerish.axrun_path.absolutePath)
)
}
}
```

### 第三步:执行命令

现在您可以像往常一样使用 `Shell.cmd()`。所有的执行命令都会自动路由到 AxManager 的提权环境中!

```kotlin
import com.topjohnwu.superuser.Shell

// 运行具有提升权限的任何命令
val result = Shell.cmd("uname -r").exec()

if (result.isSuccess) {
println("内核版本: ${result.out.joinToString("\n")}")
}
```

---

## 2. 直接使用 Axeron API

如果您的应用需要更底层的集成,或者您不想引入 `libsu` 库,您可以直接绑定到 Axeron 服务。

### 第一步:添加依赖

在您的 `build.gradle.kts` 中添加 Axeron API 和 Provider:

```kotlin
dependencies {
implementation("com.github.fahrez182.AxManager:api:<最新版本>")
implementation("com.github.fahrez182.AxManager:provider:<最新版本>")
}
```

### 第二步:声明 Provider

在您的 `AndroidManifest.xml` 中添加 `AxeronProvider`。这允许 AxManager 将 IPC binder 发送到您的应用程序。

```xml
<provider
android:name="frb.axeron.provider.AxeronProvider"
android:authorities="${applicationId}.axeron"

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

high

The authority specified here (${applicationId}.axeron) does not match the authority the server expects. According to the server implementation in AxeronService.kt (line 188), it looks for a provider with the authority ${packageName}.shizuku. Using the wrong authority will prevent the server from successfully connecting to your application.

Suggested change
android:authorities="${applicationId}.axeron"
android:authorities="${applicationId}.shizuku"

android:exported="true"
android:multiprocess="false" />
```

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

high

The documentation is missing the requirement to declare the necessary permission in the AndroidManifest.xml. The Axeron server (see AxeronService.kt, line 130) iterates through installed packages and only sends the binder to those that have requested the specific API permission. Without this declaration, the addBinderReceivedListenerSticky callback will never be triggered. Please add a <uses-permission> tag to the example.


### 第三步:监听 Binder 并执行

使用 `Axeron.addBinderReceivedListenerSticky` 等待 AxManager 服务连接,然后使用 `Axeron.newProcess` 来运行命令。

```kotlin
import frb.axeron.api.Axeron

// 监听与 AxManager 服务的连接状态
Axeron.addBinderReceivedListenerSticky {
// 我们现在已连接到 AxManager!

// 直接执行命令
val process = Axeron.newProcess("uname -r")

// 读取输出
process.inputStream.bufferedReader().useLines { lines ->
lines.forEach { println("输出: $it") }
}

// 等待命令完成
val exitCode = process.waitFor()
println("命令完成,退出码为: $exitCode")
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

The example code performs blocking operations (reading from an input stream and calling process.waitFor()) directly inside the addBinderReceivedListenerSticky callback. If this listener is executed on the main thread (which is common for default Android listeners), it will lead to an Application Not Responding (ANR) error. It is recommended to perform these operations on a background thread or using coroutines.

```