app php01 2ed823359c 第一次提交 hai 7 meses
..
utssdk 2ed823359c 第一次提交 hai 7 meses
changelog.md 2ed823359c 第一次提交 hai 7 meses
encrypt 2ed823359c 第一次提交 hai 7 meses
package.json 2ed823359c 第一次提交 hai 7 meses
readme.md 2ed823359c 第一次提交 hai 7 meses

readme.md

app后台保活,支持Android/iOS

  • ios通过后台定位或着无限播放音乐来达到后台保活的目的
  • ios商店审核时注意说明有后台播放音乐或后台定位功能
  • 支持息屏

要唤醒未启动的app可以使用插件https://ext.dcloud.net.cn/plugin?id=20180

集成步骤

  1. 拷贝demo里的nativeResources、Info.plist文件到项目根目录
  2. 集成插件,集成插件步骤请参考 https://www.cnblogs.com/wenrisheng/p/18323027

保活方式

Android采用多种方式一起使用来增加保活的概率

iOS系统支持两种保活方式(后台定位、无限循环播放无声音乐),采用其中一种即可

接口文档


import {
	UTSKeepalive
} from "@/uni_modules/wrs-uts-keepalive"
let keepalive = new UTSKeepalive()


// 设置回调
UTSKeepalive.setCallback((resp)=>{
	this.showMsg(JSON.stringify(resp))
	let opt  = resp.opt 
	switch (opt){
		// 定位改变
		case "onLocationChanged":
		if(this.isAndroid) {
			let location = resp.location
			let latitude = location.latitude
			let longitude = location.longitude
			let speed = location.speed
		} else {
			let locations = resp.locations
		}
		   
			break;
		default:
			break;
	}
})

android保活


多种方式一起使用:

let params = this.getAndroidNotification()

// 1. 开启前台服务
UTSKeepalive.startForegroundService(params)

// 2. 开启定时服务结合双进程互相唤醒方式
UTSKeepalive.startJobService(params)
UTSKeepalive.startLocalService(params)
UTSKeepalive.startRemoteService(params)

// 3. 开启锁屏监听
UTSKeepalive.startScreenLockReceiver()

// 后台定位功能,用不到后台定位可以不需要调用
let locationParams = {}
locationParams.notification = params
locationParams.location = {
	provider: "gps", // 支持gps、fused、network、passive
	minTimeMs: 500, // 间隔时间,这里为了测试效果,设置为500毫秒,实际情况根据自己业务设置
	minDistanceM: 0.5 // 间隔距离,这里为了测试效果,设置为0.5米,实际情况根据自己业务设置
}
UTSKeepalive.startLocstionService(locationParams)

provider:
(1)GPS_PROVIDER:通过 GPS 来获取地理位置的经纬度信息; 优点:获取地理位置信息精确度高; 缺点:只能在户外使用,获取经纬度信息耗时,耗电;

(2)NETWORK_PROVIDER:通过移动网络的基站或者 Wi-Fi 来获取地理位置; 优点:只要有网络,就可以快速定位,室内室外都可; 缺点:精确度不高;

(3)PASSIVE_PROVIDER:被动接收更新地理位置信息,而不用自己请求地理位置信息。

PASSIVE_PROVIDER 返回的位置是通过其他 providers 产生的,可以查询 getProvider() 方法决定位置更新的由来,需要 ACCESS_FINE_LOCATION 权限,但是如果未启用 GPS,则此 provider 可能只返回粗略位置匹配;

(4)FUSED_PROVIDER:这个本来已经被废弃了,但是目前在Android12(即android api 31)上又重新使用了起来,但是它依赖GMS,所以国内暂时无法使用。

我们通常使用gps和network这两种方式。



getAndroidNotification() {
	let channelId = 10
	let params = {}
	params.identifier = "123" // 通知ID,尽量所有的通知都用同一个identifier,不同identifier会产生多条通知
	params.channel = { // 如果已经channelId的channel则不创建,如果没有则会自动创建
		channelId: channelId,
		channelName: "保活channel",
		importance: 5, // 3: default 4: high 2: low 5: max 1: min 0: none
		lockscreenVisibility: 1, //1: public 0: private -1: secret
		description: "保活channel"
	}
	params.notification = {
		channelId: channelId, // 此消息通知是属于哪个channel的
		contentTitle: "保活通知",
		contentText: "保活",
		visibility: 1, // 1: public 0: private -1: secret
		smallIcon: { // 小图标,必传
			type: "resource", // 固定
			defType: "drawable", // 固定
			name: "not" // 文件名,不要带文件后缀,对应nativeResources/android/res/drawable文件夹下的图片
		},
		autoCancel: false
	}
	return params
}

  • Android白名单 一些android手机需要开启白名单来达到保活,需要用户手动开启,白名单主要指:
  1. 电池后台耗电管理

