欧美第十页,成人网成人A片,宾馆内激干人妻,偷偷内射,一区二区另类TS

聯(lián)想yoga13s電源鍵亮但黑屏,聯(lián)想休眠后黑屏無法啟動

大家好,今天小編來為大家解答聯(lián)想yoga13s電源鍵亮但黑屏,聯(lián)想休眠后黑屏無法啟動這個問題,聯(lián)想yoga13s電源鍵亮但黑屏,聯(lián)想休眠后黑屏無法啟動很多人還不知道,現(xiàn)在讓我們一起來看看吧!YOGA新電腦到手該怎么設置?小白教程告訴你購前需知#1聯(lián)想保修政策1.聯(lián)想對原廠部件進行保修。2.如果原廠部件產生了非損

大家好,今天小編來為大家解答聯(lián)想yoga13s電源鍵亮但黑屏,聯(lián)想休眠后黑屏無法啟動這個問題,聯(lián)想yoga13s電源鍵亮但黑屏,聯(lián)想休眠后黑屏無法啟動很多人還不知道,現(xiàn)在讓我們一起來看看吧!

YOGA新電腦到手該怎么設置?小白教程告訴你

購前需知#1 聯(lián)想保修政策

1.聯(lián)想對原廠部件進行保修。2.如果原廠部件產生了非損,則無法保修。3.自行加裝的第三方部件不保修,如鍵盤,屏幕,內存,固態(tài)等,加裝部件不影響機器原有保修 (除非機器故障是因為加裝部件引發(fā))。4.如果自行拆部件時,把主板拆壞了,主板也會喪失保修。5.預裝系統(tǒng),一年內送至服務站免費恢復。6.拯救者自購符合規(guī)格和兼容性的內存、硬盤帶至服務站,可以免費加裝。但是如果涉及到系統(tǒng)遷移,重新安裝系統(tǒng)至新加裝硬盤,需要付費。

購前需知#2 7天無理由退換貨條件

1.建議您在收到產品后,先檢查外包裝是否完好,如有暴力物流的跡象,可以拒收或者及時反饋給商家進行處理。2.首次開機之前可先檢查產品外觀是否正常,如有瑕疵請盡快反饋給商家。3.收到機器后,請檢查新機外觀是否有問題,若無問題可進行正常通電開機,按流程完成Windows的設置向導。由于Windows 11的設置向導將強制機器聯(lián)網(wǎng),聯(lián)網(wǎng)后會自動進行激活,激活后不支持7天無理由退換貨。如果您確定機器正常無誤后,再聯(lián)網(wǎng)激活Windows以及后續(xù)的Office使用。但激活后發(fā)現(xiàn)產品有任何質量問題,均可通過售后渠道正常退換維修,無需擔心。4.進行以上**作前,強烈建議您先聯(lián)系**平臺的官網(wǎng)售后,確認下是否有其他影響產品7天無理由退貨的條款和要求,可以參考《網(wǎng)絡購買商品七日無理由退貨暫行辦法》中主要相關內容。

購前需知#3 退換貨**

1.針對退換貨,7/15天的三包退換貨請直接聯(lián)系經銷商(京東官方客服,天貓官方客服、聯(lián)想商城官方客服、線下專賣店店長),如果超過15天,有特殊情況的退換貨,請撥打投訴電話,400-990-8888,轉9轉3。2.針對保修,建議聯(lián)系官方售后客服400-990-8888或聯(lián)想服務微信**人工咨詢或者在電腦預裝的聯(lián)想電腦管家點擊客戶服務咨詢。3.針對售后店面和**,在服務官網(wǎng)、聯(lián)想服務微信**中都可以查詢維修網(wǎng)點和**。

到手需知

1.機器出廠后將開啟運輸模式,全新機器不插電是無法開機的,請插上電源再開機。2.新機在工廠組裝完畢后會導入系統(tǒng)并進行檢測,這會讓SSD產生一定的通電時間、使用次數(shù)和讀寫量,如果開機使用工具檢測到新機的SSD有通電時間、使用次數(shù)和讀寫量,屬于正常情況,聯(lián)想的通電時間標準在300小時內。3.新機的屏幕(B面)與鍵盤(C面)之間會有一張無紡布,上面印有簡單的使用說明,還請閱讀。4.首次開機會進行系統(tǒng)初始化,需要等待一段時間,期間可能會多次重啟,為正常情況。5.Windows 11的設置向導將強制機器聯(lián)網(wǎng),聯(lián)網(wǎng)后會自動進行激活,激活后會影響7天無理由退換貨。6.預裝office需要您能聯(lián)網(wǎng)激活Windows之后6個月內兌換激活,否則可能會無**常兌換激活。7.國行機器中預裝的Windows和Office需要在**大陸境內網(wǎng)絡下激活,新機出國會影響Windows和Office的激活。

