更新记录

1.0.0(2026-08-23)

  • 发布插件

平台兼容性

uni-app(5.24)

Vue2 Vue3 Chrome Safari app-vue app-vue插件版本 app-nvue app-nvue插件版本 Android Android插件版本 iOS 鸿蒙
- - - - 1.0.0 1.0.0 5.0 1.0.0 - -
微信小程序 支付宝小程序 抖音小程序 百度小程序 快手小程序 京东小程序 鸿蒙元服务 QQ小程序 飞书小程序 小红书小程序 快应用-华为 快应用-联盟
- - - - - - - - - - - -

uni-app x(5.24)

Chrome Safari Android Android插件版本 iOS 鸿蒙 微信小程序
- - 5.0 1.0.0 - - -

温馨提示 如何调用插件

import {
  init,
  startKeepAlive,
  stopKeepAlive,
  isKeepAliveRunning,
  requestIgnoreBattery,
  goIgnoreBattery,
  isIgnoringBattery,
  onAutoStart,
  isNotificationEnabled,
  invokeNotification
} from "@/uni_modules/yuange-ndkservice"

初始化 NDK 保活(可选,startKeepAlive 会自动调用)

init({
  success(res) {
    console.log(res);
  },
  fail(err) {
    console.log(err);
  }
});

启动 NDK 保活(前台服务 + 原生守护进程)

let p = {
  title: "MyApp保活",
  content: "服务运行中"
};
startKeepAlive(JSON.stringify(p), {
  success(res) {
    console.log(res);
  },
  fail(err) {
    console.log(err);
  }
});

停止 NDK 保活

stopKeepAlive({
  success(res) {
    console.log(res);
  },
  fail(err) {
    console.log(err);
  }
});

查询保活状态

isKeepAliveRunning({
  success(res) {
    console.log(res);
    // res.data.daemonAlive: true=运行中, false=已停止
  },
  fail(err) {
    console.log(err);
  }
});

检查是否开启通知栏权限

isNotificationEnabled({
  success(res) { console.log(res); },
  fail(err) { console.log(err); }
});

开启通知栏权限

invokeNotification({
  success(res) { console.log(res); },
  fail(err) { console.log(err); }
});

去设置自启动、后台运行

onAutoStart({
  success(res) { console.log(res); },
  fail(err) { console.log(err); }
});

申请加入电池优化白名单

requestIgnoreBattery({
  success(res) { console.log(res); },
  fail(err) { console.log(err); }
});

跳转到电池优化设置页

goIgnoreBattery({
  success(res) { console.log(res); },
  fail(err) { console.log(err); }
});

是否加入电池优化白名单

isIgnoringBattery({
  success(res) { console.log(res); },
  fail(err) { console.log(err); }
});

完整Demo示例

<template>
    <view class="container">
        <view class="section">
            <text class="section-title">NDK 保活核心</text>
            <button @click="onInit" class="button">init 初始化</button>
            <button @click="onStartKeepAlive" class="button primary">启动保活</button>
            <button @click="onStopKeepAlive" class="button danger">停止保活</button>
            <button @click="onIsRunning" class="button">查询保活状态</button>
        </view>

        <view class="section">
            <text class="section-title">辅助设置</text>
            <button @click="onRequestIgnoreBattery" class="button">申请电池白名单</button>
            <button @click="onGoIgnoreBattery" class="button">电池优化设置页</button>
            <button @click="onIsIgnoringBattery" class="button">是否在白名单</button>
            <button @click="onAutoStart" class="button">自启动/后台运行设置</button>
        </view>

        <view class="section">
            <text class="section-title">通知权限</text>
            <button @click="onIsNotificationEnabled" class="button">通知权限状态</button>
            <button @click="onInvokeNotification" class="button">请求通知权限</button>
        </view>

        <view class="section timer-section">
            <text class="section-title">定时器验证(后台持续运行)</text>
            <text class="timer-text">{{ timerText }}</text>
            <text class="tip">{{ tipText }}</text>
        </view>

        <view class="section">
            <text class="section-title">日志</text>
            <scroll-view scroll-y class="log-scroll">
                <text class="log-text">{{ logText }}</text>
            </scroll-view>
            <button @click="onClearLog" class="button small">清空日志</button>
        </view>
    </view>
