提交 ffb6edbb 编写于 作者: DCloud-yyl's avatar DCloud-yyl

Merge branch 'alpha'

# Conflicts:
#	uni_modules/uni-fileSystemManager/package.json
#	uni_modules/uni-fileSystemManager/utssdk/app-android/FileDescriptorUtil.uts
#	uni_modules/uni-fileSystemManager/utssdk/app-android/index.uts
#	uni_modules/uni-fileSystemManager/utssdk/app-js/index.uts
#	uni_modules/uni-fileSystemManager/utssdk/interface.uts
#	uni_modules/uni-fileSystemManager/utssdk/unierror.uts
#	uni_modules/uni-getAppAuthorizeSetting/utssdk/interface.uts
#	uni_modules/uni-getAppBaseInfo/utssdk/app-android/index.uts
#	uni_modules/uni-getAppBaseInfo/utssdk/app-ios/index.uts
#	uni_modules/uni-getAppBaseInfo/utssdk/interface.uts
#	uni_modules/uni-getDeviceInfo/utssdk/app-android/device/DeviceUtil.uts
#	uni_modules/uni-getDeviceInfo/utssdk/app-ios/device/DeviceUtil.uts
#	uni_modules/uni-getDeviceInfo/utssdk/interface.uts
#	uni_modules/uni-getLocation-system/utssdk/interface.uts
#	uni_modules/uni-getNetworkType/utssdk/interface.uts
#	uni_modules/uni-getPerformance/utssdk/interface.uts
#	uni_modules/uni-getProvider/utssdk/app-android/index.uts
#	uni_modules/uni-getProvider/utssdk/app-ios/index.uts
#	uni_modules/uni-getProvider/utssdk/interface.uts
#	uni_modules/uni-getSystemInfo/utssdk/app-android/index.uts
#	uni_modules/uni-getSystemInfo/utssdk/app-ios/index.uts
#	uni_modules/uni-getSystemInfo/utssdk/interface.uts
#	uni_modules/uni-media/utssdk/app-android/index.uts
#	uni_modules/uni-media/utssdk/app-android/utils/ChooseMediaUtils.uts
#	uni_modules/uni-media/utssdk/app-android/utils/CompressUtils.uts
#	uni_modules/uni-media/utssdk/app-ios/Frameworks/DCloudMediaPicker.xcframework/Info.plist
#	uni_modules/uni-media/utssdk/app-ios/Frameworks/DCloudMediaPicker.xcframework/ios-arm64/DCloudMediaPicker.framework/DCloudMediaPicker
#	uni_modules/uni-media/utssdk/app-ios/Frameworks/DCloudMediaPicker.xcframework/ios-arm64_x86_64-simulator/DCloudMediaPicker.framework/DCloudMediaPicker
#	uni_modules/uni-media/utssdk/app-ios/Frameworks/DCloudMediaPicker.xcframework/ios-arm64_x86_64-simulator/DCloudMediaPicker.framework/_CodeSignature/CodeDirectory
#	uni_modules/uni-media/utssdk/app-ios/Frameworks/DCloudMediaPicker.xcframework/ios-arm64_x86_64-simulator/DCloudMediaPicker.framework/_CodeSignature/CodeRequirements-1
#	uni_modules/uni-media/utssdk/app-ios/Frameworks/DCloudMediaPicker.xcframework/ios-arm64_x86_64-simulator/DCloudMediaPicker.framework/_CodeSignature/CodeResources
#	uni_modules/uni-media/utssdk/app-ios/index.uts
#	uni_modules/uni-media/utssdk/app-ios/info.plist
#	uni_modules/uni-media/utssdk/interface.uts
#	uni_modules/uni-navigationBar/utssdk/app-android/index.uts
#	uni_modules/uni-network/utssdk/app-ios/index.uts
#	uni_modules/uni-network/utssdk/app-ios/interface.uts
#	uni_modules/uni-network/utssdk/app-ios/network/NetworkManager.uts
#	uni_modules/uni-network/utssdk/app-ios/network/download/DownloadController.uts
#	uni_modules/uni-network/utssdk/app-ios/network/upload/UploadController.uts
#	uni_modules/uni-network/utssdk/interface.uts
#	uni_modules/uni-payment-alipay/utssdk/app-android/Alipay.uts
#	uni_modules/uni-payment-alipay/utssdk/app-android/index.uts
#	uni_modules/uni-payment-alipay/utssdk/app-ios/config.json
#	uni_modules/uni-payment-alipay/utssdk/app-ios/index.uts
#	uni_modules/uni-payment-wxpay/utssdk/app-android/index.uts
#	uni_modules/uni-payment-wxpay/utssdk/app-android/src/WXPayEntryActivity.uts
#	uni_modules/uni-payment-wxpay/utssdk/app-android/src/Wxpay.uts
#	uni_modules/uni-payment-wxpay/utssdk/app-ios/config.json
#	uni_modules/uni-payment-wxpay/utssdk/app-ios/index.uts
#	uni_modules/uni-payment/utssdk/app-android/index.uts
#	uni_modules/uni-payment/utssdk/app-ios/index.uts
#	uni_modules/uni-payment/utssdk/interface.uts
#	uni_modules/uni-payment/utssdk/unierror.uts
#	uni_modules/uni-prompt/utssdk/app-android/res/layout/ac_recyclerview_layout_top.xml
#	uni_modules/uni-prompt/utssdk/app-android/res/layout/ac_recyclerview_layout_top_night.xml
#	uni_modules/uni-prompt/utssdk/app-android/res/layout/uni_prompt_ac_recyclerview_layout_top.xml
#	uni_modules/uni-prompt/utssdk/app-android/res/layout/uni_prompt_ac_recyclerview_layout_top_night.xml
#	uni_modules/uni-prompt/utssdk/app-android/showToast.uts
#	uni_modules/uni-route/utssdk/app-android/navigateBack.uts
#	uni_modules/uni-route/utssdk/constants.uts
#	uni_modules/uni-route/utssdk/interface.uts
#	uni_modules/uni-tabBar/utssdk/app-android/index.uts
#	uni_modules/uni-tabBar/utssdk/interface.uts
#	uni_modules/uni-websocket/utssdk/app-ios/websocket/WebsockerClient.uts
#	uni_modules/uni-websocket/utssdk/interface.uts
......@@ -61,12 +61,16 @@ export interface Uni {
* "android": {
* "osVer": "5.0",
* "uniVer": "3.8.15",
* "unixVer": "3.9.0"
* "uniUtsPlugin": "3.9.0",
* "unixVer": "3.9.0",
* "unixUtsPlugin": "3.9.0"
* },
* "ios": {
* "osVer": "x",
* "uniVer": "x",
* "unixVer": "x"
* "uniUtsPlugin": "x",
* "unixVer": "x",
* "unixUtsPlugin": "x"
* }
* },
* "web": {
......
......@@ -37,7 +37,7 @@
"getFileSystemManager": {
"name": "getFileSystemManager",
"app": {
"js": false,
"js": true,
"kotlin": true,
"swift": false
}
......
import File from 'java.io.File'
import ParcelFileDescriptor from 'android.os.ParcelFileDescriptor'
import { OpenFileOptions, OpenFileSuccessResult, OpenFileSyncOptions } from '../interface';
import { UniErrorSubject, UniErrors } from '../unierror';
import { UniErrorSubject,FileSystemManagerFailImpl,FileSystemManagerUniErrors } from '../unierror';
export class FileDescriptorUtil {
public openMap : Map<string, File> = new Map()
......@@ -28,12 +28,12 @@ export class FileDescriptorUtil {
case 'ax': //类似于 'a',但如果路径存在,则失败
{
if (file.exists()) {
let err = new UniError(UniErrorSubject, 1301005, UniErrors.get(1301005)!);
let err = new FileSystemManagerFailImpl(1301005);
options.fail?.(err)
options.complete?.(err)
} else {
if (file.parentFile?.exists() == false) {
let err = new UniError(UniErrorSubject, 1300002, UniErrors.get(1300002)!);
let err = new FileSystemManagerFailImpl(1300002);
options.fail?.(err)
options.complete?.(err)
return
......@@ -66,7 +66,7 @@ export class FileDescriptorUtil {
case 'ax+': //类似于 'a+',但如果路径存在,则失败
{
if (file.exists()) {
let err = new UniError(UniErrorSubject, 1301005, UniErrors.get(1301005)!);
let err = new FileSystemManagerFailImpl(1301005);
options.fail?.(err)
options.complete?.(err)
} else {
......@@ -84,7 +84,7 @@ export class FileDescriptorUtil {
case 'r': //打开文件用于读取。 如果文件不存在,则会发生异常
{
if (!file.exists()) {
let err = new UniError(UniErrorSubject, 1300002, UniErrors.get(1300002)!);
let err = new FileSystemManagerFailImpl(1300002);
options.fail?.(err)
options.complete?.(err)
} else {
......@@ -104,7 +104,7 @@ export class FileDescriptorUtil {
case 'r+': //打开文件用于读取和写入。 如果文件不存在,则会发生异常
{
if (!file.exists()) {
let err = new UniError(UniErrorSubject, 1300002, UniErrors.get(1300002)!);
let err = new FileSystemManagerFailImpl(1300002);
options.fail?.(err)
options.complete?.(err)
} else {
......@@ -136,7 +136,7 @@ export class FileDescriptorUtil {
case 'wx'://类似于 'w',但如果路径存在,则失败
{
if (file.exists()) {
let err = new UniError(UniErrorSubject, 1301005, UniErrors.get(1301005)!);
let err = new FileSystemManagerFailImpl(1301005);
options.fail?.(err)
options.complete?.(err)
} else {
......@@ -168,7 +168,7 @@ export class FileDescriptorUtil {
case 'wx+': // 类似于 'w+',但如果路径存在,则失败
{
if (file.exists()) {
let err = new UniError(UniErrorSubject, 1301005, UniErrors.get(1301005)!);
let err = new FileSystemManagerFailImpl(1301005);
options.fail?.(err)
options.complete?.(err)
} else {
......@@ -187,7 +187,7 @@ export class FileDescriptorUtil {
}
}
} catch (e) {
let err = new UniError(UniErrorSubject, 1300201, UniErrors.get(1300201)! + ":" + e + " " + options.filePath);
let err = new FileSystemManagerFailImpl(1300201);
options.fail?.(err)
options.complete?.(err)
}
......@@ -206,10 +206,10 @@ export class FileDescriptorUtil {
case 'ax': //类似于 'a',但如果路径存在,则失败
{
if (file.exists()) {
throw new Error(`${msgPrefix}${UniErrors[1301005]}`)
throw new Error(`${msgPrefix}${FileSystemManagerUniErrors[1301005]}`)
} else {
if (file.parentFile?.exists() == false) {
throw new Error(`${msgPrefix}${UniErrors[1300002]}`)
throw new Error(`${msgPrefix}${FileSystemManagerUniErrors[1300002]}`)
} else {
file.createNewFile()
let fd = this.open_a(file)
......@@ -228,7 +228,7 @@ export class FileDescriptorUtil {
case 'ax+': //类似于 'a+',但如果路径存在,则失败
{
if (file.exists()) {
throw new Error(`${msgPrefix}${UniErrors[1301005]}`)
throw new Error(`${msgPrefix}${FileSystemManagerUniErrors[1301005]}`)
} else {
let fd = this.open_ax(file)
this.openMap.set(fd, file)
......@@ -238,7 +238,7 @@ export class FileDescriptorUtil {
case 'r': //打开文件用于读取。 如果文件不存在,则会发生异常
{
if (!file.exists()) {
throw new Error(`${msgPrefix}${UniErrors[1300002]}`)
throw new Error(`${msgPrefix}${FileSystemManagerUniErrors[1300002]}`)
} else {
let mode = ParcelFileDescriptor.MODE_READ_ONLY
let pfd = ParcelFileDescriptor.open(file, mode);
......@@ -251,7 +251,7 @@ export class FileDescriptorUtil {
case 'r+': //打开文件用于读取和写入。 如果文件不存在,则会发生异常
{
if (!file.exists()) {
throw new Error(`${msgPrefix}${UniErrors[1300002]}`)
throw new Error(`${msgPrefix}${FileSystemManagerUniErrors[1300002]}`)
} else {
let mode = ParcelFileDescriptor.MODE_READ_WRITE
let pfd = ParcelFileDescriptor.open(file, mode);
......@@ -270,7 +270,7 @@ export class FileDescriptorUtil {
case 'wx'://类似于 'w',但如果路径存在,则失败
{
if (file.exists()) {
throw new Error(`${msgPrefix}${UniErrors[1301005]}`)
throw new Error(`${msgPrefix}${FileSystemManagerUniErrors[1301005]}`)
} else {
let fd = this.open_w(file)
this.openMap.set(fd, file)
......@@ -289,7 +289,7 @@ export class FileDescriptorUtil {
case 'wx+': // 类似于 'w+',但如果路径存在,则失败
{
if (file.exists()) {
throw new Error(`${msgPrefix}${UniErrors[1301005]}`)
throw new Error(`${msgPrefix}${FileSystemManagerUniErrors[1301005]}`)
} else {
let mode = ParcelFileDescriptor.MODE_CREATE | ParcelFileDescriptor.MODE_READ_WRITE | ParcelFileDescriptor.MODE_TRUNCATE
let pfd = ParcelFileDescriptor.open(file, mode);
......
import { WriteFileOptions, ReadFileOptions, MkDirOptions, RmDirOptions, UnLinkOptions, ReadDirOptions, AccessOptions, RenameOptions, GetFileInfoOptions, CopyFileOptions, StatOptions } from "../interface.uts"
import { ReadFileSuccessResult, FileManagerSuccessResult, ReadDirSuccessResult, GetFileInfoSuccessResult, StatSuccessResult, FileStats, Stats } from "../interface.uts"
import { GetFileSystemManager, FileSystemManager } from "../interface.uts"
import { UniErrorSubject, UniErrors } from "../unierror.uts"
export { Stats,FileStats } from '../interface.uts'
import { FileSystemManagerFailImpl, FileSystemManagerUniErrorSubject, FileSystemManagerUniErrors } from "../unierror.uts"
class InnerStats implements Stats {
/**
......@@ -93,7 +92,7 @@ class JsFileSystemManager implements FileSystemManager {
options.complete?.(ret)
},
function (code) {
let err = new UniError(UniErrorSubject, code, UniErrors.get(code)! + ":" + options.path);
let err = new FileSystemManagerFailImpl(code)
options.fail?.(err)
options.complete?.(err)
})
......@@ -103,7 +102,7 @@ class JsFileSystemManager implements FileSystemManager {
if(options.digestAlgorithm == null || options.digestAlgorithm == undefined){
options.digestAlgorithm = "md5"
} else if (options.digestAlgorithm!.toLowerCase() != 'md5' && options.digestAlgorithm!.toLowerCase() != 'sha1') {
let err = new UniError(UniErrorSubject, 1300022, UniErrors.get(1300022)! + ":invalid digestAlgorithm " + options.digestAlgorithm);
let err = new FileSystemManagerFailImpl(1300022);
options.fail?.(err)
options.complete?.(err)
return
......@@ -117,7 +116,7 @@ class JsFileSystemManager implements FileSystemManager {
options.complete?.(ret)
},
function (code) {
let err = new UniError(UniErrorSubject, code, UniErrors.get(code)! + ":" + options.filePath);
let err = new FileSystemManagerFailImpl(code);
options.fail?.(err)
options.complete?.(err)
})
......@@ -136,7 +135,7 @@ class JsFileSystemManager implements FileSystemManager {
options.complete?.(ret)
},
function (code) {
let err = new UniError(UniErrorSubject, code, UniErrors.get(code)!);
let err = new FileSystemManagerFailImpl(code);
options.fail?.(err)
options.complete?.(err)
})
......@@ -155,7 +154,7 @@ class JsFileSystemManager implements FileSystemManager {
options.complete?.(ret)
},
function (code) {
let err = new UniError(UniErrorSubject, code, UniErrors.get(code)!);
let err = new FileSystemManagerFailImpl(code);
options.fail?.(err)
options.complete?.(err)
})
......@@ -173,7 +172,7 @@ class JsFileSystemManager implements FileSystemManager {
options.complete?.(ret)
},
function (code) {
let err = new UniError(UniErrorSubject, code, UniErrors.get(code)! + ":" + options.path);
let err = new FileSystemManagerFailImpl(code);
options.fail?.(err)
options.complete?.(err)
})
......@@ -191,7 +190,7 @@ class JsFileSystemManager implements FileSystemManager {
options.complete?.(ret)
},
function (code) {
let err = new UniError(UniErrorSubject, code, UniErrors.get(code)! + ":" + options.dirPath);
let err = new FileSystemManagerFailImpl(code);
options.fail?.(err)
options.complete?.(err)
})
......@@ -214,7 +213,7 @@ class JsFileSystemManager implements FileSystemManager {
options.complete?.(ret)
},
function (code) {
let err = new UniError(UniErrorSubject, code, UniErrors.get(code)! + ":" + options.dirPath);
let err = new FileSystemManagerFailImpl(code);
options.fail?.(err)
options.complete?.(err)
})
......@@ -229,7 +228,7 @@ class JsFileSystemManager implements FileSystemManager {
options.complete?.(ret)
},
function (code) {
let err = new UniError(UniErrorSubject, code, UniErrors.get(code)! + ":" + options.dirPath);
let err = new FileSystemManagerFailImpl(code);
options.fail?.(err)
options.complete?.(err)
})
......@@ -248,7 +247,7 @@ class JsFileSystemManager implements FileSystemManager {
options.complete?.(ret)
},
function (code) {
let err = new UniError(UniErrorSubject, code, UniErrors.get(code)! + ":" + options.filePath);
let err = new FileSystemManagerFailImpl(code);
options.fail?.(err)
options.complete?.(err)
})
......@@ -266,7 +265,7 @@ class JsFileSystemManager implements FileSystemManager {
options.complete?.(ret)
},
function (code) {
let err = new UniError(UniErrorSubject, code, UniErrors.get(code)! + ":" + options.filePath);
let err = new FileSystemManagerFailImpl(code);
options.fail?.(err)
options.complete?.(err)
})
......@@ -286,7 +285,7 @@ class JsFileSystemManager implements FileSystemManager {
options.complete?.(ret)
},
function (code) {
let err = new UniError(UniErrorSubject, code, UniErrors.get(code)! + ":" + options.filePath);
let err = new FileSystemManagerFailImpl(code);
options.fail?.(err)
options.complete?.(err)
})
......
......@@ -21,7 +21,7 @@ export type FileManagerSuccessCallback = (res : FileManagerSuccessResult) => voi
/**
* 通用的错误返回结果回调
*/
export type FileManagerFailCallback = (res : UniError) => void
export type FileManagerFailCallback = (res : FileSystemManagerFail) => void
/**
* 通用的结束返回结果回调
*/
......@@ -39,7 +39,7 @@ export type ReadFileOptions = {
*/
encoding : "base64" | "utf-8",
/**
* 文件路径,支持相对地址和绝对地址
* 文件路径,支持相对地址和绝对地址,app-android平台支持代码包文件目录
*/
filePath : string.URIString,
/**
......@@ -269,7 +269,7 @@ export type ReadDirOptions = {
export type AccessOptions = {
/**
* 要删除的目录路径 (本地路径)
* 要判断是否存在的文件/目录路径 (本地路径)
*/
path : string.URIString,
......@@ -553,7 +553,7 @@ export type ReadCompressedFileResult = {
export type ReadCompressedFileCallback = (res : ReadCompressedFileResult) => void
export type ReadCompressedFileOptions = {
/**
* 要读取的文件的路径 (本地用户文件或代码包文件)
* 要读取的文件的路径 (本地用户文件或代码包文件),app-android平台支持代码包文件目录
*/
filePath : string.URIString,
/**
......@@ -779,7 +779,7 @@ export type ZipFileItem = {
export type ReadZipEntryCallback = (res : EntriesResult) => void
export type ReadZipEntryOptions = {
/**
* 要读取的压缩包的路径 (本地路径)
* 要读取的压缩包的路径 (本地路径),app-android平台支持代码包文件目录
*/
filePath : string.URIString,
/**
......@@ -829,6 +829,8 @@ export interface FileSystemManager {
readFile(options : ReadFileOptions) : void;
/**
* FileSystemManager.readFile 的同步版本参数
* @param filePath 文件路径,支持相对地址和绝对地址,app-android平台支持代码包文件目录
* @param encoding base64 / utf-8
* @uniPlatform {
* "app": {
* "android": {
......@@ -873,6 +875,9 @@ export interface FileSystemManager {
writeFile(options : WriteFileOptions) : void;
/**
* FileSystemManager.writeFile 的同步版本
* @param filePath 文件路径,只支持绝对地址
* @param data 写入的文本内容
* @param encoding 指定写入文件的字符编码,支持:ascii base64 utf-8
* @uniPlatform {
* "app": {
* "android": {
......@@ -917,6 +922,7 @@ export interface FileSystemManager {
unlink(options : UnLinkOptions) : void;
/**
* FileSystemManager.unlink 的同步版本
* @param filePath 文件路径,只支持绝对地址
* @uniPlatform {
* "app": {
* "android": {
......@@ -961,6 +967,8 @@ export interface FileSystemManager {
mkdir(options : MkDirOptions) : void;
/**
* FileSystemManager.mkdir 的同步版本
* @param dirPath 创建的目录路径 (本地路径)
* @param recursive 是否在递归创建该目录的上级目录后再创建该目录。如果对应的上级目录已经存在,则不创建该上级目录。如 dirPath 为 a/b/c/d 且 recursive 为 true,将创建 a 目录,再在 a 目录下创建 b 目录,以此类推直至创建 a/b/c 目录下的 d 目录。
* @uniPlatform {
* "app": {
* "android": {
......@@ -1005,6 +1013,8 @@ export interface FileSystemManager {
rmdir(options : RmDirOptions) : void;
/**
* FileSystemManager.rmdir 的同步版本
* @param dirPath 要删除的目录路径 (本地路径)
* @param recursive 是否递归删除目录。如果为 true,则删除该目录和该目录下的所有子目录以及文件。
* @uniPlatform {
* "app": {
* "android": {
......@@ -1049,6 +1059,7 @@ export interface FileSystemManager {
readdir(options : ReadDirOptions) : void;
/**
* FileSystemManager.readdir 的同步版本
* @param dirPath 要读取的目录路径 (本地路径)
* @uniPlatform {
* "app": {
* "android": {
......@@ -1093,6 +1104,7 @@ export interface FileSystemManager {
access(options : AccessOptions) : void;
/**
* FileSystemManager.access 的同步版本
* @param path 要判断是否存在的文件/目录路径 (本地路径)
* @uniPlatform {
* "app": {
* "android": {
......@@ -1137,6 +1149,8 @@ export interface FileSystemManager {
rename(options : RenameOptions) : void;
/**
* FileSystemManager.rename 的同步版本
* @param oldPath 源文件路径,支持本地路径
* @param newPath 新文件路径,支持本地路径
* @uniPlatform {
* "app": {
* "android": {
......@@ -1181,6 +1195,8 @@ export interface FileSystemManager {
copyFile(options : CopyFileOptions) : void;
/**
* FileSystemManager.copyFile 的同步版本
* @param srcPath 源文件路径,支持本地路径
* @param destPath 新文件路径,支持本地路径
* @uniPlatform {
* "app": {
* "android": {
......@@ -1247,6 +1263,8 @@ export interface FileSystemManager {
stat(options : StatOptions) : void;
/**
* FileSystemManager.stat 的同步版本
* @param path 文件/目录路径 (本地路径)
* @param recursive 是否递归获取目录下的每个文件的 Stats 信息
* @uniPlatform {
* "app": {
* "android": {
......@@ -1291,6 +1309,9 @@ export interface FileSystemManager {
appendFile(options : AppendFileOptions) : void;
/**
* FileSystemManager.appendFile 的同步版本
* @param filePath 要追加内容的文件路径 (本地路径)
* @param data 要追加的文本
* @param encoding 指定写入文件的字符编码支持:ascii base64 utf-8
* @uniPlatform {
* "app": {
* "android": {
......@@ -1335,6 +1356,8 @@ export interface FileSystemManager {
saveFile(options : SaveFileOptions) : void;
/**
* FileSystemManager.saveFile 的同步版本
* @param tempFilePath 临时存储文件路径 (本地路径)
* @param filePath 要存储的文件路径 (本地路径)
* @uniPlatform {
* "app": {
* "android": {
......@@ -1445,6 +1468,8 @@ export interface FileSystemManager {
truncate(options : TruncateFileOptions) : void;
/**
* 对文件内容进行截断操作 (truncate 的同步版本)
* @param filePath 要截断的文件路径 (本地路径)
* @param length 截断位置,默认0。如果 length 小于文件长度(字节),则只有前面 length 个字节会保留在文件中,其余内容会被删除;如果 length 大于文件长度,不做处理
* @uniPlatform {
* "app": {
* "android": {
......@@ -1489,6 +1514,8 @@ export interface FileSystemManager {
readCompressedFile(options : ReadCompressedFileOptions) : void;
/**
* 同步读取指定压缩类型的本地文件内容
* @param filePath 要读取的文件的路径 (本地用户文件或代码包文件),app-android平台支持代码包文件目录
* @param compressionAlgorithm 文件压缩类型,目前仅支持 'br'。
* @uniPlatform {
* "app": {
* "android": {
......@@ -1618,7 +1645,7 @@ export interface FileSystemManager {
* }
* }
*/
close(options : CloseOptions);
close(options : CloseOptions) : void;
/**
* 同步关闭文件
* @uniPlatform {
......@@ -1782,3 +1809,25 @@ export interface Uni {
*/
getFileSystemManager() : FileSystemManager
}
/**
* 错误码
* - 1200002 类型错误。仅支持 base64 / utf-8
* - 1300002 未找到文件
* - 1300013 无权限
* - 1300021 是目录
* - 1300022 参数无效
* - 1300066 目录非空
* - 1301003 对目录的非法操作
* - 1301005 文件已存在
* - 1300201 系统错误
* - 1300202 超出文件存储限制的最大尺寸
* - 1301111 brotli解压失败
* - 1302003 标志无效
* - 1300009 文件描述符错误
*/
export type FileSystemManagerErrorCode = 1200002 | 1300002 | 1300013 | 1300021 | 1300022 | 1300066 | 1301003 | 1301005 | 1300201 | 1300202 | 1301111 | 1302003 | 1300009;
export type FileSystemManagerFail = IFileSystemManagerFail;
export interface IFileSystemManagerFail extends IUniError {
errCode : FileSystemManagerErrorCode
};
import { FileSystemManagerErrorCode,IFileSystemManagerFail } from "./interface.uts"
/**
* 错误主题
*/
export const UniErrorSubject = 'uni-fileSystemManager';
export const FileSystemManagerUniErrorSubject = 'uni-fileSystemManager';
/**
* 错误码
* @UniError
*/
export const UniErrors : Map<number, string> = new Map([
export const FileSystemManagerUniErrors : Map<FileSystemManagerErrorCode, string> = new Map([
[1200002, 'type error. only support base64 / utf-8'],
[1300002, 'no such file or directory'],
......@@ -23,3 +25,11 @@ export const UniErrors : Map<number, string> = new Map([
[1302003, 'invalid flag'],
[1300009, 'bad file descriptor']
]);
export class FileSystemManagerFailImpl extends UniError implements IFileSystemManagerFail {
constructor(errCode : FileSystemManagerErrorCode) {
super();
this.errSubject = FileSystemManagerUniErrorSubject;
this.errCode = errCode;
this.errMsg = FileSystemManagerUniErrors.get(errCode) ?? "";
}
}
\ No newline at end of file
......@@ -41,7 +41,8 @@ export type GetAppAuthorizeSettingResult = {
* - authorized: 已经获得授权,无需再次请求授权
* - denied: 请求授权被拒绝,无法再次请求授权;(此情况需要引导用户打开系统设置,在设置页中打开权限)
* - not determined: 尚未请求授权,会在App下一次调用系统相应权限时请求;(仅 iOS 会出现。此种情况下引导用户打开系统设置,不展示开关)
* @type 'authorized' | 'denied' | 'not determined'
* - config error: 当前应用没有配置相册权限描述
* @type 'authorized' | 'denied' | 'not determined' | 'config error'
* @uniPlatform
* {
* "app": {
......@@ -58,13 +59,13 @@ export type GetAppAuthorizeSettingResult = {
* }
* }
*/
albumAuthorized?: 'authorized' | 'denied' | 'not determined' | null,
albumAuthorized?: 'authorized' | 'denied' | 'not determined' | 'config error' | null,
/**
* 允许 App 使用蓝牙的开关(仅 iOS 支持)
* - authorized: 已经获得授权,无需再次请求授权
* - denied: 请求授权被拒绝,无法再次请求授权;(此情况需要引导用户打开系统设置,在设置页中打开权限)
* - not determined: 尚未请求授权,会在App下一次调用系统相应权限时请求;(仅 iOS 会出现。此种情况下引导用户打开系统设置,不展示开关)
* - config error: Android平台没有该值;iOS平台:表示没有在 `manifest.json -> App模块配置` 中配置 `BlueTooth(低功耗蓝牙)` 模块
* - config error: Android平台没有该值;iOS平台:当前应用没有配置蓝牙权限描述
* @type 'authorized' | 'denied' | 'not determined' | 'config error'
* @uniPlatform
* {
......@@ -88,8 +89,23 @@ export type GetAppAuthorizeSettingResult = {
* - authorized: 已经获得授权,无需再次请求授权
* - denied: 请求授权被拒绝,无法再次请求授权;(此情况需要引导用户打开系统设置,在设置页中打开权限)
* - not determined: 尚未请求授权,会在App下一次调用系统相应权限时请求;(仅 iOS 会出现。此种情况下引导用户打开系统设置,不展示开关)
* - config error: Android平台:表示没有配置 `android.permission.CAMERA` 权限,[权限配置详情](https://uniapp.dcloud.net.cn/tutorial/app-nativeresource-android.html#permissions);iOS平台没有该值
* - config error: Android平台:表示没有配置 `android.permission.CAMERA` 权限,[权限配置详情](https://uniapp.dcloud.net.cn/tutorial/app-nativeresource-android.html#permissions);iOS平台:当前应用没有配置相机权限描述
* @type 'authorized' | 'denied' | 'not determined' | 'config error'
* @uniPlatform
* {
* "app": {
* "android": {
* "osVer": "4.4",
* "uniVer": "√",
* "unixVer": "3.9"
* },
* "ios": {
* "osVer": "12.0",
* "uniVer": "√",
* "unixVer": "4.11"
* }
* }
* }
*/
cameraAuthorized: 'authorized' | 'denied' | 'not determined' | 'config error',
/**
......@@ -97,16 +113,46 @@ export type GetAppAuthorizeSettingResult = {
* - authorized: 已经获得授权,无需再次请求授权
* - denied: 请求授权被拒绝,无法再次请求授权;(此情况需要引导用户打开系统设置,在设置页中打开权限)
* - not determined: 尚未请求授权,会在App下一次调用系统相应权限时请求;(仅 iOS 会出现。此种情况下引导用户打开系统设置,不展示开关)
* - config error: Android平台:表示没有配置 `android.permission.ACCESS_COARSE_LOCATION` 权限,[权限配置详情](https://uniapp.dcloud.net.cn/tutorial/app-nativeresource-android.html#permissions);iOS平台:表示没有在 `manifest.json -> App模块配置` 中配置 `Geolocation(定位)` 模块
* - config error: Android平台:表示没有配置 `android.permission.ACCESS_COARSE_LOCATION` 权限,[权限配置详情](https://uniapp.dcloud.net.cn/tutorial/app-nativeresource-android.html#permissions);iOS平台:当前应用没有配置定位权限描述
* @type 'authorized' | 'denied' | 'not determined' | 'config error'
* @uniPlatform
* {
* "app": {
* "android": {
* "osVer": "4.4",
* "uniVer": "√",
* "unixVer": "3.9"
* },
* "ios": {
* "osVer": "12.0",
* "uniVer": "√",
* "unixVer": "4.11"
* }
* }
* }
*/
locationAuthorized: 'authorized' | 'denied' | 'not determined' | 'config error',
/**
* 定位准确度。
* - reduced: 模糊定位
* - full: 精准定位
* - unsupported: 不支持(包括用户拒绝定位权限和没有在 `manifest.json -> App模块配置` 中配置 `Geolocation(定位)` 模块
* - unsupported: 不支持(包括用户拒绝定位权限和没有包含定位权限描述
* @type 'reduced' | 'full' | 'unsupported'
* @uniPlatform
* {
* "app": {
* "android": {
* "osVer": "4.4",
* "uniVer": "√",
* "unixVer": "3.9"
* },
* "ios": {
* "osVer": "12.0",
* "uniVer": "√",
* "unixVer": "4.11"
* }
* }
* }
*/
locationAccuracy?: 'reduced' | 'full' | 'unsupported' | null,
/**
......@@ -134,8 +180,23 @@ export type GetAppAuthorizeSettingResult = {
* - authorized: 已经获得授权,无需再次请求授权
* - denied: 请求授权被拒绝,无法再次请求授权;(此情况需要引导用户打开系统设置,在设置页中打开权限)
* - not determined: 尚未请求授权,会在App下一次调用系统相应权限时请求;(仅 iOS 会出现。此种情况下引导用户打开系统设置,不展示开关)
* - config error: Android平台:表示没有配置 `android.permission.RECORD_AUDIO` 权限,[权限配置详情](https://uniapp.dcloud.net.cn/tutorial/app-nativeresource-android.html#permissions);iOS平台没有该值
* - config error: Android平台:表示没有配置 `android.permission.RECORD_AUDIO` 权限,[权限配置详情](https://uniapp.dcloud.net.cn/tutorial/app-nativeresource-android.html#permissions);iOS平台:当前应用没有配置麦克风权限描述
* @type 'authorized' | 'denied' | 'not determined' | 'config error'
* @uniPlatform
* {
* "app": {
* "android": {
* "osVer": "4.4",
* "uniVer": "√",
* "unixVer": "3.9"
* },
* "ios": {
* "osVer": "12.0",
* "uniVer": "√",
* "unixVer": "4.11"
* }
* }
* }
*/
microphoneAuthorized: 'authorized' | 'denied' | 'not determined' | 'config error',
/**
......@@ -143,8 +204,23 @@ export type GetAppAuthorizeSettingResult = {
* - authorized: 已经获得授权,无需再次请求授权
* - denied: 请求授权被拒绝,无法再次请求授权;(此情况需要引导用户打开系统设置,在设置页中打开权限)
* - not determined: 尚未请求授权,会在App下一次调用系统相应权限时请求;(仅 iOS 会出现。此种情况下引导用户打开系统设置,不展示开关)
* - config error: Android平台没有该值;iOS平台:表示没有在 `manifest.json -> App模块配置` 中配置 `Push(推送)` 模块
* - config error: Android平台没有该值;iOS平台:没有包含推送权限描述
* @type 'authorized' | 'denied' | 'not determined' | 'config error'
* @uniPlatform
* {
* "app": {
* "android": {
* "osVer": "4.4",
* "uniVer": "√",
* "unixVer": "3.9"
* },
* "ios": {
* "osVer": "12.0",
* "uniVer": "√",
* "unixVer": "4.11"
* }
* }
* }
*/
notificationAuthorized: 'authorized' | 'denied' | 'not determined' | 'config error',
/**
......@@ -152,7 +228,7 @@ export type GetAppAuthorizeSettingResult = {
* - authorized: 已经获得授权,无需再次请求授权
* - denied: 请求授权被拒绝,无法再次请求授权;(此情况需要引导用户打开系统设置,在设置页中打开权限)
* - not determined: 尚未请求授权,会在App下一次调用系统相应权限时请求;(仅 iOS 会出现。此种情况下引导用户打开系统设置,不展示开关)
* - config error: 没有在 `manifest.json -> App模块配置` 中配置 `Push(推送)` 模块
* - config error: 当前应用没有配置推送权限描述
* @type 'authorized' | 'denied' | 'not determined' | 'config error'
* @uniPlatform
* {
......@@ -176,7 +252,7 @@ export type GetAppAuthorizeSettingResult = {
* - authorized: 已经获得授权,无需再次请求授权
* - denied: 请求授权被拒绝,无法再次请求授权;(此情况需要引导用户打开系统设置,在设置页中打开权限)
* - not determined: 尚未请求授权,会在App下一次调用系统相应权限时请求;(仅 iOS 会出现。此种情况下引导用户打开系统设置,不展示开关)
* - config error: 没有在 `manifest.json -> App模块配置` 中配置 `Push(推送)` 模块
* - config error: 当前应用没有配置推送权限描述
* @type 'authorized' | 'denied' | 'not determined' | 'config error'
* @uniPlatform
* {
......@@ -200,7 +276,7 @@ export type GetAppAuthorizeSettingResult = {
* - authorized: 已经获得授权,无需再次请求授权
* - denied: 请求授权被拒绝,无法再次请求授权;(此情况需要引导用户打开系统设置,在设置页中打开权限)
* - not determined: 尚未请求授权,会在App下一次调用系统相应权限时请求;(仅 iOS 会出现。此种情况下引导用户打开系统设置,不展示开关)
* - config error: 没有在 `manifest.json -> App模块配置` 中配置 `Push(推送)` 模块
* - config error: 当前应用没有配置推送权限描述
* @type 'authorized' | 'denied' | 'not determined' | 'config error'
* @uniPlatform
* {
......
......@@ -39,7 +39,8 @@ export const getAppBaseInfo : GetAppBaseInfo = (config : GetAppBaseInfoOptions |
"uniCompilerVersionCode",
"uniRuntimeVersionCode",
"packageName",
"signature"
"signature",
"appTheme",
];
filter = defaultFilter;
}
......@@ -136,6 +137,10 @@ function getBaseInfo(filterArray : Array<string>) : GetAppBaseInfoResult {
result.signature = AppBaseInfoDeviceUtil.getAppSignatureSHA1(activity);
}
if (filterArray.indexOf("appTheme") != -1) {
result.appTheme = UTSAndroid.getAppTheme();
}
return result;
}
......
......@@ -35,7 +35,8 @@ export const getAppBaseInfo : GetAppBaseInfo = (config : GetAppBaseInfoOptions |
"uniPlatform",
"uniRuntimeVersion",
"uniCompilerVersionCode",
"uniRuntimeVersionCode"
"uniRuntimeVersionCode",
"appTheme",
];
filter = defaultFilter;
}
......@@ -117,6 +118,10 @@ function getBaseInfo(filterArray : Array<string>) : GetAppBaseInfoResult {
result.uniRuntimeVersionCode = AppBaseInfoConvertVersionCode(UTSiOS.getRuntimeVersion());
}
if (filterArray.indexOf("appTheme") != -1) {
result.appTheme = UTSiOS.getAppTheme();
}
return result;
}
......
......@@ -8,31 +8,171 @@ export type GetAppBaseInfoOptions = {
export type GetAppBaseInfoResult = {
/**
* manifest.json 中应用appid,即DCloud appid。
*
* @uniPlatform
* {
* "app": {
* "android": {
* "osVer": "5.0",
* "uniVer": "√",
* "unixVer": "3.9+"
* },
* "ios": {
* "osVer": "12.0",
* "uniVer": "√",
* "unixVer": "4.11"
* }
* },
* "web": {
* "uniVer": "√",
* "unixVer": "4.0"
* }
* }
*/
appId?: string,
/**
* `manifest.json` 中应用名称。
*
* @uniPlatform
* {
* "app": {
* "android": {
* "osVer": "5.0",
* "uniVer": "√",
* "unixVer": "3.9+"
* },
* "ios": {
* "osVer": "12.0",
* "uniVer": "√",
* "unixVer": "4.11"
* }
* },
* "web": {
* "uniVer": "√",
* "unixVer": "4.0"
* }
* }
*/
appName?: string,
/**
* `manifest.json` 中应用版本名称。
*
* @uniPlatform
* {
* "app": {
* "android": {
* "osVer": "5.0",
* "uniVer": "√",
* "unixVer": "3.9+"
* },
* "ios": {
* "osVer": "12.0",
* "uniVer": "√",
* "unixVer": "4.11"
* }
* },
* "web": {
* "uniVer": "√",
* "unixVer": "4.0"
* }
* }
*/
appVersion?: string,
/**
* `manifest.json` 中应用版本名号。
*
* @uniPlatform
* {
* "app": {
* "android": {
* "osVer": "5.0",
* "uniVer": "√",
* "unixVer": "3.9+"
* },
* "ios": {
* "osVer": "12.0",
* "uniVer": "√",
* "unixVer": "4.11"
* }
* },
* "web": {
* "uniVer": "√",
* "unixVer": "4.0"
* }
* }
*/
appVersionCode?: string,
/**
* 应用设置的语言en、zh-Hans、zh-Hant、fr、es
*
* @uniPlatform
* {
* "app": {
* "android": {
* "osVer": "5.0",
* "uniVer": "√",
* "unixVer": "3.9+"
* },
* "ios": {
* "osVer": "12.0",
* "uniVer": "√",
* "unixVer": "4.11"
* }
* },
* "web": {
* "uniVer": "√",
* "unixVer": "4.0"
* }
* }
*/
appLanguage?: string,
/**
* 应用设置的语言
*
* @uniPlatform
* {
* "app": {
* "android": {
* "osVer": "5.0",
* "uniVer": "√",
* "unixVer": "3.9+"
* },
* "ios": {
* "osVer": "12.0",
* "uniVer": "√",
* "unixVer": "4.11"
* }
* },
* "web": {
* "uniVer": "√",
* "unixVer": "4.0"
* }
* }
*/
language?: string,
/**
* 引擎版本号。已废弃,仅为了向下兼容保留
* @deprecated 已废弃,仅为了向下兼容保留
*
* @uniPlatform
* {
* "app": {
* "android": {
* "osVer": "5.0",
* "uniVer": "√",
* "unixVer": "3.9+"
* },
* "ios": {
* "osVer": "12.0",
* "uniVer": "√",
* "unixVer": "4.11"
* }
* },
* "web": {
* "uniVer": "x",
* "unixVer": "x"
* }
* }
*/
version?: string,
/**
......@@ -205,12 +345,52 @@ export type GetAppBaseInfoResult = {
hostTheme?: string,
/**
* 是否uni-app x
*
* @uniPlatform
* {
* "app": {
* "android": {
* "osVer": "5.0",
* "uniVer": "√",
* "unixVer": "3.9+"
* },
* "ios": {
* "osVer": "12.0",
* "uniVer": "√",
* "unixVer": "4.11"
* }
* },
* "web": {
* "uniVer": "x",
* "unixVer": "4.18"
* }
* }
*/
isUniAppX ?: boolean,
/**
* uni 编译器版本
* @deprecated 已废弃,仅为了向下兼容保留
*
* @uniPlatform
* {
* "app": {
* "android": {
* "osVer": "5.0",
* "uniVer": "√",
* "unixVer": "3.9+"
* },
* "ios": {
* "osVer": "12.0",
* "uniVer": "√",
* "unixVer": "4.11"
* }
* },
* "web": {
* "uniVer": "x",
* "unixVer": "x"
* }
* }
*/
uniCompileVersion ?: string,
/**
......@@ -231,23 +411,83 @@ export type GetAppBaseInfoResult = {
* }
* },
* "web": {
* "uniVer": "",
* "unixVer": "4.0"
* "uniVer": "x",
* "unixVer": "4.18"
* }
* }
*/
uniCompilerVersion ?: string,
/**
* uni-app 运行平台。
*
* @uniPlatform
* {
* "app": {
* "android": {
* "osVer": "5.0",
* "uniVer": "√",
* "unixVer": "3.9+"
* },
* "ios": {
* "osVer": "12.0",
* "uniVer": "√",
* "unixVer": "4.11"
* }
* },
* "web": {
* "uniVer": "√",
* "unixVer": "4.0"
* }
* }
*/
uniPlatform ?: 'app' | 'web' | 'mp-weixin' | 'mp-alipay' | 'mp-baidu' | 'mp-toutiao' | 'mp-lark' | 'mp-qq' | 'mp-kuaishou' | 'mp-jd' | 'mp-360' | 'quickapp-webview' | 'quickapp-webview-union' | 'quickapp-webview-huawei',
/**
* uni 运行时版本
*
* @uniPlatform
* {
* "app": {
* "android": {
* "osVer": "5.0",
* "uniVer": "√",
* "unixVer": "3.9+"
* },
* "ios": {
* "osVer": "12.0",
* "uniVer": "√",
* "unixVer": "4.11"
* }
* },
* "web": {
* "uniVer": "x",
* "unixVer": "4.18"
* }
* }
*/
uniRuntimeVersion ?: string,
/**
* uni 编译器版本号
* @deprecated 已废弃,仅为了向下兼容保留
*
* @uniPlatform
* {
* "app": {
* "android": {
* "osVer": "5.0",
* "uniVer": "√",
* "unixVer": "3.9+"
* },
* "ios": {
* "osVer": "12.0",
* "uniVer": "√",
* "unixVer": "4.11"
* }
* },
* "web": {
* "uniVer": "x",
* "unixVer": "x"
* }
* }
*/
uniCompileVersionCode?: number,
/**
......@@ -268,14 +508,34 @@ export type GetAppBaseInfoResult = {
* }
* },
* "web": {
* "uniVer": "",
* "unixVer": "4.0"
* "uniVer": "x",
* "unixVer": "4.18"
* }
* }
*/
uniCompilerVersionCode?: number,
/**
* uni 运行时版本号
*
* @uniPlatform
* {
* "app": {
* "android": {
* "osVer": "5.0",
* "uniVer": "√",
* "unixVer": "3.9+"
* },
* "ios": {
* "osVer": "12.0",
* "uniVer": "√",
* "unixVer": "4.11"
* }
* },
* "web": {
* "uniVer": "x",
* "unixVer": "x"
* }
* }
*/
uniRuntimeVersionCode?: number,
/**
......@@ -351,6 +611,30 @@ export type GetAppBaseInfoResult = {
* }
*/
signature?: string,
/**
* 当前App的主题
*
* @uniPlatform
* {
* "app": {
* "android": {
* "osVer": "5.0",
* "uniVer": "x",
* "unixVer": "4.18"
* },
* "ios": {
* "osVer": "12.0",
* "uniVer": "x",
* "unixVer": "4.18"
* }
* },
* "web": {
* "uniVer": "x",
* "unixVer": "x"
* }
* }
*/
appTheme?: 'light' | 'dark' | 'auto' | null,
}
/**
......
......@@ -216,6 +216,15 @@ export class DeviceUtil {
return UTSAndroid.getOAID();
}
public static getRomName():string{
DeviceUtil.setCustomInfo(Build.MANUFACTURER);
return DeviceUtil.customOS ?? "";
}
public static getRomVersion():string{
DeviceUtil.setCustomInfo(Build.MANUFACTURER);
return DeviceUtil.customOSVersion ?? "";
}
/**
* 是否为平板 不是太准确
......
......@@ -24,7 +24,14 @@ export const getDeviceInfo : GetDeviceInfo = (config : GetDeviceInfoOptions | nu
"platform",
"isRoot",
"isSimulator",
"isUSBDebugging"
"isUSBDebugging",
"osName",
"osVersion",
"osLanguage",
"osTheme",
"osAndroidAPILevel",
"romName",
"romVersion"
];
filter = defaultFilter;
}
......@@ -56,7 +63,7 @@ function getBaseInfo(filterArray : Array<string>) : GetDeviceInfoResult {
result.deviceId = DeviceUtil.getDeviceID(activity);
}
if (filterArray.indexOf("devicePixelRatio") != -1) {
result.devicePixelRatio = DeviceUtil.getScaledDensity(activity) + "";
result.devicePixelRatio = DeviceUtil.getScaledDensity(activity);
}
if (filterArray.indexOf("system") != -1) {
result.system = "Android " + Build.VERSION.RELEASE;
......@@ -73,5 +80,27 @@ function getBaseInfo(filterArray : Array<string>) : GetDeviceInfoResult {
if (filterArray.indexOf("isUSBDebugging") != -1) {
result.isUSBDebugging = DeviceUtil.listeningForADB();
}
if (filterArray.indexOf("osName") != -1) {
result.osName = "android";
}
if (filterArray.indexOf("osVersion") != -1) {
result.osVersion = Build.VERSION.RELEASE;
}
if (filterArray.indexOf("osLanguage") != -1) {
result.osLanguage = UTSAndroid.getLanguageInfo(activity)["osLanguage"].toString();
}
if (filterArray.indexOf("osTheme") != -1) {
result.osTheme = UTSAndroid.getOsTheme();
}
if (filterArray.indexOf("osAndroidAPILevel") != -1) {
result.osAndroidAPILevel = Build.VERSION.SDK_INT;
}
if (filterArray.indexOf("romName") != -1) {
result.romName = DeviceUtil.getRomName();
}
if (filterArray.indexOf("romVersion") != -1) {
result.romVersion = DeviceUtil.getRomVersion();
}
return result;
}
\ No newline at end of file
......@@ -28,15 +28,6 @@ export class DeviceUtil {
return orientation;
}
public static getScreenScale(): string {
return UIScreen.main.scale.description;
}
public static getIdfa(): string {
return UTSiOS.getGgbs()
}
public static hasRootPrivilege(): boolean {
return UTSiOS.isRoot()
}
......
......@@ -3,6 +3,7 @@ import { UTSiOS } from "DCloudUTSFoundation";
import { DeviceUtil } from './device/DeviceUtil.uts';
import { GetDeviceInfo, GetDeviceInfoOptions, GetDeviceInfoResult } from '../interface.uts'
import { UIScreen , UIDevice ,UIApplication } from 'UIKit';
export const getDeviceInfo : GetDeviceInfo = (config : GetDeviceInfoOptions | null) : GetDeviceInfoResult => {
let filter : Array<string> = [];
......@@ -24,7 +25,13 @@ export const getDeviceInfo : GetDeviceInfo = (config : GetDeviceInfoOptions | nu
"system",
"platform",
"isRoot",
"isSimulator"
"isSimulator",
"osName",
"osVersion",
"osLanguage",
"osTheme",
"romName",
"romVersion"
];
filter = defaultFilter;
}
......@@ -57,7 +64,7 @@ function getBaseInfo(filterArray : Array<string>) : GetDeviceInfoResult {
result.deviceOrientation = DeviceUtil.getOrientation();
}
if (filterArray.indexOf("devicePixelRatio") != -1) {
result.devicePixelRatio = DeviceUtil.getScreenScale();
result.devicePixelRatio = Number.from(UIScreen.main.scale);
}
if (filterArray.indexOf("system") != -1) {
result.system = String(format = "iOS %@", osVersion);
......@@ -72,5 +79,24 @@ function getBaseInfo(filterArray : Array<string>) : GetDeviceInfoResult {
result.isSimulator = UTSiOS.isSimulator();
}
if (filterArray.indexOf("osName") != -1) {
result.osName = "ios";
}
if (filterArray.indexOf("osVersion") != -1) {
result.osVersion = UIDevice.current.systemVersion;
}
if (filterArray.indexOf("osLanguage") != -1) {
result.osLanguage = UTSiOS.getOsLanguage();
}
if (filterArray.indexOf("osTheme") != -1) {
result.osTheme = UTSiOS.getOsTheme();
}
if (filterArray.indexOf("romName") != -1) {
result.romName = "ios"
}
if (filterArray.indexOf("romVersion") != -1) {
result.romVersion = UIDevice.current.systemVersion;
}
return result;
}
\ No newline at end of file
......@@ -3,55 +3,297 @@ export type GetDeviceInfoOptions = {
* @description 过滤字段的字符串数组,假如要获取指定字段,传入此数组。
*/
filter: Array<string>
}
}
export type GetDeviceInfoResult = {
export type GetDeviceInfoResult = {
/**
* 设备品牌
* @deprecated 已废弃,仅为了向下兼容保留
*
* @uniPlatform
* {
* "app": {
* "android": {
* "osVer": "5.0",
* "uniVer": "√",
* "unixVer": "3.9+"
* },
* "ios": {
* "osVer": "12.0",
* "uniVer": "√",
* "unixVer": "4.11"
* }
* },
* "web": {
* "uniVer": "x",
* "unixVer": "x"
* }
* }
*/
brand?: string
/**
* 设备品牌
*
* @uniPlatform
* {
* "app": {
* "android": {
* "osVer": "5.0",
* "uniVer": "√",
* "unixVer": "3.9+"
* },
* "ios": {
* "osVer": "12.0",
* "uniVer": "√",
* "unixVer": "4.11"
* }
* },
* "web": {
* "uniVer": "x",
* "unixVer": "x"
* }
* }
*/
deviceBrand?: string,
/**
* 设备 id 。由 uni-app 框架生成并存储,清空 Storage 会导致改变
*
* @uniPlatform
* {
* "app": {
* "android": {
* "osVer": "5.0",
* "uniVer": "√",
* "unixVer": "3.9+"
* },
* "ios": {
* "osVer": "12.0",
* "uniVer": "√",
* "unixVer": "4.11"
* }
* },
* "web": {
* "uniVer": "√",
* "unixVer": "4.0"
* }
* }
*/
deviceId?: string,
/**
* 设备型号
* @deprecated 已废弃,仅为了向下兼容保留
*
* @uniPlatform
* {
* "app": {
* "android": {
* "osVer": "5.0",
* "uniVer": "√",
* "unixVer": "3.9+"
* },
* "ios": {
* "osVer": "12.0",
* "uniVer": "√",
* "unixVer": "4.11"
* }
* },
* "web": {
* "uniVer": "√",
* "unixVer": "4.0"
* }
* }
*/
model?: string,
/**
* 设备型号
*
* @uniPlatform
* {
* "app": {
* "android": {
* "osVer": "5.0",
* "uniVer": "√",
* "unixVer": "3.9+"
* },
* "ios": {
* "osVer": "12.0",
* "uniVer": "√",
* "unixVer": "4.11"
* }
* },
* "web": {
* "uniVer": "√",
* "unixVer": "4.0"
* }
* }
*/
deviceModel?: string,
/**
* 设备类型phone、pad、pc
*
* @uniPlatform
* {
* "app": {
* "android": {
* "osVer": "5.0",
* "uniVer": "√",
* "unixVer": "3.9+"
* },
* "ios": {
* "osVer": "12.0",
* "uniVer": "√",
* "unixVer": "4.11"
* }
* },
* "web": {
* "uniVer": "√",
* "unixVer": "4.0"
* }
* }
*/
deviceType?: string,
deviceType?: 'phone' | 'pad' | 'tv' | 'watch' | 'pc' | 'undefined' | 'car' | 'vr' | 'appliance',
/**
* 设备方向 竖屏 portrait、横屏 landscape
*
* @uniPlatform
* {
* "app": {
* "android": {
* "osVer": "5.0",
* "uniVer": "√",
* "unixVer": "3.9+"
* },
* "ios": {
* "osVer": "12.0",
* "uniVer": "√",
* "unixVer": "4.11"
* }
* },
* "web": {
* "uniVer": "√",
* "unixVer": "4.0"
* }
* }
*/
deviceOrientation?: string,
/**
* 设备像素比
*
* @uniPlatform
* {
* "app": {
* "android": {
* "osVer": "5.0",
* "uniVer": "√",
* "unixVer": "3.9+"
* },
* "ios": {
* "osVer": "12.0",
* "uniVer": "√",
* "unixVer": "4.11"
* }
* },
* "web": {
* "uniVer": "√",
* "unixVer": "4.0"
* }
* }
*/
devicePixelRatio?: string,
devicePixelRatio?: number,
/**
* 操作系统及版本
*
* @uniPlatform
* {
* "app": {
* "android": {
* "osVer": "5.0",
* "uniVer": "√",
* "unixVer": "3.9+"
* },
* "ios": {
* "osVer": "12.0",
* "uniVer": "√",
* "unixVer": "4.11"
* }
* },
* "web": {
* "uniVer": "√",
* "unixVer": "4.0"
* }
* }
*/
system?: string,
/**
* 客户端平台
*
* @uniPlatform
* {
* "app": {
* "android": {
* "osVer": "5.0",
* "uniVer": "√",
* "unixVer": "3.9+"
* },
* "ios": {
* "osVer": "12.0",
* "uniVer": "√",
* "unixVer": "4.11"
* }
* },
* "web": {
* "uniVer": "√",
* "unixVer": "4.0"
* }
* }
*/
platform?: string,
platform?: 'ios' | 'android' | 'mac' | 'windows' | 'linux',
/**
* 是否root
* 是否root。iOS 为是否越狱
*
* @uniPlatform
* {
* "app": {
* "android": {
* "osVer": "5.0",
* "uniVer": "x",
* "unixVer": "3.9+"
* },
* "ios": {
* "osVer": "12.0",
* "uniVer": "x",
* "unixVer": "4.11"
* }
* },
* "web": {
* "uniVer": "x",
* "unixVer": "x"
* }
* }
*/
isRoot?: boolean,
/**
* 是否是模拟器
*
* @uniPlatform
* {
* "app": {
* "android": {
* "osVer": "5.0",
* "uniVer": "x",
* "unixVer": "3.9+"
* },
* "ios": {
* "osVer": "12.0",
* "uniVer": "x",
* "unixVer": "4.11"
* }
* },
* "web": {
* "uniVer": "x",
* "unixVer": "x"
* }
* }
*/
isSimulator?: boolean,
/**
......@@ -70,20 +312,192 @@ export type GetDeviceInfoResult = {
* "uniVer": "x",
* "unixVer": "x"
* }
* },
* "web": {
* "uniVer": "x",
* "unixVer": "x"
* }
* }
*/
isUSBDebugging?: boolean,
}
/**
* 系统名称
*
* @uniPlatform
* {
* "app": {
* "android": {
* "osVer": "5.0",
* "uniVer": "x",
* "unixVer": "4.18"
* },
* "ios": {
* "osVer": "12.0",
* "uniVer": "x",
* "unixVer": "4.18"
* }
* },
* "web": {
* "uniVer": "x",
* "unixVer": "4.18"
* }
* }
*/
osName?: 'ios' | 'android' | 'macos' | 'windows' | 'linux' | null,
/**
* 操作系统版本。如 ios 版本,andriod 版本
*
* @uniPlatform
* {
* "app": {
* "android": {
* "osVer": "5.0",
* "uniVer": "x",
* "unixVer": "4.18"
* },
* "ios": {
* "osVer": "12.0",
* "uniVer": "x",
* "unixVer": "4.18"
* }
* },
* "web": {
* "uniVer": "x",
* "unixVer": "4.18"
* }
* }
*/
osVersion?: string | null,
/**
* 操作系统语言
*
* @uniPlatform
* {
* "app": {
* "android": {
* "osVer": "5.0",
* "uniVer": "x",
* "unixVer": "4.18"
* },
* "ios": {
* "osVer": "12.0",
* "uniVer": "x",
* "unixVer": "4.18"
* }
* },
* "web": {
* "uniVer": "x",
* "unixVer": "x"
* }
* }
*/
osLanguage?: string | null,
/**
* 操作系统主题
*
* @uniPlatform
* {
* "app": {
* "android": {
* "osVer": "5.0",
* "uniVer": "x",
* "unixVer": "4.18"
* },
* "ios": {
* "osVer": "12.0",
* "uniVer": "x",
* "unixVer": "4.18"
* }
* },
* "web": {
* "uniVer": "x",
* "unixVer": "x"
* }
* }
*/
osTheme?: 'light' | 'dark' | null,
/**
* Android 系统API库的版本。
*
* @uniPlatform
* {
* "app": {
* "android": {
* "osVer": "5.0",
* "uniVer": "x",
* "unixVer": "4.18"
* },
* "ios": {
* "osVer": "x",
* "uniVer": "x",
* "unixVer": "x"
* }
* },
* "web": {
* "uniVer": "x",
* "unixVer": "x"
* }
* }
*/
osAndroidAPILevel?: number | null,
/**
* rom 名称。Android 部分机型获取不到值。iOS 恒为 `ios`
*
* @uniPlatform
* {
* "app": {
* "android": {
* "osVer": "5.0",
* "uniVer": "x",
* "unixVer": "4.18"
* },
* "ios": {
* "osVer": "12.0",
* "uniVer": "x",
* "unixVer": "4.18"
* }
* },
* "web": {
* "uniVer": "x",
* "unixVer": "x"
* }
* }
*/
romName?: string | null,
/**
* rom 版本号。Android 部分机型获取不到值。iOS 为操作系统版本号(同 `osVersion`)。
*
* @uniPlatform
* {
* "app": {
* "android": {
* "osVer": "5.0",
* "uniVer": "x",
* "unixVer": "4.18"
* },
* "ios": {
* "osVer": "12.0",
* "uniVer": "x",
* "unixVer": "4.18"
* }
* },
* "web": {
* "uniVer": "x",
* "unixVer": "x"
* }
* }
*/
romVersion?: string | null,
}
/**
/**
* @param [options=包含所有字段的过滤对象] 过滤的字段对象, 不传参数默认为获取全部字段。
*/
export type GetDeviceInfo = (options?: GetDeviceInfoOptions | null) => GetDeviceInfoResult;
export type GetDeviceInfo = (options?: GetDeviceInfoOptions | null) => GetDeviceInfoResult;
export interface Uni {
export interface Uni {
/**
* GetDeviceInfo(Object object)
* @description
......@@ -118,4 +532,5 @@ export interface Uni {
```
*/
getDeviceInfo(options?: GetDeviceInfoOptions | null): GetDeviceInfoResult;
}
}
\ No newline at end of file
......@@ -22,16 +22,16 @@ export interface Uni {
* "unixVer": "3.9.0"
* },
* "ios": {
* "osVer": "x",
* "uniVer": "x",
* "unixVer": "x"
* "osVer": "12.0",
* "uniVer": "",
* "unixVer": "4.11"
* }
* },
* "web": {
* "uniVer": "√",
* "unixVer": "4.0"
* }
* }9999
* }
*
*/
getLocation(options: GetLocationOptions):void;
......@@ -112,7 +112,7 @@ export type GetLocationOptions = {
* 默认为 wgs84 返回 gps 坐标,gcj02 返回可用于uni.openLocation的坐标,web端需配置定位 SDK 信息才可支持 gcj02
* @defaultValue wgs84
*/
type?: "wgs84" | "gcj02" | "gps" | null,
type?: "wgs84" | "gcj02" | null,
/**
* 传入 true 会返回高度信息,由于获取高度需要较高精确度,会减慢接口返回速度
* @type boolean
......
## 1.1(2024-06-20)
支持iOS平台
## 1.0.1(2023-10-23)
更新android自定义基座操作步骤
## 1.0.0(2023-09-11)
......
{
"id": "uni-getLocation-tencent",
"displayName": "uni-getLocation-tencent",
"version": "1.0.1",
"version": "1.1",
"description": "基于腾讯定位服务,实现uni.getLocation 获取定位功能",
"keywords": [
"uni-getLocation-tencent"
"uni.getLocation",
"tencent"
],
"repository": "",
"engines": {
"HBuilderX": "^3.8.12"
"HBuilderX": "^4.0"
},
"dcloudext": {
"type": "uts",
......@@ -41,7 +42,8 @@
"platforms": {
"cloud": {
"tcb": "y",
"aliyun": "y"
"aliyun": "y",
"alipay": "n"
},
"client": {
"Vue": {
......@@ -50,10 +52,10 @@
},
"App": {
"app-android": {
"minVersion": "19"
"minVersion": "21"
},
"app-ios": {
"minVersion": "9"
"minVersion": "12"
}
},
"H5-mobile": {
......
# uts-tencentgeolocation腾讯定位插件使用文档
## API使用
参考[uni.getLocation](https://doc.dcloud.net.cn/uni-app-x/api/get-location.html)
## Android 平台
1. 申请腾讯地图key
[申请网址](https://lbs.qq.com/mobile/androidMapSDK/developerGuide/getKey)
2. 配置key到插件中
2. 配置key到项目
在项目根目录下添加 AndroidManifest.xml 文件,详情参考:[Android原生应用清单文件](https://uniapp.dcloud.net.cn/tutorial/app-nativeresource-android.html#%E5%BA%94%E7%94%A8%E6%B8%85%E5%8D%95%E6%96%87%E4%BB%B6-androidmanifest-xml)。将申请的 key 配置到项目 AndroidManifest.xml 的 application 节点中,如下:
```xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools"
>
<application>
<!-- 将申请到的 key 配置在 android:value 属性中 -->
<meta-data android:name="TencentMapSDK" android:value="您申请的Key" />
修改项目根目录下 AndroidManifest.xml
`<meta-data android:name="TencentMapSDK" android:value="您申请的Key" />`
</application>
</manifest>
```
3. 制作自定义基座运行后生效
提交云端打包制作自定义基座后,再在HBuilderX中真机运行。
## iOS 平台
1.申请腾讯地图key
1. 申请腾讯地图key
[申请网址](https://lbs.qq.com/mobile/androidMapSDK/developerGuide/getKey)
2.配置key到插件中
2. 配置key到插件中
将申请的key配置到插件目录下 app-ios -> info.plist 中 TencentLBSAPIKey 对应的值
在项目根目录下添加 Info.plist 文件,详情参考:[iOS原生应用配置文件](https://uniapp.dcloud.net.cn/tutorial/app-nativeresource-ios.html#infoplist)。将申请的 key 配置到项目 Info.plist 的 TencentLBSAPIKey 键值中,如下:
```xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>TencentLBSAPIKey</key>
<string>您申请的Key</string>
</dict>
</plist>
```
3. 配置访问位置权限描述信息
在项目根目录下 Info.plist 文件中添加以下权限描述信息:
```xml
<key>TencentLBSAPIKey</key>
<string>您申请的Key</string>
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>NSLocationAlwaysUsageDescription</key>
<string>后台运行期访问位置信息的许可描述</string>
<key>NSLocationWhenInUseUsageDescription</key>
<string>运行期访问位置信息的许可描述</string>
<key>NSLocationAlwaysAndWhenInUseUsageDescription</key>
<string>访问位置信息的许可描述</string>
</dict>
</plist>
```
3.配置访问位置权限描述信息
> 许可描述信息需根据应用实际业务情况准确描述,否则可能无法通过 AppStore 上架审核
> uni-app 项目也可以在 manifest.json 的 "App权限配置" 可视化界面的 "iOS隐私信息访问的许可描述" 下配置
3. 制作自定义基座运行后生效
提交云端打包制作自定义基座后,再在HBuilderX中真机运行。
## 注意事项
### 隐私合规问题
此插件使用了腾讯位置服务SDK,调用定位API会采集个人隐私信息,在业务中请确保最终用户已经同意了App的隐私协议后再调用定位API,否则会因为隐私合规问题无法上架应用市场。
选中工程中的 manifest.json -> App权限配置 -> iOS隐私信息访问的许可描述,分别配置下列权限描述信息
App的隐私政策中需披露使用的三方SDK相关情况:
- NSLocationAlwaysUsageDescription
- NSLocationWhenInUseUsageDescription
- NSLocationAlwaysAndWhenInUseUsageDescription
- Android平台腾讯位置服务SDK [合规说明](https://lbs.qq.com/mobile/androidLocationSDK/androidLBSInfo)
- iOS平台腾讯位置服务SDK [合规说明](https://lbs.qq.com/mobile/iosLocationSDK/iosLBSInfo)
4.制作自定义基座运行后生效
## 相关开发文档
- [UTS 语法](https://uniapp.dcloud.net.cn/tutorial/syntax-uts.html)
- [UTS 原生插件](https://uniapp.dcloud.net.cn/plugin/uts-plugin.html)
- [UTS 插件开发文档](https://doc.dcloud.net.cn/uni-app-x/plugin/uts-plugin.html)
......@@ -2,6 +2,6 @@
"dependencies": [
"com.tencent.map.geolocation:TencentLocationSdk-openplatform:7.3.0"
],
"minSdkVersion": "19"
"minSdkVersion": "21"
}
//
// TencentLBS.h
// TencentLBS
//
// Created by mirantslu on 16/4/19.
// Copyright © 2016年 Tencent. All rights reserved.
//
#import <UIKit/UIKit.h>
//! Project version number for TencentLBS.
FOUNDATION_EXPORT double TencentLBSVersionNumber;
//! Project version string for TencentLBS.
FOUNDATION_EXPORT const unsigned char TencentLBSVersionString[];
// In this header, you should import all the public headers of your framework using statements like #import <TencentLBS/PublicHeader.h>
#import <TencentLBS/TencentLBSLocation.h>
#import <TencentLBS/TencentLBSLocationManager.h>
#import <TencentLBS/TencentLBSLocationUtils.h>
//
// TencentLBSLocation.h
// TencentLBS
//
// Created by mirantslu on 16/4/19.
// Copyright © 2016年 Tencent. All rights reserved.
//
#import <Foundation/Foundation.h>
#import <CoreLocation/CoreLocation.h>
NS_ASSUME_NONNULL_BEGIN
#define TENCENTLBS_DEBUG 0
typedef NS_ENUM(NSInteger, TencentLBSDRProvider) {
TencentLBSDRProviderError = -2, //!< 错误,可能未开启dr
TencentLBSDRProviderUnkown = -1, //!< 定位结果来源未知
TencentLBSDRProviderFusion = 0, //!< 定位结果来源融合的结果
TencentLBSDRProviderGPS = 1, //!< 定位结果来源GPS
TencentLBSDRProviderNetWork = 2, //!< 定位结果来源网络
};
@interface TencentLBSPoi : NSObject<NSSecureCoding, NSCopying>
@property (nonatomic, copy) NSString *uid; //!< 当前POI的uid
@property (nonatomic, copy) NSString *name; //!< 当前POI的名称
@property (nonatomic, copy) NSString *address; //!< 当前POI的地址
@property (nonatomic, copy) NSString *catalog; //!< 当前POI的类别
@property (nonatomic, assign) double longitude; //!< 当前POI的经度
@property (nonatomic, assign) double latitude; //!< 当前POI的纬度
@property (nonatomic, assign) double distance; //!< 当前POI与当前位置的距离
@end
@interface TencentLBSLocation : NSObject<NSSecureCoding, NSCopying>
/**
* 返回当前位置的CLLocation信息
*/
@property (nonatomic, strong) CLLocation *location;
/**
* 返回当前位置的行政区划, 0-表示中国大陆、港、澳, 1-表示其他
*/
@property (nonatomic, assign) NSInteger areaStat;
/**
* 返回室内定位楼宇Id
*/
@property (nonatomic, copy, nullable) NSString *buildingId;
/**
* 返回室内定位楼层
*/
@property (nonatomic, copy, nullable) NSString *buildingFloor;
/**
* 返回室内定位类型,0表示普通定位结果,1表示蓝牙室内定位结果
*/
@property (nonatomic, assign) NSInteger indoorLocationType;
/**
*
*/
@property (nonatomic, assign) TencentLBSDRProvider drProvider;
/**
* 返回当前位置的名称,
* 仅当TencentLBSRequestLevel为TencentLBSRequestLevelName或TencentLBSRequestLevelAdminName或TencentLBSRequestLevelPoi有返回值,否则为空
*/
@property (nonatomic, copy, nullable) NSString *name;
/**
* 返回当前位置的地址
* 仅当TencentLBSRequestLevel为TencentLBSRequestLevelName或TencentLBSRequestLevelAdminName有返回值,否则为空
*/
@property (nonatomic, copy, nullable) NSString *address;
/**
* 返回国家编码,例如中国为156
* <b>注意:该接口涉及到WebService API,请参考https://lbs.qq.com/service/webService/webServiceGuide/webServiceOverview中的配额限制说明,
* 并将申请的有效key通过TencentLBSLocationManager的- (void)setDataWithValue: forKey:方法设置,其中key为固定值@"ReGeoCodingnKey",例如[tencentLocationManager setDataWithValue:@"您申请的key(务必正确)" forKey:@"ReGeoCodingnKey"];,否则将返回默认值0</b>
*/
@property (nonatomic, assign) NSInteger nationCode;
/**
* 返回当前位置的城市编码
* 仅当TencentLBSRequestLevel为TencentLBSRequestLevelAdminName或TencentLBSRequestLevelPoi有返回值,否则为空
*/
@property (nonatomic, copy, nullable) NSString *code;
/**
* 返回当前位置的国家
* 仅当TencentLBSRequestLevel为TencentLBSRequestLevelAdminName或TencentLBSRequestLevelPoi有返回值,否则为空
*/
@property (nonatomic, copy, nullable) NSString *nation;
/**
* 返回当前位置的省份
* 仅当TencentLBSRequestLevel为TencentLBSRequestLevelAdminName或TencentLBSRequestLevelPoi有返回值,否则为空
*/
@property (nonatomic, copy, nullable) NSString *province;
/**
* 返回当前位置的城市固话编码.
* 仅当TencentLBSRequestLevel为TencentLBSRequestLevelAdminName或TencentLBSRequestLevelPoi有返回值,否则为空
*/
@property (nonatomic, copy, nullable) NSString *cityPhoneCode;
/**
* 返回当前位置的城市
* 仅当TencentLBSRequestLevel为TencentLBSRequestLevelAdminName或TencentLBSRequestLevelPoi有返回值,否则为空
*/
@property (nonatomic, copy, nullable) NSString *city;
/**
* 返回当前位置的区县
* 仅当TencentLBSRequestLevel为TencentLBSRequestLevelAdminName或TencentLBSRequestLevelPoi有返回值,否则为空
*/
@property (nonatomic, copy, nullable) NSString *district;
/**
* 返回当前位置的乡镇
* 仅当TencentLBSRequestLevel为TencentLBSRequestLevelAdminName或TencentLBSRequestLevelPoi有返回值,否则为空
*/
@property (nonatomic, copy, nullable) NSString *town;
/**
* 返回当前位置的村
* 仅当TencentLBSRequestLevel为TencentLBSRequestLevelAdminName或TencentLBSRequestLevelPoi有返回值,否则为空
*/
@property (nonatomic, copy, nullable) NSString *village;
/**
* 返回当前位置的街道
* 仅当TencentLBSRequestLevel为TencentLBSRequestLevelAdminName或TencentLBSRequestLevelPoi有返回值,否则为空
*/
@property (nonatomic, copy, nullable) NSString *street;
/**
* 返回当前位置的街道编码
* 仅当TencentLBSRequestLevel为TencentLBSRequestLevelAdminName或TencentLBSRequestLevelPoi有返回值,否则为空
*/
@property (nonatomic, copy, nullable) NSString *street_no;
/**
* 返回当前位置周围的POI
* 仅当TencentLBSRequestLevel为TencentLBSRequestLevelPoi有返回值,否则为空
*/
@property (nonatomic, strong, nullable) NSArray<TencentLBSPoi*> *poiList;
/**
* 返回两个位置之间的横向距离
* @param location
*/
- (double)distanceFromLocation:(const TencentLBSLocation *)location;
// 测试使用
#if TENCENTLBS_DEBUG
@property (nonatomic, copy, nullable) NSString *halleyTime;
#endif
@end
NS_ASSUME_NONNULL_END
//
// TencentLBSLocationManager.h
// TencentLBS
//
// Created by mirantslu on 16/4/19.
// Copyright © 2016年 Tencent. All rights reserved.
//
#import <Foundation/Foundation.h>
#import <CoreLocation/CoreLocation.h>
#import "TencentLBSLocation.h"
NS_ASSUME_NONNULL_BEGIN
typedef NS_ENUM(NSUInteger, TencentLBSRequestLevel) {
TencentLBSRequestLevelGeo = 0,
TencentLBSRequestLevelName = 1,
TencentLBSRequestLevelAdminName = 3,
TencentLBSRequestLevelPoi = 4,
};
typedef NS_ENUM(NSUInteger, TencentLBSLocationCoordinateType) {
TencentLBSLocationCoordinateTypeGCJ02 = 0, //!< 火星坐标,即国测局坐标
TencentLBSLocationCoordinateTypeWGS84 = 1, //!< 地球坐标,注:如果是海外,无论设置的是火星坐标还是地球坐标,返回的都是地球坐标
};
typedef NS_ENUM(NSUInteger, TencentLBSLocationError) {
TencentLBSLocationErrorUnknown = 0, //!< 错误码,表示目前位置未知,但是会一直尝试获取
TencentLBSLocationErrorDenied = 1, //!< 错误码,表示定位权限被禁止
TencentLBSLocationErrorNetwork = 2, //!< 错误码,表示网络错误
TencentLBSLocationErrorHeadingFailure = 3, //!< 错误码,表示朝向无法确认
TencentLBSLocationErrorOther = 4, //!< 错误码,表示未知错误
};
typedef NS_ENUM(NSInteger, TencentLBSDRStartCode) {
TencentLBSDRStartCodeSuccess = 0, //!< 启动成功
TencentLBSDRStartCodeNotSupport = -1, //!< 传感器有缺失或没有GPS芯片
TencentLBSDRStartCodeHasStarted = -2, //!< 已经启动
TencentLBSDRStartCodeSensorFailed = -3, //!< 传感器启动失败
TencentLBSDRStartCodeGpsFailed = -4, //!< GPS启动失败
TencentLBSDRStartCodePermissionFailed = -5, //!< 没有位置权限
TencentLBSDRStartCodeUnkown = -6, //!< 未知
};
typedef NS_ENUM(NSInteger, TencentLBSDRStartMotionType) {
TencentLBSDRStartMotionTypeWalk = 2, //!< 步行
TencentLBSDRStartMotionTypeBike = 3, //!< 骑行
};
typedef NS_ENUM(NSInteger, TencentLBSAccuracyAuthorization) {
// This application has the user's permission to receive accurate location information.
TencentLBSAccuracyAuthorizationFullAccuracy,
// The user has chosen to grant this application access to location information with reduced accuracy.
// Region monitoring and beacon ranging are not available to the application. Other CoreLocation APIs
// are available with reduced accuracy.
// Location estimates will have a horizontalAccuracy on the order of about 5km. To achieve the
// reduction in accuracy, CoreLocation will snap location estimates to a nearby point which represents
// the region the device is in. Furthermore, CoreLocation will reduce the rate at which location
// estimates are produced. Applications should be prepared to receive locations that are up to 20
// minutes old.
TencentLBSAccuracyAuthorizationReducedAccuracy,
};
/**
* TencentLBSLocatingCompletionBlock 单次定位返回Block
*
* @param location 位置信息
* @param error 错误信息 参考 TencentLBSLocationError
*/
typedef void (^TencentLBSLocatingCompletionBlock)(TencentLBSLocation * _Nullable location, NSError * _Nullable error);
@protocol TencentLBSLocationManagerDelegate;
@interface TencentLBSLocationManager : NSObject
/**
* 当前位置管理器定位精度的授权状态
*/
@property(nonatomic, readonly)TencentLBSAccuracyAuthorization accuracyAuthorization;
/**
* 当前位置管理器定位权限的授权状态
*/
@property(nonatomic, readonly)CLAuthorizationStatus authorizationStatus;
/**
* API Key, 在使用定位SDK服务之前需要先绑定key。
*/
@property (nonatomic, copy) NSString* apiKey;
/**
* 实现了 TencentLBSLocationManagerDelegate 协议的类指针。
*/
@property (nonatomic, weak) id<TencentLBSLocationManagerDelegate> delegate;
/**
* 设定定位的最小更新距离。默认为 kCLDistanceFilterNone。
*/
@property (nonatomic, assign) CLLocationDistance distanceFilter;
/**
* 设定定位精度。默认为 kCLLocationAccuracyBest 。
*/
@property (nonatomic, assign) CLLocationAccuracy desiredAccuracy;
/**
* 指定定位是否会被系统自动暂停。默认为 YES 。
*/
@property (nonatomic, assign) BOOL pausesLocationUpdatesAutomatically;
/**
* 是否允许后台定位。默认为 NO。
* iOS 9.0 以上用户需要设置该选项并且在info.list里面Background Modes 中的 Location updates 处于选中状态才可以使用后台定位权限。iOS 9.0之前可以直接申请总是使用的权限来获得后台定位。
*
* 设置为 YES 的时候必须保证 Background Modes 中的 Location updates 处于选中状态,否则会抛出异常。
*/
@property (nonatomic, assign) BOOL allowsBackgroundLocationUpdates;
/**
* 用户的活动类型
*
* 设置用户的活动类型。默认值为 CLActivityTypeOther
*/
@property (nonatomic, assign) CLActivityType activityType;
/**
* 设置当朝向改变时,每隔多少度调用一次
* 只有当设备方向的改变值超过该属性值时才激发delegate的方法。
*/
@property(nonatomic, assign) CLLocationDegrees headingFilter;
/**
* 设置设备当前的朝向
*/
@property(nonatomic, assign) CLDeviceOrientation headingOrientation;
/**
* 连续定位的逆地理信息请求的Level。默认为TencentLBSRequestLevelGeo
*/
@property (nonatomic, assign) TencentLBSRequestLevel requestLevel;
/**
* 返回的TencentLBSLocation的location字段的坐标类型。默认为TencentLBSLocationCoordinateTypeGCJ02。
*
* 在一次定位过程中,只允许设置一次,不允许重复设置
*/
@property (nonatomic, assign) TencentLBSLocationCoordinateType coordinateType;
/**
* 指定POI的更新间隔。 默认是10s
*/
@property(nonatomic, assign) NSInteger poiUpdateInterval;
#pragma mark -
/**
* accuracyAuthorization
*
* Discussion:
* Return the current TencentLBSAccuracyAuthorization of the calling application.
*/
+ (TencentLBSAccuracyAuthorization)accuracyAuthorization;
/**
* 设置用户是否同意隐私协议政策
* <p>调用其他接口前必须首先调用此接口进行用户是否同意隐私政策的设置,传入YES后才能正常使用定位功能,否则TencentLBSLocationManager初始化不成功,返回nil,定位功能均无法使用</p>
* @param isAgree 是否同意隐私政策
*/
+ (void)setUserAgreePrivacy:(BOOL) isAgree;
/**
* 获取用户是否同意隐私政策协议
* <p>设置用户隐私后,可通过该接口判断用户隐私状态</p>
* @return isAgreePrivacy 是否同意隐私政策
*/
+ (BOOL)getUserAgreePrivacy;
#pragma mark -
- (void)requestWhenInUseAuthorization;
- (void)requestAlwaysAuthorization;
/**
* 当前属于模糊定位状态时,通过该接口请求暂时的完全定位精度的权限
* @param purposeKey 需要在info.plist中配置NSLocationTemporaryUsageDescriptionDictionary key值和对应的申请该权限的描述理由
* @param completion 在弹框让用户选择后的用户的反馈,如果用户授予该权限,block中的参数为nil,如果未授予,block中的参数将为PurposeKey对于的key的描述(如PurposeKey=TemporaryPurposKey_1)
*/
- (void)requestTemporaryFullAccuracyAuthorizationWithPurposeKey:(NSString *)purposeKey
completion:(void (^)(NSError *))completion;
/**
* 当前属于模糊定位状态时,通过该接口请求暂时的完全定位精度的权限
* @param purposeKey 需要在info.plist中配置NSLocationTemporaryUsageDescriptionDictionary key值和对应的申请该权限的描述理由
*/
- (void)requestTemporaryFullAccuracyAuthorizationWithPurposeKey:(NSString *)purposeKey;
#pragma mark -
/**
* 获取定位SDK的版本
*/
+(NSString *)getLBSSDKVersion;
/**
* 获取定位SDK的构建日期
*/
+(NSString *)getLBSSDKbuild;
#pragma mark -
/**
* 向SDK内部设置数据,以满足定制的需求
* @param value
* @param key
*/
- (void)setDataWithValue:(NSString *)value forKey:(NSString *)key;
/**
* 单次定位
*
* 该方法为下面方法的一层封装。
* level默认是TencentLBSRequestLevelPoi
* timeout默认是10s
*/
- (BOOL)requestLocationWithCompletionBlock:(TencentLBSLocatingCompletionBlock)completionBlock;
/**
* 单次定位
*
* 注意:不能连续调用该接口,需在上一次返回之后才能再次发起调用。该接口兼容iOS 7.0及以上,因iOS 9.0系统提供单次定位能力,故在9.0以上会调用系统单次定位接口,9.0之前SDK完成封装。可以通过调用cancelRequestLocation来取消。
*
* @param level 可以根据此参数来对应的获取POI信息
* @param timeout 表示获取POI的超时时间。
* @param completionBlock 单次定位完成后的Block
*/
- (BOOL)requestLocationWithRequestLevel:(TencentLBSRequestLevel)level
locationTimeout:(NSTimeInterval)timeout
completionBlock:(TencentLBSLocatingCompletionBlock)completionBlock;
/**
* 取消单次定位
**/
- (void)cancelRequestLocation;
/**
* 开始连续定位
*/
- (void)startUpdatingLocation;
/**
* 停止连续定位
*/
- (void)stopUpdatingLocation;
/**
* 开启更新定位朝向
*/
- (void)startUpdatingHeading;
/**
* 结束更新定位朝向
*/
- (void)stopUpdatingHeading;
/**
* 停止展示定位朝向校准提示
*/
- (void)dismissHeadingCalibrationDisplay;
#pragma mark - PDR 对外接口
/**
* 主动获取DR实时融合位置,调用startDrEngine:成功后才可能有值,业务可根据自己的频率主动获取
* @return DR融合后的定位结果
*/
-(TencentLBSLocation *)getPosition;
/**
* 启动DR引擎。引擎会自动获取传感器和GPS数据,并进行位置计算。
* 启动后DR引擎会主动开启CLLocationManager startUpdatingLocation。
*
* 注意:请确保调用之前已获取位置权限(使用期间或者始终允许)
*
* @param type 运动类型 目前支持,参考TencentLBSDRStartMotionType
* @return 返回码,参考TencentLBSDRStartCode
*/
-(TencentLBSDRStartCode)startDrEngine:(TencentLBSDRStartMotionType)type;
/**
* 停止DR引擎。内部有极短时间延迟,若在此期间调用TencentLBSLocationManager startDrEngine:可能导致启动不成功。
*/
-(void)terminateDrEngine;
/**
* 是否支持DR引擎
* @return
*/
-(BOOL)isSupport;
#pragma mark - test used
// 测试使用
#if TENCENTLBS_DEBUG
+ (void)upLoadData;
+ (NSData *)getLocationLog;
+ (void)newLocationLog;
#endif
@end
#pragma mark - TencentLBSLocationManagerDelegate
/**
* TencentLBSLocationManagerDelegate
* 定义了发生错误时的错误回调方法,连续定位的回调方法等。
*/
@protocol TencentLBSLocationManagerDelegate <NSObject>
@optional
/**
* 当定位发生错误时,会调用代理的此方法
*
* @param manager 定位 TencentLBSLocationManager 类
* @param error 返回的错误,参考 TencentLBSLocationError
*/
- (void)tencentLBSLocationManager:(TencentLBSLocationManager *)manager
didFailWithError:(NSError *)error;
/**
* 连续定位回调函数
*
* @param manager 定位 TencentLBSLocationManager 类
* @param location 定位结果
*/
- (void)tencentLBSLocationManager:(TencentLBSLocationManager *)manager
didUpdateLocation:(TencentLBSLocation *)location;
/**
* 定位权限状态改变时回调函数
* @deprecated 在iOS 14及以上废弃,由tencentLBSDidChangeAuthorization:代替
* @param manager 定位 TencentLBSLocationManager 类
* @param status 定位权限状态
*/
- (void)tencentLBSLocationManager:(TencentLBSLocationManager *)manager
didChangeAuthorizationStatus:(CLAuthorizationStatus)status;
/**
* 定位权限状态改变时回调函数
* @param manager 定位 TencentLBSLocationManager 类,由此访问authorizationStatus,accuracyAuthorization
*/
- (void)tencentLBSDidChangeAuthorization:(TencentLBSLocationManager *)manager;
/**
* 定位朝向改变时回调函数
*
* @param manager 定位 TencentLBSLocationManager 类
* @param newHeading 新的定位朝向
*/
- (void)tencentLBSLocationManager:(TencentLBSLocationManager *)manager
didUpdateHeading:(CLHeading *)newHeading;
/**
* 是否展示定位朝向校准提示的回调函数
*
* @param manager 定位 TencentLBSLocationManager 类
*/
- (BOOL)tencentLBSLocationManagerShouldDisplayHeadingCalibration:(TencentLBSLocationManager *)manager;
/**
* 只是内部调试使用,外部不应实现该接口
*/
- (void)tencentLBSLocationManager:(TencentLBSLocationManager *)manager didThrowLocation:(TencentLBSLocation *)location;
@end
NS_ASSUME_NONNULL_END
//
// TencentLBSLocationUtils.h
// TencentLBS
//
// Created by mirantslu on 16/8/11.
// Copyright © 2016年 Tencent. All rights reserved.
//
#import <Foundation/Foundation.h>
#import <CoreLocation/CoreLocation.h>
@class TencentLBSLocation;
NS_ASSUME_NONNULL_BEGIN
@interface TencentLBSLocationUtils : NSObject
/**
* 计算两个坐标点的距离
*/
+ (double)distanceBetweenTwoCoordinate2D:(const CLLocationCoordinate2D *)coordinate coordinateTwo:(const CLLocationCoordinate2D *)coordinate2;
/**
* 计算两个location的距离
*/
+ (double)distanceBetweenTwoCLLocations:(const CLLocation *)location locationTwo:(const CLLocation *)location2;
/**
* 计算两个TencentLBSLocation的距离
*/
+ (double)distanceBetweenTwoTencentLBSLocations:(const TencentLBSLocation *)location locationTwo:(const TencentLBSLocation *)location2;
/**
* 判断经纬度是否在国内
*
*/
+ (BOOL) isInRegionWithLatitude:(double)latitude longitude:(double)longitude;
/**
* wgs84坐标转成gcj02坐标
*/
+ (CLLocationCoordinate2D)WGS84TOGCJ02:(CLLocationCoordinate2D)coordinate;
@end
@interface TencentLBSServiceManager : NSObject
/**
* 设置ID,如QQ号,微信号或是其他的登录账号,可用在发布前联调使用
*/
@property (atomic, copy) NSString *deviceID;
+ (instancetype)sharedInsance;
@end
NS_ASSUME_NONNULL_END
framework module TencentLBS {
umbrella header "TencentLBS.h"
export *
module * { export * }
}
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>files</key>
<dict>
<key>Headers/TencentLBS.h</key>
<data>
hPC0/pGd4xrqNOXCT59Bc4EZx1o=
</data>
<key>Headers/TencentLBSLocation.h</key>
<data>
NTNAtRb6zd+vtrq8nFcrm/TvTno=
</data>
<key>Headers/TencentLBSLocationManager.h</key>
<data>
CqufUOM9qpXc8PkBQcTH7nFlxHU=
</data>
<key>Headers/TencentLBSLocationUtils.h</key>
<data>
ctiCEOKB25KPpldhCiCitDpWjsc=
</data>
<key>Info.plist</key>
<data>
dF6t7k2l2ACuPcw4w8e+8pX3Ds8=
</data>
<key>Modules/module.modulemap</key>
<data>
jS4bVEIZ8y6+mkDDypFhD0RkQVg=
</data>
</dict>
<key>files2</key>
<dict>
<key>Headers/TencentLBS.h</key>
<dict>
<key>hash</key>
<data>
hPC0/pGd4xrqNOXCT59Bc4EZx1o=
</data>
<key>hash2</key>
<data>
rXSLg9Gmqf/qi8hc0spd2V99ElDyGiIgDgvN30bahIQ=
</data>
</dict>
<key>Headers/TencentLBSLocation.h</key>
<dict>
<key>hash</key>
<data>
NTNAtRb6zd+vtrq8nFcrm/TvTno=
</data>
<key>hash2</key>
<data>
LmWBqRV/iCuLqRmuUPDGqTOz3n2XBrAIRkPpulu9Dms=
</data>
</dict>
<key>Headers/TencentLBSLocationManager.h</key>
<dict>
<key>hash</key>
<data>
CqufUOM9qpXc8PkBQcTH7nFlxHU=
</data>
<key>hash2</key>
<data>
ozYu6o4odbCMlj5n6GijSLmHlND06j8bgS/wHNmwwkI=
</data>
</dict>
<key>Headers/TencentLBSLocationUtils.h</key>
<dict>
<key>hash</key>
<data>
ctiCEOKB25KPpldhCiCitDpWjsc=
</data>
<key>hash2</key>
<data>
clmnufMVF2VLg4uOOY70pixlfbrZK20rr/iOxOF4+E4=
</data>
</dict>
<key>Modules/module.modulemap</key>
<dict>
<key>hash</key>
<data>
jS4bVEIZ8y6+mkDDypFhD0RkQVg=
</data>
<key>hash2</key>
<data>
j/3Yn2sASML4eiVUc877N1Qdw84cRUiapBx3Gc88OUI=
</data>
</dict>
</dict>
<key>rules</key>
<dict>
<key>^.*</key>
<true/>
<key>^.*\.lproj/</key>
<dict>
<key>optional</key>
<true/>
<key>weight</key>
<real>1000</real>
</dict>
<key>^.*\.lproj/locversion.plist$</key>
<dict>
<key>omit</key>
<true/>
<key>weight</key>
<real>1100</real>
</dict>
<key>^Base\.lproj/</key>
<dict>
<key>weight</key>
<real>1010</real>
</dict>
<key>^version.plist$</key>
<true/>
</dict>
<key>rules2</key>
<dict>
<key>.*\.dSYM($|/)</key>
<dict>
<key>weight</key>
<real>11</real>
</dict>
<key>^(.*/)?\.DS_Store$</key>
<dict>
<key>omit</key>
<true/>
<key>weight</key>
<real>2000</real>
</dict>
<key>^.*</key>
<true/>
<key>^.*\.lproj/</key>
<dict>
<key>optional</key>
<true/>
<key>weight</key>
<real>1000</real>
</dict>
<key>^.*\.lproj/locversion.plist$</key>
<dict>
<key>omit</key>
<true/>
<key>weight</key>
<real>1100</real>
</dict>
<key>^Base\.lproj/</key>
<dict>
<key>weight</key>
<real>1010</real>
</dict>
<key>^Info\.plist$</key>
<dict>
<key>omit</key>
<true/>
<key>weight</key>
<real>20</real>
</dict>
<key>^PkgInfo$</key>
<dict>
<key>omit</key>
<true/>
<key>weight</key>
<real>20</real>
</dict>
<key>^embedded\.provisionprofile$</key>
<dict>
<key>weight</key>
<real>20</real>
</dict>
<key>^version\.plist$</key>
<dict>
<key>weight</key>
<real>20</real>
</dict>
</dict>
</dict>
</plist>
{
"deploymentTarget": "9"
"frameworks": [
"libz.1.2.5.tbd"
],"deploymentTarget": "12"
}
\ No newline at end of file
import { CLLocationManager, CLAuthorizationStatus } from "CoreLocation"
import { TencentLBSLocationManager, TencentLBSLocation, TencentLBSRequestLevel, TencentLBSLocationManagerDelegate } from "TencentLBS"
import { NSError, Bundle } from "Foundation"
import { GetLocationOptions, GetLocationSuccess } from "../interface.uts"
/**
* 判断当前是否是自定义基座
*/
export function checkHasIntegration() : boolean {
// todo
return true
}
/**
* 定位 LBSLocation 类,封装定位相关方法
*/
class LBSLocation implements TencentLBSLocationManagerDelegate {
// 定义 locationManager 属性,类型为 TencentLBSLocationManager
locationManager! : TencentLBSLocationManager
locationOptions ?: GetLocationOptions
// 初始化 locationManager 方法
configLocationManager() : boolean {
if (this.locationManager == null) {
// 从 info.plist 中读取 apiKey
const apiKey = Bundle.main.infoDictionary?.["TencentLBSAPIKey"]
// infoDictionary 获取的值类型为 any?
if (apiKey == null) {
// 如果 apiKey 为 null 返回 false
console.log("apiKey 未配置")
return false
}
// 调用API前需要设置同意用户隐私协议
TencentLBSLocationManager.setUserAgreePrivacy(true)
// 初始化 locationManager 实例对象
this.locationManager = new TencentLBSLocationManager()
// 设置 apiKey (因为 apiKey 是 any?类型,需要转成 string 类型赋值)
this.locationManager.apiKey = apiKey! as string;
this.locationManager.delegate = this
}
return true
}
// 请求定位权限
requestPremission() {
if (this.configLocationManager()) {
const status = CLLocationManager.authorizationStatus()
// 如果未获取过定位权限,则发起权限请求
if (status == CLAuthorizationStatus.notDetermined) {
this.locationManager.requestWhenInUseAuthorization()
} else if (status == CLAuthorizationStatus.denied || status == CLAuthorizationStatus.restricted) {
let ret = new UniError("uni-getLocation-tencent", -30, "permission missed.");
this.locationOptions?.fail?.(ret)
this.locationOptions?.complete?.(ret)
}
}
}
// 获取单次位置信息
getLocation(locationOptions : GetLocationOptions) : boolean {
// 初始化 locationManager
if (!this.configLocationManager()) {
// 初始化失败返回 false
return false
}
this.locationOptions = locationOptions
const status = CLLocationManager.authorizationStatus()
if (status == CLAuthorizationStatus.authorizedAlways || status == CLAuthorizationStatus.authorizedWhenInUse) {
// 是否需要返回逆地理编码
let requestLevel = TencentLBSRequestLevel.geo
if (locationOptions.geocode) {
requestLevel = TencentLBSRequestLevel.name
}
// 请求单次定位信息
this.locationManager.requestLocation(with = requestLevel, locationTimeout = 10, completionBlock = (location ?: TencentLBSLocation, err ?: NSError) : void => {
if (location != null) {
// 判断 address 是否有值
var address = ""
if (location!.address != null) {
address = location!.address!
}
let response : GetLocationSuccess = {
latitude: Number(location!.location.coordinate.latitude),
longitude: Number(location!.location.coordinate.longitude),
speed: Number(location!.location.speed),
altitude: Number(location!.location.altitude),
accuracy: Number(location!.location.horizontalAccuracy),
verticalAccuracy: Number(location!.location.verticalAccuracy),
horizontalAccuracy: Number(location!.location.horizontalAccuracy),
address: address
}
locationOptions.success?.(response)
locationOptions.complete?.(response);
} else {
let ret = new UniError("uni-getLocation-tencent", -10, err!.localizedDescription);
locationOptions.fail?.(ret)
locationOptions.complete?.(ret)
}
})
} else {
this.requestPremission()
}
return true
}
// 监听位置变化
watchPosition(locationOptions : GetLocationOptions) {
// 初始化 locationManager
if (!this.configLocationManager()) {
return
}
if (locationOptions.geocode) {
this.locationManager.requestLevel = TencentLBSRequestLevel.name
} else {
this.locationManager.requestLevel = TencentLBSRequestLevel.geo
}
this.locationOptions = locationOptions
this.locationManager.startUpdatingLocation()
}
// 清除监听
clearWatch() {
// 初始化 locationManager
if (!this.configLocationManager()) {
return
}
this.locationManager.stopUpdatingLocation()
}
// 实现定位出错的 delegate 方法
tencentLBSDidChangeAuthorization(manager : TencentLBSLocationManager) {
const status = CLLocationManager.authorizationStatus()
if (status == CLAuthorizationStatus.denied || status == CLAuthorizationStatus.restricted) {
let ret = new UniError("uni-getLocation-tencent", -30, "permission missed.");
this.locationOptions?.fail?.(ret)
this.locationOptions?.complete?.(ret)
} else if (status == CLAuthorizationStatus.authorizedAlways || status == CLAuthorizationStatus.authorizedWhenInUse) {
this.getLocation(this.locationOptions!)
}
}
tencentLBSLocationManager(manager : TencentLBSLocationManager, @argumentLabel("didFailWithError") error : NSError) {
let ret = new UniError("uni-getLocation-tencent", -10, error.localizedDescription);
this.locationOptions?.fail?.(ret)
this.locationOptions?.complete?.(ret)
}
// 实现位置更新的 delegate 方法
tencentLBSLocationManager(manager : TencentLBSLocationManager, @argumentLabel("didUpdate") location : TencentLBSLocation) {
// 判断 address 是否有值
var address = ""
if (location.address != null) {
address = location.address!
}
let response : GetLocationSuccess = {
latitude: Number(location.location.coordinate.latitude),
longitude: Number(location.location.coordinate.longitude),
speed: Number(location.location.speed),
altitude: Number(location.location.altitude),
accuracy: Number(location.location.horizontalAccuracy),
verticalAccuracy: Number(location.location.verticalAccuracy),
horizontalAccuracy: Number(location.location.horizontalAccuracy),
address: address
}
this.locationOptions?.success?.(response)
this.locationOptions?.complete?.(response)
}
}
const LBSLocationTool : LBSLocation = new LBSLocation()
/**
* 请求定位权限方法
*/
export function requestPremission() {
LBSLocationTool.requestPremission()
}
/*
* 获取位置信息方法(单次定位)
*/
export function getLocation(locationOptions : GetLocationOptions) : boolean {
return LBSLocationTool.getLocation(locationOptions)
}
/**
* 持续监听位置变化
*/
export function watchPosition(locationOptions : GetLocationOptions) {
LBSLocationTool.watchPosition(locationOptions)
}
/**
* 关闭监听位置变化
*/
export function clearWatch() {
LBSLocationTool.clearWatch()
}
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>TencentLBSAPIKey</key>
<string>WZCBZ-OLPCU-TJJVJ-4LZTE-SSG5O-6JFEM</string>
<key>NSLocationAlwaysAndWhenInUseUsageDescription</key>
<string>允许使用定位权限吗</string>
<key>NSLocationAlwaysUsageDescription</key>
<string>允许一直使用定位权限</string>
<key>NSLocationWhenInUseUsageDescription</key>
<string>允许仅在app运行期间使用定位权限</string>
<key>NSLocationTemporaryUsageDescriptionDictionary</key>
<dict>
<key>key1111</key>
<string>获取准确的位置信息</string>
</dict>
<key>UIBackgroundModes</key>
<array>
<string>location</string>
</array>
</dict>
</plist>
......@@ -15,9 +15,9 @@ export interface Uni {
* "unixVer": "3.9+"
* },
* "ios": {
* "osVer": "9.0",
* "osVer": "12.0",
* "uniVer": "√",
* "unixVer": "4.06"
* "unixVer": "4.11"
* }
* },
* "web": {
......
......@@ -131,12 +131,12 @@ export interface Uni {
* "app": {
* "android": {
* "osVer": "5.0",
* "uniVer": "",
* "uniVer": "x",
* "unixVer": "3.91"
* },
* "ios": {
* "osVer": "10.0",
* "uniVer": "",
* "osVer": "12.0",
* "uniVer": "x",
* "unixVer": "x"
* }
* },
......@@ -153,5 +153,5 @@ export interface Uni {
* }
* }
*/
getPerformance: Performance
getPerformance: GetPerformance
}
......@@ -9,13 +9,16 @@ export const getProvider : GetProvider = (options: GetProviderOptions) : void =>
options.fail?.(uniError);
}
} else {
const provider = UTSAndroid.getExtApiProviders(options.service)
const providers = UTSAndroid.getProviders(options.service)
// TODO
// const providers: any[] = []
if (options.success != null) {
const result = {
service: options.service,
provider,
provider: providers.map((provider): string => {
return provider.id
}),
providers,
errMsg: 'GetProvider:ok'
} as GetProviderSuccess;
options.success?.(result);
......
......@@ -10,11 +10,14 @@ export const getProvider : GetProvider = (options: GetProviderOptions) : void =>
options.fail?.(uniError);
}
} else {
const provider = UTSiOS.getExtApiProviders(options.service)
const providers = UTSiOS.getProviders(options.service)
if (options.success != null) {
const result = {
service: options.service,
provider,
provider: providers.map((provider): string => {
return provider.id
}),
providers,
errMsg: 'GetProvider:ok'
} as GetProviderSuccess;
options.success?.(result);
......
export type GetProviderSuccess = {
/**
* 服务类型
* - oauth: 授权登录
* - share: 分享
* - payment: 支付
* - push: 推送
* - location: 定位
* @type 'oauth' | 'share' | 'payment' | 'push' | 'location'
* @type 'payment'
*/
service: 'oauth' | 'share' | 'payment' | 'push' | 'location',
service : 'payment',
/**
* 得到的服务供应商
* @type PlusShareShareService['id'][] | PlusPushClientInfo['id'][] | PlusOauthAuthService['id'][] | PlusPaymentPaymentChannel['id'][]
*/
provider: string[],
provider : string[],
/**
* 描述信息
* 得到的服务供应商服务对象
* @uniPlatform {
* "app": {
* "android": {
* "osVer": "5.0",
* "uniVer": "√",
* "unixVer": "4.18"
* },
* "ios": {
* "osVer": "9.0",
* "uniVer": "√",
* "unixVer": "4.18"
* }
* },
* "web": {
* "uniVer": "x",
* "unixVer": "x"
* }
* }
*/
providers : UniProvider[],
/**
* 错误信息
*/
errMsg: string
errMsg : string
};
export type GetProviderSuccessCallback = (result: GetProviderSuccess) => void;
export type GetProviderSuccessCallback = (result : GetProviderSuccess) => void;
export type GetProviderFail = UniError;
export type GetProviderFailCallback = (result: GetProviderFail) => void;
export type GetProviderFailCallback = (result : GetProviderFail) => void;
export type GetProviderComplete = any;
export type GetProviderCompleteCallback = (result: GetProviderComplete) => void;
export type GetProviderCompleteCallback = (result : GetProviderComplete) => void;
export type GetProviderOptions = {
/**
* 服务类型,可取值“oauth”、“share”、“payment”、“push”、“location”
* - oauth: 授权登录
* - share: 分享
* - payment: 支付
* - push: 推送
* - location: 定位
* @type 'oauth' | 'share' | 'payment' | 'push' | 'location'
* 服务类型,可取值“payment”
* - payment: 支付 (Alipay、Wxpay)
* @type 'payment'
*/
service: 'oauth' | 'share' | 'payment' | 'push' | 'location',
service : 'payment',
/**
* 接口调用成功的回调
*/
success?: GetProviderSuccessCallback | null,
success ?: GetProviderSuccessCallback | null,
/**
* 接口调用失败的回调函数
*/
fail?: GetProviderFailCallback | null,
fail ?: GetProviderFailCallback | null,
/**
* 接口调用结束的回调函数(调用成功、失败都会执行)
*/
complete?: GetProviderCompleteCallback | null
complete ?: GetProviderCompleteCallback | null
};
export type GetProvider = (options: GetProviderOptions) => void;
export type GetProvider = (options : GetProviderOptions) => void;
export interface Uni {
/**
......@@ -67,12 +81,12 @@ export interface Uni {
* "ios": {
* "osVer": "9.0",
* "uniVer": "√",
* "unixVer": "x"
* "unixVer": "4.18"
* }
* },
* "web": {
* "uniVer": "√",
* "unixVer": "4.05"
* "uniVer": "x",
* "unixVer": "x"
* }
* }
* @example
......@@ -80,5 +94,5 @@ export interface Uni {
uni.getProvider({service: ''})
```
*/
getProvider(options: GetProviderOptions) : void;
getProvider(options : GetProviderOptions) : void;
}
......@@ -77,6 +77,7 @@ export const getSystemInfoSync : GetSystemInfoSync = function () : GetSystemInfo
height: windowHeight - safeAreaInsets.top - safeAreaInsets.bottom
}
const osAndroidAPILevel = Build.VERSION.SDK_INT;
const appTheme = UTSAndroid.getAppTheme();
const result = {
SDKVersion: "",
......@@ -125,6 +126,7 @@ export const getSystemInfoSync : GetSystemInfoSync = function () : GetSystemInfo
safeAreaInsets: safeAreaInsets,
safeArea: safeArea,
osAndroidAPILevel: osAndroidAPILevel,
appTheme: appTheme,
} as GetSystemInfoResult;
return result;
} catch (e : Exception) {
......
......@@ -16,12 +16,6 @@ export const getSystemInfoSync : GetSystemInfoSync = function () : GetSystemInfo
const osVersion = UIDevice.current.systemVersion
let osTheme = 'light'
if(UTSiOS.available("iOS 13, *")){
let currentTraitCollection = UIApplication.shared.keyWindow?.traitCollection
osTheme = currentTraitCollection?.userInterfaceStyle == UIUserInterfaceStyle.dark ? "dark" : "light"
}
let deviceOrientation = 'portrait'
const orient = UIApplication.shared.statusBarOrientation;
if (orient == UIInterfaceOrientation.landscapeLeft || orient == UIInterfaceOrientation.landscapeRight) {
......@@ -50,7 +44,7 @@ export const getSystemInfoSync : GetSystemInfoSync = function () : GetSystemInfo
osName: 'ios',
osVersion: osVersion,
osLanguage: UTSiOS.getOsLanguage(),
osTheme: osTheme,
osTheme: UTSiOS.getOsTheme(),
pixelRatio: windowInfo.pixelRatio,
platform: 'ios',
screenWidth: windowInfo.screenWidth,
......@@ -74,6 +68,7 @@ export const getSystemInfoSync : GetSystemInfoSync = function () : GetSystemInfo
windowBottom: windowInfo.windowBottom,
safeAreaInsets: windowInfo.safeAreaInsets,
safeArea: windowInfo.safeArea,
appTheme: UTSiOS.getAppTheme(),
};
return result;
}
......
......@@ -3,26 +3,122 @@
export type GetSystemSettingResult = {
/**
* 蓝牙是否开启
*
* @uniPlatform
* {
* "app": {
* "android": {
* "osVer": "5.0",
* "uniVer": "√",
* "unixVer": "3.9+"
* },
* "ios": {
* "osVer": "12.0",
* "uniVer": "√",
* "unixVer": "4.11"
* }
* }
* }
*/
bluetoothEnabled?: boolean,
/**
* 蓝牙的报错信息
*
* @uniPlatform
* {
* "app": {
* "android": {
* "osVer": "5.0",
* "uniVer": "√",
* "unixVer": "3.9+"
* },
* "ios": {
* "osVer": "12.0",
* "uniVer": "√",
* "unixVer": "4.11"
* }
* }
* }
*/
bluetoothError?: string,
/**
* 位置是否开启
*
* @uniPlatform
* {
* "app": {
* "android": {
* "osVer": "5.0",
* "uniVer": "√",
* "unixVer": "3.9+"
* },
* "ios": {
* "osVer": "12.0",
* "uniVer": "√",
* "unixVer": "4.11"
* }
* }
* }
*/
locationEnabled : boolean,
/**
* wifi是否开启
*
* @uniPlatform
* {
* "app": {
* "android": {
* "osVer": "5.0",
* "uniVer": "√",
* "unixVer": "3.9+"
* },
* "ios": {
* "osVer": "12.0",
* "uniVer": "√",
* "unixVer": "4.11"
* }
* }
* }
*/
wifiEnabled?: boolean,
/**
* wifi的报错信息
*
* @uniPlatform
* {
* "app": {
* "android": {
* "osVer": "5.0",
* "uniVer": "√",
* "unixVer": "3.9+"
* },
* "ios": {
* "osVer": "x",
* "uniVer": "x",
* "unixVer": "x"
* }
* }
* }
*/
wifiError?: string,
/**
* 设备方向
*
* @uniPlatform
* {
* "app": {
* "android": {
* "osVer": "5.0",
* "uniVer": "√",
* "unixVer": "3.9+"
* },
* "ios": {
* "osVer": "12.0",
* "uniVer": "√",
* "unixVer": "4.11"
* }
* }
* }
*/
deviceOrientation : 'portrait' | 'landscape',
}
......
......@@ -31,12 +31,13 @@ declare interface Uni {
/**
* 获取设备电量
*
* 文档: [https://uniapp.dcloud.net.cn/api/system/batteryInfo.html](https://uniapp.dcloud.net.cn/api/system/batteryInfo.html)
* @tutorial https://uniapp.dcloud.net.cn/api/system/batteryInfo.html
*/
getBatteryInfo(option?: UniNamespace.GetBatteryInfoOption): void;
/**
* 同步获取电池电量信息
* @tutorial https://uniapp.dcloud.net.cn/api/system/batteryInfo.html
*/
getBatteryInfoSync(): UniNamespace.GetBatteryInfoSuccessCallbackResult;
}
......@@ -69,8 +69,7 @@ interface Uni {
/**
* 获取电池电量信息
* @description 获取电池电量信息
* @param {GetBatteryInfoOptions} options
*
* @example
* ```typescript
* uni.getBatteryInfo({
......@@ -92,7 +91,16 @@ interface Uni {
* "osVer": "12.0",
* "uniVer": "3.6.11",
* "unixVer": "4.11"
* },
* "harmony": {
* "osVer": "x",
* "uniVer": "x",
* "unixVer": "x"
* }
* },
* "web": {
* "uniVer": "3.6.11",
* "unixVer": "4.0"
* }
* }
* @uniVueVersion 2,3 //支持的vue版本
......@@ -101,7 +109,7 @@ interface Uni {
getBatteryInfo (options : GetBatteryInfoOptions) : void,
/**
* 同步获取电池电量信息
* @description 获取电池电量信息
*
* @example
* ```typescript
* uni.getBatteryInfo()
......@@ -119,7 +127,16 @@ interface Uni {
* "osVer": "12.0",
* "uniVer": "3.6.11",
* "unixVer": "4.11"
* },
* "harmony": {
* "osVer": "x",
* "uniVer": "x",
* "unixVer": "x"
* }
* },
* "web": {
* "uniVer": "3.6.11",
* "unixVer": "4.0"
* }
* }
* @uniVueVersion 2,3 //支持的vue版本
......
......@@ -86,7 +86,7 @@
"app": {
"js": false,
"kotlin": true,
"swift": false
"swift": true
}
},
"saveVideoToPhotosAlbum": {
......@@ -94,7 +94,7 @@
"app": {
"js": false,
"kotlin": true,
"swift": false
"swift": true
}
},
"getVideoInfo": {
......
import { ChooseImageOptions, ChooseVideoOptions } from "./interface.uts"
import {
UniError_ChooseImage, UniError_ChooseVideo, MediaErrorImpl
} from "./unierror.uts"
export const CODE_CAMERA_ERROR = 11;
export const CODE_GALLERY_ERROR = 12;
export const CODE_GET_IMAGE_INFO_CODE = 13
export function uniChooseImage(options : ChooseImageOptions, onSourceTypeSelect : (count : number, compressed : boolean, index : number) => void) {
let count = options.count != null ? (options.count! <= 0 ? 9 : options.count) : 9
// 默认为 false
let compressed = false;
if ((options.sizeType) != null) {
compressed = options.sizeType!.indexOf("original") < 0
}
/* source type 乱传如何处理 */
let sourceType : Array<string> = (options.sourceType != null && options.sourceType!.length > 0) ? options.sourceType! : ["album", "camera"];
let itemList = ["拍摄", "从相册选择"]
if (sourceType.length == 1) {
if (sourceType.indexOf("album") >= 0) {
onSourceTypeSelect(count!, compressed, 1)
} else if (sourceType.indexOf("camera") >= 0) {
onSourceTypeSelect(count!, compressed, 0)
}
return
}
if (sourceType.length == 2) {
uni.showActionSheet({
itemList: itemList,
success: (e) => {
onSourceTypeSelect(count!, compressed, e.tapIndex!)
},
fail: (e) => {
let error = new MediaErrorImpl(1101001, UniError_ChooseImage);
options.fail?.(error)
options.complete?.(error)
}
})
}
}
export function uniChooseVideo(options : ChooseVideoOptions, onSourceTypeSelect : (count : number, compressed : boolean, index : number) => void) {
let count = 1
// 默认为 false
let compressed = options.compressed != null ? options.compressed! : true;
/* source type 乱传如何处理 */
let sourceType : Array<string> = (options.sourceType != null && options.sourceType!.length > 0) ? options.sourceType! : ["album", "camera"];
let itemList = ["拍摄", "从相册选择"]
if (sourceType.length == 1) {
if (sourceType.indexOf("album") >= 0) {
onSourceTypeSelect(count!, compressed, 1)
} else if (sourceType.indexOf("camera") >= 0) {
onSourceTypeSelect(count!, compressed, 0)
}
return
}
if (sourceType.length == 2) {
uni.showActionSheet({
itemList: itemList,
success: (e) => {
onSourceTypeSelect(count!, compressed, e.tapIndex!)
},
fail: (e) => {
let error = new MediaErrorImpl(1101001, UniError_ChooseVideo);
options.fail?.(error)
options.complete?.(error)
}
})
}
}
\ No newline at end of file
......@@ -343,6 +343,7 @@ function copyFile(fromFilePath : string, toFilePath : string) : boolean {
if (!fromFile.canRead()) {
return false;
}
fis = new FileInputStream(fromFile);
}
if (fis == null) {
return false
......@@ -358,7 +359,6 @@ function copyFile(fromFilePath : string, toFilePath : string) : boolean {
toFile.createNewFile()
}
try {
// let fis = new FileInputStream(fromFile)
let fos = new FileOutputStream(toFile)
let byteArrays = ByteArray(1024)
var c = fis!!.read(byteArrays)
......@@ -592,6 +592,21 @@ export const getVideoInfo : GetVideoInfo = function (options : GetVideoInfoOptio
export const saveVideoToPhotosAlbum : SaveVideoToPhotosAlbum = function (options : SaveVideoToPhotosAlbumOptions) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
let requestPermissionList : Array<string> = [Manifest.permission.WRITE_EXTERNAL_STORAGE];
UTSAndroid.requestSystemPermission(UTSAndroid.getUniActivity()!, requestPermissionList, (a : boolean, b : string[]) => {
loadFile(options);
}, (a : boolean, b : string[]) => {
let error = new MediaErrorImpl(1101005, UniError_SaveVideoToPhotosAlbum);
options.fail?.(error);
options.complete?.(error);
})
} else {
loadFile(options);
}
}
function loadFile(options : SaveVideoToPhotosAlbumOptions) {
if (TextUtils.isEmpty(options.filePath)) {
let error = new MediaErrorImpl(1101003, UniError_SaveVideoToPhotosAlbum);
options.fail?.(error)
......
......@@ -8,7 +8,7 @@ import {
MediaErrorImpl
} from "../../unierror.uts"
import { getVideoMetadata } from "./MediaUtils.uts"
import { uniChooseImage, uniChooseVideo } from "../../ChooseImageUtils.uts"
import { uniChooseImage, uniChooseVideo } from "./ChooseImageUtils.uts"
import { getUniActivity } from "io.dcloud.uts.android";
import Intent from 'android.content.Intent';
import File from 'java.io.File';
......
......@@ -46,18 +46,16 @@ export function transcodeImage(options : CompressImageOptions) {
var widthStr = ""
var heightStr = ""
if (options.compressedWidth != null) {
compressOption.width = options.compressedWidth!
widthStr = options.compressedWidth.toString();
} else {
widthStr = TextUtils.isEmpty(options.width) ? "auto" : options.width!
}
if (options.compressedHeight != null) {
compressOption.height = options.compressedHeight!
heightStr = options.compressedHeight.toString();
} else {
heightStr = TextUtils.isEmpty(options.height) ? "auto" : options.height!
}
if (compressOption.width <= 0 || compressOption.height <= 0) {
getHeightAndWidth(compressOption, widthStr, heightStr)
}
getHeightAndWidth(compressOption, widthStr, heightStr);
let bitmapOptions = new BitmapFactory.Options()
bitmapOptions.inJustDecodeBounds = false;
if (srcFile.length() > 1500000) {
......@@ -175,7 +173,7 @@ function str2Float(valuestr : string, realValue : number, defValue : number) : n
}
valuestr = valuestr.toLowerCase()
if (valuestr.endsWith("px")) {
valuestr == valuestr.substring(0, valuestr.length - 2);
valuestr = valuestr.substring(0, valuestr.length - 2);
}
try {
return Integer.parseInt(valuestr)
......@@ -231,8 +229,7 @@ export function transcodeVideo(options : CompressVideoOptions) {
} else if (resolution! > 1 || resolution! <= 0) {
resolution = 1.0
}
let fileName = getFileName(inPath);
let outPath = mediaCachePath + (fileName == "" ? (System.currentTimeMillis() + ".mp4") : fileName)
let outPath = mediaCachePath + "compress_video_" + System.currentTimeMillis() + ".mp4";
let outFile = new File(outPath)
if (!outFile.getParentFile().exists()) {
outFile.getParentFile().mkdirs()
......@@ -241,14 +238,6 @@ export function transcodeVideo(options : CompressVideoOptions) {
MediaTranscoder.getInstance().transcodeVideo(inPath, outPath, MediaFormatStrategyPresets.createAndroid720pStrategy(compressLevel, resolution!), new MediaTranscoderListener(inPath, outPath, options))
}
function getFileName(path : string) : string {
const array = path.split("/")
if (array.length > 0) {
return array[array.length - 1]
}
return ""
}
class MediaTranscoderListener implements Listener {
inPath : string
outPath : string
......@@ -267,7 +256,7 @@ class MediaTranscoderListener implements Listener {
if (outFile.exists()) {
let success : CompressVideoSuccess = {
tempFilePath: "file://" + this.outPath,
size: outFile.length()
size: outFile.length() / 1024
}
this.options.success?.(success)
this.options.complete?.(success)
......
......@@ -25,7 +25,7 @@ export function getVideoMetadata(src : string) : any {
let error = new MediaErrorImpl(1101003, UniError_GetVideoInfo);
return error
}
videoInfo.size = videoFile.length()
videoInfo.size = videoFile.length() / 1024;
try {
let retriever = new MediaMetadataRetriever()
retriever.setDataSource(path)
......
......@@ -8,32 +8,32 @@
<key>BinaryPath</key>
<string>DCloudMediaPicker.framework/DCloudMediaPicker</string>
<key>LibraryIdentifier</key>
<string>ios-arm64</string>
<string>ios-arm64_x86_64-simulator</string>
<key>LibraryPath</key>
<string>DCloudMediaPicker.framework</string>
<key>SupportedArchitectures</key>
<array>
<string>arm64</string>
<string>x86_64</string>
</array>
<key>SupportedPlatform</key>
<string>ios</string>
<key>SupportedPlatformVariant</key>
<string>simulator</string>
</dict>
<dict>
<key>BinaryPath</key>
<string>DCloudMediaPicker.framework/DCloudMediaPicker</string>
<key>LibraryIdentifier</key>
<string>ios-arm64_x86_64-simulator</string>
<string>ios-arm64</string>
<key>LibraryPath</key>
<string>DCloudMediaPicker.framework</string>
<key>SupportedArchitectures</key>
<array>
<string>arm64</string>
<string>x86_64</string>
</array>
<key>SupportedPlatform</key>
<string>ios</string>
<key>SupportedPlatformVariant</key>
<string>simulator</string>
</dict>
</array>
<key>CFBundlePackageType</key>
......
......@@ -28,6 +28,10 @@
<data>
nghJYGVbKFhvAi/+2XYvdy408is=
</data>
<key>PrivacyInfo.xcprivacy</key>
<data>
L50owgIQfV6zTzg7T11NlSDYSZU=
</data>
</dict>
<key>files2</key>
<dict>
......@@ -86,6 +90,17 @@
M9nMA2y1DqhJFLOymGCa66mNVw5qDN8J1QzcxQD3H/w=
</data>
</dict>
<key>PrivacyInfo.xcprivacy</key>
<dict>
<key>hash</key>
<data>
L50owgIQfV6zTzg7T11NlSDYSZU=
</data>
<key>hash2</key>
<data>
NOpzMYrYXZEAI4Xdo9XJX+tflymAvdW2UHdZwen1+iU=
</data>
</dict>
</dict>
<key>rules</key>
<dict>
......
......@@ -5,8 +5,10 @@
<key>NSCameraUsageDescription</key>
<string>APP需要您的同意,才能使用摄像头,以便于相机拍摄</string>
<key>NSPhotoLibraryAddUsageDescription</key>
<string>APP需要您的同意,才能访问相册,以便于保存图</string>
<string>APP需要您的同意,才能访问相册,以便于保存图</string>
<key>NSPhotoLibraryUsageDescription</key>
<string>APP需要您的同意,才能访问相册,以便于图片选取</string>
<string>APP需要您的同意,才能访问相册,以便于图像选取</string>
<key>NSMicrophoneUsageDescription</key>
<string>APP需要您的同意,才能使用麦克风,以便于录制音频</string>
</dict>
</plist>
\ No newline at end of file
......@@ -23,9 +23,6 @@ export const setNavigationBarColor = defineAsyncApi<
}
const appPage = page.$nativePage
appPage!.updateStyle(
new Map<string, any | null>([
[
'navigationBar',
new Map<string, any | null>([
[
'navigationBarTextStyle',
......@@ -36,8 +33,6 @@ export const setNavigationBarColor = defineAsyncApi<
options.backgroundColor,
],
]),
],
]),
)
res.resolve(null)
},
......@@ -56,14 +51,9 @@ export const setNavigationBarTitle = defineAsyncApi<
}
const appPage = page.$nativePage
appPage!.updateStyle(
new Map<string, any | null>([
[
'navigationBar',
new Map<string, any | null>([
['navigationBarTitleText', options.title],
]),
],
]),
)
res.resolve(null)
},
......
import { Request, RequestOptions, RequestSuccess, RequestFail, RequestTask, UploadFileOptions, UploadFile, UploadTask, OnProgressUpdateResult, UploadFileSuccess, UploadFileProgressUpdateCallback, DownloadFileProgressUpdateCallback, DownloadFileOptions, OnProgressDownloadResult, DownloadFile ,DownloadFileSuccess} from './interface';
import { Request, RequestOptions, RequestSuccess, RequestFail, RequestTask, UploadFileOptions, UploadFile, UploadTask, OnProgressUpdateResult, UploadFileSuccess, UploadFileProgressUpdateCallback, DownloadFileProgressUpdateCallback, DownloadFileOptions, OnProgressDownloadResult, DownloadFile, DownloadFileSuccess } from './interface';
import { NetworkManager, NetworkRequestListener, NetworkUploadFileListener, NetworkDownloadFileListener } from './network/NetworkManager.uts'
import { Data, HTTPURLResponse, NSError, NSNumber, ComparisonResult, RunLoop, Thread } from 'Foundation';
import { StatusCode } from './network/StatusCode.uts';
import { RequestFailImpl, UploadFileFailImpl, DownloadFileFailImpl, getErrcode } from '../unierror';
class SimpleNetworkListener extends NetworkRequestListener {
private param : RequestOptions | null = null;
class SimpleNetworkListener<T> extends NetworkRequestListener {
private param : RequestOptions<T> | null = null;
private headers : Map<string, any> | null = null;
private received : number = 0;
private data : Data = new Data();
constructor(param : RequestOptions) {
constructor(param : RequestOptions<T>) {
this.param = param;
super();
}
......@@ -53,12 +53,21 @@ class SimpleNetworkListener extends NetworkRequestListener {
result['data'] = this.parseData(this.data, strData, type);
let tmp : RequestSuccess = {
data: result['data']!,
if (result['data'] == null) {
let failResult = new RequestFailImpl(getErrcode(100001));
let fail = kParam?.fail;
let complete = kParam?.complete;
fail?.(failResult);
complete?.(failResult);
return
}
let tmp = new RequestSuccess<T>({
data: result['data']! as T,
statusCode: (new NSNumber(value = response.statusCode)),
header: result['header'] ?? "",
cookies: this.parseCookie(this.headers)
};
})
let success = kParam?.success;
let complete = kParam?.complete;
success?.(tmp);
......@@ -108,13 +117,15 @@ class SimpleNetworkListener extends NetworkRequestListener {
return result;
}
private parseData(data : Data | null, dataStr : string | null, type : string | null) : any | null {
if (type != null && type!.contains("json")) {
private parseData(data : Data | null, dataStr : string | null, parseType : string | null) : any | null {
if (`${type(of = T.self)}` == "Any.Protocol" || `${type(of = T.self)}` == "Optional<Any>.Type") {
if (parseType != null && parseType!.contains("json")) {
if (dataStr == null || dataStr!.length == 0) {
return {};
}
return this.parseJson(dataStr!);
} else if (type == 'jsonp') {
return JSON.parse(dataStr!);
} else if (parseType == 'jsonp') {
if (dataStr == null || dataStr!.length == 0) {
return {};
}
......@@ -125,7 +136,7 @@ class SimpleNetworkListener extends NetworkRequestListener {
}
start += 1;
let tmp = dataStr!.slice(start, end);
return this.parseJson(tmp);
return JSON.parse(tmp);
} else {
//dataStr如果解码失败是空的时候,还需要继续尝试解码。极端情况,服务器不是utf8的,所以字符解码会出现乱码,所以特殊处理一下非utf8的字符。
if (data == null) {
......@@ -141,17 +152,22 @@ class SimpleNetworkListener extends NetworkRequestListener {
// }
// }
if (currentStr == null) {
currentStr = new String(data = data!, encoding = String.Encoding.utf8);
}
// utf8 如果失败了,就用ascii,虽然几率很小。
if (currentStr == null) {
currentStr = new String(data = data!, encoding = String.Encoding.ascii);
}
return currentStr;
}
} else {
if (dataStr == null || dataStr!.length == 0) {
return null;
}
return JSON.parse<T>(dataStr!)
}
private parseJson(str : string) : any | null {
return JSON.parse(str);
}
private parseCookie(header : Map<string, any> | null) : string[] {
......@@ -293,11 +309,11 @@ class DownloadNetworkListener implements NetworkDownloadFileListener {
}
}
onFinished(response : HTTPURLResponse, filePath: string) : void {
onFinished(response : HTTPURLResponse, filePath : string) : void {
try {
let kParam = this.options;
let tmp : DownloadFileSuccess = {
tempFilePath:filePath,
tempFilePath: filePath,
statusCode: response.statusCode
};
let success = kParam?.success;
......@@ -335,10 +351,15 @@ class DownloadNetworkListener implements NetworkDownloadFileListener {
}
export const request : Request = (options : RequestOptions) : RequestTask => {
return NetworkManager.getInstance().request(options, new SimpleNetworkListener(options));
// export const request : Request = (options : RequestOptions) : RequestTask => {
// return NetworkManager.getInstance().request(options, new SimpleNetworkListener(options));
// }
export function request<T>(options : RequestOptions<T>, _t : T.Type) : RequestTask {
return NetworkManager.getInstance().request(options, new SimpleNetworkListener<T>(options));
}
export const uploadFile : UploadFile = (options : UploadFileOptions) : UploadTask => {
return NetworkManager.getInstance().uploadFile(options, new UploadNetworkListener(options));
}
......
import { DownloadFileOptions, DownloadTask, DownloadFileProgressUpdateCallback, OnProgressDownloadResult } from '../../interface.uts';
import { NetworkDownloadFileListener } from '../NetworkManager.uts';
import { UUID, Data, URL, URLResourceKey, URLSessionDataTask, URLSessionTask, URLSession, URLSessionConfiguration, OperationQueue, URLSessionDataDelegate, URLSessionDownloadTask, NSError, URLSessionDownloadDelegate, URLRequest, FileManager, NSString, NSTemporaryDirectory, NSHomeDirectory } from 'Foundation';
import { UUID, Data, URL, URLResourceKey, URLSessionDataTask, URLSessionTask, URLSession, URLSessionConfiguration, OperationQueue, URLSessionDataDelegate, URLSessionDownloadTask, NSError, URLSessionDownloadDelegate, URLRequest, FileManager, NSString, NSTemporaryDirectory, NSHomeDirectory , CharacterSet } from 'Foundation';
import { } from 'CommonCrypto';
import { UnsafeBufferPointer, UnsafeRawBufferPointer } from 'Swift';
import { ObjCBool } from "ObjectiveC";
......@@ -66,7 +66,8 @@ export class DownloadController implements URLSessionDownloadDelegate {
}
private createDownloadRequest(options : DownloadFileOptions, listener : NetworkDownloadFileListener) : URLRequest | null {
let url = new URL(string = options.url);
const encodeUrl = this.percentEscapedString(options.url)
let url = new URL(string = encodeUrl);
if (url == null) {
let error = new NSError(domain = "invalid URL", code = 600009);
listener.onFail(error);
......@@ -90,6 +91,8 @@ export class DownloadController implements URLSessionDownloadDelegate {
let valueStr = "";
if (value instanceof UTSJSONObject) {
valueStr = JSON.stringify(value) ?? ""
}else if(value instanceof Map<string, any>){
valueStr = JSON.stringify(new UTSJSONObject(value)) ?? ""
}else{
valueStr = `${value}`
}
......@@ -99,6 +102,11 @@ export class DownloadController implements URLSessionDownloadDelegate {
return request;
}
private percentEscapedString(str: string): string {
//如果url已经有部分经过encode,那么需要先decode再encode。
return str.removingPercentEncoding?.addingPercentEncoding(withAllowedCharacters= CharacterSet.urlQueryAllowed) ?? str
}
private convertToMD5(param : string) : string {
const strData = param.data(using = String.Encoding.utf8)!
let digest = new Array<UInt8>(repeating = 0, count = new Int(CC_MD5_DIGEST_LENGTH))
......
export const DEFAULT_ANIMATION_IN = 'pop-in'
export const DEFAULT_ANIMATION_OUT = 'pop-out'
export const DEFAULT_ANIMATION_DURATION = 300
export const DEFAULT_ANIMATION_NAVIGATE_BACK = 'auto'
export const ANIMATION_IN = [
'slide-in-right',
......
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册