从 Android 6.0 开始,系统为了省电增加了休眠模式,系统待机一段时间后,会杀死后台正在运行的进程。 但系统会有一个后台运行白名单,白名单里的应用将不会受到影响 开启路径(不通机型有所不一样):「设置」 - 「电池」 - 「电池优化」 - 「未优化应用」

  • 允许后台高耗电
  • 允许自启动
  • 允许后台活动
  1. 开机自启动 开启路径(不通机型有所不一样):「应用权限设置页」 - 「所有权限」
  • 自启动(开机自动 后台启动)
  • 开机启动
  1. 锁屏清理 开启路径(不通机型有所不一样):「应用权限设置页」 - 「锁屏清理」 - 「开启」

  2. 神隐模式(小米) 开启路径(不通机型有所不一样):「应用权限设置页」 - 「神隐模式」 - 「无限制」 - 「开启定位」

  3. 还有一些其它机型有类似「绿色后台」、「应用保护」这样的设置,都需要开启

  • 跳到app设置页面,仅支持Android

    
    UTSKeepalive.goToAppSettings()
    
    
  • 请求定位权限,仅支持iOS

    
    // 0:kCLAuthorizationStatusNotDetermined
    // 1: kCLAuthorizationStatusRestricted
    // 2: kCLAuthorizationStatusDenied
    // 3: kCLAuthorizationStatusAuthorizedAlways
    // 4: kCLAuthorizationStatusAuthorizedWhenInUse
    // 5: kCLAuthorizationStatusAuthorized
    var authorizationStatus = UTSKeepalive.getAuthorizationStatus();
    if (authorizationStatus == 0) {// 没有授权过定位时,请求定位权限
    	keepalive.requestLocationAuthorization()
    }
    
    

ios保活


// 监听app前后台状态
UTSKeepalive.listenerApp((resp) => {
	let opt = resp.opt
	switch (opt) {
		// app进入后台
		case "enterBackground": {
			var authorizationStatus = UTSKeepalive.getAuthorizationStatus();

			// app进入后台,此时采用定位保活还是采用播放音乐保活可以根据自己业务决定
			if (authorizationStatus == 3) { // 当定位权限是总是一直定位时采用定位来保活
				console.log("定位保活")
				keepalive.startLocation({
					desiredAccuracy: "NearestTenMeters",
					allowsBackgroundLocationUpdates: true, // 允许后台更新位置
					pausesLocationUpdatesAutomatically: false // 不允许自动暂停更新位置
				})
			} else { // 采用播放音乐保活
				console.log("播放音乐保活")
				UTSKeepalive.setCategory("playback")
				var url = plus.io.convertLocalFileSystemURL('_www/static/bgmusic.mp3');
		
				keepalive.playMusic({
					url: url,
					numberOfLoops: -1, // 循环此时,-1表示无限循环
					volume: 0 // 音量,0
				});
			}
			// 通知系统开始后台任务
			UTSKeepalive.beginBackgroundTask()
		}
		break;
		// app回到前台
		case "enterForeground": {
			// 停止播放音乐
			keepalive.stopMusic()
			// 停止定位
			keepalive.stopLocation()
			// 通知系统结束后台任务
			UTSKeepalive.endBackgroundTask()
		}

		break;
		default:
			break;
	}
})

  • 保活验证代码

    
    onHide() {
    	//页面消失的时候开启定时器实时刷新当前时间,app退到后台后启动定时器,实时刷新当前时间,观察控制台输出的定时输出日志,如果控制台一直有打印数据说明app后台运行时还是保活的
    	// app回到前台时,如果显示的是当前时间,说明后台保活有效,定时器在后台运行时一直有效
    	if (this.timer) {
    		clearInterval(this.timer);
    	}
    
    	this.timer = setInterval(() => {
    		this.curTime = this.getCurrentTime()
    		this.count = this.count + 1
    		this.showMsg("定时任务 count: " + this.count)
    
    	}, 1000);
    },
    onShow() {
    	if (this.timer) {
    		clearInterval(this.timer);
    	}
    },