uniapp使用uts插件启动原生安卓Service

news/2025/2/22 10:44:54

uniapp使用uts插件启动原生安卓Service

  • 背景
  • 实现
  • 尾巴

背景

在上一篇文章中uniapp使用uts插件调用原生API,我们使用uts插件来实现了一个简单的例子来调用原生安卓平台的Toast。今天我们继续使用uts插件来实现一个稍微复杂点的例子,启动一个原生安卓平台的Service,通常在安卓平台,启动一个前台服务,能增加我们APP存活的几率。

实现

本次实现就继续在上一篇基础的uts插件上进行开发,如果还没有看过上一篇文章,请移步查看。

首先我们回忆下安卓平台使用原生开发语言Java/Kotlin怎么来启动一个前台服务。
1、自定义一个类来继承Service。
2、重载onCreate、onBind、onStartCommand、onDestroy等方法。
3、启动一个通知栏常驻通知。

接下来我们就用uts语法来实现以上三个步骤,这里就直接贴代码:

class ForeService extends Service {
	//无参构造,必须要
	constructor (){
		super();
	}
	override onCreate() : void {
		super.onCreate();
		console.log("onCreate");
		initNotification()
	}
	override onBind(_intent?: Intent): IBinder|null{
		console.log("onBind");
		return null;
	}
	override onStartCommand(intent:Intent ,flags:Int ,startId:Int ):Int{
		console.log("onStartCommand");
		return super.onStartCommand(intent, flags, startId);
	}
	override onDestroy():void {
		console.log("onDestroy");
	    super.onDestroy();
	    // this.stopSelf()
	}
	//前台服务常驻通知栏
	initNotification(){
		let mBuilder = new NotificationCompat.Builder(this,"uts-test");
		// 点击后让通知将消失
		mBuilder.setAutoCancel(true) 
		mBuilder.setContentText("测试")
		mBuilder.setContentTitle("测试")
		//通知产生的时间,会在通知信息里显示
		mBuilder.setWhen(System.currentTimeMillis()) 
		//设置该通知优先级
		mBuilder.setPriority(NotificationManager.IMPORTANCE_DEFAULT) 
		//ture,设置他为一个正在进行的通知。他们通常是用来表示一个后台任务,用户积极参与(如播放音乐)或以某种方式正在等待,因此占用设备(如一个文件下载,同步操作,主动网络连接)
		mBuilder.setOngoing(false) 
		//向通知添加声音、闪灯和振动效果的最简单、最一致的方式是使用当前的用户默认设置,使用defaults属性,可以组合:
		mBuilder.setDefaults(Notification.DEFAULT_ALL)         	   
		if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {  
			let manager =
				UTSAndroid.getAppContext()!.getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
			let channelId = "channelId" + System.currentTimeMillis()
			let channel = new NotificationChannel(
				channelId,
				"appName",
				NotificationManager.IMPORTANCE_HIGH
			)
			manager.createNotificationChannel(channel)
			mBuilder.setChannelId(channelId)
		}				
		mBuilder.setContentIntent(null)
		this.startForeground(102, mBuilder.build())
	}
}

注意,我们还需要导入所使用的SDK中的类,后续会统一贴出。

接下来,我们还需要暴露出两个函数用来启动服务和停止服务。熟悉原生开发的同学肯定知道启动服务需要Context上下文对象,这里uniapp已经内置了,直接使用UTSAndroid.getUniActivity()即可获取,然后Class对象则使用UTSAndroid.getJavaClass来获取。最后提出index.uts中的完整代码:

