主頁 > 移動端開發 > 如何基于 ZEGO SDK 實作 Android 通話質量監測

如何基于 ZEGO SDK 實作 Android 通話質量監測

2022-05-10 08:09:31 移動端開發

功能簡介

在進行視頻通話程序中,用戶有時候會出現網路不好的情況,比如在進行多人視頻通話或者多人唱歌時,我們需要實時顯示用戶的網路質量,
在這里插入圖片描述

示例原始碼

參考 下載示例原始碼 獲取原始碼,

相關原始碼請查看 “/ZegoExpressExample/AdvancedStreaming/src/main/java/im/zego/streammonitoring” 目錄下的檔案,

前提條件

在監測通話質量之前,請確保:

  • 已在專案中集成 ZEGO Express SDK,實作基本的實時音視頻功能,詳情請參考 快速開始 - 集成 和 快速開始 - 實作流程,
  • 已在 ZEGO 控制臺 創建專案,并申請有效的 AppID,詳情請參考 控制臺 - 專案管理 中的“專案資訊”,

基礎網路質量報告

可以通過監聽 onNetworkQuality 回呼,收到房間內用戶(包括自己)的上下行網路質量,此回呼每隔兩秒會收到一次,網路質量等級請參考 ZegoStreamQualityLevel

不同版本的 onNetworkQuality 回呼邏輯有所不同:

  • 對于使用 2.14.0 及以上版本 ZEGO Express SDK 的用戶,onNetworkQuality 回呼的邏輯為:

    • 只要推流或者拉流,就能收到自己的網路質量回呼,
    • 當拉取了其他用戶推送的音視頻流并且該用戶在房間內時,才會收到該用戶的網路質量回呼,
    • 當 “userID” 為 “null” 時,代表本次是自己的網路質量,當 “userID” 不為 “null” 時,代表是房間內其他用戶的報告,
  • 對于使用 2.10.02.13.1 版本 ZEGO Express SDK 的用戶,onNetworkQuality 回呼的邏輯為:

    • 必須既推流又拉流,才會收到自身的網路質量回呼,
    • 當拉取一條流時,推送該條流的用戶必須在同一房間內,且他也進行了拉流,才會收到該用戶的網路質量回呼,
    • 當 “userID” 為 “null” 時,代表本次是自己的網路質量,當 “userID” 不為 “null” 時,代表是房間內其他用戶的報告,

onNetworkQuality 不適用于使用 CDN 進行直播的場景,可以參考 進階質量報告 - 推流質量報告 監測 CDN 的推流質量,

public void setEngineEventHandler(){
        engine.setEventHandler(new IZegoEventHandler() {
            @Override
            public void onNetworkQuality(String userID, ZegoStreamQualityLevel upstreamQuality, ZegoStreamQualityLevel downstreamQuality) {
                super.onNetworkQuality(userID, upstreamQuality, downstreamQuality);
                if (userID == null) {
                    // 代表本地用戶(我)的網路質量
                    //("我的上行網路質量是 %lu", (unsigned long)upstreamQuality);
                    //("我的下行網路質量是 %lu", (unsigned long)downstreamQuality);
                } else {
                    //代表房間內其他用戶的網路質量
                    //("用戶 %s 的上行網路質量是 %lu", userID, (unsigned long)upstreamQuality);
                    //("用戶 %s 的下行網路質量是 %lu", userID, (unsigned long)downstreamQuality);
                }

                /*
                ZegoStreamQualityLevel.EXCELLENT, 網路質量極好
                ZegoStreamQualityLevel.GOOD, 網路質量好
                ZegoStreamQualityLevel.MEDIUM, 網路質量正常
                ZegoStreamQualityLevel.BAD, 網路質量差
                ZegoStreamQualityLevel.DIE, 網路例外
                ZegoStreamQualityLevel.UNKNOWN, 網路質量未知
                */

            }
        });
           
    }

進階質量報告

如果上述的基礎網路質量報告不能滿足需求,ZEGO 還提供了更詳細的推流質量報告、拉流質量報告以及其他相關資訊,

推流質量報告

推流質量報告指用戶把音視頻推送到 ZEGO 服務端這個程序的質量報告,包含了采集、編碼階段音視頻流的幀率,傳輸(發送)的音視頻流的幀率、碼率、延時及丟包率,

