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

Merge branch 'dev' into alpha

# Conflicts:
#	AndroidManifest.xml
#	pages/advance/advance.vue
#	uni_modules/uts-alert/utssdk/app-android/index.uts
#	uni_modules/uts-getbatteryinfo/utssdk/app-android/index.uts
#	uni_modules/uts-nativepage/utssdk/app-android/DoAppWidget.uts
#	uni_modules/uts-nativepage/utssdk/app-android/index.uts
#	uni_modules/uts-screenshot-listener/utssdk/app-android/index.uts
#	uni_modules/uts-tencentgeolocation/utssdk/app-android/index.uts
#	uni_modules/uts-tests/utssdk/Number.uts
# EditorConfig is awesome: https://EditorConfig.org
# top-most EditorConfig file
root = true
[*]
indent_style = space
indent_size = 2
end_of_line = lf
charset = utf-8
trim_trailing_whitespace = false
insert_final_newline = false
\ No newline at end of file
......@@ -6,15 +6,14 @@
>
<!--meta-data-->
<meta-data android:name="TencentMapSDK" android:value="您申请的腾讯定位App Key" />
<!--fileprovider注册,请注意authorities 需要替换为自己的唯一标识-->
<provider
android:name="androidx.core.content.FileProvider"
android:authorities="io.dcloud.hellouts.uts_nativepage.fileprovider"
android:grantUriPermissions="true"
android:exported="false">
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="@xml/filepaths" />
</provider>
<activity android:name="uni.UNI70BE9D0.RootPackageActivity"
android:launchMode="singleTask"
android:exported="true">
<intent-filter>
<action android:name="uni.UNI70BE9D0.RootPackageActivity" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</activity>
</application>
</manifest>
<!-- HBuilder X 版本要求: 3.6.11+ -->
<script lang="ts">
let firstBackTime = 0
export default {
let firstBackTime = 0
export default {
onLaunch: function () {
console.log('App Launch')
},
......@@ -11,6 +11,7 @@ export default {
onHide: function () {
console.log('App Hide')
},
// #ifdef UNI-APP-X && APP-ANDROID
onLastPageBackPress: function () {
console.log('App LastPageBackPress')
if (firstBackTime == 0) {
......@@ -27,16 +28,17 @@ export default {
uni.exit()
}
},
// #endif
onExit() {
console.log('App Exit')
},
}
}
</script>
<style>
/*每个页面公共css */
/* uni.css - 通用组件、模板样式库,可以当作一套ui库应用 */
/* #ifdef APP-VUE */
@import './common/uni.css';
/* #endif */
/*每个页面公共css */
/* uni.css - 通用组件、模板样式库,可以当作一套ui库应用 */
/* #ifdef APP-VUE */
@import './common/uni.css';
/* #endif */
</style>
\ No newline at end of file
{
"name": "HelloUTS",
"appid": "__UNI__70BE9D0",
"description": "",
"versionName": "1.0.9",
"versionCode": "109",
"transformPx": false,
"name" : "HelloUTS",
"appid" : "__UNI__70BE9D0",
"description" : "",
"versionName" : "1.0.9",
"versionCode" : "109",
"transformPx" : false,
/* 5+App特有相关 */
"app-plus": {
"usingComponents": true,
"nvueStyleCompiler": "uni-app",
"compilerVersion": 3,
"splashscreen": {
"alwaysShowBeforeRender": true,
"waiting": true,
"autoclose": true,
"delay": 0
"app-plus" : {
"usingComponents" : true,
"nvueStyleCompiler" : "uni-app",
"compilerVersion" : 3,
"splashscreen" : {
"alwaysShowBeforeRender" : true,
"waiting" : true,
"autoclose" : true,
"delay" : 0
},
/* 模块配置 */
"modules": {},
"modules" : {},
/* 应用发布信息 */
"distribute": {
"distribute" : {
/* android打包配置 */
"android": {
"permissions": [
"<uses-permission android:name=\"android.permission.CHANGE_NETWORK_STATE\"/>",
"<uses-permission android:name=\"android.permission.MOUNT_UNMOUNT_FILESYSTEMS\"/>",
"<uses-permission android:name=\"android.permission.VIBRATE\"/>",
"<uses-permission android:name=\"android.permission.READ_LOGS\"/>",
"<uses-permission android:name=\"android.permission.ACCESS_WIFI_STATE\"/>",
"<uses-feature android:name=\"android.hardware.camera.autofocus\"/>",
"<uses-permission android:name=\"android.permission.ACCESS_NETWORK_STATE\"/>",
"android" : {
"permissions" : [
"<uses-permission android:name=\"android.permission.CAMERA\"/>",
"<uses-permission android:name=\"android.permission.GET_ACCOUNTS\"/>",
"<uses-permission android:name=\"android.permission.READ_PHONE_STATE\"/>",
"<uses-permission android:name=\"android.permission.CHANGE_WIFI_STATE\"/>",
"<uses-permission android:name=\"android.permission.WAKE_LOCK\"/>",
"<uses-permission android:name=\"android.permission.FLASHLIGHT\"/>",
"<uses-feature android:name=\"android.hardware.camera\"/>",
"<uses-permission android:name=\"android.permission.WRITE_SETTINGS\"/>"
"<uses-feature android:name=\"android.hardware.camera\"/>"
],
"minSdkVersion": 21,
"abiFilters": ["armeabi-v7a"]
"minSdkVersion" : 21,
"abiFilters" : [ "arm64-v8a" ]
},
/* ios打包配置 */
"ios": {
"dSYMs": false
"ios" : {
"dSYMs" : false
},
/* SDK配置 */
"sdkConfigs": {
"ad": {}
"sdkConfigs" : {
"ad" : {}
}
}
},
/* 快应用特有相关 */
"quickapp": {},
"quickapp" : {},
/* 小程序特有相关 */
"mp-weixin": {
"appid": "",
"setting": {
"urlCheck": false
"mp-weixin" : {
"appid" : "",
"setting" : {
"urlCheck" : false
},
"usingComponents": true
"usingComponents" : true
},
"mp-alipay": {
"usingComponents": true
"mp-alipay" : {
"usingComponents" : true
},
"mp-baidu": {
"usingComponents": true
"mp-baidu" : {
"usingComponents" : true
},
"mp-toutiao": {
"usingComponents": true
"mp-toutiao" : {
"usingComponents" : true
},
"uniStatistics": {
"enable": false
"uniStatistics" : {
"enable" : false
},
"vueVersion": "3"
"vueVersion" : "3"
}
/* ios打包配置 *//* SDK配置 */
......@@ -91,13 +91,6 @@
"enablePullDownRefresh": false
}
},
{
"path": "pages/resource/fileRead",
"style": {
"navigationBarTitleText": "",
"enablePullDownRefresh": false
}
},
{
"path": "pages/advance/android/decorview",
"style": {
......
......@@ -39,6 +39,7 @@
<view class="uni-hello-text"> 获取设备信息,观察是否符合预期 </view>
</view>
<button @tap="getDeviceInfoClick">获取设备基础信息</button>
<button @tap="getFileProviderUriClick">使用外部应用访问私有文件</button>
</view>
<!-- #ifdef APP -->
</scroll-view>
......@@ -62,6 +63,8 @@ import {
getDeviceInfoTest,
privacyStateTest,
} from '@/uni_modules/uts-platform-api'
import File from 'java.io.File';
import Intent from 'android.content.Intent';
/**
* 测试在页面生命周期之外,使用api
......@@ -157,6 +160,15 @@ export default {
})
}
},
getFileProviderUriClick() {
let file = new File(UTSAndroid.getResourcePath("static/logo.png"))
const uri = UTSAndroid.getFileProviderUri(file)
console.log("uri",uri.toString())
const intent = new Intent(Intent.ACTION_VIEW, uri)
intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION) // 添加权限标志
const context = UTSAndroid.getUniActivity()!;
context.startActivity(intent);
},
getAppTempPathClick() {
if (getAppTempPathTest()) {
uni.showToast({
......
......@@ -28,7 +28,7 @@
arrayConvert
} from "../../uni_modules/uts-advance";
import {openFileWithProvider} from '../../uni_modules/uts-nativepage'
import {openFileWithProvider} from '../../uni_modules/uts-advance'
export default {
data() {
......@@ -61,9 +61,6 @@
pages: [{
name: "图片加载示例",
url: "resource/resource"
},{
name: "文件读取示例",
url: "resource/fileRead"
}]
},
{
......@@ -85,7 +82,7 @@
url: "advance/android/assetaudio"
},
{
name: "使用三方应用打开项目文件(需自定义基座)",
name: "使用三方应用打开项目文件",
function: "testOpenFileWithProvider"
},
{
......
<template>
<view>
<page-head :title="title"></page-head>
</view>
</template>
<script>
export default {
data() {
return {
title: '文件读取示例-todo',
}
},
methods: {
}
}
</script>
<style>
</style>
<template>
<view>
<page-head :title="title"></page-head>
<view class="uni-btn-v uni-common-mt">
<button type="primary" @tap="getImageBase64">读取图片base64</button>
<button type="primary" @tap="getFileText">读取文本内容</button>
</view>
</view>
</template>
<script>
import {getFileSystemManager} from '@/uni_modules/uts-file-manager'
export default {
data() {
return {
title: '文件读取示例',
logo:""
}
},
methods: {
getImageBase64:function(e){
let fileManager = getFileSystemManager()
fileManager.readFile({
encoding:'base64',
filePath:'static/logo.png',
success:function(res){
console.log("success")
console.log(res)
},
fail:function(res){
console.log('fail')
console.log(res)
},
complete:function(res){
console.log("complete")
console.log(res)
}
})
},
getFileText:function(e){
let fileManager = getFileSystemManager()
fileManager.writeFile({
filePath:'/test/1.txt',
data:'锄禾日当午,汗滴禾下土,谁知盘中餐,粒粒皆辛苦',
success:function(res){
fileManager.readFile({
encoding:'utf-8',
filePath:res.filePath,
success:function(res){
console.log("success")
console.log(res)
},
fail:function(res){
console.log('fail')
},
complete:function(res){
console.log("complete")
}
})
},
fail:function(res){
console.log('fail')
},
complete:function(res){
console.log("complete")
}
})
}
}
}
</script>
<style>
</style>
......@@ -554,3 +554,13 @@ export function arrayConvert():boolean{
return true
}
export function openFileWithProvider(url:String){
let file = new File(UTSAndroid.getResourcePath("static/logo.png"))
const uri = UTSAndroid.getFileProviderUri(file)
console.log("uri",uri.toString())
const intent = new Intent(Intent.ACTION_VIEW, uri)
intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION) // 添加权限标志
const context = UTSAndroid.getUniActivity()!;
context.startActivity(intent);
}
import Toast from 'android.widget.Toast';
import AlertDialog from 'android.app.AlertDialog';
import DialogInterface from 'android.content.DialogInterface';
......
{
"id": "uts-file-manager",
"displayName": "uts-file-manager",
"version": "1.0.0",
"description": "uts-file-manager",
"keywords": [
"uts-file-manager"
],
"repository": "",
"engines": {
"HBuilderX": "^3.6.8"
},
"dcloudext": {
"type": "uts",
"sale": {
"regular": {
"price": "0.00"
},
"sourcecode": {
"price": "0.00"
}
},
"contact": {
"qq": ""
},
"declaration": {
"ads": "",
"data": "",
"permissions": ""
},
"npmurl": ""
},
"uni_modules": {
"dependencies": [],
"encrypt": [],
"platforms": {
"cloud": {
"tcb": "u",
"aliyun": "u"
},
"client": {
"Vue": {
"vue2": "u",
"vue3": "u"
},
"App": {
"app-android": "u",
"app-ios": "u"
},
"H5-mobile": {
"Safari": "u",
"Android Browser": "u",
"微信浏览器(Android)": "u",
"QQ浏览器(Android)": "u"
},
"H5-pc": {
"Chrome": "u",
"IE": "u",
"Edge": "u",
"Firefox": "u",
"Safari": "u"
},
"小程序": {
"微信": "u",
"阿里": "u",
"百度": "u",
"字节跳动": "u",
"QQ": "u",
"钉钉": "u",
"快手": "u",
"飞书": "u",
"京东": "u"
},
"快应用": {
"华为": "u",
"联盟": "u"
}
}
}
}
}
\ No newline at end of file
# uts-file-manager
### 开发文档
[UTS 语法](https://uniapp.dcloud.net.cn/tutorial/syntax-uts.html)
[UTS API插件](https://uniapp.dcloud.net.cn/plugin/uts-plugin.html)
[UTS 组件插件](https://uniapp.dcloud.net.cn/plugin/uts-component.html)
[Hello UTS](https://gitcode.net/dcloud/hello-uts)
\ No newline at end of file
import { ReadFileSuccessResult, ReadFile,ReadFileOptions } from "../interface.uts"
import { WriteFileSuccessResult, WriteFile,WriteFileOptions } from "../interface.uts"
import { GetFileSystemManager,FileSystemManager} from "../interface.uts"
import { UniErrorSubject, UniErrors } from "../unierror.uts"
import File from "java.io.File"
import UTSAndroid from 'io.dcloud.uts.UTSAndroid';
import Base64 from "android.util.Base64"
export { ReadFileOptions, WriteFileOptions } from "../interface.uts"
class AndroidFileSystemManager implements FileSystemManager{
public readFile(options : ReadFileOptions) {
// 判断type 是否合法
if(options.encoding != 'base64' && options.encoding != 'utf-8'){
let err = new UniError(UniErrorSubject, 1200002, UniErrors.get(1200002)!);
options.fail?.(err)
options.complete?.(err)
return
}
let filePath = UTSAndroid.convert2AbsFullPath(options.filePath)
let targetFile = new File(filePath)
if (!targetFile.exists()) {
let err = new UniError(UniErrorSubject, 1300002, UniErrors.get(1300002)! + filePath);
options.fail?.(err)
options.complete?.(err)
return
}
if (targetFile.isDirectory()) {
let err = new UniError(UniErrorSubject,1301003,UniErrors.get(1301003)!);
options.fail?.(err)
options.complete?.(err)
return
}
/**
* 文件超过16M,会超过应用内存
*/
if (targetFile.length() > 16 * 1024 * 1024) {
let err = new UniError(UniErrorSubject,1300202,UniErrors.get(1300202)!);
options.fail?.(err)
options.complete?.(err)
return
}
let currentDispatcher = UTSAndroid.getDispatcher()
/**
* 执行真正的加载行为,为了避免阻塞分发到 io任务序列
*/
UTSAndroid.dispatchAsync('io',function(_){
let ret : ReadFileSuccessResult = {
data : ""
}
if(options.encoding == 'base64'){
// base64
let byteArray = targetFile.readBytes()
let base64Content = Base64.encodeToString(byteArray,Base64.NO_WRAP)
ret.data = base64Content
}else{
// text
let text = targetFile.readText()
ret.data = text
}
currentDispatcher.async(function(_){
options.success?.(ret)
options.complete?.(ret)
})
},null)
}
public writeFile(options : WriteFileOptions) {
// 判断type 是否合法
let nextFile = new File(UTSAndroid.getAppContext()?.getFilesDir(),options.filePath)
if(nextFile.exists() && nextFile.isDirectory()){
// 出错了,目标文件已存在,并且是个目录
let err = new UniError(UniErrorSubject,1301003,UniErrors.get(1301003)!);
options.fail?.(err)
options.complete?.(err)
return
}
let currentDispatcher = UTSAndroid.getDispatcher()
UTSAndroid.dispatchAsync('io',function(_){
/**
* 如果上一级目录不存在,创建之
*/
if(!nextFile.parentFile.exists()){
nextFile.parentFile.mkdirs()
}
if(!nextFile.exists()){
nextFile.createNewFile()
}
// 写入文本,暂时只支持覆盖写入
nextFile.writeText(options.data)
let ret : WriteFileSuccessResult = {
filePath: nextFile.getPath()
}
currentDispatcher.async(function(_){
options.success?.(ret)
options.complete?.(ret)
})
},null)
}
}
export const getFileSystemManager:GetFileSystemManager = function ():FileSystemManager {
return new AndroidFileSystemManager()
};
export type ReadFileSuccessResult = {
data: string
}
export type ReadFileSuccessCallback = (res: ReadFileSuccessResult) => void
export type ReadFileFailCallback = (res: UniError) => void
export type ReadFileCompleteCallback = (res: any) => void
export type ReadFileOptions = {
/**
* base64 / utf-8
*/
encoding: string,
/**
* 文件路径,支持相对地址和绝对地址
*/
filePath: string,
/**
* 接口调用的回调函数
*/
success?: ReadFileSuccessCallback | null,
/**
* 接口调用失败的回调函数
*/
fail?: ReadFileFailCallback | null,
/**
* 接口调用结束的回调函数(调用成功、失败都会执行)
*/
complete?: ReadFileCompleteCallback | null
}
export type WriteFileSuccessResult = {
filePath: string,
}
export type WriteFileSuccessCallback = (res: WriteFileSuccessResult) => void
export type WriteFileFailCallback = (res: UniError) => void
export type WriteFileCompleteCallback = (res: any) => void
export type WriteFileOptions = {
/**
* 文件路径,只支持绝对地址
*/
filePath: string,
/**
* 写入的文本内容
*/
data: string,
/**
* 接口调用的回调函数
*/
success?: WriteFileSuccessCallback | null,
/**
* 接口调用失败的回调函数
*/
fail?: WriteFileFailCallback | null,
/**
* 接口调用结束的回调函数(调用成功、失败都会执行)
*/
complete?: WriteFileCompleteCallback | null
}
export interface FileSystemManager {
readFile(config: ReadFileOptions): void;
writeFile(config: WriteFileOptions): void;
}
export type GetFileSystemManager = () => FileSystemManager;
export interface Uni {
/**
* 获取文件管理器
* @uniPlatform {
* "app": {
* "android": {
* "osVer": "4.4.4",
* "uniVer": "√",
* "unixVer": "3.9.0"
* },
* "ios": {
* "osVer": "x",
* "uniVer": "x",
* "unixVer": "x"
* }
* }
* }
* @uniVueVersion 2,3 //支持的vue版本
*/
getFileSystemManager: GetFileSystemManager
}
/**
* 错误主题
*/
export const UniErrorSubject = 'uni-file-manager';
/**
* 错误码
* @UniError
*/
export const UniErrors:Map<number, string> = new Map([
[1200002, 'type error. only support base64 / utf-8'],
[1300002, 'no such file or directory'],
[1301003, 'illegal operation on a directory'],
[1300202, 'the maximum size of the file storage limit is exceeded'],
]);
import Context from "android.content.Context";
import BatteryManager from "android.os.BatteryManager";
import { UTSAndroid } from "io.dcloud.uts";
import IntentFilter from 'android.content.IntentFilter';
import Intent from 'android.content.Intent';
......
<template>
<view class="defaultStyles">
<view >
</view>
</template>
......@@ -7,11 +8,12 @@
import TextUtils from 'android.text.TextUtils'
import Button from 'android.widget.Button'
import LinearLayout from 'android.widget.LinearLayout'
import Color from 'android.graphics.Color'
import View from 'android.view.View'
class ButtonClickListsner extends View.OnClickListener {
constructor() {}
constructor() {
super()
}
override onClick(v ? : View) {
console.log(v)
}
......@@ -19,21 +21,35 @@
//原生提供以下属性或方法的实现
export default {
/**
* 组件名称,也就是开发者使用的标签
*/
name: "uts-hello-view",
/**
* 组件涉及的事件声明,只有声明过的事件,才能被正常发送
*/
emits: ['buttonClick'],
/**
* 属性声明,组件的使用者会传递这些属性值到组件
*/
props: {
/**
* 字符串类型 属性:buttonText 需要设置默认值
*/
"buttonText": {
type: String,
default: "点击触发"
}
},
/**
* 组件内部变量声明
*/
data() {
return {}
},
/**
* 属性变化监听器实现
*/
watch: {
"buttonText": {
/**
......@@ -47,26 +63,105 @@
}
}
},
immediate: false
immediate: false //创建时是否通过此方法更新属性,默认值为false
},
},
/**
* 规则:如果没有配置expose,则methods中的方法均对外暴露,如果配置了expose,则以expose的配置为准向外暴露
* ['publicMethod'] 含义为:只有 `publicMethod` 在实例上可用
*/
expose: ['doSth'],
methods: {
/**
* 对外公开的组件方法
*/
doSth(paramA: string) {
// 这是组件的自定义方法
console.log("paramA",paramA)
},
/**
* 内部使用的组件方法
*/
privateMethod() {
}
},
/**
* 组件被创建,组件第一个生命周期,
* 在内存中被占用的时候被调用,开发者可以在这里执行一些需要提前执行的初始化逻辑
* [可选实现]
*/
created() {
},
/**
* 对应平台的view载体即将被创建,对应前端beforeMount
* [可选实现]
*/
NVBeforeLoad() {
},
/**
* 创建原生View,必须定义返回值类型
* 开发者需要重点实现这个函数,声明原生组件被创建出来的过程,以及最终生成的原生组件类型
* (Android需要明确知道View类型,需特殊校验)
* todo 补充IOS平台限制
* [必须实现]
*/
NVLoad(): LinearLayout {
//必须实现
let contentLayout = new LinearLayout($androidContext)
let button = new Button($androidContext)
let contentLayout = new LinearLayout(this.$androidContext)
let button = new Button(this.$androidContext)
button.setText("点击触发");
button.setTag("centerButton");
contentLayout.addView(button, LinearLayout.LayoutParams(500, 500));
contentLayout.addView(button, new LinearLayout.LayoutParams(500, 500));
button.setOnClickListener(new ButtonClickListsner())
return contentLayout
},
/**
* 原生View已创建
* [可选实现]
*/
NVLoaded() {
},
/**
* 原生View布局完成
* [可选实现]
*/
NVLayouted() {
},
/**
* 原生View将释放
* [可选实现]
*/
NVBeforeUnload() {},
/**
* 原生View已释放,这里可以做释放View之后的操作
* [可选实现]
*/
NVUnloaded() {
},
/**
* 组件销毁
* [可选实现]
*/
unmounted() {},
/**
* 自定组件布局尺寸
* [可选实现]
*/
NVMeasure(size: UTSSize): UTSSize {
size.width = 120.0.toFloat()
size.height = 800.0.toFloat()
return size
}
}
</script>
<style>
/* 定义默认样式值, 组件使用者没有配置时使用 */
.defaultStyles {
width: 750rpx;
height: 240rpx;
}
</style>
\ No newline at end of file
......@@ -2,7 +2,6 @@ import AppWidgetProvider from 'android.appwidget.AppWidgetProvider';
import Context from 'android.content.Context';
import AppWidgetManager from 'android.appwidget.AppWidgetManager';
import RemoteViews from 'android.widget.RemoteViews';
import Handler from 'android.os.Handler';
import R from 'io.dcloud.uni_modules.uts_nativepage.R';
export class DoAppWidget extends AppWidgetProvider {
......
......@@ -20,7 +20,6 @@ import Toast from 'android.widget.Toast';
import Service from 'android.app.Service';
import System from 'java.lang.System';
import Exception from 'java.lang.Exception';
import ResolveInfo from 'android.content.pm.ResolveInfo';
import RecyclerView from 'androidx.recyclerview.widget.RecyclerView';
import TextView from 'android.widget.TextView';
import ViewGroup from 'android.view.ViewGroup';
......@@ -185,6 +184,21 @@ class ActivityFinishListener extends OnClickListener{
}
}
class RootActivityStartListener extends OnClickListener{
host:Activity
constructor(activity:Activity){
super()
this.host = activity
}
override onClick(v?: View):void{
let intent = Intent("uni.UNI70BE9D0.RootPackageActivity")
host.startActivity(intent)
}
}
/**
* 自定义异步线程
*/
......@@ -263,12 +277,13 @@ class DemoActivity extends Activity{
let btn_finish_activity = this.findViewById<Button>(R.id.btn_finish_activity);
btn_finish_activity.setOnClickListener(new ActivityFinishListener(this));
let btn_start_root_activity = this.findViewById<Button>(R.id.btn_start_root_activity);
btn_start_root_activity.setOnClickListener(new RootActivityStartListener(this));
let recyclerView = this.findViewById<RecyclerView>(R.id.recycler_view)
let layoutManager = new LinearLayoutManager(this);
recyclerView.setLayoutManager(layoutManager);
let fruitAdapter = new FruitAdapter(utsArrayOf("香蕉","苹果","大鸭梨"));
recyclerView.setAdapter(fruitAdapter);
}
......@@ -312,14 +327,5 @@ export function gotoDemoActivity():boolean {
export function openFileWithProvider(url:String){
let file = new File(UTSAndroid.getResourcePath("static/logo.png"))
// 这里的 io.dcloud.hellouts.uts_nativepage.fileprovider 应该是你唯一的fileprovider 标识
const uri = androidx.core.content.FileProvider.getUriForFile(UTSAndroid.getUniActivity()!,"io.dcloud.hellouts.uts_nativepage.fileprovider",file)
console.log("uri",uri.toString())
const intent = new Intent(Intent.ACTION_VIEW, uri)
intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION) // 添加权限标志
const context = UTSAndroid.getUniActivity()!;
context.startActivity(intent);
}
......@@ -9,6 +9,7 @@
<Button android:layout_width="match_parent" android:layout_height="wrap_content" android:text="注册屏幕状态广播监听" android:id="@+id/btn_start_screen_listen"/>
<Button android:layout_width="match_parent" android:layout_height="wrap_content" android:text="开启异步任务" android:id="@+id/btn_start_thread"/>
<Button android:layout_width="match_parent" android:layout_height="wrap_content" android:text="关闭当前activity" android:id="@+id/btn_finish_activity"/>
<Button android:layout_width="match_parent" android:layout_height="wrap_content" android:text="打开应用根目录activity" android:id="@+id/btn_start_root_activity"/>
<androidx.recyclerview.widget.RecyclerView
android:layout_width="match_parent"
android:layout_height="match_parent"
......
......@@ -2,7 +2,6 @@ import MediaStore from "android.provider.MediaStore";
import Activity from "android.app.Activity";
import Bitmap from "android.graphics.Bitmap";
import FileOutputStream from "java.io.FileOutputStream";
import File from "java.io.File";
import Intent from 'android.content.Intent';
/**
......@@ -47,7 +46,7 @@ export function privacyStateTest(callback : (ret : boolean, desc : string) => vo
}
UTSAndroid.setPrivacyAgree(true)
UTSAndroid.dispatchAsync("io",function(res){
UTSAndroid.getDispatcher("io").async(function(_){
if (UTSAndroid.isPrivacyAgree() == false) {
// 重置没有生效
callback(false,"setPrivacyAgree error")
......@@ -56,6 +55,15 @@ export function privacyStateTest(callback : (ret : boolean, desc : string) => vo
callback(true,"pass")
},null)
// UTSAndroid.dispatchAsync("io",function(res){
// if (UTSAndroid.isPrivacyAgree() == false) {
// // 重置没有生效
// callback(false,"setPrivacyAgree error")
// console.log("setPrivacyAgree error")
// }
// callback(true,"pass")
// },null)
}
......@@ -63,13 +71,16 @@ export function privacyStateTest(callback : (ret : boolean, desc : string) => vo
* UTSAndroid.getAppTempPath 测试示例
*/
export function getAppTempPathTest() : boolean {
console.log(UTSAndroid.getAppTempPath())
// 1.0 的路径
if (UTSAndroid.getAppTempPath()!.contains("data/io.dcloud.HBuilder/apps/HBuilder/temp")) {
// 1.0 标准基座的情况
if (UTSAndroid.getAppCachePath()!.contains("data/io.dcloud.HBuilder/apps/HBuilder/temp")) {
return true
}
// 1.0 自定义基座的情况
if (UTSAndroid.getAppCachePath()!.contains("uni.UNI70BE9D0/apps/__UNI__70BE9D0/temp")) {
return true
}
// 2.0的路径
if (UTSAndroid.getAppTempPath()!.contains("cache/temp")) {
if (UTSAndroid.getAppCachePath()!.contains("cache/temp")) {
return true
}
......@@ -121,7 +132,7 @@ export function gotoCameraTake(imageDone : (event : string) => void) : boolean {
let permissionNeed = ["android.permission.CAMERA"]
UTSAndroid.requestSystemPermission(UTSAndroid.getUniActivity()!, permissionNeed, function (allRight : boolean, _grantedList : string[]) {
UTSAndroid.requestSystemPermission(UTSAndroid.getUniActivity()!, permissionNeed, function (allRight : boolean, _ : string[]) {
if (allRight) {
// 交给目前的location 引擎,真实执行
UTSAndroid.onAppActivityResult((requestCode : Int, resultCode : Int, data ?: Intent) => {
......@@ -149,7 +160,7 @@ export function gotoCameraTake(imageDone : (event : string) => void) : boolean {
} else {
//callback(false,"用户拒绝了部分权限")
}
}, function (_doNotAskAgain : boolean, _grantedList : string[]) {
}, function (_ : boolean, _ : string[]) {
//callback(false,"用户拒绝了部分权限")
})
......@@ -289,7 +300,7 @@ export function arrayPermissionFlowTest(callback : (ret : boolean, desc : string
return;
}
UTSAndroid.requestSystemPermission(UTSAndroid.getUniActivity()!, permissionNeed, function (allRight : boolean, _grantedList : string[]) {
UTSAndroid.requestSystemPermission(UTSAndroid.getUniActivity()!, permissionNeed, function (allRight : boolean, _ : string[]) {
if (allRight) {
// 交给目前的location 引擎,真实执行
// 测试权限api 返回值
......@@ -306,7 +317,7 @@ export function arrayPermissionFlowTest(callback : (ret : boolean, desc : string
} else {
callback(false, "用户拒绝了部分权限")
}
}, function (_doNotAskAgain : boolean, _grantedList : string[]) {
}, function (_ : boolean, _ : string[]) {
callback(false, "用户拒绝了部分权限")
})
......@@ -320,9 +331,9 @@ export function getDeviceInfoTest():string {
let info = ''
info += 'isUniMp: '+UTSAndroid.isUniMp() + "\n ";
info += 'getAppDarkMode: '+UTSAndroid.getAppDarkMode() + "\n ";
info += 'getLanguageInfo: '+ JSON.stringify(UTSAndroid.getLanguageInfo(UTSAndroid.getAppContext()!!)) + "\n ";
info += 'getWebViewInfo: '+ JSON.stringify(UTSAndroid.getWebViewInfo(UTSAndroid.getAppContext()!!)) + "\n ";
info += 'getDeviceID: '+UTSAndroid.getDeviceID(UTSAndroid.getAppContext()!!) + "\n ";
info += 'getLanguageInfo: '+ JSON.stringify(UTSAndroid.getLanguageInfo(UTSAndroid.getAppContext()!)) + "\n ";
info += 'getWebViewInfo: '+ JSON.stringify(UTSAndroid.getWebViewInfo(UTSAndroid.getAppContext()!)) + "\n ";
info += 'getDeviceID: '+UTSAndroid.getDeviceID(UTSAndroid.getAppContext()!) + "\n ";
info += 'getOAID: '+UTSAndroid.getOAID() + "\n ";
info += 'getInnerVersion: '+UTSAndroid.getInnerVersion() + "\n ";
info += 'getUniCompileVersion: '+UTSAndroid.getUniCompileVersion() + "\n ";
......@@ -345,12 +356,12 @@ export function getDeviceInfoTest():string {
* 任务分发测试
*/
export function dispatchAsyncTest(callback : (ret : boolean, desc : string) => void) {
UTSAndroid.dispatchAsync("main",function(res){
UTSAndroid.getDispatcher("main").async(function(_){
if(Thread.currentThread().name != 'main'){
callback(false,"main thread error")
return
}
UTSAndroid.dispatchAsync("dom",function(res){
UTSAndroid.getDispatcher("dom").async(function(_){
/**
* dom 参数,只在2.0生效,1.0会自动切换到main线程
*/
......@@ -358,7 +369,7 @@ export function dispatchAsyncTest(callback : (ret : boolean, desc : string) => v
callback(false,"dom thread error")
return
}
UTSAndroid.dispatchAsync("io",function(res){
UTSAndroid.getDispatcher("io").async(function(_){
/**
* dom 参数,只在2.0生效,1.0会自动切换到main线程
*/
......@@ -372,6 +383,7 @@ export function dispatchAsyncTest(callback : (ret : boolean, desc : string) => v
},null)
},null)
}
/**
......@@ -435,7 +447,7 @@ export function singlePermissionFlowTest(callback : (ret : boolean, desc : strin
return;
}
UTSAndroid.requestSystemPermission(UTSAndroid.getUniActivity()!, permissionNeed, function (allRight : boolean, _grantedList : string[]) {
UTSAndroid.requestSystemPermission(UTSAndroid.getUniActivity()!, permissionNeed, function (allRight : boolean, _ : string[]) {
if (allRight) {
// 测试权限api 返回值
if (!UTSAndroid.getSystemPermissionDenied(UTSAndroid.getUniActivity()!, permissionNeed).isEmpty()) {
......@@ -450,7 +462,7 @@ export function singlePermissionFlowTest(callback : (ret : boolean, desc : strin
} else {
callback(false, "用户拒绝了部分权限")
}
}, function (_doNotAskAgain : boolean, _grantedList : string[]) {
}, function (_ : boolean, _ : string[]) {
callback(false, "用户拒绝了部分权限")
})
......
import { OnUserCaptureScreen, OffUserCaptureScreen, UserCaptureScreenCallback, OnUserCaptureScreenResult } from "../interface.uts"
import { UserCaptureScreenCallback, OnUserCaptureScreenResult } from "../interface.uts"
import ActivityCompat from "androidx.core.app.ActivityCompat";
......@@ -10,7 +10,6 @@ import Build from "android.os.Build";
import FileObserver from "android.os.FileObserver";
import File from "java.io.File";
import Environment from "android.os.Environment";
import System from 'java.lang.System';
......
import ActivityCompat from "androidx.core.app.ActivityCompat";
import Manifest from "android.Manifest";
import Looper from "android.os.Looper";
import TencentLocationManager from "com.tencent.map.geolocation.TencentLocationManager";
......@@ -8,8 +6,6 @@ import TencentLocationListener from "com.tencent.map.geolocation.TencentLocation
import TencentLocation from "com.tencent.map.geolocation.TencentLocation";
import TencentLocationRequest from "com.tencent.map.geolocation.TencentLocationRequest";
import PackageManager from "android.content.pm.PackageManager";
import Class from 'java.lang.Class';
import Exception from 'java.lang.Exception';
......@@ -25,7 +21,6 @@ export function requestPremission() {
* 准备权限
*/
let permissionNeed = [Manifest.permission.ACCESS_COARSE_LOCATION,Manifest.permission.ACCESS_FINE_LOCATION];
UTSAndroid.requestSystemPermission(UTSAndroid.getUniActivity()!, permissionNeed, function (allRight:boolean,_:string[]) {
console.log("用户同意了权限",allRight)
}, function (_:boolean,_:string[]) {
......@@ -34,7 +29,6 @@ export function requestPremission() {
// 请求权限
return { name: "requestPremission"};
}
......
......@@ -279,6 +279,21 @@ export function testJSON() : Result {
console.log(retStr)
})
test('UTSJSONOject', () => {
let t1 = "1"
const a = {
test(){
t1 = "2"
console.log("test")
}
};
//console.log(a['test']);
(a['test'] as ()=>void)()
//console.log(t1);
expect(t1).toEqual("2")
//console.log(JSON.stringify(a));
})
})
......
import { describe, test, expect, Result } from './tests.uts'
class User{
name:string = "";
age:number = 0
class User {
name : string = "";
age : number = 0
}
const passcode = "secret passcode";
class Parent {
private _name: string = ""; // private是私有的,外部不能访问
get name(): string { // 读取name会触发此拦截器
private _name : string = ""; // private是私有的,外部不能访问
get name() : string { // 读取name会触发此拦截器
console.log("start to get parent.name");
return this._name;
}
set name(newName: string) { // 给name赋值会触发此拦截器
set name(newName : string) { // 给name赋值会触发此拦截器
console.log("start to set parent.name");
if (passcode == "secret passcode") { // 校验是否有权修改name的值,这里的条件可以修改以方便测试
this._name = newName;
......@@ -22,25 +22,25 @@ class Parent {
}
// 静态属性和方法
static age: number = 30
static run(): string {
static age : number = 30
static run() : string {
console.log("this is a static method")
return "static method"
}
// readonly
readonly address: string = ""
readonly address : string = ""
weight: number = 80
weight : number = 80
// constructor
constructor(weight: number) {
constructor(weight : number) {
console.log("开始实例化")
this.weight = weight
}
// 实例方法
eat(): string {
eat() : string {
console.log("this is parent")
return "parent instance method"
}
......@@ -53,7 +53,7 @@ class ChildrenTest extends Parent {
// super(weight)
// }
override eat(): string {
override eat() : string {
super.eat()
return "children instance method"
}
......@@ -64,7 +64,7 @@ class ChildrenTest extends Parent {
// #endif
}
export function testKeyWord(): Result {
export function testKeyWord() : Result {
return describe("KeyWord", () => {
test('new', () => {
......@@ -81,21 +81,24 @@ export function testKeyWord(): Result {
test('typeof', () => {
let new1 = new User()
expect(typeof(new1)).toEqual('object')
expect(typeof(123456.789)).toEqual('Double')
expect(typeof (new1)).toEqual('object')
// #ifdef APP-ANDROID || APP-IOS
expect(typeof (123456.789)).toEqual('Double')
//expect(typeof(789778979798797987979)).toEqual('number')
expect(typeof(0.0)).toEqual('Double')
expect(typeof (0.0)).toEqual('Double')
// #endif
expect(typeof("hello world")).toEqual('string')
expect(typeof([1,2,3])).toEqual('object')
expect(typeof(new Array<any>())).toEqual('object')
expect(typeof(new Set<any>())).toEqual('object')
expect(typeof ("hello world")).toEqual('string')
expect(typeof ([1, 2, 3])).toEqual('object')
expect(typeof (new Array<any>())).toEqual('object')
expect(typeof (new Set<any>())).toEqual('object')
// expect(typeof(new Map<any,any>())).toEqual('object')
expect(typeof(new Date())).toEqual('object')
expect(typeof("hello world")).toEqual('string')
expect(typeof (new Date())).toEqual('object')
expect(typeof ("hello world")).toEqual('string')
// 原生对象
// #ifndef APP-IOS
expect(typeof(UTSAndroid.getUniActivity())).toEqual('object')
// #ifdef APP-ANDROID
expect(typeof (UTSAndroid.getUniActivity())).toEqual('object')
// #endif
......@@ -103,22 +106,24 @@ export function testKeyWord(): Result {
test('instanceof', () => {
let user1:any = new User()
let user1 : any = new User()
let instanceRet1 = user1 instanceof User
expect(instanceRet1).toEqual(true)
let instanceRet2 = (typeof user1) == "string"
expect(instanceRet2).toEqual(false)
let num1:any = 3.1415926
let num1 : any = 3.1415926
let instanceRet3 = (typeof num1) == "string"
expect(instanceRet3).toEqual(false)
// #ifdef APP-ANDROID
let instanceRet4 = (typeof num1) == "number"
expect(instanceRet4).toEqual(false)
// #endif
})
test('isArray', () => {
let user1:any = new User()
let user1 : any = new User()
expect(Array.isArray(user1)).toEqual(false)
expect(Array.isArray([1,2,3])).toEqual(true)
expect(Array.isArray([1, 2, 3])).toEqual(true)
})
test('class', () => {
......
import { describe, test, expect, Result } from './tests.uts'
export function testNumber(): Result {
export function testNumber() : Result {
return describe("Number", () => {
test('toFixed', () => {
function financial(x: Number): String {
function financial(x : Number) : String {
return x.toFixed(2);
}
expect(financial(123.456)).toEqual('123.46');
......@@ -12,23 +12,23 @@ export function testNumber(): Result {
expect(financial(0)).toEqual("0.00");
expect(financial(1)).toEqual("1.00");
let num1: number = -1.1 / 0.1
let num2: number = -1.1 / 0.1
let num3: number = -1.1 / -0.1
let num1 : number = -1.1 / 0.1
let num2 : number = -1.1 / 0.1
let num3 : number = -1.1 / -0.1
console.warn(num1)
console.warn(num2)
console.warn(num3)
let obj = {"id":"3be2c600-894c-4231-aa56-82fd989cc961","result":{"result":[num1, num2, num3]}}
let obj = { "id": "3be2c600-894c-4231-aa56-82fd989cc961", "result": { "result": [num1, num2, num3] } }
console.log(JSON.stringify(obj))
// #ifndef APP-IOS
// android 专有数据类型
expect(123456.789.toFixed(2)).toEqual("123456.79");
expect(12345600123.789123.toFixed(2)).toEqual("12345600123.79");
expect((-123456.789).toFixed(5)).toEqual("-123456.78900");
expect(parseFloat("16688995566.369").toFixed(3)).toEqual("16688995566.369");
// #ifdef APP-ANDROID
// android 专有数据类型
let a1 = 56
let a2 = -122
expect(a1.toByte().toFixed(2)).toEqual("56.00");
......@@ -36,8 +36,22 @@ export function testNumber(): Result {
expect(a1.toShort().toFixed(5)).toEqual("56.00000");
expect(a2.toShort().toFixed(5)).toEqual("-122.00000");
// #endif
/**
* add since 2023-11-21
* 发现部分场景在android 6 以下与web有差异,新增以下示例
*/
let r = 2.449999999999999999;
let t1 = r.toFixed(1);
expect(t1).toEqual("2.5");
let r2 = 2.4499999999999999;
let t2 = r2.toFixed(1);
expect(t2).toEqual("2.4");
let r3 = -9007199254740991;
let t3 = r3.toFixed(15);
expect(t3).toEqual("-9007199254740991.000000000000000");
})
......@@ -79,12 +93,14 @@ export function testNumber(): Result {
expect((0xf).valueOf()).toEqual(15);
})
// #ifdef APP-ANDROID
// 数据转换操作示例
test('toX', () => {
let num = 10.123
expect(num.toInt()).toEqual(10);
expect(num.toDouble()).toEqual(10.123);
})
// #endif
test('numberEquals', () => {
let a1 = 10.123
......
import XToast from "com.hjq.xtoast.XToast";
import R from "io.dcloud.uni_modules.uts_toast.R";
import Runnable from 'java.lang.Runnable';
import Class from 'java.lang.Class';
import Exception from 'java.lang.Exception';
class UIRunnable extends Runnable {
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册