From fc2cfbf14da83f65f089c5448280c8a0472f15ed Mon Sep 17 00:00:00 2001 From: taohebin Date: Tue, 28 Nov 2023 16:11:02 +0800 Subject: [PATCH] feat: uni-progress-notification --- pages/test/test.vue | 72 ++++++++- .../uni-progress-notification/changelog.md | 6 + .../uni-progress-notification/package.json | 111 +++++++++++++ .../uni-progress-notification/readme.md | 62 ++++++++ .../utssdk/app-android/AndroidManifest.xml | 11 ++ .../app-android/TransparentActivity.uts | 48 ++++++ .../utssdk/app-android/config.json | 3 + .../utssdk/app-android/constant.uts | 2 + .../utssdk/app-android/index.uts | 150 ++++++++++++++++++ .../values/notification_progress_styles.xml | 11 ++ .../utssdk/app-ios/config.json | 3 + .../utssdk/app-ios/index.uts | 85 ++++++++++ .../utssdk/interface.uts | 137 ++++++++++++++++ .../utssdk/unierror.uts | 0 14 files changed, 697 insertions(+), 4 deletions(-) create mode 100644 uni_modules/uni-progress-notification/changelog.md create mode 100644 uni_modules/uni-progress-notification/package.json create mode 100644 uni_modules/uni-progress-notification/readme.md create mode 100644 uni_modules/uni-progress-notification/utssdk/app-android/AndroidManifest.xml create mode 100644 uni_modules/uni-progress-notification/utssdk/app-android/TransparentActivity.uts create mode 100644 uni_modules/uni-progress-notification/utssdk/app-android/config.json create mode 100644 uni_modules/uni-progress-notification/utssdk/app-android/constant.uts create mode 100644 uni_modules/uni-progress-notification/utssdk/app-android/index.uts create mode 100644 uni_modules/uni-progress-notification/utssdk/app-android/res/values/notification_progress_styles.xml create mode 100644 uni_modules/uni-progress-notification/utssdk/app-ios/config.json create mode 100644 uni_modules/uni-progress-notification/utssdk/app-ios/index.uts create mode 100644 uni_modules/uni-progress-notification/utssdk/interface.uts create mode 100644 uni_modules/uni-progress-notification/utssdk/unierror.uts diff --git a/pages/test/test.vue b/pages/test/test.vue index e6dcd41..1c4825d 100644 --- a/pages/test/test.vue +++ b/pages/test/test.vue @@ -20,7 +20,8 @@ - + + @@ -28,7 +29,13 @@ @@ -321,4 +385,4 @@ font-size: 36rpx; color: #8f8f94; } - \ No newline at end of file + diff --git a/uni_modules/uni-progress-notification/changelog.md b/uni_modules/uni-progress-notification/changelog.md new file mode 100644 index 0000000..9e05173 --- /dev/null +++ b/uni_modules/uni-progress-notification/changelog.md @@ -0,0 +1,6 @@ +## 1.0.2(2023-11-28) +修改资源的包名 +## 1.0.1(2023-11-28) +更新文档 +## 1.0.0(2023-11-28) +Android通知栏显示进度插件 diff --git a/uni_modules/uni-progress-notification/package.json b/uni_modules/uni-progress-notification/package.json new file mode 100644 index 0000000..c2db422 --- /dev/null +++ b/uni_modules/uni-progress-notification/package.json @@ -0,0 +1,111 @@ +{ + "id": "uni-progress-notification", + "displayName": "uni-progress-notification", + "version": "1.0.2", + "description": "uni-progress-notification", + "keywords": [ + "uni-progress-notification" +], + "repository": "", + "engines": { + "HBuilderX": "^3.91" + }, + "dcloudext": { + "type": "uts", + "sale": { + "regular": { + "price": "0.00" + }, + "sourcecode": { + "price": "0.00" + } + }, + "contact": { + "qq": "" + }, + "declaration": { + "ads": "无", + "data": "插件不采集任何数据", + "permissions": "TargetSDKVersion33以上时需配置\n`android.permission.POST_NOTIFICATIONS`" + }, + "npmurl": "" + }, + "uni_modules": { + "dependencies": [], + "uni-ext-api": { + "uni": { + "createNotificationProgress": { + "name": "createNotificationProgress", + "app": { + "js": true, + "kotlin": true, + "swift": false + } + }, + "finishNotificationProgress": { + "name": "finishNotificationProgress", + "app": { + "js": true, + "kotlin": true, + "swift": false + } + }, + "cancelNotificationProgress": { + "name": "cancelNotificationProgress", + "app": { + "js": true, + "kotlin": true, + "swift": false + } + } + } + }, + "encrypt": [], + "platforms": { + "cloud": { + "tcb": "y", + "aliyun": "y" + }, + "client": { + "Vue": { + "vue2": "y", + "vue3": "y" + }, + "App": { + "app-android": { + "minVersion": "19" + }, + "app-ios": "n" + }, + "H5-mobile": { + "Safari": "n", + "Android Browser": "n", + "微信浏览器(Android)": "n", + "QQ浏览器(Android)": "n" + }, + "H5-pc": { + "Chrome": "n", + "IE": "n", + "Edge": "n", + "Firefox": "n", + "Safari": "n" + }, + "小程序": { + "微信": "n", + "阿里": "n", + "百度": "n", + "字节跳动": "n", + "QQ": "n", + "钉钉": "n", + "快手": "n", + "飞书": "n", + "京东": "n" + }, + "快应用": { + "华为": "n", + "联盟": "n" + } + } + } + } +} \ No newline at end of file diff --git a/uni_modules/uni-progress-notification/readme.md b/uni_modules/uni-progress-notification/readme.md new file mode 100644 index 0000000..fd0e987 --- /dev/null +++ b/uni_modules/uni-progress-notification/readme.md @@ -0,0 +1,62 @@ +# uni-download-notification + +## 使用说明 + +Android平台创建显示进度的通知栏消息 + +**注意: 需要自定义基座,否则点击通知栏消息不会拉起应用** + +### uni.createNotificationProgress(options : CreateNotificationProgressOptions) : void, + +创建显示进度的通知栏消息 + +参数说明 + +``` +export type CreateNotificationProgressOptions = { + /** + * 通知标题 + * @defaultValue 应用名称 + */ + title ?: string | null + /** + * 通知内容 + */ + content : string, + /** + * 进度 + */ + progress : number +} +``` + +### uni.finishNotificationProgress(options: FinishNotificationProgressOptions) : void + +完成时调用的API,比如下载完成后需要显示下载完成并隐藏进度时调用。 + +参数说明 + + +``` +export type FinishNotificationProgressOptions = { + /** + * 通知标题 + * @defaultValue 应用名称 + */ + title ?: string | null + /** + * 通知内容 + */ + content : string, + /** + * 点击通知消息回调 + */ + callback : () => void +} +``` + + +### cancelNotificationProgress() : void + +取消通知消息显示 + diff --git a/uni_modules/uni-progress-notification/utssdk/app-android/AndroidManifest.xml b/uni_modules/uni-progress-notification/utssdk/app-android/AndroidManifest.xml new file mode 100644 index 0000000..4d679e4 --- /dev/null +++ b/uni_modules/uni-progress-notification/utssdk/app-android/AndroidManifest.xml @@ -0,0 +1,11 @@ + + + + + + + + \ No newline at end of file diff --git a/uni_modules/uni-progress-notification/utssdk/app-android/TransparentActivity.uts b/uni_modules/uni-progress-notification/utssdk/app-android/TransparentActivity.uts new file mode 100644 index 0000000..025b502 --- /dev/null +++ b/uni_modules/uni-progress-notification/utssdk/app-android/TransparentActivity.uts @@ -0,0 +1,48 @@ +import Activity from "android.app.Activity"; +import Bundle from 'android.os.Bundle'; +import Build from 'android.os.Build'; +import View from 'android.view.View'; +import Color from 'android.graphics.Color'; +import WindowManager from 'android.view.WindowManager'; +import { globalNotificationProgressFinishCallBack } from './index.uts'; +import { ACTION_DOWNLOAD_FINISH } from "./constant.uts" + + +export class TransparentActivity extends Activity { + constructor() { + super() + } + + override onCreate(savedInstanceState : Bundle | null) { + super.onCreate(savedInstanceState) + this.fullScreen(this) + const action = this.getIntent().getAction() + if (action == ACTION_DOWNLOAD_FINISH) { + globalNotificationProgressFinishCallBack() + this.overridePendingTransition(0, 0) + } + + setTimeout(() => { + this.finish() + }, 20) + } + + private fullScreen(activity : Activity) { + if (Build.VERSION.SDK_INT >= 19) { + if (Build.VERSION.SDK_INT >= 21) { + const window = activity.getWindow(); + const decorView = window.getDecorView(); + const option = View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN | View.SYSTEM_UI_FLAG_LAYOUT_STABLE; + decorView.setSystemUiVisibility(option); + window.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS); + window.setStatusBarColor(Color.TRANSPARENT); + } else { + const window = activity.getWindow(); + const attributes = window.getAttributes(); + const flagTranslucentStatus = WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS; + attributes.flags |= flagTranslucentStatus; + window.setAttributes(attributes); + } + } + } +} \ No newline at end of file diff --git a/uni_modules/uni-progress-notification/utssdk/app-android/config.json b/uni_modules/uni-progress-notification/utssdk/app-android/config.json new file mode 100644 index 0000000..7deedfa --- /dev/null +++ b/uni_modules/uni-progress-notification/utssdk/app-android/config.json @@ -0,0 +1,3 @@ +{ + "minSdkVersion": "19" +} \ No newline at end of file diff --git a/uni_modules/uni-progress-notification/utssdk/app-android/constant.uts b/uni_modules/uni-progress-notification/utssdk/app-android/constant.uts new file mode 100644 index 0000000..8652ac4 --- /dev/null +++ b/uni_modules/uni-progress-notification/utssdk/app-android/constant.uts @@ -0,0 +1,2 @@ +export const ACTION_DOWNLOAD_FINISH = "ACTION_DOWNLOAD_FINISH" +export const ACTION_DOWNLOAD_PROGRESS = "ACTION_DOWNLOAD_PROGRESS" \ No newline at end of file diff --git a/uni_modules/uni-progress-notification/utssdk/app-android/index.uts b/uni_modules/uni-progress-notification/utssdk/app-android/index.uts new file mode 100644 index 0000000..48c3f5e --- /dev/null +++ b/uni_modules/uni-progress-notification/utssdk/app-android/index.uts @@ -0,0 +1,150 @@ +import Build from 'android.os.Build'; +import Context from 'android.content.Context'; +import NotificationManager from 'android.app.NotificationManager'; +import NotificationChannel from 'android.app.NotificationChannel'; +import Notification from 'android.app.Notification'; +import Intent from 'android.content.Intent'; +import ComponentName from 'android.content.ComponentName'; +import PendingIntent from 'android.app.PendingIntent'; +import { CreateNotificationProgressOptions, FinishNotificationProgressOptions } from '../interface.uts'; +import { ACTION_DOWNLOAD_FINISH, ACTION_DOWNLOAD_PROGRESS} from "./constant.uts" + + +export { TransparentActivity } from './TransparentActivity.uts'; + + +const DOWNLOAD_PROGRESS_NOTIFICATION_ID : Int = 7890 +const DC_DOWNLOAD_CHANNEL_ID = "下载文件" +const DC_DOWNLOAD_CHANNEL_NAME = "用于显示现在进度的渠道" + + +let notificationBuilder : Notification.Builder | null = null + +let timeId = -1 + +let histroyProgress = 0 + +let isProgress = false + +export let globalNotificationProgressFinishCallBack = () => { } + +export function createNotificationProgress(options : CreateNotificationProgressOptions) : void { + const { content, progress } = options + if (progress == 100) { + return + } + + histroyProgress = progress + if (timeId != -1) { + return + } + + const context = UTSAndroid.getAppContext() as Context + if (!isProgress) { + realCreateNotificationProgress(options.title ?? getAppName(context), content, histroyProgress) + isProgress = true + } else { + timeId = setTimeout(() => { + realCreateNotificationProgress(options.title ?? getAppName(context), content, histroyProgress) + timeId = -1 + }, 1000) + } +} + + +export function cancelNotificationProgress() : void { + const context = UTSAndroid.getAppContext() as Context + const notificationManager = context.getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager + notificationManager.cancel(DOWNLOAD_PROGRESS_NOTIFICATION_ID) + reset() +} + + +function realCreateNotificationProgress(title : string, content : string, progress : number) : void { + const context = UTSAndroid.getAppContext() as Context + const notificationManager = context.getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager + createDownloadChannel(notificationManager) + const builder = createNotificationBuilder(context) + builder.setProgress(100, progress.toInt(), false) + builder.setContentTitle(title) + builder.setContentText(content) + builder.setContentIntent(createPendingIntent(context, ACTION_DOWNLOAD_PROGRESS)); + notificationManager.notify(DOWNLOAD_PROGRESS_NOTIFICATION_ID, builder.build()) +} + + +export function finishNotificationProgress(options : FinishNotificationProgressOptions) { + globalNotificationProgressFinishCallBack = options.callback + const context = UTSAndroid.getAppContext() as Context + const notificationManager = context.getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager + createDownloadChannel(notificationManager) + const builder = createNotificationBuilder(context) + builder.setProgress(0, 0, false) + builder.setContentTitle(options.title ?? getAppName(context)) + builder.setContentText(options.content) + builder.setOngoing(false) + builder.setAutoCancel(true); + builder.setContentIntent(createPendingIntent(context, ACTION_DOWNLOAD_FINISH)); + notificationManager.notify(DOWNLOAD_PROGRESS_NOTIFICATION_ID, builder.build()) + reset() +} + +function reset() { + isProgress = false + notificationBuilder = null + histroyProgress = 0 + if (timeId != -1) { + clearTimeout(timeId) + timeId = -1 + } +} + + + +function createPendingIntent(context : Context, action : string) : PendingIntent { + const i = new Intent(action); + i.setComponent(new ComponentName(context.getPackageName(), "uts.sdk.modules.uniProgressNotification.TransparentActivity")); + let flags = PendingIntent.FLAG_ONE_SHOT; + if (Build.VERSION.SDK_INT >= 23) { + flags = PendingIntent.FLAG_ONE_SHOT | PendingIntent.FLAG_IMMUTABLE; + } + return PendingIntent.getActivity(context, DOWNLOAD_PROGRESS_NOTIFICATION_ID, i, flags); +} + + +function createDownloadChannel(notificationManager : NotificationManager) { + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { + const channel = new NotificationChannel( + DC_DOWNLOAD_CHANNEL_ID, + DC_DOWNLOAD_CHANNEL_NAME, + NotificationManager.IMPORTANCE_LOW + ) + notificationManager.createNotificationChannel(channel) + } +} + +function createNotificationBuilder(context : Context) : Notification.Builder { + if (notificationBuilder == null) { + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { + notificationBuilder = new Notification.Builder(context, DC_DOWNLOAD_CHANNEL_ID) + } else { + notificationBuilder = new Notification.Builder(context) + } + notificationBuilder!!.setSmallIcon(context.getApplicationInfo().icon) + notificationBuilder!!.setOngoing(true) + notificationBuilder!!.setSound(null) + } + return notificationBuilder!! +} + +function getAppName(context : Context) : string { + let appName = "" + try { + const packageManager = context.getPackageManager() + const applicationInfo = packageManager.getApplicationInfo(context.getPackageName(), 0) + appName = packageManager.getApplicationLabel(applicationInfo) as string + } catch (e : Exception) { + e.printStackTrace() + } + return appName +} diff --git a/uni_modules/uni-progress-notification/utssdk/app-android/res/values/notification_progress_styles.xml b/uni_modules/uni-progress-notification/utssdk/app-android/res/values/notification_progress_styles.xml new file mode 100644 index 0000000..cc01105 --- /dev/null +++ b/uni_modules/uni-progress-notification/utssdk/app-android/res/values/notification_progress_styles.xml @@ -0,0 +1,11 @@ + + + + \ No newline at end of file diff --git a/uni_modules/uni-progress-notification/utssdk/app-ios/config.json b/uni_modules/uni-progress-notification/utssdk/app-ios/config.json new file mode 100644 index 0000000..d628124 --- /dev/null +++ b/uni_modules/uni-progress-notification/utssdk/app-ios/config.json @@ -0,0 +1,3 @@ +{ + "deploymentTarget": "9" +} \ No newline at end of file diff --git a/uni_modules/uni-progress-notification/utssdk/app-ios/index.uts b/uni_modules/uni-progress-notification/utssdk/app-ios/index.uts new file mode 100644 index 0000000..e45e1e4 --- /dev/null +++ b/uni_modules/uni-progress-notification/utssdk/app-ios/index.uts @@ -0,0 +1,85 @@ +/** + * 引用 iOS 系统库,示例如下: + * import { UIDevice } from "UIKit"; + * [可选实现,按需引入] + */ + +/* 引入 interface.uts 文件中定义的变量 */ +import { MyApiOptions, MyApiResult, MyApi, MyApiSync } from '../interface.uts'; + +/* 引入 unierror.uts 文件中定义的变量 */ +import { MyApiFailImpl } from '../unierror'; + +/** + * 引入三方库 + * [可选实现,按需引入] + * + * 在 iOS 平台引入三方库有以下两种方式: + * 1、通过引入三方库framework 或者.a 等方式,需要将 .framework 放到 ./Frameworks 目录下,将.a 放到 ./Libs 目录下。更多信息[详见](https://uniapp.dcloud.net.cn/plugin/uts-plugin.html#ios-平台原生配置) + * 2、通过 cocoaPods 方式引入,将要引入的 pod 信息配置到 config.json 文件下的 dependencies-pods 字段下。详细配置方式[详见](https://uniapp.dcloud.net.cn/plugin/uts-ios-cocoapods.html) + * + * 在通过上述任意方式依赖三方库后,使用时需要在文件中 import: + * 示例:import { LottieLoopMode } from 'Lottie' + */ + +/** + * UTSiOS 为平台内置对象,不需要 import 可直接调用其API,[详见](https://uniapp.dcloud.net.cn/uts/utsios.html) + */ + +/** + * 异步方法 + * + * uni-app项目中(vue/nvue)调用示例: + * 1、引入方法声明 import { myApi } from "@/uni_modules/uts-api" + * 2、方法调用 + * myApi({ + * paramA: false, + * complete: (res) => { + * console.log(res) + * } + * }); + * + */ +export const myApi : MyApi = function (options : MyApiOptions) { + + if (options.paramA == true) { + // 返回数据 + const res : MyApiResult = { + fieldA: 85, + fieldB: true, + fieldC: 'some message' + }; + options.success?.(res); + options.complete?.(res); + + } else { + // 返回错误 + let failResult = new MyApiFailImpl(9010001); + options.fail?.(failResult) + options.complete?.(failResult) + } + +} + +/** + * 同步方法 + * + * uni-app项目中(vue/nvue)调用示例: + * 1、引入方法声明 import { myApiSync } from "@/uni_modules/uts-api" + * 2、方法调用 + * myApiSync(true); + * + */ +export const myApiSync : MyApiSync = function (paramA : boolean) : MyApiResult { + // 返回数据,根据插件功能获取实际的返回值 + const res : MyApiResult = { + fieldA: 85, + fieldB: paramA, + fieldC: 'some message' + }; + return res; +} + +/** + * 更多插件开发的信息详见:https://uniapp.dcloud.net.cn/plugin/uts-plugin.html + */ diff --git a/uni_modules/uni-progress-notification/utssdk/interface.uts b/uni_modules/uni-progress-notification/utssdk/interface.uts new file mode 100644 index 0000000..0538f13 --- /dev/null +++ b/uni_modules/uni-progress-notification/utssdk/interface.uts @@ -0,0 +1,137 @@ +export type uni = { + /** + * createNotificationProgress() + * @description + * 创建通知栏下载进度消息 + * @param {CreateNotificationProgressOptions} + * @return {void} + * @uniPlatform { + * "app": { + * "android": { + * "osVer": "4.4", + * "uniVer": "3.9+", + * "unixVer": "3.9+" + * }, + * "ios": { + * "osVer": "x", + * "uniVer": "x", + * "unixVer": "x" + * } + * } + * } + * @example + ```typescript + uni.createNotificationProgress({ + title: "正在下载升级包", + content: "进度 50%", + progress: 50 + } + ``` + */ + createNotificationProgress : (options : CreateNotificationProgressOptions) => void, + /** + * finishNotificationProgress() + * @description + * 通知栏显示下载完成,并且传入点击通知栏消息的回调。 + * @param {FinishNotificationProgressOptions} + * @return {void} + * @uniPlatform { + * "app": { + * "android": { + * "osVer": "4.4", + * "uniVer": "3.9+", + * "unixVer": "3.9+" + * }, + * "ios": { + * "osVer": "x", + * "uniVer": "x", + * "unixVer": "x" + * } + * } + * } + * @example + ```typescript + uni.finishNotificationProgress({ + title: "安装升级包", + content: "下载完成。", + callback: () => { + uni.installApk({ + filePath: e.tempFilePath, + complete(res) { + console.log(res); + } + }) + } + } + ``` + */ + finishNotificationProgress : (options: FinishNotificationProgressOptions) => void, + /** + * cancelNotificationProgress() + * @description + * 取消通知消息显示 + * @param {void} + * @return {void} + * @uniPlatform { + * "app": { + * "android": { + * "osVer": "4.4", + * "uniVer": "3.9+", + * "unixVer": "3.9+" + * }, + * "ios": { + * "osVer": "x", + * "uniVer": "x", + * "unixVer": "x" + * } + * } + * } + * @example + ```typescript + uni.cancelNotificationProgress() + ``` + */ + cancelNotificationProgress : () => void +} + +export type CreateNotificationProgressOptions = { + /** + * 通知标题 + * @defaultValue 应用名称 + */ + title ?: string | null + /** + * 通知内容 + */ + content : string, + /** + * 进度 + */ + progress : number +} + + +export type FinishNotificationProgressOptions = { + /** + * 通知标题 + * @defaultValue 应用名称 + */ + title ?: string | null + /** + * 通知内容 + */ + content : string, + /** + * 点击通知消息回调 + */ + callback : () => void +} + + +export type CreateNotificationProgress = (options : CreateNotificationProgressOptions) => void; + + +export type CancelNotificationProgress = () => void; + + +export type FinishNotificationProgress = (options: FinishNotificationProgressOptions) => void \ No newline at end of file diff --git a/uni_modules/uni-progress-notification/utssdk/unierror.uts b/uni_modules/uni-progress-notification/utssdk/unierror.uts new file mode 100644 index 0000000..e69de29 -- GitLab