可以通過注冊 onPublisherQualityUpdate 接收推流質量回呼,推流成功后每隔三秒會收到此回呼,可根據 quality(ZegoPublishStreamQuality) 引數實時了解推送的音視頻流的健康情況,

  • 大多數情況下,只需關注 “quality” 的 “level” 引數,以 “level” 列舉值來判斷推流的綜合質量,詳情可參考 ZegoStreamQualityLevel
  • 如果想關注更詳細的推流質量引數,可以參考 ZegoPublishStreamQuality
    engine.setEventHandler(new IZegoEventHandler() {

            // 開發者可以在此回呼中監控具體的質量以上報到業務服務器做監控,或者監控質量物件的某個欄位以給用戶友好的提示
            @Override
            public void onPublisherQualityUpdate(String streamID, ZegoPublishStreamQuality quality) {
                String networkQuality = "";
                // level 代表了推流質量的綜合分數,大部分情況下,開發者可以參考此分數展示上行網路的質量

                switch (quality.level) {
                    case EXCELLENT:
                        networkQuality = "非常好";
                        break;
                    case GOOD:
                        networkQuality = "好";
                        break;
                    case MEDIUM:
                        networkQuality = "一般";
                        break;
                    case BAD:
                        networkQuality = "差";
                        break;
                    case DIE:
                        networkQuality = "失敗";
                        break;
                    case UNKNOWN:
                        networkQuality = "未知";
                        break;
                    default:
                        break;
                }
                //("網路質量是:%s", networkQuality);
            }
        });

拉流質量報告

拉流質量報告指用戶拉取播放音視頻流這個程序的質量報告,包含了接收的音視頻流的幀率、碼率、延時和丟包率,解碼階段音視頻流的幀率,以及渲染階段的幀率、卡頓率、音視頻整體質量,

可以通過注冊 onPlayerQualityUpdate 接收拉流質量回呼,拉流成功后每隔三秒會收到此回呼,開發者可根據 quality(ZegoPlayStreamQuality) 引數實時了解拉取的音視頻流的健康情況,

  • 大多數情況下,只需關注 “quality” 的 “level” 引數,以 “level” 列舉值來判斷拉流的綜合質量,詳情可參考 ZegoStreamQualityLevel
  • 如果想關注更詳細的拉流質量引數,可以參考 ZegoPlayStreamQuality
    engine.setEventHandler(new IZegoEventHandler() {
            // 開發者可以在此回呼中監控具體的質量以上報到業務服務器做監控,或者監控質量物件的某個欄位以給用戶友好的提示
            @Override
            public void onPlayerQualityUpdate(String streamID, ZegoPlayStreamQuality quality) {
                String networkQuality = "";
                // level 代表了拉流質量的綜合分數,大部分情況下,開發者可以參考此分數展示下行網路的質量

                switch (quality.level) {
                    case EXCELLENT:
                        networkQuality = "非常好";
                        break;
                    case GOOD:
                        networkQuality = "好";
                        break;
                    case MEDIUM:
                        networkQuality = "一般";
                        break;
                    case BAD:
                        networkQuality = "差";
                        break;
                    case DIE:
                        networkQuality = "失敗";
                        break;
                    case UNKNOWN:
                        networkQuality = "未知";
                        break;
                    default:
                        break;
                }
                //("網路質量是:%s", networkQuality);
            }
        });
}

MOS 音質評分

ZEGO Express SDK 2.16.0 版本開始,拉流質量回呼 onPlayerQualityUpdate 中新增 "mos" 欄位,表示對拉流音質的評分,開發者對音頻質量比較關注時,可通過該欄位了解當前音頻的質量情況,

mos 欄位的取值范圍為 [-1, 5],其中 -1 表示未知(例如例外拉流時無法評分),[0, 5] 表示評分,實時音頻 MOS 評分對應的主觀音質感受如下:

MOS 值 評價標準
4.0~5.0 音質很好,清晰流暢,聽的清楚,
3.5~4.0 音質較好,偶有音質損傷,但依然清晰流暢,聽的清楚,
3.0~3.5 音質一般,偶有卡頓,需要一點注意力才能聽清,
2.5~3.0 音質較差,卡頓頻繁,需要集中注意力才能聽清,
2.0~2.5 音質很差,部分語意丟失,難以交流,
小于 2.0 音質極差,大量語意丟失,無法交流,
-1 未知,