import Context from 'android.content.Context';
import Toast from 'android.widget.Toast';
import Intent from 'android.content.Intent';
import Service from "android.app.Service";
import IBinder from 'android.os.IBinder';
import NotificationCompat from 'androidx.core.app.NotificationCompat';
import NotificationManager from 'android.app.NotificationManager';
import NotificationChannel from 'android.app.NotificationChannel';
import Notification from 'android.app.Notification';
import Build from 'android.os.Build';
import System from 'java.lang.System';
//这里用作启动服务后的回调
export type ServiceOptions = {
    success?: (res: object) => void
    stop?: (res: object) => void
}
//停止服务
export function stopService() : void {
	console.log('stopService',UTSAndroid.getJavaClass(ForeService()).name)
	let intent = new Intent(UTSAndroid.getUniActivity(), UTSAndroid.getJavaClass(ForeService()));
	UTSAndroid.getAppContext()!.stopService(intent);
}
//启动服务
export function startService(options: ServiceOptions) : void {
	let intent = new Intent(UTSAndroid.getUniActivity(), UTSAndroid.getJavaClass(ForeService()));
	if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
		console.log('startForegroundService')
		UTSAndroid.getAppContext()!.startForegroundService(intent);
	}else{
		console.log('startService')
		UTSAndroid.getAppContext()!.startService(intent);
	}
	//启动成功后的回到,我们这里默认调用了startService后就成功启动服务
	options.success?.({
		msg: "success"
	})
}

class ForeService extends Service {
	constructor (){
		super();
	}
	override onCreate() : void {
		super.onCreate();
		console.log("onCreate");
		initNotification()
	}
	override onBind(_intent?: Intent): IBinder|null{
		console.log("onBind");
		return null;
	}
	override onStartCommand(intent:Intent ,flags:Int ,startId:Int ):Int{
		console.log("onStartCommand");
		return super.onStartCommand(intent, flags, startId);
	}
	override onDestroy():void {
		console.log("onDestroy");
	    super.onDestroy();
	    // this.stopSelf()
	}
	
	initNotification(){
		let mBuilder = new NotificationCompat.Builder(this,"uts-test");
		
		// 点击后让通知将消失
		mBuilder.setAutoCancel(true) 
		mBuilder.setContentText("测试")
		mBuilder.setContentTitle("测试")
		//通知产生的时间,会在通知信息里显示
		mBuilder.setWhen(System.currentTimeMillis()) 
		//设置该通知优先级
		mBuilder.setPriority(NotificationManager.IMPORTANCE_DEFAULT) 
		//ture,设置他为一个正在进行的通知。他们通常是用来表示一个后台任务,用户积极参与(如播放音乐)或以某种方式正在等待,因此占用设备(如一个文件下载,同步操作,主动网络连接)
		mBuilder.setOngoing(false) 
		//向通知添加声音、闪灯和振动效果的最简单、最一致的方式是使用当前的用户默认设置,使用defaults属性,可以组合:
		mBuilder.setDefaults(Notification.DEFAULT_ALL)         	   
		if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {  
			let manager =
				UTSAndroid.getAppContext()!.getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
			let channelId = "channelId" + System.currentTimeMillis()
			let channel = new NotificationChannel(
				channelId,
				"appName",
				NotificationManager.IMPORTANCE_HIGH
			)
			manager.createNotificationChannel(channel)
			mBuilder.setChannelId(channelId)
		}				
		mBuilder.setContentIntent(null)
		this.startForeground(102, mBuilder.build())
	}
}

到这里全部完成了么?no,no,no,还记得上篇文章中我们提到的AndroidManifest.xml文件么?这里派上了用场,我们还需要注册我们的服务(安卓中四大组件必须在AndroidManifest.xml中注册)。

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools"
	package="uts.sdk.modules.myToast">
    <uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
	<application>
		<service android:name="uts.sdk.modules.myToast.ForeService"  android:exported="true"/>
	</application>
</manifest>

这里service包名前缀为uts.sdk.modules不可改动,因为我们是modules形式插件,然后myToast是你插件命名的驼峰标识,最后名字则是自定义的Service类名,包名不对会导致无法正确启动服务。

在vue页面中调用就很简单了,放两个按钮,然后引入插件中的startService和stopService函数。

<template>
	<view class="content">
		<image class="logo" 
			src="/static/logo.png"
			@click="handleStart"></image>
		
		<image class="logo"
			src="/static/logo.png"
			@click="handleStop"></image>
		
	</view>
</template>

<script>
	//引入函数
	import { 
		startService,
		stopService
	} from "@/uni_modules/my-toast"
	export default {
		data() {
			return {
				title: 'Hello',
				interval: null
			}
		},
		onLoad() {

		},
		methods: {
			handleStart(){
				startService({
                    success: res=> {
                        console.log(res)
						this.interval = setInterval(() => {
							console.log('task is running...')
						}, 10000)
                    }
                })
			},
			handleStop(){
				if(this.interval){
					clearInterval(this.interval)
					this.interval = null
				}
				stopService()
			}
		}
	}
