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

embedded/2025/2/25 11:51:44/

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 NotificationManagerlet 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) => voidstop?: (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 NotificationManagerlet 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.ppmy.cn/embedded/165046.html

相关文章

前端面试-webpack篇

Webpack的构建流程 Webpack 的构建流程可以总结为以下几个关键步骤&#xff1a; 初始化参数&#xff1a; 从配置文件和命令行参数中读取并合并配置&#xff0c;得到最终的构建参数。 开始编译&#xff1a; 初始化 Compiler 对象&#xff0c;加载所有配置的插件&#xff0c;执行…

策略模式Spring框架下开发实例

策略类Spring框架下开发实例 先列出策略模式下需要那些类: 策略接口 (Strategy)&#xff0c;定义所有策略类必须遵循的行为。 具体策略类&#xff08;如 ConcreteStrategyA、ConcreteStrategyB&#xff09;&#xff0c;实现不同的算法或行为。 上下文类 (Context)&#xff0c;…

机器学习数学通关指南——微分中值定理和积分中值定理

前言 本文隶属于专栏《机器学习数学通关指南》&#xff0c;该专栏为笔者原创&#xff0c;引用请注明来源&#xff0c;不足和错误之处请在评论区帮忙指出&#xff0c;谢谢&#xff01; 本专栏目录结构和参考文献请见《机器学习数学通关指南》 正文 1. 定义与核心结论 积分中值…

AI知识库和全文检索的区别

1、AI知识库的作用 AI知识库是基于人工智能技术构建的智能系统&#xff0c;能够理解、推理和生成信息。它的核心作用包括&#xff1a; 1.1 语义理解 自然语言处理&#xff08;NLP&#xff09;&#xff1a;AI知识库能够理解用户查询的语义&#xff0c;而不仅仅是关键词匹配。 …

.manifest是什么文件格式

.manifest 文件是一种用于描述应用程序或组件元数据的文件&#xff0c;其格式和内容因平台和应用类型而异。在某些情况下&#xff0c;.manifest 文件采用 JSON 格式&#xff0c;例如在 Web 应用程序中&#xff0c;manifest.json 文件用于定义应用的名称、版本、图标、启动页面等…

C#最新语言特性

C#最新语言特性 近几年持续引入多个新特性以提升开发效率和代码质量&#xff0c;截至今年2025年2月&#xff0c;C#的最新稳定版本是C#13&#xff0c;它是在2024年11月发布的&#xff0c;下方是一些C#13中的新特性以及近期版本特性。 C#13版本 params集合增强 params关键字得…

DeepSeek R1/V3满血版——在线体验与API调用

前言&#xff1a;在人工智能的大模型发展进程中&#xff0c;每一次新模型的亮相都宛如一颗投入湖面的石子&#xff0c;激起层层波澜。如今&#xff0c;DeepSeek R1/V3 满血版强势登场&#xff0c;为大模型应用领域带来了全新的活力与变革。 本文不但介绍在线体验 DeepSeek R1/…

冒泡排序:简单又易于实现的排序算法

大家好&#xff0c;今天我们来聊聊 冒泡排序&#xff08;Bubble Sort&#xff09;算法。听名字是不是很简单&#xff0c;感觉就像是水面上泡泡一样&#xff1f;没错&#xff0c;冒泡排序的名字来源于这种排序过程中&#xff0c;较大的元素像气泡一样逐步“冒泡”到数组的顶端。…