提交 c5c49cec 编写于 作者: dcloud_wdl's avatar dcloud_wdl

Merge remote-tracking branch 'origin/alpha'

......@@ -20,7 +20,8 @@
<button @tap="testonMemoryWarning">开启内存不足告警监听</button>
<button @tap="testoffMemoryWarning">关闭内存不足告警监听</button>
<button @tap="getLocationTest" style="width: 100%;">获取定位</button>
<button type="default" @click="handleInstallApk">安装apk</button>
<button type="default" @click="handleInstallApk">安装apk</button>
<button type="default" @click="handleShowNotificationProgress">显示通知栏下载进度</button>
</view>
</template>
......@@ -28,7 +29,13 @@
<script>
import {
installApk
} from "@/uni_modules/uni-installApk"
} from "@/uni_modules/uni-installApk"
let pre = 0
let speed = 1
let preTime = 0
let isBegin = false
export default {
data() {
......@@ -290,7 +297,64 @@
console.log(res);
}
})
},
},
handleShowNotificationProgress(){
const task = uni.downloadFile({
url: "http://192.168.213.108:8080/test.apk",
success(e) {
console.log("success111 :", e);
uni.finishNotificationProgress({
title: "安装升级包",
content: "下载完成。",
callback: () => {
uni.installApk({
filePath: e.tempFilePath,
complete(res) {
console.log(res);
}
})
}
})
},
fail(e) {
console.log("fail : ", e);
}
});
task.onProgressUpdate((res) => {
const sd = this.calculateSpeed(res.totalBytesWritten)
const remian = ((res.totalBytesExpectedToWrite - res.totalBytesWritten) / sd).toFixed(0)
const remianStr = sd != 1 ? "剩余时间 " + remian + "" : "正在计算"
uni.createNotificationProgress({
title: "正在下载升级包",
content: remianStr,
progress: res.progress
})
if (res.progress == 100) {
pre = 0
speed = 1
preTime = Date.now()
isBegin = false
}
})
},
calculateSpeed(current) {
//简略的计算下载速度
if (!isBegin) {
preTime = Date.now()
isBegin = true
return speed
}
const currentTime = Date.now()
if (currentTime - preTime > 1000) {
speed = current - pre
pre = current
preTime = currentTime
}
return speed
}
}
}
</script>
......@@ -321,4 +385,4 @@
font-size: 36rpx;
color: #8f8f94;
}
</style>
\ No newline at end of file
</style>
import { ExitOptions, ExitSuccess, ExitCompleteCallback, Exit } from "../interface.uts"
import { ExitOptions, ExitSuccess, Exit } from "../interface.uts"
/**
......
import { ExitOptions, ExitFailCallback, ExitCompleteCallback, Exit} from "../interface.uts"
import { ExitOptions, Exit} from "../interface.uts"
import { ExitFailImpl } from "../unierror.uts"
......
......@@ -25,6 +25,7 @@ export const UniErrors:Map<number, string> = new Map([
* ExitFail的实现
*/
export class ExitFailImpl extends UniError implements IExitError {
override errCode: ExitErrorCode
constructor (
errCode: ExitErrorCode
) {
......
......@@ -7,7 +7,7 @@ export type GetAppBaseInfoOptions = {
export type GetAppBaseInfoResult = {
/**
* manifest.json 中应用appid,即DCloud appid。
* manifest.json 中应用appid,即DCloud appid。
*/
appId?: string,
/**
......@@ -23,11 +23,11 @@ export type GetAppBaseInfoResult = {
*/
appVersionCode?: string,
/**
* 应用设置的语言en、zh-Hans、zh-Hant、fr、es
* 应用设置的语言en、zh-Hans、zh-Hant、fr、es
*/
appLanguage?: string,
/**
* 应用设置的语言
* 应用设置的语言
*/
language?: string,
/**
......@@ -36,8 +36,8 @@ export type GetAppBaseInfoResult = {
*/
version?: string,
/**
* 应用资源(wgt)的版本名称。
*
* 应用资源(wgt)的版本名称。
*
* @uniPlatform {
* "app": {
* "android": {
......@@ -55,8 +55,8 @@ export type GetAppBaseInfoResult = {
*/
appWgtVersion?: string,
/**
* 小程序宿主语言
*
* 小程序宿主语言
*
* @uniPlatform {
* "app": {
* "android": {
......@@ -75,7 +75,7 @@ export type GetAppBaseInfoResult = {
hostLanguage?: string,
/**
* App、小程序宿主版本。
*
*
* @uniPlatform {
* "app": {
* "android": {
......@@ -93,8 +93,8 @@ export type GetAppBaseInfoResult = {
*/
hostVersion?: string,
/**
* 小程序宿主名称
*
* 小程序宿主名称
*
* @uniPlatform {
* "app": {
* "android": {
......@@ -112,8 +112,8 @@ export type GetAppBaseInfoResult = {
*/
hostName?: string,
/**
* 小程序宿主包名
*
* 小程序宿主包名
*
* @uniPlatform {
* "app": {
* "android": {
......@@ -131,8 +131,8 @@ export type GetAppBaseInfoResult = {
*/
hostPackageName?: string,
/**
* uni小程序SDK版本、小程序客户端基础库版本
*
* uni小程序SDK版本、小程序客户端基础库版本
*
* @uniPlatform {
* "app": {
* "android": {
......@@ -151,7 +151,7 @@ export type GetAppBaseInfoResult = {
hostSDKVersion?: string,
/**
* 系统当前主题,取值为light或dark。微信小程序全局配置"darkmode":true时才能获取,否则为 undefined (不支持小游戏)
*
*
* @uniPlatform {
* "app": {
* "android": {
......@@ -203,7 +203,7 @@ export type GetAppBaseInfo = (options?: GetAppBaseInfoOptions | null) => GetAppB
export interface Uni {
/**
* GetAppBaseInfo(Object object)
* @description
* @description
* 获取app基本信息
* @param {GetAppBaseInfoOptions} options [options=包含所有字段的过滤对象] 过滤的字段对象, 不传参数默认为获取全部字段。
* @return {object}
......@@ -218,7 +218,7 @@ export interface Uni {
* "ios": {
* "osVer": "9.0",
* "uniVer": "√",
* "unixVer": "3.9+"
* "unixVer": "x"
* }
* }
* }
......
......@@ -19,36 +19,36 @@ export type GetDeviceInfoResult = {
*/
deviceId?: string,
/**
* 设备型号
* 设备型号
*/
model?: string,
/**
* 设备型号
* 设备型号
*/
deviceModel?: string,
/**
* 设备类型phone、pad、pc
* 设备类型phone、pad、pc
*/
deviceType?: string,
/**
* 设备方向 竖屏 portrait、横屏 landscape
* 设备方向 竖屏 portrait、横屏 landscape
*/
deviceOrientation?: string,
/**
* 设备像素比
* 设备像素比
*/
devicePixelRatio?: string,
/**
* 操作系统及版本
* 操作系统及版本
*/
system?: string,
/**
* 客户端平台
* 客户端平台
*/
platform?: string,
/**
* oaid标识 Android专有
*
*
* @uniPlatform {
* "app": {
* "android": {
......@@ -75,7 +75,7 @@ export type GetDeviceInfoResult = {
isSimulator?: boolean,
/**
* adb是否开启
*
*
* @uniPlatform {
* "app": {
* "android": {
......@@ -94,7 +94,7 @@ export type GetDeviceInfoResult = {
isUSBDebugging?: boolean,
/**
* idfa标识 iOS专有
*
*
* @uniPlatform {
* "app": {
* "android": {
......@@ -105,7 +105,7 @@ export type GetDeviceInfoResult = {
* "ios": {
* "osVer": "9.0",
* "uniVer": "√",
* "unixVer": ""
* "unixVer": "x"
* }
* }
* }
......@@ -126,7 +126,7 @@ export type GetDeviceInfo = (options?: GetDeviceInfoOptions | null) => GetDevice
export interface Uni {
/**
* GetDeviceInfo(Object object)
* @description
* @description
* 获取设备信息
* @param {GetDeviceInfoOptions} options [options=包含所有字段的过滤对象] 过滤的字段对象, 不传参数默认为获取全部字段。
* @return {object}
......@@ -141,7 +141,7 @@ export interface Uni {
* "ios": {
* "osVer": "9.0",
* "uniVer": "√",
* "unixVer": "3.9+"
* "unixVer": "x"
* }
* }
* }
......
......@@ -34,7 +34,7 @@ export type GetSystemSetting = () => GetSystemSettingResult
export interface Uni {
/**
* GetSystemSetting()
* @description
* @description
* 获取系统设置
* @return {object}
* @tutorial https://uniapp.dcloud.net.cn/api/system/getsystemsetting.html
......@@ -48,7 +48,7 @@ export interface Uni {
* "ios": {
* "osVer": "9.0",
* "uniVer": "√",
* "unixVer": "3.9+"
* "unixVer": "x"
* }
* }
* }
......
......@@ -91,7 +91,7 @@ interface Uni {
* "ios": {
* "osVer": "9.0",
* "uniVer": "3.6.11",
* "unixVer": "3.9.0"
* "unixVer": "x"
* }
* }
* }
......@@ -118,7 +118,7 @@ interface Uni {
* "ios": {
* "osVer": "9.0",
* "uniVer": "3.6.11",
* "unixVer": "3.9.0"
* "unixVer": "x"
* }
* }
* }
......
## 1.0.4(2023-12-08)
兼容asset目录文件的处理
## 1.0.3(2023-10-27)
遵循UniError规范
## 1.0.2(2023-10-27)
......
{
"id": "uni-installApk",
"displayName": "uni-installApk",
"version": "1.0.3",
"version": "1.0.4",
"description": "uni-installApk",
"keywords": [
"uni-installApk"
......
import { InstallApkOptions, InstallApkSuccess } from "../interface.uts"
import { InstallApkOptions, InstallApkSuccess } from "../interface.uts"
import { InstallApkFailImpl } from "../unierror.uts"
import Intent from 'android.content.Intent';
import Build from 'android.os.Build';
......@@ -6,34 +6,78 @@ import File from 'java.io.File';
import FileProvider from 'androidx.core.content.FileProvider';
import Context from 'android.content.Context';
import Uri from 'android.net.Uri';
import FileOutputStream from 'java.io.FileOutputStream';
export function installApk(options : InstallApkOptions) : void {
const context = UTSAndroid.getAppContext() as Context
const filePath = UTSAndroid.convert2AbsFullPath(options.filePath)
const apkFile = new File(filePath)
if (!apkFile.exists() && !apkFile.isFile()) {
let error = new InstallApkFailImpl(1300002);
options.fail?.(error)
options.complete?.(error)
return
}
const intent = new Intent()
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
intent.setAction(Intent.ACTION_VIEW)
if (Build.VERSION.SDK_INT >= 24) {
const authority = context.getPackageName() + ".dc.fileprovider"
const apkUri = FileProvider.getUriForFile(context, authority, apkFile)
intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
intent.setDataAndType(apkUri, "application/vnd.android.package-archive");
} else {
intent.setDataAndType(Uri.fromFile(apkFile), "application/vnd.android.package-archive");
}
context.startActivity(intent)
const success : InstallApkSuccess = {
errMsg: "success"
}
options.success?.(success)
options.complete?.(success)
}
\ No newline at end of file
const context = UTSAndroid.getAppContext() as Context
var filePath = UTSAndroid.convert2AbsFullPath(options.filePath)
var apkFile : File | null = null;
if (filePath.startsWith("/android_asset/")) {
filePath = filePath.replace("/android_asset/", "")
apkFile = copyAssetFileToPrivateDir(context, filePath)
} else {
apkFile = new File(filePath)
}
if (apkFile != null && !apkFile.exists() && !apkFile.isFile()) {
let error = new InstallApkFailImpl(1300002);
options.fail?.(error)
options.complete?.(error)
return
}
const intent = new Intent()
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
intent.setAction(Intent.ACTION_VIEW)
if (Build.VERSION.SDK_INT >= 24) {
const authority = context.getPackageName() + ".dc.fileprovider"
const apkUri = FileProvider.getUriForFile(context, authority, apkFile!!)
intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
intent.setDataAndType(apkUri, "application/vnd.android.package-archive");
} else {
intent.setDataAndType(Uri.fromFile(apkFile!!), "application/vnd.android.package-archive");
}
context.startActivity(intent)
const success : InstallApkSuccess = {
errMsg: "success"
}
options.success?.(success)
options.complete?.(success)
}
function copyAssetFileToPrivateDir(context : Context, fileName : string) : File | null {
try {
const destPath = context.getCacheDir().getPath() + "/apks/" + fileName
const outFile = new File(destPath)
const parentFile = outFile.getParentFile()
if (parentFile != null) {
if (!parentFile.exists()) {
parentFile.mkdirs()
}
}
if (!outFile.exists()) {
outFile.createNewFile()
}
const inputStream = context.getAssets().open(fileName)
const outputStream = new FileOutputStream(outFile)
let buffer = new ByteArray(1024);
do {
let len = inputStream.read(buffer);
if (len == -1) {
break;
}
outputStream.write(buffer, 0, len)
} while (true)
inputStream.close()
outputStream.close()
return outFile
} catch (e : Exception) {
e.printStackTrace()
}
return null
}
declare namespace UniNamespace {
interface InstallApkSuccess {
/**
* 安装成功消息
*/
errMsg : string
}
type InstallApkErrorCode = 1300002
interface InstallApkFail {
errCode : InstallApkErrorCode
}
type InstallApkComplete = any
type InstallApkSuccessCallback = (res : InstallApkSuccess) => void
type InstallApkFailCallback = (err : InstallApkFail) => void
type InstallApkCompleteCallback = (res : InstallApkComplete) => void
interface InstallApkOptions {
/**
* apk文件地址
*/
filePath : string,
/**
* 接口调用成功的回调函数
* @defaultValue null
*/
success ?: InstallApkSuccessCallback | null,
/**
* 接口调用失败的回调函数
* @defaultValue null
*/
fail ?: InstallApkFailCallback | null,
/**
* 接口调用结束的回调函数(调用成功、失败都会执行)
* @defaultValue null
*/
complete ?: InstallApkCompleteCallback | null
}
}
declare interface Uni {
/**
* installApk()
* @description
* 安装apk
* @param {InstallApkOptions}
* @return {void}
* @uniPlatform {
* "app": {
* "android": {
* "osVer": "4.4",
* "uniVer": "3.94+",
* "unixVer": "3.94+"
* },
* "ios": {
* "osVer": "x",
* "uniVer": "x",
* "unixVer": "x"
* }
* }
* }
* @example
```typescript
uni.installApk({
filePath: "/xx/xx/xx.apk",
complete: (res: any) => {
console.log("complete => " + JSON.stringify(res));
}
});
```
*/
installApk(options : UniNamespace.InstallApkOptions) : void
}
import { UTSAndroid } from "io.dcloud.uts"
import { OnMemoryWarning, OffMemoryWarning } from "../interface.uts"
import { OnMemoryWarning, OffMemoryWarning, MemoryWarningCallback, MemoryWarningCallbackResult } from "../interface.uts"
let listeners: UTSCallback[] = []
let listeners: MemoryWarningCallback[] = []
const onAppTrimMemoryListener = (ret: number) => {
listeners.forEach(listener => {
let res = {
level:ret
}
listener(res)
let res: MemoryWarningCallbackResult = {
level:ret
}
listener(res)
})
}
@Suppress("DEPRECATION")
export const onMemoryWarning : OnMemoryWarning = function (callback: UTSCallback) {
export const onMemoryWarning : OnMemoryWarning = function (callback: MemoryWarningCallback) {
if (listeners.length == 0) {
// 仅首次执行底层的实际监听
UTSAndroid.onAppTrimMemory(onAppTrimMemoryListener)
......@@ -28,7 +28,7 @@ export const onMemoryWarning : OnMemoryWarning = function (callback: UTSCallbac
@Suppress("DEPRECATION")
export const offMemoryWarning : OffMemoryWarning = function (callback: UTSCallback | null) {
export const offMemoryWarning : OffMemoryWarning = function (callback: MemoryWarningCallback | null) {
if(callback == null){
// 清除全部回调
......
import { NotificationCenter } from 'Foundation';
import { UIApplication } from "UIKit"
import { Selector } from "ObjectiveC"
import { OnMemoryWarning, OffMemoryWarning } from "../interface.uts"
import { OnMemoryWarning, OffMemoryWarning, MemoryWarningCallback, MemoryWarningCallbackResult } from "../interface.uts"
class MemoryWarningTool {
static listeners: UTSCallback[] = []
static listener: MemoryWarningCallback | null = null
// 监听内存警告
static listenMemoryWarning(callback: UTSCallback) {
static listenMemoryWarning(callback: MemoryWarningCallback) {
// 只有首次才需要注册监听事件
if (this.listeners.length == 0) {
if (this.listener == null) {
// 注册监听内存警告通知事件及设置回调方法
// target-action 回调方法需要通过 Selector("方法名") 构建
const method = Selector("receiveMemoryWarning")
NotificationCenter.default.addObserver(this, selector = method, name = UIApplication.didReceiveMemoryWarningNotification, object = null)
}
this.listeners.push(callback)
this.listener = callback
}
// 内存警告回调的方法
// target-action 的方法前需要添加 @objc 前缀
@objc static receiveMemoryWarning() {
// 触发回调
this.listeners.forEach(listener => {
listener({})
})
let res: MemoryWarningCallbackResult = {
level: 0
};
this.listener?.(res);
}
// 移除监听事件
static removeListen(callback: UTSCallback | null) {
// 移除所有监听
if (callback == null) {
this.listeners = []
// 移除监听事件
NotificationCenter.default.removeObserver(this)
return
}
// 清除指定回调
const index = this.listeners.indexOf(callback!)
if (index > -1) {
this.listeners.splice(index, 1)
}
static removeListen(callback: MemoryWarningCallback | null) {
this.listener = null;
NotificationCenter.default.removeObserver(this)
}
}
// 开启监听内存警告
export const onMemoryWarning : OnMemoryWarning = function (callback: UTSCallback) {
export const onMemoryWarning : OnMemoryWarning = function (callback: MemoryWarningCallback) {
MemoryWarningTool.listenMemoryWarning(callback)
}
// 关闭监听内存警告
export const offMemoryWarning : OffMemoryWarning = function (callback: UTSCallback | null) {
export const offMemoryWarning : OffMemoryWarning = function (callback: MemoryWarningCallback | null) {
MemoryWarningTool.removeListen(callback)
}
\ No newline at end of file
}
declare namespace UniNamespace {
interface MemoryWarningCallbackResult {
/**
* 内存警告等级(仅安卓平台有效,iOS始终是0)
*/
level: number
}
/**
* uni.onMemoryWarning/uni.offMemoryWarning回调函数定义
*/
type MemoryWarningCallback = (res: MemoryWarningCallbackResult) => void
type OnMemoryWarning = (callback: MemoryWarningCallback) => void
type OffMemoryWarning = (callback : MemoryWarningCallback | null) => void
}
declare interface Uni {
/**
* 开启监听内存警告
*
* @param {MemoryWarningCallback} callback
* @tutorial https://uniapp.dcloud.net.cn/api/system/memory.html#onmemorywarning
* @uniPlatform {
* "app": {
* "android": {
* "osVer": "4.4.4",
* "uniVer": "3.7.7",
* "unixVer": "3.9.0"
* },
* "ios": {
* "osVer": "9.0",
* "uniVer": "3.7.7",
* "unixVer": "3.9.0"
* }
* }
* }
* @uniVersion 3.7.7
* @uniVueVersion 2,3 //支持的vue版本
* @autotest { expectCallback: true }
*/
onMemoryWarning(callback: UniNamespace.MemoryWarningCallback) : void,
/**
* 取消监听内存不足告警事件
*
* @param {MemoryWarningCallback} callback
* @tutorial https://uniapp.dcloud.net.cn/api/system/memory.html#offmemorywarning
* @uniPlatform {
* "app": {
* "android": {
* "osVer": "4.4.4",
* "uniVer": "3.7.7",
* "unixVer": "3.9.0"
* },
* "ios": {
* "osVer": "9.0",
* "uniVer": "3.7.7",
* "unixVer": "3.9.0"
* }
* }
* }
* @uniVersion 3.7.7
* @uniVueVersion 2,3 //支持的vue版本
* @autotest { expectCallback: true }
*/
offMemoryWarning(callback : UniNamespace.MemoryWarningCallback | null) : void
}
/**
* uni.onMemoryWarning/uni.offMemoryWarning回调参数
*/
export type MemoryWarningCallbackResult = {
/**
* 内存警告等级(仅安卓平台有效,iOS始终是0)
*/
level: number
}
export type OnMemoryWarning = (callback: UTSCallback) => void
/**
* uni.onMemoryWarning/uni.offMemoryWarning回调函数定义
*/
export type MemoryWarningCallback = (res: MemoryWarningCallbackResult) => void
export type OnMemoryWarning = (callback: MemoryWarningCallback) => void
export type OffMemoryWarning = (callback : UTSCallback | null) => void
export type OffMemoryWarning = (callback : MemoryWarningCallback | null) => void
export interface Uni {
/**
* 开启监听内存警告
*
* @param {UTSCallback} callback
*
* @param {MemoryWarningCallback} callback
* @tutorial https://uniapp.dcloud.net.cn/api/system/memory.html#onmemorywarning
* @uniPlatform {
* "app": {
......@@ -19,7 +33,7 @@ export interface Uni {
* "ios": {
* "osVer": "9.0",
* "uniVer": "3.7.7",
* "unixVer": "3.9.0"
* "unixVer": "x"
* }
* }
* }
......@@ -27,11 +41,11 @@ export interface Uni {
* @uniVueVersion 2,3 //支持的vue版本
* @autotest { expectCallback: true }
*/
onMemoryWarning(callback: UTSCallback) : void,
onMemoryWarning(callback: MemoryWarningCallback) : void,
/**
* 取消监听内存不足告警事件
*
* @param {UTSCallback} callback
*
* @param {MemoryWarningCallback} callback
* @tutorial https://uniapp.dcloud.net.cn/api/system/memory.html#offmemorywarning
* @uniPlatform {
* "app": {
......@@ -43,7 +57,7 @@ export interface Uni {
* "ios": {
* "osVer": "9.0",
* "uniVer": "3.7.7",
* "unixVer": "3.9.0"
* "unixVer": "x"
* }
* }
* }
......@@ -51,5 +65,5 @@ export interface Uni {
* @uniVueVersion 2,3 //支持的vue版本
* @autotest { expectCallback: true }
*/
offMemoryWarning(callback : UTSCallback | null) : void
}
\ No newline at end of file
offMemoryWarning(callback : MemoryWarningCallback | null) : void
}
......@@ -40,21 +40,21 @@ export type RequestOptions<T> = {
dataType?: string | null,
/**
* 设置响应的数据类型。
*
*
* @deprecated 不支持
* @autodoc false
*/
responseType?: string | null,
/**
* 验证 ssl 证书
*
*
* @deprecated 不支持
* @autodoc false
*/
sslVerify?: boolean | null,
/**
* 跨域请求时是否携带凭证(cookies)
*
*
* @uniPlatform {
* "app": {
* "android": {
......@@ -69,7 +69,7 @@ export type RequestOptions<T> = {
* }
* }
* }
*
*
*/
withCredentials?: boolean | null,
/**
......@@ -121,7 +121,7 @@ export type RequestSuccess<T> = {
* - PUT PUT方法用有效载荷请求替换目标资源的所有当前表示。
* - PATCH PATCH方法用于对资源应用部分修改。
* - DELETE DELETE方法删除指定的资源。
* - HEAD HEAD方法请求一个与GET请求的响应相同的响应,但没有响应体。
* - HEAD HEAD方法请求一个与GET请求的响应相同的响应,但没有响应体。
* - OPTIONS OPTIONS 方法用于描述目标资源的通信选项。
*/
export type RequestMethod = "GET" | "POST" | "PUT" | "PATCH" | "DELETE" | "HEAD" | "OPTIONS";
......@@ -153,9 +153,9 @@ export type RequestCompleteCallback = (option: any) => void;
export interface RequestTask {
/**
* abort()
* @description
* @description
* 中断网络请求。
* @param {void}
* @param {void}
* @return {void}
* @tutorial https://uniapp.dcloud.net.cn/api/request/request.html#request
* @uniPlatform {
......@@ -168,7 +168,7 @@ export interface RequestTask {
* "ios": {
* "osVer": "9.0",
* "uniVer": "√",
* "unixVer": "3.9+"
* "unixVer": "x"
* }
* }
* }
......@@ -307,9 +307,9 @@ export type UploadFileProgressUpdateCallback = (result: OnProgressUpdateResult)
export interface UploadTask {
/**
* abort()
* @description
* @description
* 中断上传任务。
* @param {void}
* @param {void}
* @return {void}
* @tutorial https://uniapp.dcloud.net.cn/api/request/network-file.html#uploadfile
* @uniPlatform {
......@@ -338,7 +338,7 @@ export interface UploadTask {
abort(): void,
/**
* onProgressUpdate()
* @description
* @description
* 监听上传进度变化。
* @param {UploadFileProgressUpdateCallback} callback
* @return {void}
......@@ -450,9 +450,9 @@ export type DownloadFileProgressUpdateCallback = (result: OnProgressDownloadResu
export interface DownloadTask {
/**
* abort()
* @description
* @description
* 中断下载任务。
* @param {void}
* @param {void}
* @return {void}
* @tutorial https://uniapp.dcloud.net.cn/api/request/network-file.html#downloadfile
* @uniPlatform {
......@@ -481,7 +481,7 @@ export interface DownloadTask {
abort(): void,
/**
* onProgressUpdate()
* @description
* @description
* 监听下载进度变化。
* @param {DownloadFileProgressUpdateCallback} callback
* @return {void}
......@@ -516,10 +516,10 @@ export interface DownloadTask {
export interface Uni {
/**
* Request()
* @description
* @description
* 发起网络请求。
* @param {RequestOptions} options
* @return {RequestTask | null}
* @return {RequestTask | null}
* @tutorial https://uniapp.dcloud.net.cn/api/request/request.html
* @uniPlatform {
* "app": {
......@@ -531,7 +531,7 @@ export interface Uni {
* "ios": {
* "osVer": "9.0",
* "uniVer": "√",
* "unixVer": "3.9+"
* "unixVer": "x"
* }
* }
* }
......@@ -567,7 +567,7 @@ export interface Uni {
request<T>(param: RequestOptions<T>): RequestTask | null;
/**
* UploadFile()
* @description
* @description
* 将本地资源上传到开发者服务器。
* @param {UploadFileOptions} options
* @return {UploadTask | null}
......@@ -604,7 +604,7 @@ export interface Uni {
uploadFile(options: UploadFileOptions): UploadTask | null;
/**
* DownloadFile()
* @description
* @description
* 下载文件资源到本地,客户端直接发起一个 HTTP GET 请求,返回文件的本地临时路径。
* @param {DownloadFileOptions} options
* @return {DownloadTask | null}
......
......@@ -63,9 +63,9 @@ export type ShowToastOptions = {
/**
* uni.showToast函数定义
* 弹出toast
*
* @param {ShowToastOptions} options
* 弹出toast
*
* @param {ShowToastOptions} options
* @tutorial https://uniapp.dcloud.net.cn/api/ui/prompt.html#showtoast
* @uniPlatform {
* "app": {
......@@ -77,7 +77,7 @@ export type ShowToastOptions = {
* "ios": {
* "osVer": "9.0",
* "uniVer": "√",
* "unixVer": "3.9.0"
* "unixVer": "x"
* }
* }
* }
......@@ -87,7 +87,7 @@ export type ShowToast = (options: ShowToastOptions) => void
/**
* uni.hideToast函数定义
* 隐藏toast
*
*
* @tutorial https://uniapp.dcloud.net.cn/api/ui/prompt.html#hidetoast
* @uniPlatform {
* "app": {
......@@ -99,7 +99,7 @@ export type ShowToast = (options: ShowToastOptions) => void
* "ios": {
* "osVer": "9.0",
* "uniVer": "√",
* "unixVer": "3.9.0"
* "unixVer": "x"
* }
* }
* }
......@@ -155,8 +155,8 @@ export type ShowLoadingOptions = {
/**
* uni.showLoading函数定义
* 弹出loading
*
* @param {ShowLoadingOptions} options
*
* @param {ShowLoadingOptions} options
* @tutorial https://uniapp.dcloud.net.cn/api/ui/prompt.html#showloading
* @uniPlatform {
* "app": {
......@@ -168,7 +168,7 @@ export type ShowLoadingOptions = {
* "ios": {
* "osVer": "9.0",
* "uniVer": "√",
* "unixVer": "3.9.0"
* "unixVer": "x"
* }
* }
* }
......@@ -178,7 +178,7 @@ export type ShowLoading = (options: ShowLoadingOptions) => void
/**
* uni.hideLoading函数定义
* 隐藏loading
*
*
* @tutorial https://uniapp.dcloud.net.cn/api/ui/prompt.html#hideloading
* @uniPlatform {
* "app": {
......@@ -190,11 +190,11 @@ export type ShowLoading = (options: ShowLoadingOptions) => void
* "ios": {
* "osVer": "9.0",
* "uniVer": "√",
* "unixVer": "3.9.0"
* "unixVer": "x"
* }
* }
* }
*
*
*/
export type HideLoading = () => void
......@@ -286,10 +286,10 @@ export type ShowModalOptions = {
/**
* uni.showModal 函数定义
*
*
* 弹出modal
*
* @param {ShowModalOptions} options
*
* @param {ShowModalOptions} options
* @tutorial https://uniapp.dcloud.net.cn/api/ui/prompt.html#showmodal
* @uniPlatform {
* "app": {
......@@ -301,7 +301,7 @@ export type ShowModalOptions = {
* "ios": {
* "osVer": "9.0",
* "uniVer": "√",
* "unixVer": "3.9.0"
* "unixVer": "x"
* }
* }
* }
......@@ -390,10 +390,10 @@ export type ShowActionSheetOptions = {
/**
* uni.showActionSheet函数定义
*
*
* 弹出actionSheet
*
* @param {ShowActionSheetOptions} options
*
* @param {ShowActionSheetOptions} options
* @tutorial https://uniapp.dcloud.net.cn/api/ui/prompt.html#showactionsheet
* @uniPlatform {
* "app": {
......@@ -405,7 +405,7 @@ export type ShowActionSheetOptions = {
* "ios": {
* "osVer": "9.0",
* "uniVer": "√",
* "unixVer": "3.9.0"
* "unixVer": "x"
* }
* }
* }
......@@ -438,7 +438,7 @@ export interface Uni {
* "ios": {
* "osVer": "9.0",
* "uniVer": "√",
* "unixVer": "3.9.0"
* "unixVer": "x"
* }
* }
* }
......@@ -461,7 +461,7 @@ export interface Uni {
* "ios": {
* "osVer": "9.0",
* "uniVer": "√",
* "unixVer": "3.9.0"
* "unixVer": "x"
* }
* }
* }
......@@ -490,7 +490,7 @@ export interface Uni {
* "ios": {
* "osVer": "9.0",
* "uniVer": "√",
* "unixVer": "3.9.0"
* "unixVer": "x"
* }
* }
* }
......@@ -520,7 +520,7 @@ export interface Uni {
* "ios": {
* "osVer": "9.0",
* "uniVer": "√",
* "unixVer": "3.9.0"
* "unixVer": "x"
* }
* }
* }
......@@ -556,7 +556,7 @@ export interface Uni {
* "ios": {
* "osVer": "9.0",
* "uniVer": "√",
* "unixVer": "3.9.0"
* "unixVer": "x"
* }
* }
* }
......@@ -588,7 +588,7 @@ export interface Uni {
* "ios": {
* "osVer": "9.0",
* "uniVer": "√",
* "unixVer": "3.9.0"
* "unixVer": "x"
* }
* }
* }
......
{
"id": "uni-push",
"displayName": "uni-push",
"version": "1.0.0",
"description": "uni-push",
"keywords": [
"uni-push"
],
"repository": "",
"engines": {
"HBuilderX": "^3.6.8"
},
"dcloudext": {
"type": "uts",
"sale": {
"regular": {
"price": "0.00"
},
"sourcecode": {
"price": "0.00"
}
},
"contact": {
"qq": ""
},
"declaration": {
"ads": "",
"data": "",
"permissions": ""
},
"npmurl": ""
},
"uni_modules": {
"dependencies": [],
"uni-ext-api": {
"uni": {
"getPushClientId": {
"name": "getPushClientId",
"app": {
"js": false,
"kotlin": true,
"swift": false
}
},
"onPushMessage": {
"name": "onPushMessage",
"app": {
"js": false,
"kotlin": true,
"swift": false
}
},
"offPushMessage": {
"name": "offPushMessage",
"app": {
"js": false,
"kotlin": true,
"swift": false
}
},
"getChannelManager": {
"name": "getChannelManager",
"app": {
"js": false,
"kotlin": true,
"swift": false
}
},
"createPushMessage": {
"name": "createPushMessage",
"app": {
"js": false,
"kotlin": true,
"swift": false
}
}
}
},
"encrypt": [],
"platforms": {
"cloud": {
"tcb": "u",
"aliyun": "u"
},
"client": {
"Vue": {
"vue2": "u",
"vue3": "u"
},
"App": {
"app-android": "u",
"app-ios": "u"
},
"H5-mobile": {
"Safari": "u",
"Android Browser": "u",
"微信浏览器(Android)": "u",
"QQ浏览器(Android)": "u"
},
"H5-pc": {
"Chrome": "u",
"IE": "u",
"Edge": "u",
"Firefox": "u",
"Safari": "u"
},
"小程序": {
"微信": "u",
"阿里": "u",
"百度": "u",
"字节跳动": "u",
"QQ": "u",
"钉钉": "u",
"快手": "u",
"飞书": "u",
"京东": "u"
},
"快应用": {
"华为": "u",
"联盟": "u"
}
}
}
}
}
\ No newline at end of file
# uni-push
`uni-push` 工程,是基于 DCloud-UTS 架构之上的封装个推消息推送 `SDK` 的插件工程,使用此模块可轻松实现服务端向客户端推送通知和透传消息的功能。
### 插件使用说明
#### 导入插件
```uts
import * as GTPlugin from "../../uni_modules/uni-push"
```
#### 初始化
```typescript
//初始化个推推送
GTPlugin.initPush();
```
#### 推送消息事件
> 添加透传消息回调,对应的GTPlugin.offPushMessage()可移除对应监听callback(传入null,可移除所有监听callback)
```typescript
GTPlugin.onPushMessage((res) => {
console.log("onPushMessage => " + JSON.stringify(res))
})
```
| 名称 | 类型 | 描述 |
| ---- | ------------- | ----------------------------------------------------------- |
| type | String | 事件类型,"click"-从系统推送服务点击消息启动应用事件;"receive"-应用从推送服务器接收到推送消息事件。 |
| data | String、Object | 消息内容 |
#### 日志
开发阶段,需要使用到日志辅助。
```typescript
//设置日志回调,可以在控制台看到[GT-PUSH]的日志
GTPlugin.setDebugLogger(function(res) {
console.log(res)
});
```
当插件正常初始化会出现以下日志:
```uts
16:47:53.254 [GT-PUSH] [LogController] Sdk version = 3.3.0.0 at pages/index/index.vue:25
16:47:54.052 [GT-PUSH] [ServiceManager] ServiceManager start from initialize... at pages/index/index.vue:25
16:47:54.073 [GT-PUSH] PushCore started at pages/index/index.vue:25
16:47:54.274 [GT-PUSH] onHandleIntent() = get sdk service pid at pages/index/index.vue:25
16:47:54.292 [GT-PUSH] onHandleIntent() areNotificationsEnabled at pages/index/index.vue:25
16:47:54.353 [GT-PUSH] [LoginInteractor] Start login appid = nU*******wzf at pages/index/index.vue:25
16:47:54.571 收到 cid onReceiveClientId : 3061f********ce7578eb24 at pages/index/index.vue:29
16:47:54.592 [GT-PUSH] onHandleIntent() = received client id at pages/index/index.vue:25
16:47:54.593 [GT-PUSH] [LoginResult] Login successed with cid = 3061f********ce7578eb24 at pages/index/index.vue:25
```
#### 推送相关动作
> 设置推送相关动作回调,更多可查看`app-android/index.uts`下面的 `UserPushAction`类
```typescript
GTPlugin.setPushAction({
onReceiveClientId: function(cid) {
console.log("收到 cid onReceiveClientId : " + cid)
}
});
```
#### 唯一的推送标识
获取客户端唯一的推送标识
```typescript
GTPlugin.getPushClientId({
success: (res) => {
console.log("getPushClientId success => " + JSON.stringify(res));
},
fail: (res) => {
console.log("getPushClientId fail => " + JSON.stringify(res));
},
complete: (res) => {
console.log("getPushClientId complete => " + JSON.stringify(res));
}
});
```
**OBJECT 参数说明**
| 参数名 | 类型 | 必填 | 说明 |
| -------- | -------- | --- | ------------------------ |
| success | Function | 是 | 接口调用的回调函数,详见返回参数说明 |
| fail | Function | 否 | 接口调用失败的回调函数 |
| complete | Function | 否 | 接口调用结束的回调函数(调用成功、失败都会执行) |
**success 返回参数说明**
| 参数 | 类型 | 说明 |
| ------ | ------ | ---------------------------------------- |
| cid | String | 个推客户端推送id,对应uni-id-device表的push_clientid |
| errMsg | String | 错误描述 |
**fail 返回参数说明**
| 参数 | 类型 | 说明 |
| ------ | ------ | ---- |
| errMsg | String | 错误描述 |
### APP_ID申请
可登录[个推官网](https://dev.getui.com/)注册申请应用,获取APP相关信息。
### 多厂商
多厂商渠道可以参考[[厂商应用开通指南-个推文档中心](https://docs.getui.com/getui/mobile/vendor/vendor_open/)[厂商 SDK 集成指南-个推文档中心](https://docs.getui.com/getui/mobile/vendor/androidstudio/)
> 注意:华为厂商需要把`agconnect-services.json` 放到${工程根目录}/nativeResources/android/ 目录下
### 开发文档
[个推推送SDK](https://docs.getui.com/getui/start/accessGuide/)
[多厂商接入](https://docs.getui.com/getui/mobile/vendor/vendor_open/)
### 注意事项
`AndroidManifest.xml`中,必须声明插件`flag`
```xml
<!-- 标识dcloud -->
<meta-data android:name="GETUI_PLUGIN_FLAG" android:value="dcloud"/>
```
<?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.uniPush">
<application>
<activity android:name="io.dcloud.uniapp.UniAppActivity">
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<data android:host="io.dcloud.unipush" android:path="/" android:scheme="unipush" />
</intent-filter>
</activity>
<!-- 如果插件中注册组件时, 包名应为: `uts.sdk.modules.uniPush.PushActionService` , 但由于此插件是内部插件, 所以包名改为: `uts.sdk.modules.DCloudUniPush.PushActionService` -->
<service android:name="uts.sdk.modules.DCloudUniPush.PushActionService" android:exported="false" />
<meta-data android:name="GETUI_APPID" android:value="${GETUI_APPID}" />
<meta-data android:name="MIPUSH_APPID" android:value="XM_${MIPUSH_APPID}" />
<meta-data android:name="MIPUSH_APPKEY" android:value="XM_${MIPUSH_APPKEY}" />
<meta-data android:name="MEIZUPUSH_APPID" android:value="MZ_${MEIZUPUSH_APPID}" />
<meta-data android:name="MEIZUPUSH_APPKEY" android:value="MZ_${MEIZUPUSH_APPKEY}" />
<meta-data android:name="OPPOPUSH_APPKEY" android:value="OP_${OPPOPUSH_APPKEY}" />
<meta-data android:name="OPPOPUSH_APPSECRET" android:value="OP_${OPPOPUSH_APPSECRET}" />
<meta-data android:name="com.huawei.hms.client.appid" android:value="${com.huawei.hms.client.appid}" />
<meta-data android:name="com.vivo.push.app_id" android:value="${com.vivo.push.app_id}" />
<meta-data android:name="com.vivo.push.api_key" android:value="${com.vivo.push.api_key}" />
<meta-data android:name="dcloud_unipush_auto_notification" android:value="${dcloud_unipush_auto_notification}" />
</application>
</manifest>
\ No newline at end of file
{
"parameters": {
"appid": {
"placeholder": "GETUI_APPID"
},
"mipush_appid": {
"placeholder": "MIPUSH_APPID"
},
"mipush_appkey": {
"placeholder": "MIPUSH_APPKEY"
},
"meizupush_appid": {
"placeholder": "MEIZUPUSH_APPID"
},
"meizupush_appkey": {
"placeholder": "MEIZUPUSH_APPKEY"
},
"oppopush_appkey": {
"placeholder": "OPPOPUSH_APPKEY"
},
"oppopush_appsecret": {
"placeholder": "OPPOPUSH_APPSECRET"
},
"huaweipush_appid": {
"placeholder": "com.huawei.hms.client.appid"
},
"vivopush_appid": {
"placeholder": "com.vivo.push.app_id"
},
"vivopush_appkey": {
"placeholder": "com.vivo.push.api_key"
},
"dcloud_unipush_auto_notification": {
"placeholder": "dcloud_unipush_auto_notification"
}
},
"files": [{
"source": "push_unipush_huaweipush_agconnect-services.json",
"target": "agconnect-services.json",
"des": "HMS配置文件"
}]
}
\ No newline at end of file
import Context from "android.content.Context";
import GTPlugin from "com.getui.sdk.GTPlugin";
import IPushAction from "com.getui.sdk.IPushAction";
import GTCmdMessage from "com.igexin.sdk.message.GTCmdMessage";
import GTNotificationMessage from "com.igexin.sdk.message.GTNotificationMessage";
import GTTransmitMessage from "com.igexin.sdk.message.GTTransmitMessage";
import IUserLoggerInterface from "com.igexin.sdk.IUserLoggerInterface";
export function gtInit(context : Context) : void {
GTPlugin.initialize(context);
}
export function getClientId(context : Context) : string {
return GTPlugin.getClientId(context);
}
export function setPushAction(action : UserPushAction) : void {
GTPlugin.setPushAction(action);
}
export type GTPushActionOptions = {
onReceiveServicePid ?: (res : number) => void
/**
* 接收clientId(cid)
*/
onReceiveClientId ?: (res : string) => void
/**
* 此方法用于接收和处理透传消息。透传消息个推只传递数据,不做任何处理,客户端接收到透传消息后需要自己去做后续动作处理,如通知栏展示、弹框等。
* 如果开发者在客户端将透传消息创建了通知栏展示,建议将展示和点击回执上报给个推。
*/
onReceiveMessageData ?: (res : string) => void
/**
* cid 离线上线通知
*/
onReceiveOnlineState ?: (res : boolean) => void
/**
* 各种事件处理回执
*/
onReceiveCommandResult ?: (res : GTCmdMessage) => void
/**
* 通知点击,只有个推通道下发的通知会回调此方法
*/
onNotificationMessageClicked ?: (res : string) => void
/**
* 通知到达,只有个推通道下发的通知会回调此方法
*/
onNotificationMessageArrived ?: (res : GTNotificationMessage) => void
}
export class UserPushAction implements IPushAction {
constructor(
private options : GTPushActionOptions) {
}
override onReceiveServicePid(ctx : Context, pid : Int) {
this.options.onReceiveServicePid?.(pid)
}
/**
* 接收clientId(cid)
*/
override onReceiveClientId(ctx : Context, cid : string) {
this.options.onReceiveClientId?.(cid)
}
/**
* 此方法用于接收和处理透传消息。透传消息个推只传递数据,不做任何处理,客户端接收到透传消息后需要自己去做后续动作处理,如通知栏展示、弹框等。
* 如果开发者在客户端将透传消息创建了通知栏展示,建议将展示和点击回执上报给个推。
*
* class GTTransmitMessage {
* private String taskId;
* private String messageId;
* private String payloadId;
* private byte[] payload;
* }
*/
override onReceiveMessageData(ctx : Context, message : GTTransmitMessage) {
this.options.onReceiveMessageData?.(new String(message.getPayload()))
}
/**
* cid 离线/上线通知
*/
override onReceiveOnlineState(ctx : Context, state : boolean) {
this.options.onReceiveOnlineState?.(state)
}
/**
* 各种事件处理回执
*/
override onReceiveCommandResult(ctx : Context, message : GTCmdMessage) {
this.options.onReceiveCommandResult?.(message)
}
/**
* 通知点击,只有个推通道下发的通知会回调此方法
*/
override onNotificationMessageClicked(ctx : Context, message : GTNotificationMessage) {
const params = {
"title": message.getTitle(),
"content": message.getContent()
};
this.options.onNotificationMessageClicked?.(JSON.stringify(params))
}
/**
* 通知到达,只有个推通道下发的通知会回调此方法
*/
override onNotificationMessageArrived(ctx : Context, message : GTNotificationMessage) {
this.options.onNotificationMessageArrived?.(message)
}
}
class UserLoggerInterface implements IUserLoggerInterface {
constructor(private callback : (log : string) => void) {
}
override log(s : string) {
this.callback?.(s)
}
}
/**
* 个推推送sdk调试日志信息
* setDebugLogger 接口仅限调试的时候使用,切勿发布到线上版本,重复调用仅以第一次为准。
*/
export function setDebugLogger(callback : (log : string) => void) {
const ctx = UTSAndroid.getAppContext();
if (ctx != null) {
GTPlugin.setDebugLogger(ctx, new UserLoggerInterface(callback))
}
}
\ No newline at end of file
import { GetPushClientIdOptions, GetPushClientIdSuccess, GetPushClientIdFail, OnPushMessageCallback, OnPushMessageCallbackResult, OnPushMessageType, CreatePushMessageOptions, ChannelManager } from '../interface.uts'
import { gtInit, GTPushActionOptions, UserPushAction, setPushAction } from './gt-sdk/GTPush.uts'
import Context from 'android.content.Context';
import { PushMessage } from './push/PushMessage.uts';
import PackageManager from 'android.content.pm.PackageManager';
import ApplicationInfo from 'android.content.pm.ApplicationInfo';
import Activity from 'android.app.Activity';
import TextUtils from 'android.text.TextUtils';
import { PushState } from './push/PushState.uts';
import { PushManager } from './push/PushManager.uts';
import { StringUtil } from './push/utils/StringUtil.uts';
import SharedPreferences from 'android.content.SharedPreferences';
import Handler from 'android.os.Handler';
import { PushChannelManager } from './push/PushChannelManager.uts';
import Bundle from 'android.os.Bundle';
import Intent from 'android.content.Intent';
import Uri from 'android.net.Uri';
import { globalPushMessageCallbacks, sendEvent } from './push/PushManager.uts'
export { PushActionService } from './push/PushActionService.uts';
const SP_NAME = "clientid_unipush";
const SP_KEY_CLIENT_ID = "clientid";
let gtCallBack : UserPushAction | null = null;
let gtPushInitialize = false
/**
* 个推推送sdk初始化
*/
function initPush() {
const ctx = UTSAndroid.getAppContext();
if (ctx != null && !gtPushInitialize) {
gtPushInitialize = true;
gtInit(ctx);
setPushAction(getGTCallBack());
}
}
/**
* 获取客户端唯一的推送标识(注意:这是一个异步的方法)
*/
export function getPushClientId(options : GetPushClientIdOptions) {
initPush()
const ctx = UTSAndroid.getAppContext() as Context;
const sp = ctx.getSharedPreferences(SP_NAME, Context.MODE_PRIVATE) as SharedPreferences;
const clientId = sp.getString(SP_KEY_CLIENT_ID, "")
if (TextUtils.isEmpty(clientId)) {
const handler = new Handler()
const changeListener = new (class implements SharedPreferences.OnSharedPreferenceChangeListener {
override onSharedPreferenceChanged(sharedPreferences : SharedPreferences, key : string) : void {
if (key != SP_KEY_CLIENT_ID) {
return
}
handler.removeCallbacksAndMessages(null)
sharedPreferences.unregisterOnSharedPreferenceChangeListener(this)
const cid = sharedPreferences.getString(SP_KEY_CLIENT_ID, "")
const res : GetPushClientIdSuccess = { errMsg: "success", cid: cid!! }
options.success?.(res)
options.complete?.(res)
}
})
sp.registerOnSharedPreferenceChangeListener(changeListener)
const runnable = new (class implements Runnable {
override run() {
const clientId = sp.getString(SP_KEY_CLIENT_ID, "")
if (!TextUtils.isEmpty(clientId)) {
const res : GetPushClientIdSuccess = { errMsg: "success", cid: clientId!! }
options.success?.(res)
options.complete?.(res)
} else {
const res : GetPushClientIdFail = {
errSubject: "uni-push",
errCode: -1,
errMsg: "failed,check appkey or appid",
}
options.fail?.(res)
options.complete?.(res)
}
}
})
handler.postDelayed(runnable, 15000)
} else {
const res : GetPushClientIdSuccess = { errMsg: "success", cid: clientId!! }
options.success?.(res)
options.complete?.(res)
}
}
/**
* 增加监听推送消息事件(应用在线的时候没有通知栏消息,全部是透传。), 注意: 使用时,开发者需要注册写到第一个activity的周期内 , 即首页.
*/
export function onPushMessage(callback : OnPushMessageCallback | null) {
initPush()
if (callback == null) {
return;
}
if (globalPushMessageCallbacks.indexOf(callback) == -1) {
globalPushMessageCallbacks.push(callback)
}
processOfflineMessage()
// 处理没有注册监听时,已经接到的消息,此时从缓存里取
PushManager.getInstance().comsumeMessages("click", (msgs : PushMessage[]) => {
msgs.forEach((msg) => {
sendEvent("click", msg)
})
})
PushManager.getInstance().comsumeMessages("receive", (msgs : PushMessage[]) => {
msgs.forEach((msg) => {
sendEvent("receive", msg)
})
})
}
/**
* 移除推送消息监听事件(没有传入参数,则移除App级别的所有事件监听器。)
*/
export function offPushMessage(callback : OnPushMessageCallback | null) {
if (callback == null) {
const len = globalPushMessageCallbacks.length;
globalPushMessageCallbacks.splice(0, len)
return;
}
let index = globalPushMessageCallbacks.indexOf(callback)
if (index == -1) {
return;
}
globalPushMessageCallbacks.splice(index, 1)
}
export function getChannelManager() : ChannelManager {
return PushChannelManager.getInstance()
}
export function createPushMessage(options : CreatePushMessageOptions) : void {
const context = UTSAndroid.getAppContext() as Context
const appId = UTSAndroid.getAppId()
const pushMessage = new PushMessage(JSON.stringify(options), getApplicationName(), false)
const min = 0
if (pushMessage.mDelay == min.toLong()) {
PushManager.getInstance().addPushMessage(appId, pushMessage)
PushManager.getInstance().createNotification(context, pushMessage)
} else {
new Handler().postDelayed(new (class implements Runnable {
override run() {
PushManager.getInstance().addPushMessage(appId, pushMessage)
PushManager.getInstance().createNotification(context, pushMessage)
}
}), pushMessage.mDelay * 1000)
}
}
function getGTCallBack() : UserPushAction {
if (gtCallBack == null) {
const options = {
onReceiveClientId(cid : string) {
const context = UTSAndroid.getAppContext() as Context;
const sp = context.getSharedPreferences(SP_NAME, Context.MODE_PRIVATE);
const editor = sp.edit();
editor.putString(SP_KEY_CLIENT_ID, cid);
editor.commit();
},
onNotificationMessageClicked(res : string) {
const pushMessage = new PushMessage(res, getApplicationName(), false)
if (!sendEvent("click", pushMessage)) {
PushManager.getInstance().addNeedExecClickMessage(pushMessage)
}
},
onReceiveMessageData(res : string) {
if (!TextUtils.isEmpty(res)) {
let isUniPush2 = false
const jsonObject = JSON.parseObject(res)
const unipushVersionStr = jsonObject?.getString("unipush_version")
if (!TextUtils.isEmpty(unipushVersionStr)) {
const unipushVersion = parseFloat(unipushVersionStr!!)
if (unipushVersion == 2.0) {
isUniPush2 = true;
}
}
if (isUniPush2) {
processForUniPush2(res);
} else {
processForUniPush(res);
}
}
},
} as GTPushActionOptions;
gtCallBack = new UserPushAction(options);
}
return gtCallBack!!;
}
/**
* 处理离线消息
*/
function processOfflineMessage() {
const activity = UTSAndroid.getUniActivity() as Activity
const intent = activity.getIntent()
// const testStr = "intent://io.dcloud.unipush/?#Intent;scheme=unipush;launchFlags=0x4000000;package=uni.UNI8CD4C4C;component=uni.UNI8CD4C4C/io.dcloud.uniapp.UniAppActivity;S.UP-OL-SU=true;S.unipush_version=2.0;S.payload={\"cccccforceNotification\":\"xxx\",\"path\":\"XXX\"};S.title=xxx;S.content=xxx;S.unipush_data={\"forceNotification\":\"xxx\",\"path\":\"XXX\"};end"
// const intent = Intent.parseUri(testStr , 0)
if (intent.hasExtra("UP-OL-SU")) {
let isUniPush2 = false;
const unipushVersionStr = intent.getStringExtra("unipush_version");
if (!TextUtils.isEmpty(unipushVersionStr)) {
const unipushVersion = parseFloat(unipushVersionStr!!)
if (unipushVersion == 2.0) {
isUniPush2 = true;
}
}
const params = {}
if (isUniPush2) {
try {
params["title"] = intent.getStringExtra("title")
params["content"] = intent.getStringExtra("content")
params["unipush_version"] = intent.getStringExtra("unipush_version")
const channelId = intent.getStringExtra("channelId");
const category = intent.getStringExtra("category");
if (!TextUtils.isEmpty(channelId)) {
params["channelId"] = channelId
}
if (!TextUtils.isEmpty(category)) {
params["category"] = category
}
let payload = intent.getStringExtra("payload");
const payloadJsonObject = JSON.parseObject(payload ?? "")
if (payloadJsonObject == null) {
if (payload != null) {
//如果后端传的不是json,而是纯字符串,就需要单独处理,去掉多余的引号,并且枚举一下类型.
//双引号套双引号,就说明是传的字符串.
if (payload.startsWith("\"")) {
payload = StringUtil.trimString(payload, '"');
params["payload"] = payload
} else {
const payloadInt = StringUtil.getInt(payload);
const payloadDouble = StringUtil.getDouble(payload);
if (payloadInt != null) {
params["payload"] = payloadInt
} else if (payloadDouble != null) {
params["payload"] = payloadDouble
} else if (payload == "true" || payload == "false") {
params["payload"] = payload.toBoolean()
} else {
params["payload"] = payload
}
}
}
} else {
params["payload"] = payloadJsonObject
}
const unipush_data = intent.getStringExtra("unipush_data");
const unipushDataJsonObject = JSON.parseObject(unipush_data ?? "");
if (unipushDataJsonObject != null) {
unipushDataJsonObject.toMap().forEach((value, key) => {
params[key] = value
})
}
intent.removeExtra("UP-OL-SU");
intent.removeExtra("title");
intent.removeExtra("content");
intent.removeExtra("payload");
intent.removeExtra("unipush_version");
intent.removeExtra("unipush_data");
intent.removeExtra("channelId");
intent.removeExtra("category");
const data = JSON.stringify(params)
const pushMessage = new PushMessage(data, getApplicationName(), true);
if (!sendEvent("click", pushMessage)) {
PushManager.getInstance().addNeedExecClickMessage(pushMessage)
}
} catch (e : Exception) {
e.printStackTrace();
}
} else {
try {
params["title"] = intent.getStringExtra("title")
params["content"] = intent.getStringExtra("content")
params["payload"] = intent.getStringExtra("payload")
const channelId = intent.getStringExtra("channelId");
const category = intent.getStringExtra("category");
if (!TextUtils.isEmpty(channelId)) {
params["channelId"] = channelId
}
if (!TextUtils.isEmpty(category)) {
params["category"] = category
}
intent.removeExtra("UP-OL-SU");
intent.removeExtra("title");
intent.removeExtra("content");
intent.removeExtra("payload");
intent.removeExtra("channelId");
intent.removeExtra("category");
const data = JSON.stringify(params)
const pushMessage = new PushMessage(data, getApplicationName(), true);
if (!sendEvent("click", pushMessage)) {
PushManager.getInstance().addNeedExecClickMessage(pushMessage)
}
} catch (e : Exception) {
e.printStackTrace();
}
}
}
}
function processForUniPush(data : string) : void {
const context = UTSAndroid.getAppContext() as Context
const pushMessage = new PushMessage(data, getApplicationName(), false)
const needPush = PushState.getAutoNotification()
if (needPush && pushMessage.getNeedCreateNotification()) {
PushManager.getInstance().createNotification(context, pushMessage)
} else if (!sendEvent("receive", pushMessage)) {
PushManager.getInstance().addNeedExecReceiveMessage(pushMessage);
}
PushManager.getInstance().addPushMessage(UTSAndroid.getAppId(), pushMessage);
}
function processForUniPush2(data : string) : void {
const context = UTSAndroid.getAppContext() as Context
const jsonObject = JSON.parseObject(data)
if (jsonObject != null) {
const forceNotification = jsonObject.getBoolean("force_notification")
const pushMessage = new PushMessage(data, getApplicationName(), true)
if (forceNotification != null && forceNotification) {
PushManager.getInstance().createNotification(context, pushMessage)
} else if (!sendEvent("receive", pushMessage)) {
PushManager.getInstance().addNeedExecReceiveMessage(pushMessage);
}
PushManager.getInstance().addPushMessage(UTSAndroid.getAppId(), pushMessage);
}
}
function getApplicationName() : string {
let packageManager : PackageManager | null = null
let applicationInfo : ApplicationInfo | null = null
const context = UTSAndroid.getAppContext() as Context;
try {
packageManager = context.getApplicationContext().getPackageManager()
applicationInfo = packageManager.getApplicationInfo(context.getPackageName(), 0)
} catch (_ : Exception) {
}
if (applicationInfo == null) {
return ""
}
return packageManager?.getApplicationLabel(applicationInfo).toString() ?? ""
}
\ No newline at end of file
import Service from 'android.app.Service';
import Intent from 'android.content.Intent';
import IBinder from 'android.os.IBinder';
import { PushManager } from './PushManager.uts';
export class PushActionService extends Service {
constructor(){
super();
}
override onBind(intent : Intent) : IBinder | null {
return null
}
override onStartCommand(intent : Intent | null, flag : Int, startId : Int) : Int {
if (intent != null) {
PushManager.getInstance().processAction(this.getBaseContext(), intent)
}
return super.onStartCommand(intent, flag, startId)
}
}
\ No newline at end of file
import { ChannelManager, SetPushChannelOptions } from "../../interface.uts";
import Context from 'android.content.Context';
import Build from 'android.os.Build';
import NotificationManager from 'android.app.NotificationManager';
import NotificationChannelGroup from 'android.app.NotificationChannelGroup';
import NotificationChannel from 'android.app.NotificationChannel';
import TextUtils from 'android.text.TextUtils';
import ContentResolver from 'android.content.ContentResolver';
import Uri from 'android.net.Uri';
import RingtoneManager from 'android.media.RingtoneManager';
export class PushChannelManager implements ChannelManager {
static LOCAL_PUSH_CHANNEL_ID = "DcloudChannelID";
static LOCAL_PUSH_GROUP_ID = "DcloudGroupID";
private static INSTANCE : PushChannelManager | null = null
static getInstance() : PushChannelManager {
if (this.INSTANCE == null) {
this.INSTANCE = new PushChannelManager()
}
return this.INSTANCE!!
}
createDefaultChannel(context : Context) {
if (Build.VERSION.SDK_INT >= 26) {
const notificationManager = context.getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
const pChannelId = PushChannelManager.LOCAL_PUSH_CHANNEL_ID
const pChannelName = context.getResources().getString(R.string.dcloud_feature_aps_notification_channel)
if (notificationManager.getNotificationChannel(pChannelId) == null) {
notificationManager.createNotificationChannelGroup(new NotificationChannelGroup(PushChannelManager.LOCAL_PUSH_GROUP_ID, context.getResources().getString(R.string.dcloud_feature_aps_notification_group)))
const channel = new NotificationChannel(pChannelId, pChannelName, NotificationManager.IMPORTANCE_DEFAULT)
channel.enableLights(true)
channel.setShowBadge(true)
notificationManager.createNotificationChannel(channel)
}
}
}
/**
* 设置推送渠道
*/
setPushChannel(options : SetPushChannelOptions) : void {
if (Build.VERSION.SDK_INT >= 26) {
const context = UTSAndroid.getAppContext() as Context
const notificationManager = context.getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager;
if (notificationManager.getNotificationChannel(options.channelId) == null) {
const notificationChannel = new NotificationChannel(options.channelId, options.channelDesc, NotificationManager.IMPORTANCE_DEFAULT);
notificationChannel.setShowBadge(true);
let sound = 0;
if (!TextUtils.isEmpty(options.soundName)) {
const packName = context.getApplicationInfo().packageName
sound = context.getResources().getIdentifier(options.soundName!!, "raw", packName)
}
let uriStr = "";
if (sound != 0) {
uriStr = ContentResolver.SCHEME_ANDROID_RESOURCE + "://" + context.getPackageName() + "/raw/" + sound;
}
if (!TextUtils.isEmpty(uriStr)) {
notificationChannel.setSound(Uri.parse(uriStr), null);
} else {
const uri = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);//默认铃音
notificationChannel.setSound(uri, null);
}
if (options.importance != null) {
notificationChannel.setImportance(options.importance!!.toInt());
}
if (options.lockscreenVisibility != null) {
notificationChannel.setLockscreenVisibility(options.lockscreenVisibility!!.toInt());
}
notificationChannel.enableLights(options.enableLights ?? false);
notificationChannel.enableVibration(options.enableVibration ?? false);
notificationManager.createNotificationChannel(notificationChannel);
}
}
}
/**
* 获取当前应用注册的所有的通知渠道。
*/
getAllChannels() : string[] {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
const context = UTSAndroid.getAppContext() as Context
const nm = context.getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
const channels : string[] = []
const list = nm.getNotificationChannels()
for (let i:Int = 0; i < list.size; i++) {
channels.push(list.get(i).toString())
}
return channels
}else{
return [] as string[]
}
}
}
\ No newline at end of file
import Context from 'android.content.Context';
import Intent from 'android.content.Intent';
import { PushChannelManager } from './PushChannelManager.uts';
import { PushMessage } from './PushMessage.uts';
import NotificationManager from 'android.app.NotificationManager';
import ComponentName from 'android.content.ComponentName';
import PendingIntent from 'android.app.PendingIntent';
import Build from 'android.os.Build';
import TextUtils from 'android.text.TextUtils';
import Notification from 'android.app.Notification';
import Bitmap from 'android.graphics.Bitmap';
import BitmapFactory from 'android.graphics.BitmapFactory';
import File from 'java.io.File';
import { OnPushMessageCallback, OnPushMessageType, OnPushMessageCallbackResult } from '../../interface.uts'
export const globalPushMessageCallbacks : OnPushMessageCallback[] = []
export function sendEvent(type : OnPushMessageType, pushMessage : PushMessage) : boolean {
const data = pushMessage.getJsonObject()
const result : OnPushMessageCallbackResult = {
type: type,
data: data
}
if (globalPushMessageCallbacks.length == 0) {
return false
} else {
globalPushMessageCallbacks.forEach((cb : OnPushMessageCallback) => {
cb(result)
})
return true
}
}
export class PushManager {
private static INSTANCE : PushManager | null = null
private ACTION_TYPE_CREATE = "ACTION_TYPE_CREATE"
private ACTION_TYPE_REMOVE = "ACTION_TYPE_REMOVE"
private ACTION_TYPE_CLEAR = "ACTION_TYPE_CLEAR"
private ACTION_TYPE_CLICK = "ACTION_TYPE_CLICK"
private mAppMessages : Map<string, Array<PushMessage>> = new Map()
private mNeedExecClickMessages : PushMessage[] = []
private mNeedExecReceiveMessages : PushMessage[] = []
static getInstance() : PushManager {
if (this.INSTANCE == null) {
this.INSTANCE = new PushManager()
}
return this.INSTANCE!!
}
createNotification(context : Context, message : PushMessage) {
PushChannelManager.getInstance().createDefaultChannel(context)
const intent = new Intent(this.ACTION_TYPE_CREATE)
intent.putExtras(message.toBundle())
this.processAction(context, intent)
}
addPushMessage(pAppid : string, pMsg : PushMessage) {
let _arr = this.mAppMessages.get(pAppid);
if (_arr == null) {
_arr = new Array<PushMessage>();
this.mAppMessages.set(pAppid, _arr);
}
_arr.push(pMsg);
}
addNeedExecClickMessage(pushMessage : PushMessage) {
if (this.mNeedExecClickMessages.length > 0) {
this.mNeedExecClickMessages = []
}
this.mNeedExecClickMessages.push(pushMessage)
}
addNeedExecReceiveMessage(pushMessage : PushMessage) {
this.mNeedExecReceiveMessages.push(pushMessage)
}
removePushMessage(pAppid : String, pPushMsg : PushMessage) {
const _arr = this.mAppMessages.get(pAppid);
if (_arr != null && _arr.indexOf(pPushMsg) > 0) {
_arr.splice(_arr.indexOf(pPushMsg), 1);
}
}
/**
* 消费缓存的消息
*/
comsumeMessages(type : string, cb : (msgs : PushMessage[]) => void) {
if (type == "click") {
cb(this.mNeedExecClickMessages)
this.mNeedExecClickMessages.splice(0)
} else if (type == "receive") {
cb(this.mNeedExecReceiveMessages)
this.mNeedExecReceiveMessages.splice(0)
}
}
processAction(context : Context, intent : Intent) {
const notificationManager = context.getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
const action = intent.getAction()
switch (action) {
case this.ACTION_TYPE_CREATE:
{
const title = intent.getStringExtra("title");
const message = intent.getStringExtra("content");
const nId = intent.getIntExtra("nId", 0);
const when = intent.getLongExtra("when", 0);
const appid = intent.getStringExtra("appid");
const icon = intent.getStringExtra("icon");
const sound = intent.getStringExtra("sound");
const category = intent.getStringExtra("category");
let channelId = intent.getStringExtra("channelId");
const i = new Intent(this.ACTION_TYPE_CLICK);
i.setComponent(new ComponentName(context.getPackageName(), "uts.sdk.modules.DCloudUniPush.PushActionService"));
i.putExtras(intent.getExtras()!!);
let flags = PendingIntent.FLAG_ONE_SHOT;
if (Build.VERSION.SDK_INT >= 23) {
flags = PendingIntent.FLAG_ONE_SHOT | PendingIntent.FLAG_IMMUTABLE;
}
const contentIntent = PendingIntent.getService(context, nId, i, flags);
let builder : Notification.Builder | null = null;
if (Build.VERSION.SDK_INT >= 26) {
if (TextUtils.isEmpty(channelId)) {
channelId = PushChannelManager.LOCAL_PUSH_CHANNEL_ID;
}
builder = new Notification.Builder(context, channelId);
} else {
builder = new Notification.Builder(context);
}
let bitmap : Bitmap | null = null;
try {
if (!TextUtils.isEmpty(icon) && this.fileIsExist(icon!!)) {
bitmap = BitmapFactory.decodeFile(icon!!);
}
} catch (e : Exception) {
e.printStackTrace();
}
if (bitmap != null) {
builder.setLargeIcon(bitmap);
}
const id_small = context.getResources().getIdentifier("push_small", "drawable", context.getPackageName())
if (id_small <= 0) {
builder.setSmallIcon(context.getApplicationInfo().icon); //设置图标
} else {
builder.setSmallIcon(id_small); //设置图标
}
const id = context.getResources().getIdentifier("push", "drawable", context.getPackageName())
if (bitmap == null) {
let largeBitmap : Bitmap | null = null;
if (id <= 0) {
largeBitmap = BitmapFactory.decodeResource(context.getResources(), context.getApplicationInfo().icon);
} else {
largeBitmap = BitmapFactory.decodeResource(context.getResources(), id);
}
if (null != largeBitmap) {
builder.setLargeIcon(largeBitmap);
}
}
builder.setContentTitle(title); //设置标题
builder.setContentText(message); //消息内容
if (Build.VERSION.SDK_INT >= 24) {
builder.setShowWhen(true);
}
builder.setWhen(when); //发送时间
// 添加声音提示
if ("system" == sound) {
builder.setDefaults(Notification.DEFAULT_SOUND); //设置默认的提示音,振动方式,灯光
}
builder.setAutoCancel(true);//打开程序后图标消失
builder.setContentIntent(contentIntent);
builder.setCategory(category);
const notification = builder.build();
try {
notificationManager.notify(nId, notification);
} catch (e : Exception) {
e.printStackTrace();
}
}
break;
case this.ACTION_TYPE_REMOVE:
{
const _id = intent.getIntExtra("id", 0);
if (_id != null) {
notificationManager.cancel(_id);
}
}
break;
case this.ACTION_TYPE_CLEAR:
{
notificationManager.cancelAll();
const _appid = intent.getStringExtra("_appId");
if (_appid != null) {
const appMsg = PushManager.getInstance().mAppMessages;
appMsg.delete(_appid);
}
}
break;
case this.ACTION_TYPE_CLICK:
{
this.clickHandle(intent, notificationManager);
const packagename = context.getPackageName();// 启动类所在包名
const pm = context.getPackageManager();
const _intent = pm.getLaunchIntentForPackage(packagename);
const appid = intent.getStringExtra("appid");
_intent?.putExtra("appid", appid);
const isStartWeb = intent?.getBooleanExtra("__start_first_web__", false) ?? false;
if (isStartWeb) {
_intent?.putExtra("__start_first_web__", isStartWeb);
_intent?.putExtra("__first_web_url__", intent?.getStringExtra("__first_web_url__"));
}
_intent?.putExtra("__start_from__", 3);
_intent?.putExtra("__payload__", intent?.getStringExtra("payload"));
_intent?.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_NEW_TASK);
context.startActivity(_intent);
}
break;
}
}
clickHandle(intent : Intent, _notificationManager : NotificationManager) {
const _bundle = intent.getExtras()!!;
const appid = _bundle.getString("appid");
const uuid = _bundle.getString("uuid");
if (_notificationManager != null) {//作为插件时,手助负责创建通知栏消息
const _id = intent.getIntExtra("id", 0);
_notificationManager.cancel(_id);
}
let _pushMessage : PushMessage | null = null
if (appid != null && uuid != null) {
_pushMessage = this.findPushMessage(appid!!, uuid!!);
}
if (_pushMessage != null) {
let isStartWeb = false;
if (!TextUtils.isEmpty(_pushMessage.mPayload)) {
try {
const payLoadJson = JSON.parseObject(_pushMessage.mPayload ?? "")
const url = payLoadJson?.getString("__adurl")
if (!TextUtils.isEmpty(url)) {
intent.putExtra("__start_first_web__", true);
intent.putExtra("__first_web_url__", url);
isStartWeb = true;
}
} catch (e : Exception) {
e.printStackTrace();
}
}
if (!isStartWeb && !sendEvent("click", _pushMessage)) {
this.addNeedExecClickMessage(_pushMessage);
}
// 点击后的消息,需要移除消息记录,避免getAllMessage时不正确
if (appid != null) {
this.removePushMessage(appid, _pushMessage);
}
} else {
_pushMessage = new PushMessage(_bundle);
if (!TextUtils.isEmpty(_pushMessage.mPayload)) {
try {
const payLoadJson = JSON.parseObject(_pushMessage.mPayload!!)
const url = payLoadJson?.getString("__adurl")
if (!TextUtils.isEmpty(url)) {
intent.putExtra("__start_first_web__", true);
intent.putExtra("__first_web_url__", url);
}
} catch (e : Exception) {
e.printStackTrace();
}
}
this.addNeedExecClickMessage(_pushMessage);
}
_bundle.clear();
}
findPushMessage(pAppid : String, pUuid : String) : PushMessage | null {
let _ret : PushMessage | null = null;
const _arr = this.mAppMessages.get(pAppid);
if (_arr == null) {//若没有通过appid获取到消息集合,则通过uuid遍历所有消息
this.mAppMessages.forEach((value : PushMessage[], key : string) => {
if (value != null) {
value.forEach((value : PushMessage) => {
if (pUuid == value.getMessageUUID()) {
_ret = value
}
})
}
})
} else if (_arr != null) {
_arr.forEach((value : PushMessage) => {
if (pUuid == value.getMessageUUID()) {
_ret = value
}
})
}
return _ret;
}
fileIsExist(path : string) : boolean {
const realPath = UTSAndroid.convert2AbsFullPath(path)
const file = new File(realPath)
return file.exists()
}
}
\ No newline at end of file
import TextUtils from 'android.text.TextUtils'
import Bundle from 'android.os.Bundle';
export class PushMessage {
private mTitle : string | null = null
private contentJson : string | null = null
private mContent : string | null = null
mPayloadJSON : UTSJSONObject | null = null
mPayload : string | null = null
private mWhen : Long = 0
mDelay : Long = 0
private mPath : string | null = null
private mForceNotification : string | null = null
private channelId = ""
private category = ""
private mMessageAppid : string | null = null
private mIconPath : string | null = null
private mUUID : string | null = null
private nID : number = 0
private isCover = false
private sound = "system"
private static mNotificationId = 1
private needCreateNotification = true
private pushVersion : Float = 1.0.toFloat()
private extJSON : UTSJSONObject | null = null
constructor(data : string, defaultTitle : string, isUniPush2 : boolean) {
if (!isUniPush2) {
this.contentJson = data
this.parseJson(data, UTSAndroid.getAppId(), defaultTitle)
} else {
this.extJSON = JSON.parseObject(data)
this.mMessageAppid = UTSAndroid.getAppId()
this.pushVersion = 2.0.toFloat()
if (this.extJSON != null) {
this.channelId = this.extJSON!!.getString("channelId") ?? ""
this.category = this.extJSON!!.getString("category") ?? ""
}
}
this.setMessageUUID()
this.setNotificationID()
}
$constructor(b : Bundle) {
this.mTitle = b.getString("title");
this.mContent = b.getString("content");
this.nID = b.getInt("nId");
this.mWhen = b.getLong("when");
this.sound = b.getString("sound") ?? "system";
this.mMessageAppid = b.getString("appid");
this.mUUID = b.getString("uuid");
this.mPayload = b.getString("payload");
this.mIconPath = b.getString("icon");
this.channelId = b.getString("channelId", "");
this.category = b.getString("category", "");
}
getNeedCreateNotification() : boolean {
return this.needCreateNotification;//payload为空串时需要创建
}
getMessageUUID() : string | null {
return this.mUUID
}
getJsonObject() : UTSJSONObject {
if (this.extJSON != null) {
if (this.pushVersion == (2.0.toFloat())) {
try {
this.extJSON!!["__UUID__"] = this.mUUID
this.extJSON!!["appid"] = this.mMessageAppid
} catch (e : Exception) {
e.printStackTrace()
return {};
}
}
return this.extJSON!!
} else {
const result = {} as UTSJSONObject;
result["__UUID__"] = this.mUUID
result["title"] = this.mTitle
result["appid"] = this.mMessageAppid
result["content"] = this.mContent
if (this.mPayloadJSON != null) {
result["payload"] = this.cleanNullValue(this.mPayloadJSON!!)
} else {
let payLoadObj : UTSJSONObject | null = null
if (this.mPayload != null) {
payLoadObj = JSON.parseObject(this.mPayload!!)
}
if (payLoadObj != null) {
result["payload"] = this.cleanNullValue(payLoadObj)
} else {
result["payload"] = this.mPayload
}
}
if (!TextUtils.isEmpty(this.mPath)) {
result["path"] = this.mPath
}
if (!TextUtils.isEmpty(this.mForceNotification)) {
result["force_notification"] = this.mForceNotification
}
if (!TextUtils.isEmpty(this.channelId)) {
result["channelId"] = this.channelId
}
if (!TextUtils.isEmpty(this.category)) {
result["category"] = this.category
}
return result
}
}
cleanNullValue(json : UTSJSONObject) : UTSJSONObject {
const result = {}
json.toMap().forEach((value, key) => {
if (value != null) {
result[key] = value
}
})
return result
}
toBundle() : Bundle {
const bundle = new Bundle()
if (this.extJSON != null && this.pushVersion == (2.0.toFloat())) {
bundle.putInt("nId", this.nID.toInt());
bundle.putLong("when", this.mWhen);
bundle.putString("sound", this.sound);
bundle.putString("appid", this.mMessageAppid);
bundle.putString("uuid", this.mUUID);
bundle.putString("icon", this.mIconPath);
const map = this.extJSON!!.toMap()
map.forEach((value, key) => {
if (value != null) {
if (typeof value == 'string') {
bundle.putString(key, value as string);
} else if (value instanceof Integer) {
bundle.putInt(key, value as Int);
} else if (value instanceof Double) {
bundle.putDouble(key, value);
} else if (typeof value == 'boolean') {
bundle.putBoolean(key, value as boolean);
} else if (value instanceof UTSJSONObject) {
bundle.putString(key, (value as UTSJSONObject).toJSONString());
}
}
})
return bundle
}
bundle.putString("title", this.mTitle);
bundle.putString("content", this.mContent);
bundle.putInt("nId", this.nID.toInt());
bundle.putLong("when", this.mWhen);
bundle.putString("sound", this.sound);
bundle.putString("appid", this.mMessageAppid);
bundle.putString("uuid", this.mUUID);
if (this.mPayloadJSON != null) {
bundle.putString("payload", this.mPayloadJSON!!.toJSONString());
} else {
bundle.putString("payload", this.mPayload);
}
bundle.putString("icon", this.mIconPath);
bundle.putString("channelId", this.channelId);
bundle.putString("category", this.category);
return bundle
}
private setMessageUUID() : void {
this.mUUID = "androidPushMsg" + this.hashCode()
}
private setNotificationID() : void {
if (!this.isCover) {
PushMessage.mNotificationId++
}
this.nID = PushMessage.mNotificationId
}
/**
* 解析消息的数据
* @param defaultAppid 通过appid 查询到icon资源 , 1.0强需求, 2.0 不需求
*/
private parseJson(data : string, defaultAppid : string, defaultTitle : string) : void {
const json = JSON.parseObject(data)
if (json != null) {
let t_appid = json.getString("appid")
const content = json.getString("content")
if (content != null) {
this.mContent = content
} else {
const message = json.getString("message")
if (message != null) {
this.mContent = message
} else {
this.needCreateNotification = true
this.mContent = data
}
}
if (this.hasOwnProperty(json, "payload")) {
const payloadJson = json.getJSON("payload")
if (payloadJson != null) {
this.mPayloadJSON = payloadJson
} else {
this.mPayload = json.getString("payload")
}
} else {
if (this.hasOwnProperty(json, "Payload")) {
const payloadJson = json.getJSON("Payload")
if (payloadJson != null) {
this.mPayloadJSON = payloadJson
} else {
this.mPayload = json.getString("Payload")
}
} else {
this.needCreateNotification = false
this.mPayload = data
}
}
if (this.hasOwnProperty(json, "title")) {
this.mTitle = json.getString("title")
} else {
this.needCreateNotification = false
this.mTitle = defaultTitle
}
this.isCover = json.getBoolean("cover") ?? false
if ("none" == json.getString("sound")) {
this.sound = "none"
}
this.mWhen = (json.getNumber("when") ?? 0).toLong()
this.mDelay = (json.getNumber("delay") ?? 0).toLong()
this.mPath = json.getString("path")
this.mForceNotification = json.getString("force_notification")
this.channelId = json.getString("channelId") ?? ""
this.category = json.getString("category") ?? ""
if (TextUtils.isEmpty(t_appid)) {
t_appid = defaultAppid
}
this.mMessageAppid = t_appid
const iconPath = json.getString("icon") ?? ""
this.mIconPath = UTSAndroid.convert2AbsFullPath(iconPath)
} else {
this.needCreateNotification = false
this.mContent = data
this.mPayload = data
this.mTitle = defaultTitle
}
}
private hasOwnProperty(jsonObject : UTSJSONObject, key : string) : boolean {
return jsonObject.getAny(key) != null
}
}
\ No newline at end of file
import Context from 'android.content.Context';
import PackageManager from 'android.content.pm.PackageManager';
import Bundle from 'android.os.Bundle';
import TextUtils from 'android.text.TextUtils';
export class PushState {
private static sMetaDatas : Bundle | null = null
static getAutoNotification() : boolean {
const context = UTSAndroid.getAppContext() as Context
const sp = context.getSharedPreferences("push_db_name", Context.MODE_PRIVATE)
const autoNotification = this.getMetaValue(context, "dcloud_unipush_auto_notification")
let needPush = true
if (autoNotification != null) {
if (!autoNotification.equals("ture", true)) {
needPush = false;
}
}
needPush = sp.getBoolean("auto_notification", needPush);
return needPush
}
private static getMetaValue(context : Context, metaKey : string) : string | null {
if (this.sMetaDatas == null) {
try {
this.sMetaDatas = context.getPackageManager().getApplicationInfo(context.getPackageName(), PackageManager.GET_META_DATA).metaData;
} catch (e : Exception) {
e.printStackTrace();
return null;
}
}
if (this.sMetaDatas != null) {
const value = this.sMetaDatas!!.get(metaKey)
if (value != null && !TextUtils.isEmpty(value as string)) {
return value as string;
}
}
return null;
}
}
\ No newline at end of file
export class StringUtil {
static trimString(pSrc : string, removed : string) : string {
const pTrimChar = removed.charAt(0)
let _ret = pSrc;
if (_ret != null && _ret != "") {
const _startPosi = _ret.charAt(0) == pTrimChar ? 1 : 0;
const _count = _ret.length;
const _endPosi = _ret.charAt(_count - 1) == pTrimChar ? _count - 1 : _count;
_ret = _ret.substring(_startPosi, _endPosi);
}
return _ret;
}
static getInt(content : string) : number | null {
try {
return content.toInt();
} catch (e : Exception) {
return null;
}
}
static getDouble(content : string) : number | null {
try {
return content.toDouble()
} catch (e : Exception) {
return null;
}
}
}
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<resources
xmlns:tools="http://schemas.android.com/tools"
tools:keep="@layout/getui_notification,
@drawable/push,
@drawable/push_small,
/>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="dcloud_feature_aps_notification_channel">消息推送</string>
<string name="dcloud_feature_aps_notification_group">推送消息</string>
</resources>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="dcloud_feature_aps_notification_channel" >unipush</string>
<string name="dcloud_feature_aps_notification_group" >message push</string>
</resources>
\ No newline at end of file
export interface Uni {
/**
* getPushClientId()
* @description
* 获取客户端唯一的推送标识
* @param {GetPushClientIdOptions}
* @return {void}
* @tutorial http://uniapp.dcloud.io/api/plugins/push.html#getpushclientid
* @uniPlatform {
* "app": {
* "android": {
* "osVer": "4.4",
* "uniVer": "√",
* "unixVer": "3.97"
* },
* "ios": {
* "osVer": "9.0",
* "uniVer": "x",
* "unixVer": "x"
* }
* }
* }
* @example
```typescript
uni.getPushClientId({
complete: (res: any) => {
console.log("getPushClientId complete => " + JSON.stringify(res));
}
});
```
*/
getPushClientId(options : GetPushClientIdOptions) : void;
/**
* onPushMessage()
* @description
* 启动监听推送消息事件
* @param {OnPushMessageCallback}
* @return {void}
* @tutorial http://uniapp.dcloud.io/api/plugins/push.html#onpushmessage
* @uniPlatform {
* "app": {
* "android": {
* "osVer": "4.4",
* "uniVer": "√",
* "unixVer": "3.97"
* },
* "ios": {
* "osVer": "9.0",
* "uniVer": "x",
* "unixVer": "x"
* }
* }
* }
* @example
```typescript
uni.onPushMessage((res : OnPushMessageCallbackResult) => {
console.log("onPushMessage => " + JSON.stringify(res))
});
```
*/
onPushMessage(callback : OnPushMessageCallback) : void;
/**
* offPushMessage()
* @description
* 关闭推送消息监听事件
* @param {OnPushMessageCallback}
* @return {void}
* @tutorial http://uniapp.dcloud.io/api/plugins/push.html#offpushmessage
* @uniPlatform {
* "app": {
* "android": {
* "osVer": "4.4",
* "uniVer": "√",
* "unixVer": "3.97"
* },
* "ios": {
* "osVer": "9.0",
* "uniVer": "x",
* "unixVer": "x"
* }
* }
* }
* @example
```typescript
const cb = (res : OnPushMessageCallbackResult) => {
console.log("onPushMessage => " + JSON.stringify(res))
}
uni.offPushMessage(cb);
```
*/
offPushMessage(callback : OnPushMessageCallback) : void;
/**
* getChannelManager()
* @description
* 获取通知渠道管理器,Android 8系统以上才可以设置通知渠道,Android 8系统以下返回null。
* @param {void}
* @return {ChannelManager}
* @uniPlatform {
* "app": {
* "android": {
* "osVer": "4.4",
* "uniVer": "3.97",
* "unixVer": "3.97"
* },
* "ios": {
* "osVer": "9.0",
* "uniVer": "x",
* "unixVer": "x"
* }
* }
* }
* @example
```typescript
const channelManager = uni.getChannelManager();
channelManager.setPushChannel({
channelId: "test1",
channelDesc: "test1 desc",
soundName: "pushsound"
})
const channels = channelManager.getAllChannels() as string[]
console.log("channels : " + channels);
```
*/
getChannelManager() : ChannelManager;
/**
* createPushMessage()
* @description
* 创建本地通知栏消息
* @param {CreatePushMessageOptions}
* @return {void}
* @tutorial http://uniapp.dcloud.io/api/plugins/push.html#createpushmessage
* @uniPlatform {
* "app": {
* "android": {
* "osVer": "4.4",
* "uniVer": "√",
* "unixVer": "3.97"
* },
* "ios": {
* "osVer": "9.0",
* "uniVer": "x",
* "unixVer": "x"
* }
* }
* }
* @example
```typescript
uni.createPushMessage({
title:"hello",
content: "content"
});
```
*/
createPushMessage(options : CreatePushMessageOptions) : void;
}
export type GetPushClientId = (options : GetPushClientIdOptions) => void;
export type GetPushClientIdSuccess = {
/**
* 个推客户端推送id,对应uni-id-device表的push_clientid
*/
cid : string,
/**
* 错误描述
*/
errMsg : string
};
export type GetPushClientIdSuccessCallback = (result : GetPushClientIdSuccess) => void;
export type GetPushClientIdFail = UniError;
export type GetPushClientIdFailCallback = (result : GetPushClientIdFail) => void;
export type GetPushClientIdComplete = any;
export type GetPushClientIdCompleteCallback = (result : GetPushClientIdComplete) => void;
export type GetPushClientIdOptions = {
/**
* 接口调用成功的回调函数
* @defaultValue null
*/
success : GetPushClientIdSuccessCallback | null,
/**
* 接口调用失败的回调函数
* @defaultValue null
*/
fail : GetPushClientIdFailCallback | null,
/**
* 接口调用结束的回调函数(调用成功、失败都会执行)
* @defaultValue null
*/
complete : GetPushClientIdCompleteCallback | null
};
/**
* 事件类型
* - click 从系统推送服务点击消息启动应用事件
* - receive 应用从推送服务器接收到推送消息事件
*/
export type OnPushMessageType = "click" | "receive";
export type OnPushMessageCallbackResult = {
/**
* 事件类型
* @type{OnPushMessageType}
*/
type : OnPushMessageType,
/**
* 消息内容
*/
data : UTSJSONObject
};
export type OnPushMessageCallback = (result : OnPushMessageCallbackResult) => void;
export type OnPushMessage = (callback : OnPushMessageCallback) => void;
export type OffPushMessage = (callback : OnPushMessageCallback) => void;
export type GetChannelManager = () => ChannelManager;
export type SetPushChannelOptions = {
/**
* 添加的声音文件,注意raw目录下必须要有 ,不传此字段将使用默认铃音。
* @defaultValue null
*/
soundName? : string | null,
/**
* 通知渠道id
*/
channelId : string,
/**
* 通知渠道描述
*/
channelDesc : string,
/**
* 呼吸灯闪烁
* @defaultValue false
*/
enableLights? : boolean | null,
/**
* 震动
* @defaultValue false
*/
enableVibration? : boolean | null,
/**
* 通知的重要性级别,可选范围IMPORTANCE_LOW:2、IMPORTANCE_DEFAULT:3、IMPORTANCE_HIGH:4 。
* @defaultValue 3
*/
importance? : number | null,
/**
* 锁屏可见性,可选范围VISIBILITY_PRIVATE:0、VISIBILITY_PUBLIC:1、VISIBILITY_SECRET:-1、VISIBILITY_NO_OVERRIDE:-1000。
* @defaultValue -1000
*/
lockscreenVisibility? : number | null
}
export interface ChannelManager {
/**
* 设置推送渠道
*
* @uniPlatform {
* "app": {
* "android": {
* "osVer": "4.4",
* "uniVer": "√",
* "unixVer": "3.97"
* },
* "ios": {
* "osVer": "9.0",
* "uniVer": "x",
* "unixVer": "x"
* }
* }
* }
*/
setPushChannel(options : SetPushChannelOptions) : void;
/**
* 获取当前应用注册的所有的通知渠道。
*
* @uniPlatform {
* "app": {
* "android": {
* "osVer": "4.4",
* "uniVer": "√",
* "unixVer": "3.97"
* },
* "ios": {
* "osVer": "9.0",
* "uniVer": "x",
* "unixVer": "x"
* }
* }
* }
*/
getAllChannels() : Array<string>;
}
export type CreatePushMessage = (options : CreatePushMessageOptions) => void;
export type CreatePushMessageSuccess = {};
export type CreatePushMessageSuccessCallback = (result : CreatePushMessageSuccess) => void;
export type CreatePushMessageFail = UniError;
export type CreatePushMessageFailCallback = (result : CreatePushMessageFail) => void;
export type CreatePushMessageComplete = any;
export type CreatePushMessageCompleteCallback = (result : CreatePushMessageComplete) => void;
export type CreatePushMessageOptions = {
/**
* 是否覆盖上一次提示的消息
* @type boolean
* @defaultValue false
*/
cover? : boolean | null,
/**
* 提示消息延迟显示的时间,单位为s
* @defaultValue 0
*/
delay? : number | null,
/**
* 推送消息的图标
* @defaultValue null
*/
icon? : string | null,
/**
* 推送消息的提示音
* - system: 使用系统通知提示音(默认值)
* - none: 不使用提示音
* @type 'system' | 'none'
* @defaultValue "system"
*/
sound? : string | null,
/**
* 推送消息的标题
* @defaultValue ""
*/
title? : string | null,
/**
* 消息显示的内容,在系统通知中心中显示的文本内容
*/
content : string,
/**
* 消息承载的数据,可根据业务逻辑自定义数据格式
* @defaultValue null
*/
payload? : any | null,
/**
* 消息上显示的提示时间
* @defaultValue 当前时间
*/
when? : number | null,
/**
* 渠道id
* @defaultValue "DcloudChannelID"
* @uniPlatform {
* "app": {
* "android": {
* "osVer": "4.4",
* "uniVer": "√",
* "unixVer": "3.97"
* },
* "ios": {
* "osVer": "9.0",
* "uniVer": "x",
* "unixVer": "x"
* }
* }
* }
*/
channelId? : string | null,
/**
* 通知类别
* @defaultValue null
* @uniPlatform {
* "app": {
* "android": {
* "osVer": "4.4",
* "uniVer": "√",
* "unixVer": "3.97"
* },
* "ios": {
* "osVer": "9.0",
* "uniVer": "x",
* "unixVer": "x"
* }
* }
* }
*/
category? : string | null,
/**
* 接口调用成功的回调函数
* @defaultValue null
*/
success : CreatePushMessageSuccessCallback | null,
/**
* 接口调用失败的回调函数
* @defaultValue null
*/
fail : CreatePushMessageFailCallback | null,
/**
* 接口调用结束的回调函数(调用成功、失败都会执行)
* @defaultValue null
*/
complete : CreatePushMessageCompleteCallback | null
};
......@@ -244,9 +244,9 @@ export type ClearStorageSync = () => void
export interface Uni {
/**
* uni.setStorage函数定义
* 将数据存储在本地storage存储中指定的 key 中,会覆盖掉原来该 key 对应的内容,这是一个异步接口。
*
* @param {SetStorageOptions} options
* 将数据存储在本地storage存储中指定的 key 中,会覆盖掉原来该 key 对应的内容,这是一个异步接口。
*
* @param {SetStorageOptions} options
* @tutorial https://uniapp.dcloud.net.cn/api/storage/storage.html#setstorage
* @uniPlatform {
* "app": {
......@@ -258,7 +258,7 @@ export interface Uni {
* "ios": {
* "osVer": "9.0",
* "uniVer": "2.0.3",
* "unixVer": "3.9.0"
* "unixVer": "x"
* }
* }
* }
......@@ -269,7 +269,7 @@ export interface Uni {
/**
* uni.setStorageSync函数定义
* 将 data 存储在本地storage存储中指定的 key 中,会覆盖掉原来该 key 对应的内容,这是一个同步接口。
*
*
* @param {string} key 本地storage存储中的指定的 key
* @param {any} data 需要存储的内容,只支持原生类型、及能够通过 JSON.stringify 序列化的对象
* @tutorial https://uniapp.dcloud.net.cn/api/storage/storage.html#setstoragesync
......@@ -283,7 +283,7 @@ export interface Uni {
* "ios": {
* "osVer": "9.0",
* "uniVer": "2.0.3",
* "unixVer": "3.9.0"
* "unixVer": "x"
* }
* }
* }
......@@ -294,20 +294,20 @@ export interface Uni {
/**
* uni.getStorage函数定义
* 从本地存储中异步获取指定 key 对应的内容。
*
* @param {GetStorageOptions} options
*
* @param {GetStorageOptions} options
* @tutorial https://uniapp.dcloud.net.cn/api/storage/storage.html#getstorage
* @uniPlatform {
* "app": {
* "android": {
* "osVer": "4.4.4",
* "uniVer": "2.0.3",
* "unixVer": "3.9.0"
* "unixVer": "x"
* },
* "ios": {
* "osVer": "9.0",
* "uniVer": "2.0.3",
* "unixVer": "3.9.0"
* "unixVer": "x"
* }
* }
* }
......@@ -318,7 +318,7 @@ export interface Uni {
/**
* uni.getStorageSync函数定义
* 从本地存储中同步获取指定 key 对应的内容。
*
*
* @param {string} key 本地存储中的指定的 key
* @tutorial https://uniapp.dcloud.net.cn/api/storage/storage.html#getstoragesync
* @uniPlatform {
......@@ -331,7 +331,7 @@ export interface Uni {
* "ios": {
* "osVer": "9.0",
* "uniVer": "2.0.3",
* "unixVer": "3.9.0"
* "unixVer": "x"
* }
* }
* }
......@@ -342,8 +342,8 @@ export interface Uni {
/**
* uni.getStorageInfo函数定义
* 异步获取当前 storage 的相关信息。
*
* @param {GetStorageInfoOptions} options
*
* @param {GetStorageInfoOptions} options
* @tutorial https://uniapp.dcloud.net.cn/api/storage/storage.html#getstorageinfo
* @uniPlatform {
* "app": {
......@@ -355,7 +355,7 @@ export interface Uni {
* "ios": {
* "osVer": "9.0",
* "uniVer": "2.0.3",
* "unixVer": "3.9.0"
* "unixVer": "x"
* }
* }
* }
......@@ -366,10 +366,10 @@ export interface Uni {
/**
* uni.getStorageInfoSync函数定义
* 同步获取当前 storage 的相关信息。
*
*
*
*
* @tutorial https://uniapp.dcloud.net.cn/api/storage/storage.html#getstorageinfosync
*
*
* @uniPlatform {
* "app": {
* "android": {
......@@ -380,7 +380,7 @@ export interface Uni {
* "ios": {
* "osVer": "9.0",
* "uniVer": "2.0.3",
* "unixVer": "3.9.0"
* "unixVer": "x"
* }
* }
* }
......@@ -391,11 +391,11 @@ export interface Uni {
/**
* uni.removeStorage函数定义
* 从本地存储中异步移除指定 key。
*
* @param {RemoveStorageOptions} options
*
*
* @param {RemoveStorageOptions} options
*
* @tutorial hhttps://uniapp.dcloud.net.cn/api/storage/storage.html#removestorage
*
*
* @uniPlatform {
* "app": {
* "android": {
......@@ -406,7 +406,7 @@ export interface Uni {
* "ios": {
* "osVer": "9.0",
* "uniVer": "2.0.3",
* "unixVer": "3.9.0"
* "unixVer": "x"
* }
* }
* }
......@@ -417,11 +417,11 @@ export interface Uni {
/**
* uni.removeStorageSync函数定义
* 从本地存储中同步移除指定 key。
*
*
* @param {string} key 本地存储中的指定的 key
*
*
* @tutorial https://uniapp.dcloud.net.cn/api/storage/storage.html#removestoragesync
*
*
* @uniPlatform {
* "app": {
* "android": {
......@@ -432,7 +432,7 @@ export interface Uni {
* "ios": {
* "osVer": "9.0",
* "uniVer": "2.0.3",
* "unixVer": "3.9.0"
* "unixVer": "x"
* }
* }
* }
......@@ -443,9 +443,9 @@ export interface Uni {
/**
* uni.clearStorage函数定义
* 清除本地数据存储。
*
*
* @tutorial https://uniapp.dcloud.net.cn/api/storage/storage.html#clearstorage
*
*
* @uniPlatform {
* "app": {
* "android": {
......@@ -456,7 +456,7 @@ export interface Uni {
* "ios": {
* "osVer": "9.0",
* "uniVer": "2.0.3",
* "unixVer": "3.9.0"
* "unixVer": "x"
* }
* }
* }
......@@ -467,9 +467,9 @@ export interface Uni {
/**
* uni.clearStorageSync函数定义
* 清除本地数据存储。
*
*
* @tutorial https://uniapp.dcloud.net.cn/api/storage/storage.html#clearstoragesync
*
*
* @uniPlatform {
* "app": {
* "android": {
......@@ -480,7 +480,7 @@ export interface Uni {
* "ios": {
* "osVer": "9.0",
* "uniVer": "2.0.3",
* "unixVer": "3.9.0"
* "unixVer": "x"
* }
* }
* }
......
declare namespace UniNamespace {
type OnUserCaptureScreenCallback = (res?: { errMsg: string }) => void
/**
* uni.onUserCaptureScreen/uni.offUserCaptureScreen回调参数
*/
type OnUserCaptureScreenCallbackResult = {
/**
* 截屏文件路径(仅Android返回)
*/
path ?: string
}
/**
* uni.onUserCaptureScreen/uni.offUserCaptureScreen回调函数定义
*/
type UserCaptureScreenCallback = (res : OnUserCaptureScreenCallbackResult) => void
type OnUserCaptureScreen = (callback : UserCaptureScreenCallback | null) => void
type OffUserCaptureScreen = (callback : UserCaptureScreenCallback | null) => void
/**
* uni.setUserCaptureScreen成功回调参数
*/
type SetUserCaptureScreenSuccess = {
}
/**
* uni.setUserCaptureScreen成功回调函数定义
*/
type SetUserCaptureScreenSuccessCallback = (res : SetUserCaptureScreenSuccess) => void
/**
* 错误码
* - 12001 "setUserCaptureScreen:system not support"
* - 12010 "setUserCaptureScreen:system internal error"
*/
type SetUserCaptureScreenErrorCode = 12001 | 12010;
/**
* SetUserCaptureScreen 的错误回调参数
*/
interface SetUserCaptureScreenFail {
errCode : SetUserCaptureScreenErrorCode
}
/**
* uni.setUserCaptureScreen失败回调函数定义
*/
type SetUserCaptureScreenFailCallback = (res : SetUserCaptureScreenFail) => void
/**
* uni.setUserCaptureScreen完成回调函数定义
*/
type SetUserCaptureScreenCompleteCallback = (res : any) => void
/**
* uni.setUserCaptureScreen参数
*/
type SetUserCaptureScreenOptions = {
/**
* true: 允许用户截屏 false: 不允许用户截屏,防止用户截屏到应用页面内容
*/
enable : boolean;
/**
* 接口调用成功的回调函数
*/
// success : SetUserCaptureScreenSuccessCallback | null,
success ?: SetUserCaptureScreenSuccessCallback,
/**
* 接口调用失败的回调函数
*/
// fail : SetUserCaptureScreenFailCallback | null,
fail ?: SetUserCaptureScreenFailCallback,
/**
* 接口调用结束的回调函数(调用成功、失败都会执行)
*/
// complete : SetUserCaptureScreenSuccessCallback | SetUserCaptureScreenFailCallback | null
complete ?: SetUserCaptureScreenCompleteCallback
}
type SetUserCaptureScreen = (options : SetUserCaptureScreenOptions) => void
}
declare interface Uni {
/**
* 监听用户主动截屏事件,用户使用系统截屏按键截屏时触发此事件。
* 开启截屏监听
*
* @param {UserCaptureScreenCallback} callback
* @tutorial https://uniapp.dcloud.net.cn/api/system/capture-screen.html#onusercapturescreen
* @uniPlatform {
* "app": {
* "android": {
* "osVer": "4.4.4",
* "uniVer": "3.7.7",
* "unixVer": "3.9.0"
* },
* "ios": {
* "osVer": "9.0",
* "uniVer": "3.7.7",
* "unixVer": "x"
* }
* }
* }
* @uniVersion 3.7.7
* @uniVueVersion 2,3 //支持的vue版本
* @autotest { expectCallback: true }
*/
onUserCaptureScreen(callback : UniNamespace.UserCaptureScreenCallback | null) : void,
/**
* 关闭截屏监听
*
* 文档: [https://uniapp.dcloud.net.cn/api/system/capture-screen.html#onusercapturescreen](https://uniapp.dcloud.net.cn/api/system/capture-screen.html#onusercapturescreen)
* @param {UserCaptureScreenCallback} callback
* @tutorial https://uniapp.dcloud.net.cn/api/system/capture-screen.html#offusercapturescreen
* @uniPlatform {
* "app": {
* "android": {
* "osVer": "4.4.4",
* "uniVer": "3.7.7",
* "unixVer": "3.9.0"
* },
* "ios": {
* "osVer": "9.0",
* "uniVer": "3.7.7",
* "unixVer": "x"
* }
* }
* }
* @uniVersion 3.7.7
* @uniVueVersion 2,3 //支持的vue版本
* @autotest { expectCallback: true }
*/
onUserCaptureScreen(callback: UniNamespace.OnUserCaptureScreenCallback): void;
offUserCaptureScreen(callback : UniNamespace.UserCaptureScreenCallback | null) : void,
/**
* 用户主动截屏事件。取消事件监听。
* 设置防截屏
*
* 文档: [https://uniapp.dcloud.net.cn/api/system/capture-screen.html#offusercapturescreen](https://uniapp.dcloud.net.cn/api/system/capture-screen.html#offusercapturescreen)
* @param {SetUserCaptureScreenOptions} options
* @tutorial https://uniapp.dcloud.net.cn/api/system/capture-screen.html#setusercapturescreen
* @uniPlatform {
* "app": {
* "android": {
* "osVer": "4.4.4",
* "uniVer": "3.7.7",
* "unixVer": "3.9.0"
* },
* "ios": {
* "osVer": "13.0",
* "uniVer": "3.7.7",
* "unixVer": "x"
* }
* }
* }
* @uniVersion 3.7.7
* @uniVueVersion 2,3 //支持的vue版本
*/
offUserCaptureScreen(callback: UniNamespace.OnUserCaptureScreenCallback): void;
setUserCaptureScreen(options : UniNamespace.SetUserCaptureScreenOptions) : void
}
......@@ -54,7 +54,7 @@
},
"client": {
"Vue": {
"vue2": "n",
"vue2": "y",
"vue3": "y"
},
"App": {
......
......@@ -3,20 +3,21 @@ import { CaptiveNetwork, kCNNetworkInfoKeySSID, kCNNetworkInfoKeyBSSID } from 'S
import { NSArray, NSDictionary } from 'Foundation';
import { CFString } from 'CoreFoundation';
import { UIDevice } from 'UIKit';
import { WifiOption, WifiConnectOption, GetConnectedWifiOptions, UniWifiInfo, UniWifiResult, UniWifiCallback, StartWifi, StopWifi, GetWifiList, OnGetWifiList, OffGetWifiList, GetConnectedWifi, ConnectWifi, OnWifiConnected, OnWifiConnectedWithPartialInfo, OffWifiConnected, OnOffWifiConnectedWithPartialInfo, SetWifiList } from "../interface.uts"
import { UniWifiResultCallbackWithPartialInfo, UniGetWifiListCallback, UniWifiResultCallback, WifiOption, WifiConnectOption, GetConnectedWifiOptions, UniWifiInfo, UniWifiResult, UniWifiCallback, StartWifi, StopWifi, GetWifiList, OnGetWifiList, OffGetWifiList, GetConnectedWifi, ConnectWifi, OnWifiConnected, OnWifiConnectedWithPartialInfo, OffWifiConnected, OffWifiConnectedWithPartialInfo, SetWifiList } from "../interface.uts"
import { WifiFailImpl, getErrcode } from '../unierror';
/*
/*
* 系统定位权限获取类
*/
class LocationPromiseService implements CLLocationManagerDelegate {
static promiseCompletionHandler: ((res: boolean)=>void)[] = []
manager?: CLLocationManager
constructor(manager?: CLLocationManager) {
this.manager = manager
}
initlizeManager(): boolean {
if (this.manager == null) {
this.manager = new CLLocationManager()
......@@ -24,20 +25,20 @@ class LocationPromiseService implements CLLocationManagerDelegate {
}
return true
}
locationManager(manager: CLLocationManager, @argumentLabel("didChangeAuthorization") status: CLAuthorizationStatus) {
if (status == CLAuthorizationStatus.authorizedAlways || status == CLAuthorizationStatus.authorizedWhenInUse) {
LocationPromiseService.promiseCompletionHandler.forEach((handler): void => {
handler(true)
})
} else if (status == CLAuthorizationStatus.notDetermined) {
} else if (status == CLAuthorizationStatus.notDetermined) {
manager.requestWhenInUseAuthorization()
} else if (status == CLAuthorizationStatus.denied) {
LocationPromiseService.promiseCompletionHandler.forEach((handler): void => {
handler(false)
})
}
}
}
requestPromise(@escaping completion: (res: boolean)=>void) {
let status: CLAuthorizationStatus = CLLocationManager.authorizationStatus()
if (status == CLAuthorizationStatus.notDetermined) {
......@@ -52,20 +53,20 @@ class LocationPromiseService implements CLLocationManagerDelegate {
this.manager!.requestWhenInUseAuthorization()
LocationPromiseService.promiseCompletionHandler.push(completion)
}
}
}
}
}
const locationPromiseService: LocationPromiseService = new LocationPromiseService(null)
/*
* 获取系统定位权限
/*
* 获取系统定位权限
*/
function requestLocationPromise(@escaping completion: (res: boolean)=>void) {
locationPromiseService.requestPromise(completion)
}
/*
/*
* 获取当前连接的wifi信息(通过定位权限)
*/
function fetchConnectedWifiWithLocationPromise(option: GetConnectedWifiOptions) {
......@@ -76,20 +77,20 @@ function fetchConnectedWifiWithLocationPromise(option: GetConnectedWifiOptions)
secure: false,
signalStrength: 0,
frequency: 0
}
}
if (arr != null) {
let list = arr! as NSArray
let index: Int = 0
while (index < list.count) {
let item = list[index]
while (index < list.count) {
let item = list[index]
let interfaceName = item as string
let dic = CNCopyCurrentNetworkInfo(interfaceName as CFString)
if (dic != null) {
let dict = dic! as NSDictionary
let SSID = dict[kCNNetworkInfoKeySSID as string]
let SSID = dict[kCNNetworkInfoKeySSID as string]
let BSSID = dict[kCNNetworkInfoKeyBSSID as string]
if (SSID != null && BSSID != null) {
let ssid = SSID! as string
let bssid = BSSID! as string
......@@ -103,7 +104,7 @@ function fetchConnectedWifiWithLocationPromise(option: GetConnectedWifiOptions)
}
index++
}
if (wifiInfo.BSSID!.length > 0 && wifiInfo.SSID.length > 0) {
let res: UniWifiResult = {
errSubject: "uni-getConnectedWifi",
......@@ -114,12 +115,12 @@ function fetchConnectedWifiWithLocationPromise(option: GetConnectedWifiOptions)
option.success?.(res)
option.complete?.(res)
}else {
let err = new UniError("uni-getConnectedWifi",12010,"getConnectedWifi:system internal error");
let err = new WifiFailImpl(getErrcode(12010));
option.fail?.(err)
option.complete?.(err)
}
}else {
let err = new UniError("uni-getConnectedWifi",12010,"getConnectedWifi:system internal error");
let err = new WifiFailImpl(getErrcode(12010));
option.fail?.(err)
option.complete?.(err)
}
......@@ -127,7 +128,7 @@ function fetchConnectedWifiWithLocationPromise(option: GetConnectedWifiOptions)
/*
/*
* 保存全局数据信息
*/
class UniWiFiModuleGloabInfo {
......@@ -138,14 +139,14 @@ class UniWiFiModuleGloabInfo {
/*
* 初始化wifi模块
/*
* 初始化wifi模块
*/
export const startWifi: StartWifi = function (option: WifiOption) {
UniWiFiModuleGloabInfo.alreadyStartWifi = true
let res: UniWifiResult = {
errSubject: "uni-startWifi",
errCode: 0,
errCode: 0,
errMsg: "startWifi:ok",
wifi: null
}
......@@ -153,15 +154,15 @@ export const startWifi: StartWifi = function (option: WifiOption) {
option.complete?.(res)
}
/*
* 停止wifi模块
/*
* 停止wifi模块
*/
export const stopWifi: StopWifi = function (option: WifiOption) {
UniWiFiModuleGloabInfo.alreadyStartWifi = false
LocationPromiseService.promiseCompletionHandler = []
LocationPromiseService.promiseCompletionHandler = []
let res: UniWifiResult = {
errSubject: "uni-stopWifi",
errCode: 0,
errCode: 0,
errMsg: "stopWifi:ok",
wifi: null
}
......@@ -169,11 +170,11 @@ export const stopWifi: StopWifi = function (option: WifiOption) {
option.complete?.(res)
}
/*
/*
* 获取wifi列表, 在调用之前需要引导用户跳转到系统设置-WIFI设置页面,系统搜索周边wifi后app才能接收到回调
*/
export const getWifiList: GetWifiList = function (option: WifiOption) {
let err = new UniError("uni-getWifiList",12001,"getWifiList:system not support");
let err = new WifiFailImpl(getErrcode(12001));
option.fail?.(err)
option.complete?.(err)
}
......@@ -181,11 +182,11 @@ export const getWifiList: GetWifiList = function (option: WifiOption) {
/* 获取wifi列表的回调
* note: 请在getWifiList方法的回调里调用该方法
*/
export const onGetWifiList: OnGetWifiList = function (callback: UniWifiCallback) {
export const onGetWifiList: OnGetWifiList = function (callback: UniGetWifiListCallback) {
}
/*
/*
* 注销获取wifi列表的回调
*/
export const offGetWifiList: OffGetWifiList = function (callback: UniWifiCallback) {
......@@ -193,12 +194,12 @@ export const offGetWifiList: OffGetWifiList = function (callback: UniWifiCallbac
}
/*
/*
* 获取当前连接的wifi信息
*/
export const getConnectedWifi: GetConnectedWifi = function (option: GetConnectedWifiOptions) {
if (UniWiFiModuleGloabInfo.alreadyStartWifi == false) {
let err = new UniError("uni-getConnectedWifi",12000,"getConnectedWifi:not init");
let err = new WifiFailImpl(getErrcode(12000));
option.fail?.(err)
option.complete?.(err)
} else{
......@@ -207,7 +208,7 @@ export const getConnectedWifi: GetConnectedWifi = function (option: GetConnected
if (success == true) {
fetchConnectedWifiWithLocationPromise(option)
}else {
let err = new UniError("uni-getConnectedWifi",12007,"getConnectedWifi:user denied");
let err = new WifiFailImpl(getErrcode(12007));
option.fail?.(err)
option.complete?.(err)
}
......@@ -218,50 +219,50 @@ export const getConnectedWifi: GetConnectedWifi = function (option: GetConnected
}
}
/*
/*
* 连接wifi
*/
export const connectWifi: ConnectWifi = function (option: WifiConnectOption) {
let err = new UniError("uni-connectWifi",12001,"connectWifi:system not support");
let err = new WifiFailImpl(getErrcode(12001));
option.fail?.(err)
option.complete?.(err)
}
/*
/*
* 连上wifi事件的监听函数
*/
export const onWifiConnected: OnWifiConnected = function (callback: UniWifiCallback) {
export const onWifiConnected: OnWifiConnected = function (callback: UniWifiResultCallback) {
}
/*
/*
* 连上wifi事件的监听函数, wifiInfo仅包含ssid
*/
export const onWifiConnectedWithPartialInfo: OnWifiConnectedWithPartialInfo = function (callback: UniWifiCallback) {
export const onWifiConnectedWithPartialInfo: OnWifiConnectedWithPartialInfo = function (callback: UniWifiResultCallbackWithPartialInfo) {
}
/*
/*
* 移除连接上wifi的事件的监听函数,不传此参数则移除所有监听函数。
*/
export const offWifiConnected: OffWifiConnected = function (callback: UniWifiCallback | null) {
}
/*
/*
* 移除连接上wifi的事件的监听函数,不传此参数则移除所有监听函数。
*/
export const onOffWifiConnectedWithPartialInfo: OnOffWifiConnectedWithPartialInfo = function (callback: UniWifiCallback | null) {
export const offWifiConnectedWithPartialInfo: OffWifiConnectedWithPartialInfo = function (callback: UniWifiResultCallbackWithPartialInfo | null) {
}
/*
/*
* 设置 wifiList 中 AP 的相关信息。在 onGetWifiList 回调后调用,iOS特有接口。
*/
export const setWifiList: SetWifiList = function (option: WifiOption) {
let err = new UniError("uni-setWifiList",12001,"setWifiList:system not support");
let err = new WifiFailImpl(getErrcode(12001));
option.fail?.(err)
option.complete?.(err)
}
\ No newline at end of file
}
declare namespace UniNamespace {
type UniWifiComplete = any
type WifiSuccessCallback = (res : UniWifiResult) => void
type WifiFailCallback = (err : UniWifiFail) => void
type WifiCompleteCallback = (res : UniWifiComplete) => void
type UniWifiCallback = () => void
type WifiErrorCode = 1300002
interface UniWifiInfo {
SSID : string;
BSSID ?: string;
secure ?: boolean;
signalStrength ?: number;
frequency ?: number;
}
interface UniWifiResult {
errCode : number,
errSubject : string,
errMsg : string,
wifi : UniWifiInfo | null
}
interface UniWifiFail {
errCode : WifiErrorCode
}
interface WifiConnectOption {
SSID : string | null;
BSSID : string | null;
password : string | null;
maunal : boolean | null;
partialInfo : boolean | null; //ios不生效
success : WifiSuccessCallback | null;
fail : WifiFailCallback | null;
complete : WifiCompleteCallback | null;
}
interface GetConnectedWifiOptions {
partialInfo : boolean | null;
success : WifiSuccessCallback | null;
fail : WifiFailCallback | null;
complete ?: WifiCompleteCallback | null;
}
interface WifiOption {
success : WifiSuccessCallback | null,
fail : WifiFailCallback | null,
complete : InstallApkCompleteCallback | null
}
interface UniWifiInfoWithPartialInfo {
SSID : string;
}
type UniGetWifiListCallback = (wifiInfo:UTSJSONObject) => void
type UniWifiResultCallback = (wifiInfo:UniWifiResult) => void
type UniWifiResultCallbackWithPartialInfo = (wifiInfo:UniWifiInfoWithPartialInfo) => void
}
declare interface Uni {
/**
* 初始化Wi-Fi模块
*
* @param {WifiOption} option
* @tutorial https://uniapp.dcloud.net.cn/api/system/wifi.html#startwifi
* @uniPlatform {
* "app": {
* "android": {
* "osVer": "4.4.4",
* "uniVer": "3.7.0",
* "unixVer": "3.9.0"
* },
* "ios": {
* "osVer": "9.0",
* "uniVer": "3.7.7",
* "unixVer": "3.9.0"
* }
* }
* }
* @uniVersion 3.7.7
* @uniVueVersion 2,3 //支持的vue版本
* @autotest { after: 'stopWifi' }
*/
startWifi(option : UniNamespace.WifiOption): void,
/**
* 关闭 Wi-Fi 模块
*
* @param {WifiOption} option
* @tutorial https://uniapp.dcloud.net.cn/api/system/wifi.html#stopwifi
* @uniPlatform {
* "app": {
* "android": {
* "osVer": "4.4.4",
* "uniVer": "3.7.0",
* "unixVer": "3.9.0"
* },
* "ios": {
* "osVer": "9.0",
* "uniVer": "3.7.7",
* "unixVer": "3.9.0"
* }
* }
* }
* @uniVersion 3.7.7
* @uniVueVersion 2,3 //支持的vue版本
* @autotest { before: 'startWifi' }
*/
stopWifi(option : UniNamespace.WifiOption) : void,
/**
* @param {WifiConnectOption} option
* @tutorial https://uniapp.dcloud.net.cn/api/system/wifi.html#connectWifi
* @uniPlatform {
* "app": {
* "android": {
* "osVer": ">=4.4 && <10.0",
* "uniVer": "3.7.0",
* "unixVer": "3.9.0"
* },
* "ios": {
* "osVer": "9.0",
* "uniVer": "3.7.7",
* "unixVer": "3.9.0"
* }
* }
* }
* @uniVersion 3.7.7
* @uniVueVersion 2,3 //支持的vue版本
* @autotest {
generated: false,
pollution: false,
cases:[
{
before: 'startWifi',
after: 'stopWifi',
input: [{
maunal:false,
SSID:"Xiaomi_20D0",
password:"streamApp!2016",
}],
output:{
callbackType: 'success',
value: { errCode: 12013 ,errMsg: "connectWifi:wifi config may be expired",errSubject: "uni-connectWifi"}
}
}
]
}
*/
connectWifi(option : UniNamespace.WifiConnectOption) : void,
/**
* 请求获取 Wi-Fi 列表。wifiList 数据会在 onGetWifiList 注册的回调中返回。
* @param {WifiOption} option
* @tutorial https://uniapp.dcloud.net.cn/api/system/wifi.html#getWifiList
* @uniPlatform {
* "app": {
* "android": {
* "osVer": "4.4.4",
* "uniVer": "3.7.0",
* "unixVer": "3.9.0"
* },
* "ios": {
* "osVer": "9.0",
* "uniVer": "3.7.7",
* "unixVer": "3.9.0"
* }
* }
* }
* @uniVersion 3.7.7
* @uniVueVersion 2,3 //支持的vue版本
* @autotest { before: 'startWifi', after: 'stopWifi' }
*/
getWifiList(option : UniNamespace.WifiOption) : void,
/**
* 监听获取到 Wi-Fi 列表数据事件。
*
* @param {UniWifiCallback} callback
* @tutorial https://uniapp.dcloud.net.cn/api/system/wifi.html#onGetWifiList
* @uniPlatform {
* "app": {
* "android": {
* "osVer": "4.4.4",
* "uniVer": "3.7.0",
* "unixVer": "3.9.0"
* },
* "ios": {
* "osVer": "9.0",
* "uniVer": "3.7.7",
* "unixVer": "3.9.0"
* }
* }
* }
* @uniVersion 3.7.7
* @uniVueVersion 2,3 //支持的vue版本
* @autotest { expectCallback: true }
* @autotest {
generated: false,
pollution: false,
expectCallback: true,
before: 'startWifi',
after: 'onGetWifiListAfter',
cases: [
{
output: {
value: 0,
returnKey: '.wifiList.length',
jestExpectSyntax: 'toBeGreaterThan'
},
}
]
}
*/
onGetWifiList(callback : UniNamespace.UniGetWifiListCallback) : void,
/**
* 移除获取到 Wi-Fi 列表数据事件的监听函数。
*
* @param {UniWifiCallback} callback
* @tutorial https://uniapp.dcloud.net.cn/api/system/wifi.html#offGetWifiList
* @uniPlatform {
* "app": {
* "android": {
* "osVer": "4.4.4",
* "uniVer": "3.7.0",
* "unixVer": "3.9.0"
* },
* "ios": {
* "osVer": "9.0",
* "uniVer": "3.7.7",
* "unixVer": "3.9.0"
* }
* }
* }
* @uniVersion 3.7.7
* @uniVueVersion 2,3 //支持的vue版本
* @autotest { expectCallback: true }
*/
offGetWifiList(callback : UniNamespace.UniWifiCallback) : void,
/**
* 获取已连接的 Wi-Fi 信息
*
* @param {GetConnectedWifiOptions} option
* @tutorial https://uniapp.dcloud.net.cn/api/system/wifi.html#getConnectedWifi
* @uniPlatform {
* "app": {
* "android": {
* "osVer": "4.4.4",
* "uniVer": "3.7.0",
* "unixVer": "3.9.0"
* },
* "ios": {
* "osVer": "9.0",
* "uniVer": "3.7.7",
* "unixVer": "3.9.0"
* }
* }
* }
* @uniVersion 3.7.7
* @uniVueVersion 2,3 //支持的vue版本
* @autotest { before: 'startWifi', after: 'stopWifi' }
*/
getConnectedWifi(option : UniNamespace.GetConnectedWifiOptions) : void,
/**
* 监听连接上 Wi-Fi 的事件
*
* @param {UniWifiCallback} callback
* @tutorial https://uniapp.dcloud.net.cn/api/system/wifi.html#onWifiConnected
* @uniPlatform {
* "app": {
* "android": {
* "osVer": "4.4.4",
* "uniVer": "3.7.0",
* "unixVer": "3.9.0"
* },
* "ios": {
* "osVer": "9.0",
* "uniVer": "3.7.7",
* "unixVer": "3.9.0"
* }
* }
* }
* @uniVersion 3.7.7
* @uniVueVersion 2,3 //支持的vue版本
* @autotest { expectCallback: true }
*/
onWifiConnected(callback : UniNamespace.UniWifiResultCallback) : void,
/**
* 监听连接上 Wi-Fi 的事件。
*
* @param {UniWifiCallback} callback
* @tutorial https://uniapp.dcloud.net.cn/api/system/wifi.html#onWifiConnectedWithPartialInfo
* @uniPlatform {
* "app": {
* "android": {
* "osVer": "4.4.4",
* "uniVer": "3.7.0",
* "unixVer": "3.9.0"
* },
* "ios": {
* "osVer": "9.0",
* "uniVer": "3.7.7",
* "unixVer": "3.9.0"
* }
* }
* }
* @uniVersion 3.7.7
* @uniVueVersion 2,3 //支持的vue版本
* @autotest { expectCallback: true }
*/
onWifiConnectedWithPartialInfo(callback : UniNamespace.UniWifiResultCallbackWithPartialInfo) : void,
/**
* 移除连接上 Wi-Fi 的事件的监听函数。
*
* @param {UniWifiCallback} callback
* @tutorial https://uniapp.dcloud.net.cn/api/system/wifi.html#offWifiConnected
* @uniPlatform {
* "app": {
* "android": {
* "osVer": "4.4.4",
* "uniVer": "3.7.0",
* "unixVer": "3.9.0"
* },
* "ios": {
* "osVer": "9.0",
* "uniVer": "3.7.7",
* "unixVer": "3.9.0"
* }
* }
* }
* @uniVersion 3.7.7
* @uniVueVersion 2,3 //支持的vue版本
* @autotest { expectCallback: true }
*/
offWifiConnected(callback ?: UniNamespace.UniWifiCallback) : void,
/**
* 移除连接上 Wi-Fi 的事件的监听函数。
*
* @param {UniWifiCallback} callback
* @tutorial https://uniapp.dcloud.net.cn/api/system/wifi.html#offWifiConnectedWithPartialInfo
* @uniPlatform {
* "app": {
* "android": {
* "osVer": "x",
* "uniVer": "x",
* "unixVer": "x"
* },
* "ios": {
* "osVer": "x",
* "uniVer": "x",
* "unixVer": "x"
* }
* }
* }
* @uniVersion 3.7.7
* @uniVueVersion 2,3 //支持的vue版本
* @autotest { expectCallback: true }
*/
offWifiConnectedWithPartialInfo(callback ?: UniNamespace.UniWifiResultCallbackWithPartialInfo) : void,
/**
* SetWifiList 暂未实现
*
* @uniPlatform {
* "app": {
* "android": {
* "osVer": "x",
* "uniVer": "x",
* "unixVer": "x"
* },
* "ios": {
* "osVer": "x",
* "uniVer": "x",
* "unixVer": "x"
* }
* }
* }
*/
setWifiList(option : UniNamespace.WifiOption) : void,
}
import { WifiErrorCode, WifiFail} from "./interface.uts"
/**
* 错误主题
*/
export const UniErrorSubject = 'uni-wifi';
/**
* 错误码
* @UniError
*/
export const WifiUniErrors : Map<WifiErrorCode, string> = new Map([
/**
* 未先调用 startWifi 接口
*/
[12000, 'not init.'],
/**
* 当前系统不支持相关能力
*/
[12001, 'system not support'],
/**
* 密码错误
*/
[12002, 'password error Wi-Fi'],
/**
* Android 特有,未打开 Wi-Fi 开关
*/
[12005, 'wifi not turned on'],
/**
* 用户拒绝授权链接 Wi-Fi
*/
[12007, 'user denied'],
/**
* 系统其他错误,需要在 errmsg 打印具体的错误原因
*/
[12010, 'unknown error'],
/**
* 系统保存的 Wi-Fi 配置过期,建议忘记 Wi-Fi 后重试,仅 Android 支持
*/
[12013, 'wifi config may be expired'],
]);
export function getErrcode(errCode : number) : WifiErrorCode {
const res = WifiUniErrors[errCode];
return res == null ? 12000 : errCode;
}
export class WifiFailImpl extends UniError implements WifiFail {
constructor(errCode : WifiErrorCode) {
super();
this.errSubject = UniErrorSubject;
this.errCode = errCode;
this.errMsg = WifiUniErrors[errCode] ?? "";
}
}
## 1.0.7(2023-12-11)
去除无用代码
## 1.0.6(2023-12-11)
修改文档
## 1.0.5(2023-12-11)
1.修改插件名称
2.修改插件引入方式为import导入
## 1.0.4(2023-11-30)
1. createNotificationProgress增加`onClick`回调
2.修复在小米部分系统上,通知消息会归类于不重要通知的bug
## 1.0.3(2023-11-28)
更新截图
## 1.0.2(2023-11-28)
修改资源的包名
## 1.0.1(2023-11-28)
更新文档
## 1.0.0(2023-11-28)
Android通知栏显示进度插件
此差异已折叠。
此差异已折叠。
<?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.utsProgressNotification">
<uses-permission android:name="android.permission.POST_NOTIFICATIONS"/>
<application>
<activity android:name="uts.sdk.modules.utsProgressNotification.TransparentActivity"
android:theme="@style/DCNotificationProgressTranslucentTheme" android:hardwareAccelerated="true"
android:screenOrientation="user" android:exported="true">
</activity>
</application>
</manifest>
{
"minSdkVersion": "19"
}
\ No newline at end of file
export const ACTION_DOWNLOAD_FINISH = "ACTION_DOWNLOAD_FINISH"
export const ACTION_DOWNLOAD_PROGRESS = "ACTION_DOWNLOAD_PROGRESS"
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<resources>
<style name="DCNotificationProgressTranslucentTheme">
<item name="android:windowBackground">@android:color/transparent</item>
<item name="android:colorBackgroundCacheHint">@null</item>
<item name="android:windowIsTranslucent">true</item>
<item name="android:windowAnimationStyle">@android:style/Animation</item>
<item name="android:windowNoTitle">true</item>
<item name="android:windowContentOverlay">@null</item>
</style>
</resources>
\ No newline at end of file
{
"deploymentTarget": "9"
}
\ No newline at end of file
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册