</script>

<style>
	.content {
		display: flex;
		flex-direction: column;
		align-items: center;
		justify-content: center;
	}

	.logo {
		height: 200rpx;
		width: 200rpx;
		margin-top: 200rpx;
		margin-left: auto;
		margin-right: auto;
		margin-bottom: 50rpx;
	}

	.text-area {
		display: flex;
		justify-content: center;
	}

	.title {
		font-size: 36rpx;
		color: #8f8f94;
	}
</style>

点击靠上的按钮启动服务,我们看下运行效果图:
在这里插入图片描述
可以看到我们前台服务已经启动,你可以在回调中执行你的任务。这里需要注意的是因为需要常驻通知栏,需要去设置中授权应用通知权限。

尾巴

今天的文章就到这里,本篇文章和上一篇uniapp使用uts插件调用原生API有较强关联,建议先看上一篇文章在看这篇文章。有问题可以给我留言,希望能帮助到有需要的人。如果你喜欢我的文章欢迎给我点赞,谢谢!


http://www.niftyadmin.cn/n/5862125.html

相关文章

uni-app开发安卓和ios app 真机调试

一、安卓真机调试 首先打开我们的hbuilder项目&#xff0c;点击运行&#xff0c;如下所示 之后会弹出这个界面&#xff0c;安卓手机可以先打开开发者模式&#xff0c;然后用usb数据线将手机和电脑连接起来 这里讲一下怎么打开开发者模式&#xff0c;以小米手机为例 设置-我的…

[C#]C# winform部署yolov12目标检测的onnx模型

yolov12官方框架&#xff1a;github.com/sunsmarterjie/yolov12 【测试环境】 vs2019 netframework4.7.2 opencvsharp4.8.0 onnxruntime1.16.3 【效果展示】 【调用代码】 using System; using System.Collections.Generic; using System.ComponentModel; using System.…

说一下Http中常见的状态码和字段

部分内容来源&#xff1a;小林coding Http常见的状态码 1xx&#xff08;信息性状态码&#xff09; 100 Continue&#xff1a;客户端应继续其请求。101 Switching Protocols&#xff1a;服务器根据客户端的请求切换协议。 2xx&#xff08;成功状态码&#xff09; 200 OK&am…

如何确定服务器是否被黑客入侵爆破

服务器被黑客入侵爆破&#xff08;如暴力破解密码或利用漏洞攻击&#xff09;是网络安全中常见的威胁之一。这类攻击可能导致数据泄露、服务中断甚至系统完全失控。本文将详细介绍如何检测服务器是否被黑客入侵爆破&#xff0c;并提供实用的代码示例和解决方案。 一、黑客入侵…

蓝桥杯刷题2.21|笔记

参考的是蓝桥云课十四天的那个题单&#xff0c;不知道我发这个有没有问题&#xff0c;如果有问题找我我立马删文。&#xff08;参考蓝桥云课里边的题单&#xff0c;跟着大佬走&#xff0c;应该是没错滴&#xff0c;加油加油&#xff09; 一、握手问题 #include <iostream&g…

Transformer解析——(四)Decoder

本系列已完结&#xff0c;全部文章地址为&#xff1a; Transformer解析——&#xff08;一&#xff09;概述-CSDN博客 Transformer解析——&#xff08;二&#xff09;Attention注意力机制-CSDN博客 Transformer解析——&#xff08;三&#xff09;Encoder-CSDN博客 Transforme…

策略模式介绍和代码示例

策略模式&#xff08;Strategy Pattern&#xff09;是一种行为设计模式&#xff0c;它定义了一系列算法&#xff0c;并将每一个算法封装起来&#xff0c;使它们可以互换&#xff0c;算法的变化不会影响到使用算法的客户。策略模式让算法独立于其使用者&#xff0c;并且可以根据…

VMWare安装Debian操作系统

参考链接 https://blog.csdn.net/weixin_61536532/article/details/129778310 注意 如果希望折腾Linux&#xff0c;建议缺省使用英语。在极端情况下&#xff0c;系统可能会只能输出ASCII码&#xff0c;使用中文可能会导致无法正常打印log 本文使用VMWare WorkStation Pro&a…