</template>

<script>
    import {
        init,
        startKeepAlive,
        stopKeepAlive,
        isKeepAliveRunning,
        requestIgnoreBattery,
        goIgnoreBattery,
        isIgnoringBattery,
        onAutoStart,
        isNotificationEnabled,
        invokeNotification
    } from "@/uni_modules/yuange-ndkservice"

    export default {
        data() {
            return {
                logText: "",
                timerText: "保活定时器:未启动",
                tipText: "",
                startTime: 0,
                timerId: null
            }
        },
        onLoad() {
            this.refreshTimer();
            // 每秒刷新定时器显示
            this.timerId = setInterval(() => {
                this.refreshTimer();
            }, 1000);
        },
        onUnload() {
            if (this.timerId) {
                clearInterval(this.timerId);
                this.timerId = null;
            }
        },
        onShow() {
            // 从后台返回时立即刷新,验证是否一直在后台运行
            this.refreshTimer();
        },
        methods: {
            // ==================== NDK 保活核心 ====================

            onInit() {
                this.log(">>> init");
                init({
                    success: (res) => {
                        this.log("init success: " + JSON.stringify(res));
                        this.refreshTimer();
                    },
                    fail: (err) => {
                        this.log("init fail: " + JSON.stringify(err));
                    }
                });
            },

            onStartKeepAlive() {
                this.log(">>> startKeepAlive");
                let p = {
                    title: "NDK保活测试",
                    content: "服务运行中"
                };
                startKeepAlive(JSON.stringify(p), {
                    success: (res) => {
                        this.log("startKeepAlive success: " + JSON.stringify(res));
                        this.startTime = Date.now();
                        this.refreshTimer();
                    },
                    fail: (err) => {
                        this.log("startKeepAlive fail: " + JSON.stringify(err));
                    }
                });
            },

            onStopKeepAlive() {
                this.log(">>> stopKeepAlive");
                stopKeepAlive({
                    success: (res) => {
                        this.log("stopKeepAlive success: " + JSON.stringify(res));
                        this.startTime = 0;
                        this.refreshTimer();
                    },
                    fail: (err) => {
                        this.log("stopKeepAlive fail: " + JSON.stringify(err));
                    }
                });
            },

            onIsRunning() {
                this.log(">>> isKeepAliveRunning");
                isKeepAliveRunning({
                    success: (res) => {
                        this.log("isKeepAliveRunning success: " + JSON.stringify(res));
                        try {
                            let data = typeof res.data === 'string' ? JSON.parse(res.data) : res.data;
                            if (data && data.daemonAlive) {
                                this.startTime = this.startTime || Date.now();
                            }
                            this.refreshTimer();
                        } catch (e) {}
                    },
                    fail: (err) => {
                        this.log("isKeepAliveRunning fail: " + JSON.stringify(err));
                    }
                });
            },

            // ==================== 辅助设置 ====================

            onRequestIgnoreBattery() {
                this.log(">>> requestIgnoreBattery");
                requestIgnoreBattery({
                    success: (res) => { this.log("requestIgnoreBattery: " + JSON.stringify(res)); },
                    fail: (err) => { this.log("requestIgnoreBattery fail: " + JSON.stringify(err)); }
                });
            },

            onGoIgnoreBattery() {
                this.log(">>> goIgnoreBattery");
                goIgnoreBattery({
                    success: (res) => { this.log("goIgnoreBattery: " + JSON.stringify(res)); },
                    fail: (err) => { this.log("goIgnoreBattery fail: " + JSON.stringify(err)); }
                });
            },

            onIsIgnoringBattery() {
                this.log(">>> isIgnoringBattery");
                isIgnoringBattery({
                    success: (res) => { this.log("isIgnoringBattery: " + JSON.stringify(res)); },
                    fail: (err) => { this.log("isIgnoringBattery fail: " + JSON.stringify(err)); }
                });
            },

            onAutoStart() {
                this.log(">>> onAutoStart");
                onAutoStart({
                    success: (res) => { this.log("onAutoStart: " + JSON.stringify(res)); },
                    fail: (err) => { this.log("onAutoStart fail: " + JSON.stringify(err)); }
                });
            },

            // ==================== 通知权限 ====================

            onIsNotificationEnabled() {
                this.log(">>> isNotificationEnabled");
                isNotificationEnabled({
                    success: (res) => { this.log("isNotificationEnabled: " + JSON.stringify(res)); },
                    fail: (err) => { this.log("isNotificationEnabled fail: " + JSON.stringify(err)); }
                });
            },

            onInvokeNotification() {
                this.log(">>> invokeNotification");
                invokeNotification({
                    success: (res) => { this.log("invokeNotification: " + JSON.stringify(res)); },
                    fail: (err) => { this.log("invokeNotification fail: " + JSON.stringify(err)); }
                });
            },

            // ==================== 定时器验证逻辑 ====================

            refreshTimer() {
                if (!this.startTime) {
                    this.timerText = "保活定时器:未启动";
                    this.tipText = "点击「启动保活」开始验证后台持续运行";
                    return;
                }

                let elapsed = Date.now() - this.startTime;
                let h = Math.floor(elapsed / 3600000);
                let m = Math.floor((elapsed % 3600000) / 60000);
                let s = Math.floor((elapsed % 60000) / 1000);
                let timeStr = String(h).padStart(2, '0') + ":" + String(m).padStart(2, '0') + ":" + String(s).padStart(2, '0');

                let now = new Date();
                let nowStr = String(now.getHours()).padStart(2, '0') + ":" +
                    String(now.getMinutes()).padStart(2, '0') + ":" +
                    String(now.getSeconds()).padStart(2, '0');

                this.timerText =
                    "运行时长: " + timeStr + "\n" +
                    "当前时间: " + nowStr + "\n" +
                    "启动时间: " + new Date(this.startTime).toLocaleTimeString();
                this.tipText =
                    "验证方法:将应用退到后台/锁屏一段时间,返回后查看运行时长是否持续累计。";
            },

            // ==================== 日志 ====================

            log(msg) {
                let now = new Date();
                let timeStr = String(now.getHours()).padStart(2, '0') + ":" +
                    String(now.getMinutes()).padStart(2, '0') + ":" +
                    String(now.getSeconds()).padStart(2, '0');
                this.logText = "[" + timeStr + "] " + msg + "\n" + this.logText;
            },

            onClearLog() {
                this.logText = "";
            }
        }
    }