使用小技巧#1 使用Fn+Q一鍵切換散熱模式

YOGA和小新目前的機型均搭載Fn+Q一鍵切換散熱模式的功能,按住Fn鍵再按Q鍵可以在安靜模式——均衡模式——野獸模式間進行循環(huán)切換,成功切換時,屏幕上會顯示當前的模式圖標。

安靜模式下機器將會主動限制風扇的轉速,同時會限制整機功耗;均衡模式顧名思義,比較均衡,會根據(jù)當前的負載自動調節(jié)風扇轉速;野獸模式將會讓機器以最大性能發(fā)揮,但是會增加風扇轉速。大家可以根據(jù)自己的需求選擇運行模式。

#2 使用Fn+R一鍵切換屏幕刷新率

我們的高刷屏機型,如YOGA 14s 2021、YOGA 16s 2022、小新Pro 14 高刷版和小新 Pro 16 銳龍獨顯版等都具備Fn+R一鍵切換屏幕刷新率功能,可以一鍵在高刷新率和60Hz之間進行切換,使用方法非常簡單,直接按Fn+R即可,屏幕上會顯示切換后對應的刷新率圖標。

如果沒有起效,請手動運行一次預裝的Lenovo Hotkeys軟件,之后將會持續(xù)起效。

#3 按Fn+空格調整鍵盤背光燈亮度

目前YOGA和小新機型均配備鍵盤背光燈,可以按Fn+空格調整它的開關及亮度,屏幕上會出現(xiàn)圖標提示。

對于小新Pro 14、YOGA 14s 2021、YOGA 13s 2021、YOGA Pro 13s 2021、YOGA Pro 14s 2021和YOGA Pro 14s Carbon 2022這些機型,一共有四擋背光可調,分別為關——50%亮度——100%亮度——自動亮度。對于其他機型,則是有三擋可調,分別為關——亮——更亮。

#4 快速進入BIOS

有時候需要進入BIOS修改一些設置,可以在重啟后黑屏時按F2鍵進入,如果無法進入,可以嘗試在完全關機的情況下按Delete左側第二個鍵,機器會自行啟動并顯示啟動菜單,用方向鍵移動到BIOS Setup,用回車確定后會進入。

#5 開啟人走自動鎖屏功能

配備人臉識別前置攝像頭的機型支持人走自動鎖屏功能,該功能通過前置攝像頭內置的ToF傳感器實現(xiàn),軟件上需要在預裝的聯(lián)想電腦管家中開啟。

打開電腦管家,在工具箱頁面中找到智能感知。

**攝像頭自動登錄功能可以讓您坐到電腦前時自動亮屏并觸發(fā)人臉解鎖,無需**作即可解鎖;自動鎖定屏幕可以在您離開電腦時自動鎖定賬戶,保護隱私不泄漏。按需開啟相關功能即可。

#6 如何關閉/開啟開蓋開機

新的機器默認開啟開蓋開機功能,不管在關機、休眠還是睡眠狀態(tài)下,掀開上蓋都可以喚醒機器,如果需要修改這個功能的狀態(tài),可以在聯(lián)想電腦管家的工具箱中找到開蓋開機功能,開關它即可。

#7 F1~F12對應的快捷鍵都是啥?

輕薄本默認將F1~F12鍵映射為功能快捷鍵,這排功能鍵的具體功能如下表:

原始按鍵功能Esc切換F1~F12功能F1靜音F2音量減F3音量增F4關閉/開啟麥克風F5亮度減F6亮度增F7擴展屏幕F8飛行模式F9系統(tǒng)設置F10鎖屏F11多任務切換F12計算器Insert聯(lián)想電腦管家PrtSc截圖工具

其中Fn+Esc可以快速切換功能鍵的映射狀態(tài),Esc旁有指示燈,與拯救者機型相反,亮著的時候功能鍵恢復為傳統(tǒng)F1~F12,燈滅時為默認的功能快捷鍵。

#8 如何啟用/禁用觸控板

目前可以通過Windows系統(tǒng)設置來控制觸控板工作狀態(tài),Windows 10中這個開關位于“設備-觸摸板”中,Windows 11中位于“藍牙和其他設備-觸摸板”中。

需要說明兩點:

1.如果設置觸摸板關閉,重新開機后觸摸板不會自動打開,并非觸控板故障。2.“連接鼠標時讓觸摸板保持打開狀態(tài)”:取消勾選此項可實現(xiàn)插入鼠標自動禁用觸摸板功能。部分鼠標驅動軟件,即使沒有連接鼠標,也會使系統(tǒng)誤以為接通鼠標狀態(tài)。沒插鼠標但后臺有鼠標軟件運行時,取消勾選此功能,觸摸板不會自動啟用。

