JLBA202505130001_关于吉林银行新建AI智能培训系统的需求_修复兼容性问题

This commit is contained in:
田岩
2025-12-24 17:34:39 +08:00
parent af5946fc70
commit f6bce46d39
53 changed files with 411 additions and 195 deletions
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
+2 -2
View File
@@ -8,8 +8,8 @@ android {
applicationId "cn.com.jlbank.ai"
minSdkVersion 21
targetSdkVersion 33
versionName System.getenv("versionName") ?: "1.0.0"
versionCode System.getenv("versionCode")?.toInteger() ?: 1
versionName System.getenv("versionName") ?: "0.0.4"
versionCode System.getenv("versionCode")?.toInteger() ?: 4
multiDexEnabled true
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
File diff suppressed because one or more lines are too long
@@ -7,8 +7,8 @@
"id": "__UNI__EDE0E52",
"name": "tra-app",
"version": {
"name": "0.0.3",
"code": 3
"name": "0.0.4",
"code": 4
},
"description": "",
"developer": {
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -1 +1 @@
.nav-bar[data-v-6f106210]{width:100%;height:var(--status-bar-height);position:fixed}.nav-bar-seat[data-v-6f106210]{width:100%;height:var(--status-bar-height)}.nav-bar-div[data-v-6f106210]{z-index:1900;width:100%;position:relative}uni-view[data-v-843a5998],uni-scroll-view[data-v-843a5998],uni-swiper-item[data-v-843a5998]{display:flex;flex-direction:column;flex-shrink:0;flex-grow:0;flex-basis:auto;align-items:stretch;align-content:flex-start}@font-face{font-family:uvicon-iconfont;src:url(../../assets/uvicons.04d281cc.ttf) format("truetype")}.uv-icon[data-v-843a5998]{display:flex;align-items:center}.uv-icon--left[data-v-843a5998]{flex-direction:row-reverse;align-items:center}.uv-icon--right[data-v-843a5998]{flex-direction:row;align-items:center}.uv-icon--top[data-v-843a5998]{flex-direction:column-reverse;justify-content:center}.uv-icon--bottom[data-v-843a5998]{flex-direction:column;justify-content:center}.uv-icon__icon[data-v-843a5998]{font-family:uvicon-iconfont;position:relative;display:flex;flex-direction:row;align-items:center}.uv-icon__icon--primary[data-v-843a5998]{color:#06f}.uv-icon__icon--success[data-v-843a5998]{color:#5ac725}.uv-icon__icon--error[data-v-843a5998]{color:#f56c6c}.uv-icon__icon--warning[data-v-843a5998]{color:#f9ae3d}.uv-icon__icon--info[data-v-843a5998]{color:#909399}.uv-icon__img[data-v-843a5998]{height:auto;will-change:transform}.uv-icon__label[data-v-843a5998]{line-height:1}.uv-border[data-v-1b8a7a55]{border-width:.5px!important;border-color:#dadbde!important;border-style:solid}.uv-border-bottom[data-v-1b8a7a55]{border-bottom-width:.5px!important;border-color:#dadbde!important;border-bottom-style:solid}uni-view[data-v-1b8a7a55],uni-scroll-view[data-v-1b8a7a55],uni-swiper-item[data-v-1b8a7a55]{display:flex;flex-direction:column;flex-shrink:0;flex-grow:0;flex-basis:auto;align-items:stretch;align-content:flex-start}.uv-input[data-v-1b8a7a55]{display:flex;flex-direction:row;align-items:center;justify-content:space-between;flex:1}.uv-input--radius[data-v-1b8a7a55],.uv-input--square[data-v-1b8a7a55]{border-radius:4px}.uv-input--no-radius[data-v-1b8a7a55]{border-radius:0}.uv-input--circle[data-v-1b8a7a55]{border-radius:100px}.uv-input__content[data-v-1b8a7a55]{flex:1;display:flex;flex-direction:row;align-items:center;justify-content:space-between}.uv-input__content__field-wrapper[data-v-1b8a7a55]{position:relative;display:flex;flex-direction:row;margin:0;flex:1}.uv-input__content__field-wrapper__field[data-v-1b8a7a55]{line-height:26px;text-align:left;color:#303133;height:24px;font-size:15px;flex:1}.uv-input__content__clear[data-v-1b8a7a55]{width:20px;height:20px;border-radius:100px;background-color:#c6c7cb;display:flex;flex-direction:row;align-items:center;justify-content:center;transform:scale(.82);margin-left:15px}.uv-input__content__subfix-icon[data-v-1b8a7a55]{margin-left:4px}.uv-input__content__prefix-icon[data-v-1b8a7a55]{margin-right:4px}.no_search[data-v-3ea77890]{width:100%;display:flex;flex-direction:column;align-items:center;margin-top:3.125rem}.no_search .img[data-v-3ea77890]{width:7.1875rem}.no_search .text[data-v-3ea77890]{color:#999;font-size:.9375rem}.history_div[data-v-3ea77890]{width:100%}.history_item[data-v-3ea77890]{padding:.25rem 0;color:#777}.title_div[data-v-3ea77890]{display:flex;justify-content:space-between;align-items:center;width:100%;height:2.1875rem;margin:.3125rem 0}.title_div .text[data-v-3ea77890]{font-size:1rem;font-weight:700}.title_div .delete_img[data-v-3ea77890]{display:flex;align-items:center;justify-content:center;padding:.625rem 0 .625rem 1rem}.title_div .delete_img .img[data-v-3ea77890]{height:.75rem}.search_content[data-v-3ea77890]{background-color:#fff;margin-top:-.1875rem;border-radius:.375rem .375rem 0 0;display:flex;flex-direction:column;align-items:center;padding:0 .9375rem;min-height:6.25rem;transition:max-height .3s ease}.search_content .bg_img[data-v-3ea77890]{width:84%;margin:.625rem auto}.fixed_search_div[data-v-3ea77890]{padding:calc(.3125rem + var(--status-bar-height)) .46875rem .75rem .3125rem;background:linear-gradient(90deg,#f1f7ff,#d8edff,#c3e6ff);display:flex;align-items:center}.fixed_search_div .back_div[data-v-3ea77890]{padding:.3125rem .3125rem .3125rem .625rem}.fixed_search_div .back_div .back-icon[data-v-3ea77890]{position:relative;width:1.25rem;height:1.25rem;cursor:pointer}.fixed_search_div .back_div .back-icon[data-v-3ea77890]:before,.fixed_search_div .back_div .back-icon[data-v-3ea77890]:after{content:"";position:absolute;transition:all .3s ease}.fixed_search_div .back_div .back-icon[data-v-3ea77890]:after{top:25%;left:25%;width:40%;height:40%;border-top:.125rem solid #2b2c2e;border-left:.125rem solid #2b2c2e;transform:rotate(-45deg)}.main_div[data-v-3ea77890]{display:flex;flex-direction:column}
.nav-bar[data-v-4b9b9f99]{width:100%;height:var(--status-bar-height);position:fixed}.nav-bar-seat[data-v-4b9b9f99]{width:100%;height:var(--status-bar-height)}.nav-bar-div[data-v-4b9b9f99]{z-index:1900;width:100%;position:relative}uni-view[data-v-843a5998],uni-scroll-view[data-v-843a5998],uni-swiper-item[data-v-843a5998]{display:flex;flex-direction:column;flex-shrink:0;flex-grow:0;flex-basis:auto;align-items:stretch;align-content:flex-start}@font-face{font-family:uvicon-iconfont;src:url(../../assets/uvicons.04d281cc.ttf) format("truetype")}.uv-icon[data-v-843a5998]{display:flex;align-items:center}.uv-icon--left[data-v-843a5998]{flex-direction:row-reverse;align-items:center}.uv-icon--right[data-v-843a5998]{flex-direction:row;align-items:center}.uv-icon--top[data-v-843a5998]{flex-direction:column-reverse;justify-content:center}.uv-icon--bottom[data-v-843a5998]{flex-direction:column;justify-content:center}.uv-icon__icon[data-v-843a5998]{font-family:uvicon-iconfont;position:relative;display:flex;flex-direction:row;align-items:center}.uv-icon__icon--primary[data-v-843a5998]{color:#06f}.uv-icon__icon--success[data-v-843a5998]{color:#5ac725}.uv-icon__icon--error[data-v-843a5998]{color:#f56c6c}.uv-icon__icon--warning[data-v-843a5998]{color:#f9ae3d}.uv-icon__icon--info[data-v-843a5998]{color:#909399}.uv-icon__img[data-v-843a5998]{height:auto;will-change:transform}.uv-icon__label[data-v-843a5998]{line-height:1}.uv-border[data-v-1b8a7a55]{border-width:.5px!important;border-color:#dadbde!important;border-style:solid}.uv-border-bottom[data-v-1b8a7a55]{border-bottom-width:.5px!important;border-color:#dadbde!important;border-bottom-style:solid}uni-view[data-v-1b8a7a55],uni-scroll-view[data-v-1b8a7a55],uni-swiper-item[data-v-1b8a7a55]{display:flex;flex-direction:column;flex-shrink:0;flex-grow:0;flex-basis:auto;align-items:stretch;align-content:flex-start}.uv-input[data-v-1b8a7a55]{display:flex;flex-direction:row;align-items:center;justify-content:space-between;flex:1}.uv-input--radius[data-v-1b8a7a55],.uv-input--square[data-v-1b8a7a55]{border-radius:4px}.uv-input--no-radius[data-v-1b8a7a55]{border-radius:0}.uv-input--circle[data-v-1b8a7a55]{border-radius:100px}.uv-input__content[data-v-1b8a7a55]{flex:1;display:flex;flex-direction:row;align-items:center;justify-content:space-between}.uv-input__content__field-wrapper[data-v-1b8a7a55]{position:relative;display:flex;flex-direction:row;margin:0;flex:1}.uv-input__content__field-wrapper__field[data-v-1b8a7a55]{line-height:26px;text-align:left;color:#303133;height:24px;font-size:15px;flex:1}.uv-input__content__clear[data-v-1b8a7a55]{width:20px;height:20px;border-radius:100px;background-color:#c6c7cb;display:flex;flex-direction:row;align-items:center;justify-content:center;transform:scale(.82);margin-left:15px}.uv-input__content__subfix-icon[data-v-1b8a7a55]{margin-left:4px}.uv-input__content__prefix-icon[data-v-1b8a7a55]{margin-right:4px}.no_search[data-v-3ea77890]{width:100%;display:flex;flex-direction:column;align-items:center;margin-top:3.125rem}.no_search .img[data-v-3ea77890]{width:7.1875rem}.no_search .text[data-v-3ea77890]{color:#999;font-size:.9375rem}.history_div[data-v-3ea77890]{width:100%}.history_item[data-v-3ea77890]{padding:.25rem 0;color:#777}.title_div[data-v-3ea77890]{display:flex;justify-content:space-between;align-items:center;width:100%;height:2.1875rem;margin:.3125rem 0}.title_div .text[data-v-3ea77890]{font-size:1rem;font-weight:700}.title_div .delete_img[data-v-3ea77890]{display:flex;align-items:center;justify-content:center;padding:.625rem 0 .625rem 1rem}.title_div .delete_img .img[data-v-3ea77890]{height:.75rem}.search_content[data-v-3ea77890]{background-color:#fff;margin-top:-.1875rem;border-radius:.375rem .375rem 0 0;display:flex;flex-direction:column;align-items:center;padding:0 .9375rem;min-height:6.25rem;transition:max-height .3s ease}.search_content .bg_img[data-v-3ea77890]{width:84%;margin:.625rem auto}.fixed_search_div[data-v-3ea77890]{padding:calc(.3125rem + var(--status-bar-height)) .46875rem .75rem .3125rem;background:linear-gradient(90deg,#f1f7ff,#d8edff,#c3e6ff);display:flex;align-items:center}.fixed_search_div .back_div[data-v-3ea77890]{padding:.3125rem .3125rem .3125rem .625rem}.fixed_search_div .back_div .back-icon[data-v-3ea77890]{position:relative;width:1.25rem;height:1.25rem;cursor:pointer}.fixed_search_div .back_div .back-icon[data-v-3ea77890]:before,.fixed_search_div .back_div .back-icon[data-v-3ea77890]:after{content:"";position:absolute;transition:all .3s ease}.fixed_search_div .back_div .back-icon[data-v-3ea77890]:after{top:25%;left:25%;width:40%;height:40%;border-top:.125rem solid #2b2c2e;border-left:.125rem solid #2b2c2e;transform:rotate(-45deg)}.main_div[data-v-3ea77890]{display:flex;flex-direction:column}
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -1 +1 @@
.uni-popup[data-v-4d2f82f0]{position:fixed;z-index:99}.uni-popup.top[data-v-4d2f82f0],.uni-popup.left[data-v-4d2f82f0],.uni-popup.right[data-v-4d2f82f0]{top:0}.uni-popup .uni-popup__wrapper[data-v-4d2f82f0]{display:block;position:relative}.uni-popup .uni-popup__wrapper.left[data-v-4d2f82f0],.uni-popup .uni-popup__wrapper.right[data-v-4d2f82f0]{padding-top:0;flex:1}.fixforpc-z-index[data-v-4d2f82f0]{z-index:999}.fixforpc-top[data-v-4d2f82f0]{top:0}.overlay-box[data-v-19e7c522]{position:fixed;left:0;top:0;width:100vw;height:100vh;z-index:999;background-color:rgba(0,0,0,.65)}.overlay-box uni-movable-view[data-v-19e7c522]{display:flex;align-items:center;justify-content:center;width:100%;height:100%}.overlay-box uni-movable-area[data-v-19e7c522]{height:100%;width:100%;position:fixed;overflow:hidden}.overlay-box uni-movable-view uni-image[data-v-19e7c522]{width:100%}.nav-bar[data-v-6f106210]{width:100%;height:var(--status-bar-height);position:fixed}.nav-bar-seat[data-v-6f106210]{width:100%;height:var(--status-bar-height)}.nav-bar-div[data-v-6f106210]{z-index:1900;width:100%;position:relative}.live-container[data-v-974a2859]{position:absolute;right:0;top:4.6875rem;overflow:hidden;border-radius:.625rem;width:8.4375rem;height:15rem}.pusher-container[data-v-974a2859]{overflow:hidden;border-radius:.625rem}.isVideo .role-info[data-v-75f2bd84]{display:none}.isVideo.show-box[data-v-75f2bd84]{background:linear-gradient(120deg,rgba(51,51,51,.2),rgba(102,102,102,.2),rgba(51,51,51,.2));backdrop-filter:blur(0px)}.title-time[data-v-75f2bd84],.title-tip[data-v-75f2bd84]{text-align:center;color:#fff;line-height:1.8125rem;font-size:1.1875rem;margin:0 auto}.role-name[data-v-75f2bd84]{margin-bottom:.8125rem;text-align:center;color:#fff;line-height:1.8125rem;font-size:1.1875rem}.title-tip[data-v-75f2bd84]{padding-right:.625rem;position:relative}.title-tip[data-v-75f2bd84]:after{content:"";position:absolute;animation:loading-75f2bd84 2.5s infinite}@keyframes loading-75f2bd84{0%{content:""}25%{content:"."}50%{content:".."}75%{content:"..."}to{content:""}}.switch-div[data-v-75f2bd84]{display:flex;justify-content:flex-end;align-items:center;margin-right:.625rem;margin-top:.3125rem;width:100%}.switch-div .switch-text[data-v-75f2bd84]{font-weight:400;font-size:.875rem;color:#fff}.switch-div .switch[data-v-75f2bd84]{transform:scale(.7) rotate(180deg)}.switch-div .switch[data-v-75f2bd84] .uni-switch-input.uni-switch-input-checked{border-color:#9eacbf!important;background-color:#9eacbf!important}.switch-div .switch[data-v-75f2bd84] .uni-switch-input:after{top:5px;left:5px;width:20px;height:20px}.switch-div .switch[data-v-75f2bd84] .uni-switch-input:before{background-color:#62a1ff!important;border-color:#62a1ff!important}.switch-div .switch[data-v-75f2bd84] .uni-switch-input:not(.uni-switch-input-checked){background-color:#62a1ff!important;border-color:#62a1ff!important}.fl1-div-1[data-v-75f2bd84]{min-height:3.75rem;max-height:7.5rem}.show-box[data-v-75f2bd84]{background:linear-gradient(120deg,rgba(51,51,51,.8),rgba(102,102,102,.8),rgba(51,51,51,.8));backdrop-filter:blur(10px);width:100vw;height:100vh;position:fixed;top:0;left:0;z-index:999;display:flex;flex-direction:column;align-items:center}.show-box-avatar[data-v-75f2bd84]{width:100vw;height:100vh;position:fixed;top:0;left:0;z-index:900}.role-info[data-v-75f2bd84]{position:relative;width:100vw;padding-top:6.5625rem}.role-info .role-avatar[data-v-75f2bd84]{width:5.78125rem;height:5.78125rem;border-radius:50%;overflow:hidden;position:absolute;left:50%;transform:translate(-50%);top:0}.body-scene[data-v-75f2bd84]{overflow:auto;width:calc(100% - 2.875rem);padding:.8125rem;color:rgba(255,255,255,.8);border:.125rem dashed rgba(255,255,255,.3);border-radius:.5rem;opacity:0;transition:opacity .5s ease}.body-scene.show[data-v-75f2bd84]{opacity:1}.close-btn[data-v-75f2bd84]{width:3.6875rem;height:3.6875rem;background-image:url(../../static/images/sparring/close-talk.png);background-repeat:no-repeat;background-position:center;background-size:cover;border-radius:50%;margin-top:1.4375rem;margin-bottom:3.5rem;flex-shrink:0}
.uni-popup[data-v-4d2f82f0]{position:fixed;z-index:99}.uni-popup.top[data-v-4d2f82f0],.uni-popup.left[data-v-4d2f82f0],.uni-popup.right[data-v-4d2f82f0]{top:0}.uni-popup .uni-popup__wrapper[data-v-4d2f82f0]{display:block;position:relative}.uni-popup .uni-popup__wrapper.left[data-v-4d2f82f0],.uni-popup .uni-popup__wrapper.right[data-v-4d2f82f0]{padding-top:0;flex:1}.fixforpc-z-index[data-v-4d2f82f0]{z-index:999}.fixforpc-top[data-v-4d2f82f0]{top:0}.overlay-box[data-v-19e7c522]{position:fixed;left:0;top:0;width:100vw;height:100vh;z-index:999;background-color:rgba(0,0,0,.65)}.overlay-box uni-movable-view[data-v-19e7c522]{display:flex;align-items:center;justify-content:center;width:100%;height:100%}.overlay-box uni-movable-area[data-v-19e7c522]{height:100%;width:100%;position:fixed;overflow:hidden}.overlay-box uni-movable-view uni-image[data-v-19e7c522]{width:100%}.nav-bar[data-v-4b9b9f99]{width:100%;height:var(--status-bar-height);position:fixed}.nav-bar-seat[data-v-4b9b9f99]{width:100%;height:var(--status-bar-height)}.nav-bar-div[data-v-4b9b9f99]{z-index:1900;width:100%;position:relative}.live-container[data-v-974a2859]{position:absolute;right:0;top:4.6875rem;overflow:hidden;border-radius:.625rem;width:8.4375rem;height:15rem}.pusher-container[data-v-974a2859]{overflow:hidden;border-radius:.625rem}.isVideo .role-info[data-v-75f2bd84]{display:none}.isVideo.show-box[data-v-75f2bd84]{background:linear-gradient(120deg,rgba(51,51,51,.2),rgba(102,102,102,.2),rgba(51,51,51,.2));backdrop-filter:blur(0px)}.title-time[data-v-75f2bd84],.title-tip[data-v-75f2bd84]{text-align:center;color:#fff;line-height:1.8125rem;font-size:1.1875rem;margin:0 auto}.role-name[data-v-75f2bd84]{margin-bottom:.8125rem;text-align:center;color:#fff;line-height:1.8125rem;font-size:1.1875rem}.title-tip[data-v-75f2bd84]{padding-right:.625rem;position:relative}.title-tip[data-v-75f2bd84]:after{content:"";position:absolute;animation:loading-75f2bd84 2.5s infinite}@keyframes loading-75f2bd84{0%{content:""}25%{content:"."}50%{content:".."}75%{content:"..."}to{content:""}}.switch-div[data-v-75f2bd84]{display:flex;justify-content:flex-end;align-items:center;margin-right:.625rem;margin-top:.3125rem;width:100%}.switch-div .switch-text[data-v-75f2bd84]{font-weight:400;font-size:.875rem;color:#fff}.switch-div .switch[data-v-75f2bd84]{transform:scale(.7) rotate(180deg)}.switch-div .switch[data-v-75f2bd84] .uni-switch-input.uni-switch-input-checked{border-color:#9eacbf!important;background-color:#9eacbf!important}.switch-div .switch[data-v-75f2bd84] .uni-switch-input:after{top:5px;left:5px;width:20px;height:20px}.switch-div .switch[data-v-75f2bd84] .uni-switch-input:before{background-color:#62a1ff!important;border-color:#62a1ff!important}.switch-div .switch[data-v-75f2bd84] .uni-switch-input:not(.uni-switch-input-checked){background-color:#62a1ff!important;border-color:#62a1ff!important}.fl1-div-1[data-v-75f2bd84]{min-height:3.75rem;max-height:7.5rem}.show-box[data-v-75f2bd84]{background:linear-gradient(120deg,rgba(51,51,51,.8),rgba(102,102,102,.8),rgba(51,51,51,.8));backdrop-filter:blur(10px);width:100vw;height:100vh;position:fixed;top:0;left:0;z-index:999;display:flex;flex-direction:column;align-items:center}.show-box-avatar[data-v-75f2bd84]{width:100vw;height:100vh;position:fixed;top:0;left:0;z-index:900}.role-info[data-v-75f2bd84]{position:relative;width:100vw;padding-top:6.5625rem}.role-info .role-avatar[data-v-75f2bd84]{width:5.78125rem;height:5.78125rem;border-radius:50%;overflow:hidden;position:absolute;left:50%;transform:translate(-50%);top:0}.body-scene[data-v-75f2bd84]{overflow:auto;width:calc(100% - 2.875rem);padding:.8125rem;color:rgba(255,255,255,.8);border:.125rem dashed rgba(255,255,255,.3);border-radius:.5rem;opacity:0;transition:opacity .5s ease}.body-scene.show[data-v-75f2bd84]{opacity:1}.close-btn[data-v-75f2bd84]{width:3.6875rem;height:3.6875rem;background-image:url(../../static/images/sparring/close-talk.png);background-repeat:no-repeat;background-position:center;background-size:cover;border-radius:50%;margin-top:1.4375rem;margin-bottom:3.5rem;flex-shrink:0}
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -1,11 +1,13 @@
@file:Suppress("UNCHECKED_CAST", "USELESS_CAST", "INAPPLICABLE_JVM_NAME", "UNUSED_ANONYMOUS_PARAMETER", "NAME_SHADOWING", "UNNECESSARY_NOT_NULL_ASSERTION")
package uts.sdk.modules.tyCamera
import android.content.Context
import android.graphics.Bitmap
import android.graphics.ImageFormat
import android.hardware.camera2.CameraCaptureSession
import android.hardware.camera2.CameraCharacteristics
import android.hardware.camera2.CameraDevice
import android.hardware.camera2.CameraManager
import android.hardware.camera2.CaptureRequest
import android.media.Image
import android.media.ImageReader
import android.os.Handler
@@ -21,8 +23,119 @@ import kotlinx.coroutines.Deferred
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.async
import io.dcloud.uts.UTSAndroid
val width: Int = 176
val height: Int = 144
open class MyApiOptions (
@JsonNotNull
open var paramA: Boolean = false,
open var success: ((res: String) -> Unit)? = null,
open var fail: ((res: MyApiFail) -> Unit)? = null,
open var complete: ((res: Any) -> Unit)? = null,
) : UTSObject()
typealias MyApiErrorCode = Number
interface MyApiFail : IUniError {
override var errCode: MyApiErrorCode
}
typealias CameraFacingType = String
open class CameraHelper {
private var context: Context
private var cameraManager: CameraManager
private var currentCameraId: String? = null
private var totalRotation: Number = 0
constructor(context: Context){
this.context = context
this.cameraManager = context.getSystemService(Context.CAMERA_SERVICE) as CameraManager
if (this.cameraManager == null) {
throw UTSError("CameraHelper: 获取CameraManager失败,请检查摄像头权限或设备支持性")
}
}
public open fun getCameraIdByFacing(facing: CameraFacingType): String {
try {
val cameraIds = this.cameraManager.getCameraIdList()
if (cameraIds.size === 0) {
console.error("CameraHelper: 无可用摄像头ID")
throw UTSError()
}
var targetCameraId: String? = null
for(id in resolveUTSValueIterator(cameraIds)){
val characteristics = this.cameraManager.getCameraCharacteristics(id)
val lensFacing = characteristics.get(CameraCharacteristics.LENS_FACING)
if (lensFacing !== null && lensFacing === (if (facing === "BACK") {
CameraCharacteristics.LENS_FACING_BACK
} else {
CameraCharacteristics.LENS_FACING_FRONT
}
)) {
targetCameraId = id
break
}
}
if (targetCameraId === null) {
throw UTSError()
}
console.log("CameraHelper: \u6210\u529F\u83B7\u53D6" + (if (facing === "BACK") {
"后置"
} else {
"前置"
}
) + "\u6444\u50CF\u5934ID\uFF1A" + targetCameraId)
return targetCameraId
}
catch (e: Throwable) {
console.error("CameraHelper: \u83B7\u53D6" + (if (facing === "BACK") {
"后置"
} else {
"前置"
}
) + "\u6444\u50CF\u5934ID\u5F02\u5E38\uFF1A", e.message)
throw UTSError()
}
}
public open fun openCameraByFacing(facing: CameraFacingType, callback: CameraDevice.StateCallback, handler: Handler? = null): Unit {
var cameraId: String
try {
cameraId = this.getCameraIdByFacing(facing)
}
catch (e: Throwable) {
throw UTSError()
}
val characteristics = this.cameraManager.getCameraCharacteristics(cameraId)
val streamConfigurationMap = characteristics.get(android.hardware.camera2.CameraCharacteristics.SCALER_STREAM_CONFIGURATION_MAP)
if (streamConfigurationMap !== null) {
val supportedSizes = streamConfigurationMap.getOutputSizes(ImageFormat.YUV_420_888)
for(size in resolveUTSValueIterator(supportedSizes)){
console.log(object : UTSJSONObject() {
var width = size.getWidth()
var height = size.getHeight()
})
}
}
this.cameraManager.openCamera(cameraId, callback, handler)
}
public open fun closeCamera(): Unit {}
public open fun getCurrentCameraId(): String? {
return this.currentCameraId
}
public open fun getTotalRotation(): Number {
return this.totalRotation
}
private fun getBackCameraId(cameraIds: UTSArray<String>): String? {
for(id in resolveUTSValueIterator(cameraIds)){
val characteristics = this.cameraManager.getCameraCharacteristics(id)
val facing = characteristics.get(CameraCharacteristics.LENS_FACING)
if (facing !== null && facing === CameraCharacteristics.LENS_FACING_BACK) {
return id
}
}
return null
}
private fun calculateCameraRotation(cameraId: String): Unit {}
public open fun release(): Unit {
this.currentCameraId = null
this.totalRotation = 0
console.log("CameraHelper: 摄像头辅助类资源已释放")
}
}
val width: Int = 720
val height: Int = 480
var backgroundHandler: Handler? = null
var handlerThread: HandlerThread? = null
var imageReader: ImageReader? = null
@@ -100,7 +213,14 @@ fun yuvToJpegBase64(image: android.media.Image): String {
return ""
}
val jpegBytes = outputStream.toByteArray()
val base64Raw = android.util.Base64.encodeToString(jpegBytes, android.util.Base64.DEFAULT)
val srcBitmap: Bitmap = android.graphics.BitmapFactory.decodeByteArray(jpegBytes, 0, jpegBytes.size)
val matrix = android.graphics.Matrix()
matrix.postRotate((-90 as Number).toFloat())
val outputStream2 = java.io.ByteArrayOutputStream()
val rotatedBitmap = android.graphics.Bitmap.createBitmap(srcBitmap, 0, 0, srcBitmap.getWidth(), srcBitmap.getHeight(), matrix, true)
rotatedBitmap.compress(android.graphics.Bitmap.CompressFormat.JPEG, 80, outputStream2)
val BitmapBytes = outputStream2.toByteArray()
val base64Raw = android.util.Base64.encodeToString(BitmapBytes, android.util.Base64.DEFAULT)
val base64Jpeg = "data:image/jpeg;base64," + base64Raw
outputStream.close()
return base64Jpeg
@@ -110,7 +230,7 @@ fun yuvToJpegBase64(image: android.media.Image): String {
return ""
}
}
fun startCameraPreview(callback: (data: Any) -> Unit): Unit {
fun startCameraPreview(options: MyApiOptions): Unit {
val context = UTSAndroid.getAppContext()
val activity = UTSAndroid.getUniActivity()
if (context == null || activity == null) {
@@ -120,13 +240,10 @@ fun startCameraPreview(callback: (data: Any) -> Unit): Unit {
handlerThread = HandlerThread("CameraBackground", -8)
handlerThread!!!!.start()
backgroundHandler = Handler(handlerThread!!!!.getLooper())
val cameraManager = context.getSystemService(Context.CAMERA_SERVICE) as CameraManager
val cameraId = getValidCameraInfo(cameraManager)
if (cameraId == null) {
console.error("错误:cameraId为null,说明没有摄像头")
return
}
val cameraHelper = CameraHelper(context)
val totalRotation = cameraHelper.getTotalRotation()
try {
console.log("width, height", width, height)
imageReader = ImageReader.newInstance(width, height, ImageFormat.YUV_420_888, 8)
val localImageReader = imageReader
if (localImageReader == null) {
@@ -138,8 +255,7 @@ fun startCameraPreview(callback: (data: Any) -> Unit): Unit {
if (imageProxy === null) {
return
}
console.log("正确设置监听器")
callback(yuvToJpegBase64(imageProxy))
options.success?.invoke(yuvToJpegBase64(imageProxy))
imageProxy.close()
return
}
@@ -166,6 +282,7 @@ fun startCameraPreview(callback: (data: Any) -> Unit): Unit {
captureSession = session
val requestBuilder = this.localCameraDevice.createCaptureRequest(android.hardware.camera2.CameraDevice.TEMPLATE_PREVIEW)
requestBuilder.addTarget(this.surface)
requestBuilder.set(CaptureRequest.JPEG_ORIENTATION, 270)
session.setRepeatingRequest(requestBuilder.build(), null, backgroundHandler)
}
override fun onConfigureFailed(session: android.hardware.camera2.CameraCaptureSession): Unit {
@@ -197,7 +314,7 @@ fun startCameraPreview(callback: (data: Any) -> Unit): Unit {
}
}
val cameraStateCallback = CustomCameraStateCallback()
cameraManager.openCamera(cameraId, cameraStateCallback, backgroundHandler)
cameraHelper.openCameraByFacing("FRONT", cameraStateCallback, backgroundHandler)
}
catch (e: Throwable) {
console.error("启动摄像头失败:", e)
@@ -268,46 +385,23 @@ fun stopCameraPreview(): Unit {
console.error("释放摄像头资源时发生全局异常:", e)
}
}
fun getValidCameraInfo(cameraManager: CameraManager): String? {
try {
val cameraIds = cameraManager.getCameraIdList()
if (cameraIds.size == 0) {
console.error("无可用摄像头ID")
return null
}
var cameraId = ""
for(id in resolveUTSValueIterator(cameraIds)){
val characteristics = cameraManager.getCameraCharacteristics(id)
val facing = characteristics.get(CameraCharacteristics.LENS_FACING)
if (facing === Integer.valueOf(CameraCharacteristics.LENS_FACING_FRONT)) {
cameraId = id
break
}
}
if (cameraId === "" && cameraIds.size > 0) {
cameraId = cameraIds[0]
}
if (cameraId === "") {
console.error("无可用摄像头ID")
return null
}
return cameraId
}
catch (e: Throwable) {
console.error("获取摄像头信息异常:", e.message)
return null
}
open class MyApiOptionsJSONObject : UTSJSONObject() {
open var paramA: Boolean = false
open var success: UTSCallback? = null
open var fail: UTSCallback? = null
open var complete: UTSCallback? = null
}
fun startCameraPreviewByJs(callback: UTSCallback): Unit {
return startCameraPreview(if (callback.fnJS != null) {
callback.fnJS
} else {
callback.fnJS = fun(data: Any){
callback(data)
}
callback.fnJS
fun startCameraPreviewByJs(options: MyApiOptionsJSONObject): Unit {
return startCameraPreview(MyApiOptions(paramA = options.paramA, success = fun(res: String): Unit {
options.success?.invoke(res)
}
as (data: Any) -> Unit)
, fail = fun(res: MyApiFail): Unit {
options.fail?.invoke(res)
}
, complete = fun(res: Any): Unit {
options.complete?.invoke(res)
}
))
}
fun stopCameraPreviewByJs(): Unit {
return stopCameraPreview()
@@ -3,7 +3,7 @@ import DCloudUTSFoundation
@objcMembers
public class MyApiOptions : NSObject, UTSObject {
public var paramA: Bool = false
public var success: ((_ res: MyApiResult) -> Void)?
public var success: ((_ res: String) -> Void)?
public var fail: ((_ res: MyApiFail) -> Void)?
public var complete: ((_ res: Any) -> Void)?
public subscript(_ key: String) -> Any? {
@@ -30,49 +30,16 @@ public class MyApiOptions : NSObject, UTSObject {
}
public init(_ obj: UTSJSONObject) {
self.paramA = obj["paramA"] as! Bool
self.success = obj["success"] as! ((_ res: MyApiResult) -> Void)?
self.success = obj["success"] as! ((_ res: String) -> Void)?
self.fail = obj["fail"] as! ((_ res: MyApiFail) -> Void)?
self.complete = obj["complete"] as! ((_ res: Any) -> Void)?
}
}
@objc(UTSSDKModulesTyCameraMyApiResult)
@objcMembers
public class MyApiResult : NSObject, UTSObject {
public var fieldA: NSNumber!
public var fieldB: Bool = false
public var fieldC: String!
public subscript(_ key: String) -> Any? {
get {
return utsSubscriptGetValue(key)
}
set {
switch(key){
case "fieldA":
self.fieldA = try! utsSubscriptCheckValue(newValue)
case "fieldB":
self.fieldB = try! utsSubscriptCheckValue(newValue)
case "fieldC":
self.fieldC = try! utsSubscriptCheckValue(newValue)
default:
break
}
}
}
public override init() {
super.init()
}
public init(_ obj: UTSJSONObject) {
self.fieldA = obj["fieldA"] as! NSNumber
self.fieldB = obj["fieldB"] as! Bool
self.fieldC = obj["fieldC"] as! String
}
}
public typealias MyApiErrorCode = NSNumber
public protocol MyApiFail : IUniError {
var errCode: MyApiErrorCode { get set }
}
public typealias MyApi = (_ options: MyApiOptions) -> Void
public typealias MyApiSync = (_ paramA: Bool) -> MyApiResult
public var UniErrorSubject = "uts-api"
public var MyAPIErrors: Map<MyApiErrorCode, String> = Map([
[
@@ -167,7 +134,7 @@ public func myApiByJs(_ options: MyApiOptionsJSONObject) -> Void {
return myApi(MyApiOptions(UTSJSONObject([
"paramA": options.paramA,
"success": {
(res: MyApiResult) -> Void in
(res: String) -> Void in
options.success?(res)
},
"fail": {