</script>

<style>
    .container {
        padding: 20rpx;
    }

    .section {
        margin-bottom: 30rpx;
    }

    .section-title {
        font-size: 28rpx;
        font-weight: bold;
        color: #333;
        margin-bottom: 15rpx;
        display: block;
    }

    .button {
        margin-bottom: 15rpx;
        background-color: #f0f0f0;
        color: #333;
        font-size: 28rpx;
    }

    .button.primary {
        background-color: dodgerblue;
        color: white;
    }

    .button.danger {
        background-color: #e74c3c;
        color: white;
    }

    .button.small {
        font-size: 24rpx;
        padding: 10rpx;
    }

    .timer-section {
        background-color: #f8f8f8;
        padding: 20rpx;
        border-radius: 10rpx;
    }

    .timer-text {
        font-size: 32rpx;
        font-family: monospace;
        color: #333;
        white-space: pre-line;
    }

    .tip {
        font-size: 22rpx;
        color: #999;
        margin-top: 15rpx;
        white-space: pre-line;
    }

    .log-scroll {
        height: 400rpx;
        background-color: #1e1e1e;
        border-radius: 10rpx;
        padding: 15rpx;
    }

    .log-text {
        font-size: 22rpx;
        color: #4caf50;
        font-family: monospace;
        white-space: pre-line;
    }
</style>

隐私、权限声明

1. 本插件需要申请的系统权限列表:

android.permission.FOREGROUND_SERVICE

2. 本插件采集的数据、发送的服务器地址、以及数据用途说明:

插件不采集任何数据

3. 本插件是否包含广告,如包含需详细说明广告表达方式、展示频率:

暂无用户评论。