其他資訊監測

推流/拉流狀態變化通知

1. 推流狀態回呼

在推流成功后,可以通過 onPublisherStateUpdate 獲取推流狀態變更的通知,

engine.setEventHandler(new IZegoEventHandler() {
    @Override
    public void onPublisherStateUpdate(String streamID, ZegoPublisherState state, int errorCode, JSONObject extendedData) {
        super.onPublisherStateUpdate(streamID, state, errorCode, extendedData);
        // 當 state 為 PUBLISHER_STATE_NO_PUBLISH 時,且 errcode 非 0,表示推流失敗,同時不會再進行重試推流了,此時可在界面作出推流失敗提示;    
        // 當 state 為 PUBLISHER_STATE_PUBLISH_REQUESTING 時,且 errcode 非 0,表示在重試推流,此時如果超出重試時間未成功推流會拋出推流失敗通知,
    }
}

可以根據回呼內的 “state” 引數是否在 “正在請求推流狀態” 來大體判斷用戶的推流網路情況,“state” 引數的取值與用戶推流狀態對應如下:

列舉值 說明
ZegoPublisherState.NO_PUBLISH 未推流狀態,在推流前處于該狀態,如果推流程序出現穩態的例外,例如 AppID 或 Token 不正確,或者如果其他用戶已經在推送流,推送相同流 ID 的流會失敗,都會進入未推流狀態,
ZegoPublisherState.PUBLISH_REQUESTING 正在請求推流狀態,推流操作執行成功后會進入正在請求推流狀態,通常通過該狀態進行 UI 界面的展示,如果因為網路質量不佳產生的中斷,SDK 會進行內部重試,也會回到正在請求推流狀態,
ZegoPublisherState.PUBLISHING 正在推流狀態,進入該狀態表明推流已經成功,用戶可以正常通信,

引數 “extendedData” 為狀態更新附帶的擴展資訊,若使用 ZEGO 的 CDN 內容分發網路,在推流成功后,該引數的內容的鍵為 “flv_url_list”、“rtmp_url_list”、“hls_url_list”,分別對應 flv、rtmp、hls 協議的拉流 URL,

2. 拉流狀態變更回呼

在拉流成功后,開發者可通過 onPlayerStateUpdate 獲取推流狀態變更的通知,

engine.setEventHandler(new IZegoEventHandler() {
    @Override
    public void onPlayerStateUpdate(String streamID, ZegoPlayerState state, int errorCode, JSONObject extendedData) {
        super.onPlayerStateUpdate(streamID, state, errorCode, extendedData);
        // 當 state 為 PLAYER_STATE_NO_PLAY 時,且 errcode 非 0,表示拉流失敗,同時不會再進行重試拉流了,此時可在界面作出拉流失敗提示;
        // 當 state 為 PLAYER_STATE_PLAY_REQUESTING 時,且 errcode 非 0,表示重試拉流,此時如果超出重試時間未成功拉到流會拋出拉流失敗通知,
    }
}

開發者可根據 “state” 引數是否在 “正在請求拉流狀態” 來大體判斷用戶的拉流網路情況,“state” 引數的取值與用戶拉流狀態對應如下:

列舉值 說明
ZegoPlayerState.NO_PLAY 未拉流狀態,在拉流前處于該狀態,如果拉流程序出現穩態的例外,例如 AppID 或 Token 不正確,都會進入未拉流狀態,
ZegoPlayerState.PLAY_REQUESTING 正在請求拉流狀態,拉流操作執行成功后會進入正在請求拉流狀態,通常通過該狀態進行應用界面的展示,如果因為網路質量不佳產生的中斷,SDK 會進行內部重試,也會回到正在請求拉流狀態,
ZegoPlayerState.PLAYING 正在拉流狀態,進入該狀態表明拉流已經成功,用戶可以正常通信,

接收到音頻/視頻首幀的通知

1. 推流端音頻采集首幀回呼

可以通過注冊 onPublisherCapturedAudioFirstFrame 接收音頻首幀回呼,呼叫推流介面成功后,SDK 采集到第一幀音頻資料時會收到此回呼,

在未推流或未預覽的情況下,首次推流或首次預覽,即 SDK 內部的音視頻模塊的引擎啟動時,會去采集本機設備的音頻資料,會收到該回呼,開發者可根據該回呼判斷 SDK 是否真的采集到音頻資料,若未收到該回呼,說明音頻采集設備被占用或例外,

engine.setEventHandler(new IZegoEventHandler() {
    @Override
    public void onPublisherCapturedAudioFirstFrame() {
        super.onPublisherCapturedAudioFirstFrame();
    }
}

2. 推流端視頻采集首幀回呼

可以通過注冊 onPublisherCapturedVideoFirstFrame 接收視頻首幀回呼,呼叫推流介面成功后,SDK 采集到第一幀視頻資料時會收到此回呼,

在未推流或未預覽的情況下,首次推流或首次預覽,即 SDK 內部的音視頻模塊的引擎啟動時,會去采集本機設備的視頻資料,會收到該回呼,可以根據該回呼判斷 SDK 是否真的采集到視頻資料,若未收到該回呼,說明視頻采集設備被占用或例外,

engine.setEventHandler(new IZegoEventHandler() {
    @Override
    public void onPublisherCapturedVideoFirstFrame(ZegoPublishChannel channel) {
    super.onPublisherCapturedVideoFirstFrame(channel);
    }
}

3. 拉流端音頻接收首幀回呼

開發者可通過注冊 onPlayerRecvAudioFirstFrame 監聽拉流端音頻接收首幀回呼,呼叫拉流介面成功后,SDK 拉流拉到第一幀音頻資料時會收到此回呼,

engine.setEventHandler(new IZegoEventHandler() {
    @Override
    public void onPlayerRecvAudioFirstFrame(String streamID) {
        super.onPlayerRecvAudioFirstFrame(streamID);
        AppLogger.getInstance().receiveCallback("onPlayerRecvAudioFirstFrame streamID:%s",streamID);
    }
}

4. 拉流端視頻接收首幀回呼

可以通過注冊 onPlayerRecvVideoFirstFrame 監聽拉流端接收視頻首幀回呼,呼叫拉流介面成功后,SDK 拉流拉到第一幀視頻資料時會收到此回呼,

engine.setEventHandler(new IZegoEventHandler() {
    @Override
    public void onPlayerRecvVideoFirstFrame(String streamID) {
        super.onPlayerRecvVideoFirstFrame(streamID);
    }
}

5. 拉流端渲染完視頻首幀回呼

可以通過注冊 onPlayerRenderVideoFirstFrame 監聽拉流端渲染完視頻首幀回呼,呼叫拉流介面成功后,SDK 拉流并渲染完第一幀視頻資料后會收到此回呼,

可以用該回呼來統計首幀耗時或更新播放流的 UI 組件,

engine.setEventHandler(new IZegoEventHandler() {
    @Override
    public void onPlayerRenderVideoFirstFrame(String streamID){
        super.onPlayerRenderVideoFirstFrame(streamID);
    }
}

視頻解析度變化的回呼

1. 采集視頻解析度變更回呼

可以通過注冊 onPublisherVideoSizeChanged 監聽采集視頻大小變更回呼,推流成功后,在推流中途如果視頻采集解析度發生變化將會收到此回呼,

當在未推流或未預覽的情況下,首次推流或首次預覽,即 SDK 內部的音視頻模塊的引擎啟動時,會去采集本機設備的視頻資料,此時采集解析度會改變,

可以根據此回呼來去除本地預覽的 UI 的遮蓋等類似操作,也可以根據該回呼的解析度來動態調整預覽視圖的比例等,

engine.setEventHandler(new IZegoEventHandler() {
    @Override
    public void onPublisherVideoSizeChanged(int width, int height, ZegoPublishChannel channel) {
        super.onPublisherVideoSizeChanged(width, height, channel);
    }
}

2. 拉流解析度變更通知

您可以通過注冊 onPlayerVideoSizeChanged 獲取拉流解析度變更通知,拉流成功后,在拉流中途如果有視頻解析度發生變化將會收到此回呼,用戶可根據流的最終解析度調整顯示,

  • 若拉的流只有音頻資料,會收不到該回呼,
  • 若推流端由于網路問題觸發 SDK 內部的流量控制時,可能會動態減小推流端的編碼解析度,此時也會收到此回呼,所拉的音視頻流真正渲染到所設定 UI 播放界面時會觸發此回呼,開發者可利用該回呼通知來更新或切換真正播放流的 UI 組件,
engine.setEventHandler(new IZegoEventHandler() {
    @Override
    public void onPlayerVideoSizeChanged(String streamID, int width, int height) {
    }
}

API 參考串列

方法 描述
onPublisherQualityUpdate 推流質量回呼
onPlayerQualityUpdate 拉流質量更新回呼
onPublisherStateUpdate 推流狀態回呼
onPlayerStateUpdate 拉流狀態回呼
onPublisherCapturedAudioFirstFrame 推流端音頻采集首幀回呼
onPublisherCapturedVideoFirstFrame 推流端視頻采集首幀回呼
onPlayerRecvAudioFirstFrame 拉流端音頻接收首幀回呼
onPlayerRecvVideoFirstFrame 拉流端視頻接收首幀回呼
onPlayerRenderVideoFirstFrame 拉流端渲染完視頻首幀回呼
onPublisherVideoSizeChanged 采集視頻大小變更回呼
onPlayerVideoSizeChanged 拉流解析度變更通知
onPublisherRelayCDNStateUpdate 添加/洗掉轉推 CDN 地址狀態回呼
onPlayerRecvSEI 收到遠端流的 SEI 內容

獲取Demo

獲取本文的Demo、開發檔案、技術支持,
獲取SDK的商務活動、熱門產品,
注冊即構ZEGO開發者帳號,快速開始,

音視頻場景解決方案分享,更多詳情可搜索官網(https://zegoguanwang.datasink.sensorsdata.cn/t/pB)

轉載請註明出處,本文鏈接:https://www.uj5u.com/yidong/471862.html

標籤:其他

上一篇:94個JS/eTS開源組件首發上新,肯定有你要用的一款!

下一篇:使用BeautifulSoup抓取URL回圈

標籤雲
其他(157675) Python(38076) JavaScript(25376) Java(17977) C(15215) 區塊鏈(8255) C#(7972) AI(7469) 爪哇(7425) MySQL(7132) html(6777) 基礎類(6313) sql(6102) 熊猫(6058) PHP(5869) 数组(5741) R(5409) Linux(5327) 反应(5209) 腳本語言(PerlPython)(5129) 非技術區(4971) Android(4554) 数据框(4311) css(4259) 节点.js(4032) C語言(3288) json(3245) 列表(3129) 扑(3119) C++語言(3117) 安卓(2998) 打字稿(2995) VBA(2789) Java相關(2746) 疑難問題(2699) 细绳(2522) 單片機工控(2479) iOS(2429) ASP.NET(2402) MongoDB(2323) 麻木的(2285) 正则表达式(2254) 字典(2211) 循环(2198) 迅速(2185) 擅长(2169) 镖(2155) 功能(1967) .NET技术(1958) Web開發(1951) python-3.x(1918) HtmlCss(1915) 弹簧靴(1913) C++(1909) xml(1889) PostgreSQL(1872) .NETCore(1853) 谷歌表格(1846) Unity3D(1843) for循环(1842)

熱門瀏覽
  • 【從零開始擼一個App】Dagger2

    Dagger2是一個IOC框架,一般用于Android平臺,第一次接觸的朋友,一定會被搞得暈頭轉向。它延續了Java平臺Spring框架代碼碎片化,注解滿天飛的傳統。嘗試將各處代碼片段串聯起來,理清思緒,真不是件容易的事。更不用說還有各版本細微的差別。 與Spring不同的是,Spring是通過反射 ......

    uj5u.com 2020-09-10 06:57:59 more
  • Flutter Weekly Issue 66

    新聞 Flutter 季度調研結果分享 教程 Flutter+FaaS一體化任務編排的思考與設計 詳解Dart中如何通過注解生成代碼 GitHub 用對了嗎?Flutter 團隊分享如何管理大型開源專案 插件 flutter-bubble-tab-indicator A Flutter librar ......

    uj5u.com 2020-09-10 06:58:52 more
  • Proguard 常用規則

    介紹 Proguard 入口,如何查看輸出,如何使用 keep 設定入口以及使用實體,如何配置壓縮,混淆,校驗等規則。

    ......

    uj5u.com 2020-09-10 06:59:00 more
  • Android 開發技術周報 Issue#292

    新聞 Android即將獲得類AirDrop功能:可向附近設備快速分享檔案 谷歌為安卓檔案管理應用引入可安全隱藏資料的Safe Folder功能 Android TV新主界面將顯示電影、電視節目和應用推薦內容 泄露的Android檔案暗示了傳說中的谷歌Pixel 5a與折疊屏新機 谷歌發布Andro ......

    uj5u.com 2020-09-10 07:00:37 more
  • AutoFitTextureView Error inflating class

    報錯: Binary XML file line #0: Binary XML file line #0: Error inflating class xxx.AutoFitTextureView 解決: <com.example.testy2.AutoFitTextureView android: ......

    uj5u.com 2020-09-10 07:00:41 more
  • 根據Uri,Cursor沒有獲取到對應的屬性

    Android: 背景:呼叫攝像頭,拍攝視頻,指定保存的地址,但是回傳的Cursor檔案,只有名稱和大小的屬性,沒有其他諸如時長,連ID屬性都沒有 使用 cursor.getInt(cursor.getColumnIndexOrThrow(MediaStore.Video.Media.DURATIO ......

    uj5u.com 2020-09-10 07:00:44 more
  • Android連載29-持久化技術

    一、持久化技術 我們平時所使用的APP產生的資料,在記憶體中都是瞬時的,會隨著斷電、關機等丟失資料,因此android系統采用了持久化技術,用于存盤這些“瞬時”資料 持久化技術包括:檔案存盤、SharedPreference存盤以及資料庫存盤,還有更復雜的SD卡記憶體儲。 二、檔案存盤 最基本存盤方式, ......

    uj5u.com 2020-09-10 07:00:47 more
  • Android Camera2Video整合到自己專案里

    背景: Android專案里呼叫攝像頭拍攝視頻,原本使用的 MediaStore.ACTION_VIDEO_CAPTURE, 后來因專案需要,改成了camera2 1.Camera2Video 官方demo有點問題,下載后,不能直接整合到專案 問題1.多次拍攝視頻崩潰 問題2.雙擊record按鈕, ......

    uj5u.com 2020-09-10 07:00:50 more
  • Android 開發技術周報 Issue#293

    新聞 谷歌為Android TV開發者提供多種新功能 Android 11將自動填表功能整合到鍵盤輸入建議中 谷歌宣布Android Auto即將支持更多的導航和數字停車應用 谷歌Pixel 5只有XL版本 搭載驍龍765G且將比Pixel 4更便宜 [圖]Wear OS將迎來重磅更新:應用啟動時間 ......

    uj5u.com 2020-09-10 07:01:38 more
  • 海豚星空掃碼投屏 Android 接收端 SDK 集成 六步驟

    掃碼投屏,開放網路,獨占設備,不需要額外下載軟體,微信掃碼,發現設備。支持標準DLNA協議,支持倍速播放。視頻,音頻,圖片投屏。好點意思。還支持自定義基于 DLNA 擴展的操作動作。好像要收費,沒體驗。 這里簡單記錄一下集成程序。 一 跟目錄的build.gradle添加私有mevan倉庫 mave ......

    uj5u.com 2020-09-10 07:01:43 more
最新发布
  • 歡迎頁輪播影片

    如圖,引導開始,球從上落下,同時淡入文字,然后文字開始輪播,最后一頁時停止,點擊進入首頁。 在來看看效果圖。 重力球先不講,主要歡迎輪播簡單實作 首先新建一個類 TextTranslationXGuideView,用于影片展示 文本是類似的,最后會有個圖片箭頭影片,布局很簡單,就是一個 TextVi ......

    uj5u.com 2023-04-20 08:40:31 more
  • 【FAQ】關于華為推送服務因營銷訊息頻次管控導致服務通訊類訊息

    一. 問題描述 使用華為推送服務下發IM訊息時,下發訊息請求成功且code碼為80000000,但是手機總是收不到訊息; 在華為推送自助分析(Beta)平臺查看發現,訊息發送觸發了頻控。 二. 問題原因及背景 2023年1月05日起,華為推送服務對咨詢營銷類訊息做了單個設備每日推送數量上限管理,具體 ......

    uj5u.com 2023-04-20 08:40:11 more
  • 歡迎頁輪播影片

    如圖,引導開始,球從上落下,同時淡入文字,然后文字開始輪播,最后一頁時停止,點擊進入首頁。 在來看看效果圖。 重力球先不講,主要歡迎輪播簡單實作 首先新建一個類 TextTranslationXGuideView,用于影片展示 文本是類似的,最后會有個圖片箭頭影片,布局很簡單,就是一個 TextVi ......

    uj5u.com 2023-04-20 08:39:36 more
  • 【FAQ】關于華為推送服務因營銷訊息頻次管控導致服務通訊類訊息

    一. 問題描述 使用華為推送服務下發IM訊息時,下發訊息請求成功且code碼為80000000,但是手機總是收不到訊息; 在華為推送自助分析(Beta)平臺查看發現,訊息發送觸發了頻控。 二. 問題原因及背景 2023年1月05日起,華為推送服務對咨詢營銷類訊息做了單個設備每日推送數量上限管理,具體 ......

    uj5u.com 2023-04-20 08:39:13 more
  • iOS從UI記憶體地址到讀取成員變數(oc/swift)

    開發除錯時,我們發現bug時常首先是從UI顯示發現例外,下一步才會去定位UI相關連的資料的。XCode有給我們提供一系列debug工具,但是很多人可能還沒有形成一套穩定的除錯流程,因此本文嘗試解決這個問題,順便提出一個暴論:UI顯示例外問題只需要兩個步驟就能完成定位作業的80%: 定位例外 UI 組 ......

    uj5u.com 2023-04-19 09:16:23 more
  • FIDE重磅更新!性能飛躍!體驗有禮!

    FIDE 開發者工具重構升級啦!實作500%性能提升,誠邀體驗! 一直以來不少開發者朋友在社區反饋,在使用 FIDE 工具的程序中,時常會遇到諸如加載不及時、代碼預覽/渲染性能不如意的情況,十分影響開發體驗。 作為技術團隊,我們深知一件趁手的開發工具對開發者的重要性,因此,在2023年開年,FinC ......

    uj5u.com 2023-04-19 09:16:15 more
  • 游戲內嵌社區服務開放,助力開發者提升玩家互動與留存

    華為 HMS Core 游戲內嵌社區服務提供快速訪問華為游戲中心論壇能力,支持玩家直接在游戲內瀏覽帖子和交流互動,助力開發者擴展內容生產和觸達的場景。 一、為什么要游戲內嵌社區? 二、游戲內嵌社區的典型使用場景 1、游戲內打開論壇 您可以在游戲內繪制論壇入口,為玩家提供沉浸式發帖、瀏覽、點贊、回帖、 ......

    uj5u.com 2023-04-19 09:15:46 more
  • iOS從UI記憶體地址到讀取成員變數(oc/swift)

    開發除錯時,我們發現bug時常首先是從UI顯示發現例外,下一步才會去定位UI相關連的資料的。XCode有給我們提供一系列debug工具,但是很多人可能還沒有形成一套穩定的除錯流程,因此本文嘗試解決這個問題,順便提出一個暴論:UI顯示例外問題只需要兩個步驟就能完成定位作業的80%: 定位例外 UI 組 ......

    uj5u.com 2023-04-19 09:14:53 more
  • FIDE重磅更新!性能飛躍!體驗有禮!

    FIDE 開發者工具重構升級啦!實作500%性能提升,誠邀體驗! 一直以來不少開發者朋友在社區反饋,在使用 FIDE 工具的程序中,時常會遇到諸如加載不及時、代碼預覽/渲染性能不如意的情況,十分影響開發體驗。 作為技術團隊,我們深知一件趁手的開發工具對開發者的重要性,因此,在2023年開年,FinC ......

    uj5u.com 2023-04-19 09:14:08 more
  • 游戲內嵌社區服務開放,助力開發者提升玩家互動與留存

    華為 HMS Core 游戲內嵌社區服務提供快速訪問華為游戲中心論壇能力,支持玩家直接在游戲內瀏覽帖子和交流互動,助力開發者擴展內容生產和觸達的場景。 一、為什么要游戲內嵌社區? 二、游戲內嵌社區的典型使用場景 1、游戲內打開論壇 您可以在游戲內繪制論壇入口,為玩家提供沉浸式發帖、瀏覽、點贊、回帖、 ......

    uj5u.com 2023-04-19 09:08:34 more