#9 如何修改電池充電模式

Windows 10下可直接點擊任務欄上的聯(lián)想電腦管家小掛件,在彈出的窗口里可以快速切換電池充電模式。

Windows 11下因為任務欄的修改,需要打開聯(lián)想電腦管家,在設備狀態(tài)頁面中點擊耗電排行,充電模式位于彈出的側邊窗口的右上角。

#10 如何更新驅動

更新驅動推薦使用聯(lián)想電腦管家的驅動更新功能,它的驅動版本和官網(wǎng)同步。部分公版驅動版本可能會新,但可能存在一些穩(wěn)定性和兼容性問題,推薦使用官方驅動。

#11 如何重置系統(tǒng)

如果需要還原出廠自帶的系統(tǒng),推薦通過系統(tǒng)自帶的重置功能進行,Windows 10該功能位于“系統(tǒng)設置——更新和安全——恢復”,點擊“重置此電腦”的開始即可。Windows 11中該功能位于“系統(tǒng)設置——系統(tǒng)——恢復——重置此電腦”,點擊“重置此電腦”的開始即可。

Office 2021激活相關

Office 2021的激活信息改成了和設備綁定,不再和微軟賬戶綁定,所以在完成系統(tǒng)激活之后,打開Office就會進入激活流程,部分出廠稍早的機器在這里會提示您更新Office,更新過后Office也會自動激活。

#聯(lián)想##聯(lián)想服務#

鴻蒙分布式相機“踩坑”分享

實現(xiàn)分布式相機其實很簡單,正如官方介紹的一樣,當被控端相機被連接成功后,可以像使用本地設備一樣使用遠程相機。

我們先看下效果:

上一篇已經完整的介紹了如何開發(fā)一個本地相機,對于分布式相機我們需要完成以下幾個步驟。

前置條件:兩臺帶攝像頭的設備建議使用相同版本的 OH 系統(tǒng),本案例使用 OpenHarmony 3.2 beta5連接在同一個網(wǎng)絡開發(fā)步驟:引入設備管理(@ohos.distributedHardware.deviceManager)通過 deviceManager 發(fā)現(xiàn)周邊設備通過 pin 碼完成設備認證獲取和展示可信設備在可信設備直接選擇切換不同設備的攝像頭在主控端查看被控端的攝像頭圖像

以上描述的功能在應用開發(fā)時可以使用一張草圖來表示,草圖中切換設備->彈窗顯示設備列表的過程,草圖如下:

代碼

①RemoteDeviceModel.ts

說明: 遠程設備業(yè)務處理類,包括獲取可信設備列表、獲取周邊設備列表、**設備狀態(tài)(上線、下線、狀態(tài)變化)、**設備連接失敗、設備授信認證、卸載設備狀態(tài)**等。

代碼如下:

import deviceManager from ‘@ohos.distributedHardware.deviceManager’import Logger from ‘./util/Logger’const TAG: string = ‘RemoteDeviceModel’let subscribeId: number = -1export class RemoteDeviceModel { private deviceList: Array<deviceManager.DeviceInfo> = [] private discoverList: Array<deviceManager.DeviceInfo> = [] private callback: () => void private authCallback: () => void private deviceManager: deviceManager.DeviceManager constructor() { } public registerDeviceListCallback(bundleName : string, callback) { if (typeof (this.deviceManager) !== ‘undefined’) { this.registerDeviceListCallbackImplement(callback) return } Logger.info(TAG, `deviceManager.createDeviceManager begin`) try { deviceManager.createDeviceManager(bundleName, (error, value) => { if (error) { Logger.info(TAG, `createDeviceManager failed.`) return } this.deviceManager = value this.registerDeviceListCallbackImplement(callback) Logger.info(TAG, `createDeviceManager callback returned, error= ${error},value= ${value}`) }) } catch (err) { Logger.error(TAG, `createDeviceManager failed, code is ${err.code}, message is ${err.message}`) } Logger.info(TAG, `deviceManager.createDeviceManager end`) } private deviceStateChangeActionOffline(device) { if (this.deviceList.length <= 0) { this.callback() return } for (let j = 0; j < this.deviceList.length; j++) { if (this.deviceList[j ].deviceId === device.deviceId) { this.deviceList[j] = device break } } Logger.info(TAG, `offline, device list= ${JSON.stringify(this.deviceList)}`) this.callback() } private registerDeviceListCallbackImplement(callback) { Logger.info(TAG, `registerDeviceListCallback`) this.callback = callback if (this.deviceManager === undefined) { Logger.info(TAG, `deviceManager has not initialized`) this.callback() return } Logger.info(TAG, `getTrustedDeviceListSync begin`) try { let list = this.deviceManager.getTrustedDeviceListSync() Logger.info(TAG, `getTrustedDeviceListSync end, deviceList= ${JSON.stringify(list)}`) if (typeof (list) !== ‘undefined’ && typeof (list.length) !== ‘undefined’) { this.deviceList = list } } catch (err) { Logger.error(`getTrustedDeviceListSync failed, code is ${err.code}, message is ${err.message}`) } this.callback() Logger.info(TAG, `callback finished`) this.deviceManager.on(‘deviceStateChange’, (data) => { if (data === null) { return } Logger.info(TAG, `deviceStateChange data= ${JSON.stringify(data)}`) switch (data.action) { case deviceManager.DeviceStateChangeAction.READY: this.discoverList = [] this.deviceList.push(data.device) try { let list = this.deviceManager.getTrustedDeviceListSync() if (typeof (list) !== ‘undefined’ && typeof (list.length) !== ‘undefined’) { this.deviceList = list } this.callback() } catch (err) { Logger.error(TAG, `getTrustedDeviceListSync failed, code is ${err.code}, message is ${err.message}`) } break case deviceManager.DeviceStateChangeAction.OFFLINE: case deviceManager.DeviceStateChangeAction.CHANGE: this.deviceStateChangeActionOffline(data.device) break default: break } }) this.deviceManager.on(‘deviceFound’, (data) => { if (data === null) { return } Logger.info(TAG, `deviceFound data= ${JSON.stringify(data)}`) this.deviceFound(data) }) this.deviceManager.on(‘discoverFail’, (data) => { Logger.info(TAG, `discoverFail data= ${JSON.stringify(data)}`) }) this.deviceManager.on(‘serviceDie’, () => { Logger.info(TAG, `serviceDie`) }) this.startDeviceDiscovery() } private deviceFound(data) { for (var i = 0;i < this.discoverList.length; i++) { if (this.discoverList[i].deviceId === data.device.deviceId) { Logger.info(TAG, `device founded ignored`) return } } this.discoverList[this.discoverList.length] = data.device Logger.info(TAG, `deviceFound self.discoverList= ${this.discoverList}`) this.callback() } private startDeviceDiscovery() { if (subscribeId >= 0) { Logger.info(TAG, `started DeviceDiscovery`) return } subscribeId = Math.floor(65536 * Math.random()) let info = { subscribeId: subscribeId, mode: deviceManager.DiscoverMode.DISCOVER_MODE_ACTIVE, medium: deviceManager.ExchangeMedium.COAP, freq: deviceManager.ExchangeFreq.HIGH, isSameAccount: false, isWakeRemote: true, capability: deviceManager.SubscribeCap.SUBSCRIBE_CAPABILITY_DDMP } Logger.info(TAG, `startDeviceDiscovery ${subscribeId}`) try { // todo 多次啟動發(fā)現(xiàn)周邊設備有什么影響嗎? this.deviceManager.startDeviceDiscovery(info) } catch (err) { Logger.error(TAG, `startDeviceDiscovery failed, code is ${err.code}, message is ${err.message}`) } } public unregisterDeviceListCallback() { Logger.info(TAG, `stopDeviceDiscovery $subscribeId}`) this.deviceList = [] this.discoverList = [] try { this.deviceManager.stopDeviceDiscovery(subscribeId) } catch (err) { Logger.error(TAG, `stopDeviceDiscovery failed, code is ${err.code}, message is ${err.message}`) } this.deviceManager.off(‘deviceStateChange’) this.deviceManager.off(‘deviceFound’) this.deviceManager.off(‘discoverFail’) this.deviceManager.off(‘serviceDie’) } public authenticateDevice(device, extraInfo, callBack) { Logger.info(TAG, `authenticateDevice ${JSON.stringify(device)}`) for (let i = 0; i < this.discoverList.length; i++) { if (this.discoverList[i].deviceId !== device.deviceId) { continue } let authParam = { ‘authType’: 1, ‘appIcon’: ”, ‘appThumbnail’: ”, ‘extraInfo’: extraInfo } try { this.deviceManager.authenticateDevice(device, authParam, (err, data) => { if (err) { Logger.error(TAG, `authenticateDevice error: ${JSON.stringify(err)}`) this.authCallback = null return } Logger.info(TAG, `authenticateDevice succeed: ${JSON.stringify(data)}`) this.authCallback = callBack }) } catch (err) { Logger.error(TAG, `authenticateDevice failed, code is ${err.code}, message is ${err.message}`) } } } /** * 已認證設備列表 */ public getDeviceList(): Array<deviceManager.DeviceInfo> { return this.deviceList } /** * 發(fā)現(xiàn)設備列表 */ public getDiscoverList(): Array<deviceManager.DeviceInfo> { return this.discoverList }}

getDeviceList() :獲取已認證的設備列表;getDiscoverList:發(fā)現(xiàn)周邊設備的列表。

②DeviceDialog.ets

說明:通過 RemoteDeviceModel.getDiscoverList() 和通過 RemoteDeviceModel.getDeviceList() 獲取到所有周邊設備列表,用戶通過點擊”切換設備”按鈕彈窗顯示所有設備列表信息。

import deviceManager from ‘@ohos.distributedHardware.deviceManager’;const TAG = ‘DeviceDialog’// 分布式設備選擇彈窗@CustomDialogexport struct DeviceDialog { private controller?: CustomDialogController // 彈窗控制器 @Link deviceList: Array<deviceManager.DeviceInfo> // 設備列表 @Link selectIndex: number // 選中的標簽 build() { Column() { List() { ForEach(this.deviceList, (item: deviceManager.DeviceInfo, index) => { ListItem() { Row() { Text(item.deviceName) .fontSize(22) .width(350) .fontColor(Color.Black) Image(index === this.selectIndex ? $r(‘app.media.checked’) : $r(‘app.media.uncheck’)) .width(35) .objectFit(ImageFit.Contain) } .height(55) .onClick(() => { console.info(`${TAG} select device ${item.deviceId}`) if (index === this.selectIndex) { console.info(`${TAG} device not change`) } else { this.selectIndex = index } this.controller.close() }) } }, item => item.deviceName) } .width(‘100%’) .height(150) Button() { Text($r(‘app.string.cancel’)) .width(‘100%’) .height(45) .fontSize(18) .fontColor(Color.White) .textAlign(TextAlign.Center) }.onClick(() => { this.controller.close() }) .backgroundColor(‘#ed3c13’) } .width(‘100%’) .padding(20) .backgroundColor(Color.White) .border({ color: Color.White, radius: 20 }) }}

③打開設備列表彈窗

說明:在 index.ets 頁面中,點擊“切換設備”按鈕即可以開啟設備列表彈窗,通過 @Watch(‘selectedIndexChange’) **用戶選擇的設備標簽,在 devices 中獲取到具體的 DeviceInfo 對象。

代碼如下:

@State @Watch(‘selectedIndexChange’) selectIndex: number = 0 // 設備列表 @State devices: Array<deviceManager.DeviceInfo> = [] // 設備選擇彈窗 private dialogController: CustomDialogController = new CustomDialogController({ builder: DeviceDialog({ deviceList: $devices, selectIndex: $selectIndex, }), autoCancel: true, alignment: DialogAlignment.Center }) showDialog() { console.info(`${TAG} RegisterDeviceListCallback begin`) distributed.registerDeviceListCallback(BUNDLE_NAME, () => { console.info(`${TAG} RegisterDeviceListCallback callback entered`) this.devices = [] // 添加本地設備 this.devices.push({ deviceId: Constant.LOCAL_DEVICE_ID, deviceName: Constant.LOCAL_DEVICE_NAME, deviceType: 0, networkId: ”, range: 1 // 發(fā)現(xiàn)設備的距離 }) let discoverList = distributed.getDiscoverList() let deviceList = distributed.getDeviceList() let discoveredDeviceSize = discoverList.length let deviceSize = deviceList.length console.info(`${TAG} discoveredDeviceSize:${discoveredDeviceSize} deviceSize:${deviceSize}`) let deviceTemp = discoveredDeviceSize > 0 ? discoverList : deviceList for (let index = 0; index < deviceTemp.length; index++) { this.devices.push(deviceTemp[index]) } }) this.dialogController.open() console.info(`${TAG} RegisterDeviceListCallback end`) }async selectedIndexChange() { console.info(`${TAG} select device index ${this.selectIndex}`) let discoverList: Array<deviceManager.DeviceInfo> = distributed.getDiscoverList() if (discoverList.length <= 0) { this.mCurDeviceID = this.devices[this.selectIndex].deviceId await this.switchDevice() this.devices = [] return } let selectDeviceName = this.devices[this.selectIndex].deviceName let extraInfo = { ‘targetPkgName’: BUNDLE_NAME, ‘appName’: APP_NAME, ‘appDescription’: APP_NAME, ‘business’: ‘0’ } distributed.authenticateDevice(this.devices[this.selectIndex], extraInfo, async () => { // 獲取到相關的設備ID,啟動遠程應用 for (var index = 0; index < distributed.getDeviceList().length; index++) { let deviceName = distributed.getDeviceList()[index].deviceName if (deviceName === selectDeviceName) { this.mCurDeviceID = distributed.getDeviceList()[index].deviceId await this.switchDevice() } } }) this.devices = [] }④重新加載相機

說明:根據(jù)用戶選擇的設備標簽獲取到當前用戶需要切換的相機設備對象,重新加載相機,重新加載需要釋放原有的相機資源,然后重新構建 createCameraInput、createPreviewOutput、createSession。

可能你注意到這里好像沒有執(zhí)行 createPhotoOutput,這是因為在實踐過程中發(fā)現(xiàn),添加了一個當前設備所支持的拍照配置到會話管理(CaptureSession.addOutput())時,系統(tǒng)會返回當前拍照配置流不支持,并關閉相機,導致相機預覽黑屏,所以這里沒有添加。

issues:遠程相機拍照失敗 not found in supported streams。

mCameraService:這個是相機管理類,代碼可以查看上一篇:OpenHarmony 分布式相機(上)中查看。

代碼如下:

/** * 切換攝像頭 * 同一臺設備上切換不同攝像頭 */ async switchCamera() { console.info(`${TAG} switchCamera`) let cameraList = this.mCameraService.getDeviceCameras(this.mCurDeviceID) if (cameraList && cameraList.length > 1) { let cameraCount: number = cameraList.length console.info(`${TAG} camera list ${cameraCount}}`) if (this.mCurCameraIndex < cameraCount – 1) { this.mCurCameraIndex += 1 } else { this.mCurCameraIndex = 0 } await this.reloadCamera() } else { this.showToast($r(‘app.string.only_one_camera_hint’)) } } /** * 重新加載攝像頭 */ async reloadCamera() { // 顯示切換loading this.isSwitchDeviceing = true // 先關閉當前**,再切換新的** await this.mCameraService.releaseCamera() await this.startPreview() }private async startPreview() { console.info(`${TAG} startPreview`) await this.mCameraService.createCameraInput(this.mCurCameraIndex, this.mCurDeviceID) await this.mCameraService.createPreviewOutput(this.surfaceId, this.previewImpl) if (this.mCurDeviceID === Constant.LOCAL_DEVICE_ID) { // fixme xjs 如果是遠程相機,則不支持拍照,添加拍照輸出流會導致相機黑屏 await this.mCameraService.createPhotoOutput(this.functionBackImpl) } await this.mCameraService.createSession(this.surfaceId) }⑤加載過度動畫

說明:在相機切換中會需要釋放原相機的資源,在重啟新相機,在通過軟總線通道同步遠程相機的預覽數(shù)據(jù)。

這里需要一些時間,根據(jù)目前測試,在網(wǎng)絡穩(wěn)定狀態(tài)下,切換時間 3~5s,網(wǎng)絡不穩(wěn)定狀態(tài)下,切換最長需要 13s,當然有時候會出現(xiàn)無法切換成功,這種情況可能是遠程設備已經下線,無法再獲取到數(shù)據(jù)。

代碼如下:

@State isSwitchDeviceing: boolean = false // 是否正在切換相機 if (this.isSwitchDeviceing) { Column() { Image($r(‘app.media.load_switch_camera’)) .width(400) .height(306) .objectFit(ImageFit.Fill) Text($r(‘app.string.switch_camera’)) .width(‘100%’) .height(50) .fontSize(16) .fontColor(Color.White) .align(Alignment.Center) } .width(‘100%’) .height(‘100%’) .backgroundColor(Color.Black) .justifyContent(FlexAlign.Center) .alignItems(HorizontalAlign.Center) .onClick(() => { }) }

至此,分布式相機的整體流程就已實現(xiàn)完成。下面我們介紹下分布式相機開發(fā)中所遇到的問題。

分布式相機問題一覽

對于開發(fā)過程中所遇到的一些坑,前面多少有簡單的提到一些,這里做一次規(guī)整,也算是一次回顧。

①首次授權成功無法顯示相機預覽

解析:我們正常會在 MainAbility.ts 的 onCreate() 函數(shù)加載的時候執(zhí)行申請授權,在 index.ets 頁面中,當 XComponent 組件 onLoad() 回調后執(zhí)行初始化相機**作,代碼如下:

MainAbility.ts:

const TAG: string = ‘[DistributedCamera]’let permissionList: Array<string> = [ “ohos.permission.MEDIA_LOCATION”, “ohos.permission.READ_MEDIA”, “ohos.permission.WRITE_MEDIA”, “ohos.permission.CAMERA”, “ohos.permission.MICROPHONE”, “ohos.permission.DISTRIBUTED_DATASYNC”]export default class MainAbility extends Ability { async onCreate(want, launchParam) { console.info(`${TAG} onCreate`) globalThis.cameraAbilityContext = this.context await globalThis.cameraAbilityContext.requestPermissionsFromUser(permissionList) } }

index.ets:

// …// 截取部分主要代碼Column() { XComponent({ id: ‘componentId’, type: ‘surface’, controller: this.XComponentController }).onLoad(async () => { console.info(`${TAG} XComponent onLoad is called`) this.XComponentController.setXComponentSurfaceSize({ surfaceWidth: Resolution.DEFAULT_WIDTH, surfaceHeight: Resolution.DEFAULT_HEIGHT }) this.surfaceId = this.XComponentController.getXComponentSurfaceId() console.info(`${TAG} surfaceId: ${this.surfaceId}`) await this.initCamera() }).height(‘100%’) .width(‘100%’) } .width(‘100%’) .height(‘75%’) .margin({ bottom: 20 })// …

應用啟動后,調用了 requestPermissionsFromUser() 請求權限后,但未手動授權時,查看相關日志:

日志告訴我們,page 的生命周期已啟動到 onShow,并且頁面布局也完成了加載,XComponent 組件回調 onLoad()。

但是由于還未授權,導致無法初始化相機,此時即便授權成功,也不會再進行初始化,導致相機無法啟動,無預覽視圖。

知道原因后,我們可以有多種方式解決,重點就是在授權完成后,需要再次觸發(fā)初始化相機,讓相機啟動才可以正常預覽。

我的處理方式:在 index.ets 頁面中處理授權定義是否已授權的標識,用于判斷是否可以初始化相機定義是否已經初始化相機標識,防止對此初始化在 page 頁面初始化函數(shù) aboutToAppear() 中請求權限,并在權限申請結果中添加初始化相機**作XComponent 組件回調 onLoad() 初始化相機**作不變index.ets:

private isInitCamera: boolean = false // 是否已初始化相機 private isPermissions: boolean = false // 是否完成授權 async aboutToAppear() { console.info(`${TAG} aboutToAppear`) globalThis.cameraAbilityContext.requestPermissionsFromUser(permissionList).then(async (data) => { console.info(`${TAG} data permissions: ${JSON.stringify(data.permissions)}`) console.info(`${TAG} data authResult: ${JSON.stringify(data.authResults)}`) // 判斷授權是否完成 let resultCount: number = 0 for (let result of data.authResults) { if (result === 0) { resultCount += 1 } } if (resultCount === permissionList.length) { this.isPermissions = true } await this.initCamera() // 獲取縮略圖 this.mCameraService.getThumbnail(this.functionBackImpl) }) }

②相機應用未關閉,系統(tǒng)息屏后重新點亮,重新返回相機應用,無預覽輸出流返回

解析:從現(xiàn)象看,預覽畫面卡在息屏前的狀態(tài),需要退出應用后,重啟應用才能正常預覽。從日志上看沒有查看到具體的原因,只是 camera_host 的數(shù)據(jù)量日志消失。

猜想:相機在系統(tǒng)息屏后強制關閉,需要重新加載相機才能正常預覽,實現(xiàn)方式如下:

在 page 的 onPageShow() 回調函數(shù)中重新初始化相機。在 page 的 onPageHide() 函數(shù)中釋放相機資源,減少系統(tǒng)資源不必要的消耗。index.ets:

async onPageShow() { console.info(`${TAG} onPageShow`) await this.initCamera() } onPageHide() { console.info(`${TAG} onPageHide`) this.isSwitchDeviceing = false this.isInitCamera = false this.mCameraService.releaseCamera() }

結論: 實踐驗證此方法有效解決息屏后點亮返回相機無法預覽的問題。

③加載遠程相機,在會話管理中添加拍照輸出流,無法拍照,預覽黑屏

解析:兩臺設備 pin 碼認證通過,連接成功,在主控端選擇一臺被控端設備時,加載相機,流程與加載本地相機相同。

流程如下:

createCameraInput()createPreviewOutput()createPhotoOutput()createSession()* createSession.beginConfig()* createSession.addInput(CameraInput)* createSession.addOutput(PreviewOutput)* createSession.addOutput(PhotoOutput)* createSession.commitConfig()* createSession.start()

經過排查,發(fā)現(xiàn)日志中返回異常 not found in supported streams,詳情可以查看關聯(lián) issues。

原因:在創(chuàng)建 PhotoOutput 時需要傳遞支持的拍照配置信息 Profile,這里的 Profile 可以通過 CmeraManager.getSupportedOutputCapability() 返回的相機輸出能力 CameraOutputCapability 對象獲取,但遠程相機設備拍照輸出能力列表返回空。

但通過查看本地相機拍照輸出能力可知 DAYU200 設備支持的 Profile 信息:

photoProfile {“format”:2000,”size”:{“width”:1280,”height”:960}}

通過此將 photoProfile 作為遠程相機設備構建拍照輸出流的入?yún)鼍芭恼蛰敵隽?,并把此添加到拍照會話管理中,但是界面出現(xiàn)不支持此相機配置,最終關閉了相機,導致黑屏。

解決方案:根據(jù)此問題,目前只能根據(jù)場景判斷是否需要添加拍照輸出流到會話管理,對于本地相機則可以添加拍照輸出流,執(zhí)行拍照業(yè)務,遠程相機則不添加拍照輸出流,這也就不能執(zhí)行拍照業(yè)務,希望社區(qū)有解決方案。

④切換不同設備上的相機,相機預覽輸出流出現(xiàn)異常,無法顯示遠程相機的畫面

解析: 此問題存在的原因可能有多種,這里我說下我遇到的情況。

(1)分布式連接被斷開,但是因為底層機制,設備之間下線需要在一段時間內才能上報(預計 5 分鐘),所以在應用層看到可以連接的遠端設備,其實已經下線了,這時當然不能切換到遠程相機。

(2)與問題 3 中描述的相同,因為添加了一個無法支持的拍照配置信息導致相機被關閉。

解決方案:

等待線下通知,再重新連接設備,或者等待設備自動完成重連,簡單粗暴就是重啟設備。待社區(qū)反饋。⑤相機業(yè)務在主線程執(zhí)行,需要將業(yè)務移動到子線程,防止 UI 線程堵塞

解析:如題描述,目前可能存在堵塞 UI 線程的可能,需要將一些耗時的**作移動到子線程,比如預覽、拍照保存圖片等。

目前正在修改優(yōu)化,關于 ets 的異步線程 worker 可以查看之前寫的一篇關于:??OpenHarmony stage worker 多線程??。

⑥遠程相機預覽數(shù)據(jù)傳輸存在 500ms 的延遲

解析:在 wifi 環(huán)境下,被控端相機將預覽數(shù)據(jù)通過軟總線傳輸?shù)街骺囟孙@示,有 500ms 左右的延遲,此問題待排查,具體是那個環(huán)境出現(xiàn)的延遲。

⑦no permission for function call

解析:用戶動態(tài)授予:允許不同設備間的數(shù)據(jù)(ohos.permission.DISTRIBUTED_DATASYNC) 交換權限后,DeviceManager.startDeviceDiscovery() 啟動發(fā)現(xiàn)周邊設備總會出現(xiàn)異常。

日志中提示:

discoverFail data= {“subscribeId”:26386,”reason”:-20007,”errInfo”:”no permission for function call.”}

原因: 非系統(tǒng)應用無法使用 DeviceManager,詳細可查看:issues。

解決方案:系統(tǒng)應用和普通應用是通過簽名來區(qū)分,那只要通過修改簽名 UnsgnedReleasedProfileTemplate.json 文件中的 app-feature 值為 ohos_system_app,即為系統(tǒng)應用。

聯(lián)想yoga13s電源鍵亮但黑屏,聯(lián)想休眠后黑屏無法啟動和聯(lián)想yoga13s電源鍵亮但黑屏,聯(lián)想休眠后黑屏無法啟動的問題分享結束啦,以上的文章解決了您的問題嗎?歡迎您下次再來哦!

原創(chuàng)文章,作者:Admin,如若轉載,請注明出處:http://m.cxzzxj.cn/195413.html

中国熟妇freesex| 亚州国产精品无码久久| 亚洲午夜爱爱香蕉片| 尤物久久久久久久久久| 色天天躁夜夜躁天干天干| 99热一二三区| 亚洲欧美在线免费中文| 久久99白丝大胸| 精品人妻嫩草A√| 老司机精品无码久久播放| 99精品国产青青牛奶一区二区| 国产成人无码精品久久久软件| 欧美日韩中文色| 午夜老湿机aV| 中文成人精品久久| 大城县| 亚洲人成网站观看在线播放超?| 国产精品久久久久久久久丫| 精品人妻伦一二三区久久春菊| 久久无码一区二区爽爽爽| 国产一级毛片国语一级AV| 高清无码一二三四区| 极上人妻JULIA中文字幕在线| 新版中文官网资源av| www色就是色| 日韩无码国产精品不卡| 欧美精品高清综合久久久| 亚洲熟妇色无码一级毛片| 国产精品视频系列专区| 国产成人高清精品免费鸭子| 日韩欧美成人电澋| 亚洲日韩电影久久| 午夜爽爽爽男女免费观看| 亚洲精品自拍区在线观看| 欧美高清一区精品| 91美女一区二区三区| 久久99精品视免费看| 久久成人国产精品青青| 香蕉欧美高清系列视频| 国产精品日产无码aⅤ永久不卡| 国产精品日本亚洲77|