App打包

APP打包封装 https://cloud.nextcli.com/app/package

App 应用打包使用说明

本服务可将任何网站 URL 打包为 Android 与 Windows 应用(iOS、Mac 版本正在开发中),并在应用内部集成了防屏蔽功能,使海内外用户均可自由访问目标网站,不受防火墙限制。

同时,您也可以在此生成并下载专用的 Android 与 Windows 防屏蔽 SDK,将其整合至您的 App,以便突破网络访问限制。以下示例以 X(推特) 为例,展示如何使用本功能。

一、APP打包

字段
说明

APP包名/APP ID

APP适用系统

普通用户可选择打包Android APK、Windows EXE; 安卓AAR、Windows DLL 则是面向专业开发者的SDK。

APP主页链接

打开APP时,主页显示内容所在的链接网址;

APP图标

APP安装在桌面上显示的图标; Android推荐使用 512×512px 的图标以获得最佳效果; Windows同样512×512px 的图标,也可以直接使用网站的favicon.ico链接。

1.2. 打包与下载

  • 点击“打包”后,预计 1~5 分钟完成。需手动刷新查看进度。

  • 打包产物下载链接有效期为 1小时,过期后需重新打包。

  • 如果打包失败,请检查错误提示;如无法解决可联系客服。

1.3. 其他说明

  • 新用户在创建第一个应用后,可获得 1年 的每月 1G 流量套餐。

2.1 流量加速

  • 开启流量加速后,白名单中的域名将启用防屏蔽功能。

  • 如果当月流量用完,需要再次购买套餐或流量包才能继续使用流量加速。

2.2 什么是加速白名单?

  • 流量加速开启后,白名单中的域名会通过加速通道,消耗套餐流量;其他域名则使用普通网络。

  • 创建应用后,系统会自动将应用主页链接的域名加入到加速白名单。

    例如,若应用主页链接为 abc.x.com,则默认将 abc.x.com 添加到白名单。

  • 您还可以手动添加更多域名到白名单,例如添加 123.x.com 、www.google.com,则该域名流量将走加速通道。

2.3 白名单规则

  1. 仅可添加域名(不能包含 http 或 https)。

  2. 若添加一级域名(如 x.com),其所有二级或子域名(如 m.x.com, www.x.com)皆自动纳入白名单。

  3. 若只添加二级域名(如 m.x.com),则不包含 x.com。

  • 新用户创建第一个应用后,系统会免费提供 1年 的每月 1G 流量套餐。

  • 您可多次购买同一套餐,后购买的套餐将覆盖之前的套餐,同时重置 App 的流量用量和到期时间。

  • ⚠️注意,必须先拥有一个套餐,才能购买流量包。流量包的有效期与当月套餐同步。

  • 如需更多套餐选项,请联系客服。

四、开发者文档

完整示例可查看 GitHub 项目

4.1 生成AAR

  1. 在创建应用时选择 AAR 作为目标产物,主页链接可先填后端 API 地址(后续可于白名单中修改)。

  2. 打包产物解压后将获得 checksum 文件与 xxx.aar 文件。

  3. sdk调用前需要把checksum复制到app的内部存储文件夹下,因为sdk需要校验这个文件,然后初始化sdk,参考以下demo

// kotlin 示例
CoroutineScope(Dispatchers.IO).launch {
    try {
        moveAssetsFileToInternalStorage(context, "checksum")

        // code=1 正常启动
        // 这里sdk工作目录必须和checksum文件在同一个目录
        val errCode = Safetunnel.newInstance(context.filesDir.absolutePath)

        // code=1 正常启动
        val startCode = Safetunnel.start()

        // 获取代理端口,应用层流量转发到这个端口即可使用流量加速功能
        val port = Safetunnel.getPort()
    } catch (e: Exception) {
        // log
    }

// Android复制assets文件到内部存储
private suspend fun moveAssetsFileToInternalStorage(
    context: Context,
    fileName: String
): Boolean {
    return withContext(Dispatchers.IO) {
        var inputStream: InputStream? = null
        try {
            inputStream = context.assets.open(fileName)
            // ⚠️注意:sdk工作目录必须和checksum文件在同一个目录
            val outFile = File(context.filesDir, fileName).apply {
                parentFile?.mkdirs()
            }
            if (!outFile.exists()) {
                // 将文件内容从输入流复制到输出流
                inputStream.copyTo(outFile.outputStream())
                Log.d(
                    "TAG",
                    "File $fileName moved to internal storage: ${outFile.absolutePath}"
                )
            }
            true
        } catch (e: Exception) {
            Log.e("TAG", "Failed to move file $fileName to internal storage: ${e.message}")
            false
        } finally {
            // 关闭流
            inputStream?.close()
        }
    }
}

  1. 应用层示例,这里以网络请求为例,更多使用示例请查看demo;

# Android kotlin 示例
val proxy =
    Proxy(Proxy.Type.SOCKS, InetSocketAddress("127.0.0.1", Safetunnel.getPort()))
okHttpClient.proxy(proxy)


参考链接

Android 开发者文档(英文)

Windows 应用打包(Microsoft 官方文档)

最后更新于