Android10模擬器上調(diào)試雙屏異顯

??????Android SDK 提供了Display類,實現(xiàn)在主屏幕之外的擴展屏幕上顯示不同于主屏幕的UI,而擴展屏幕上的UI顯示,實質(zhì)上是顯示了一個系統(tǒng)級別的Dialog,我們可以將自已的View加入到此Dialog中進行顯示。
??????擴展屏可以有一個或超過一個,實際的應(yīng)用中需要底層驅(qū)動的支持。在官方的模擬器中我們可以模擬出一個副屏,進行調(diào)試(當然除了模擬器,我們的手機也可以進行模擬)
??????以Android10官方模擬器為例,來說明如何進行雙屏異顯的調(diào)試。
一、設(shè)置Simulate secondary displays
??????模擬器中打開"設(shè)置-開發(fā)者選項"界面,在列表中找到"Simulate secondary displays"條目。
點擊后,在彈出的對話框中選擇副屏的分辨率:



??????比如我們選中720p,模擬器屏幕的左上角上會立即呈現(xiàn)出副屏的窗口,其顯示內(nèi)容默認為與主屏顯示一致:



??????副屏窗口就是一個Dialog,可以拖動,讓其顯示在合適的位置。
二、實現(xiàn)副屏異顯
??????因為副屏默認顯示與主屏一致,如果要實現(xiàn)雙屏異顯,我們需要在APP中進行開發(fā),將自定義布局加入到副屏中進行顯示。
1、申請權(quán)限
AndroidManifest.xml中添加兩個權(quán)限:
<uses-permission android:name= "android.permission.SYSTEM_ALERT_WINDOW" />
<uses-permission android:name= "android.permission.SYSTEM_OVERLAY_WINDOW"/>

因為android 6.0及之后 android.permission.SYSTEM_OVERLAY_WINDOW需要系統(tǒng)動態(tài)授權(quán)才能啟用,所以在APP啟動時加入如下代碼進行動態(tài)授權(quán):

if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.M) {
    //啟動Activity讓用戶授權(quán)
    if (!Settings.canDrawOverlays(this)) {
        val intent: Intent = Intent(
              Settings.ACTION_MANAGE_OVERLAY_PERMISSION, Uri.parse( "package:$packageName"))
              startActivityForResult(intent, 1010)
    }
}

系統(tǒng)會彈出授權(quán)窗口,開啟即可:



2、獲取副屏的Display對象

//獲取顯示管理服務(wù)代理對象
 val displayManger = activity.getSystemService(Context.DISPLAY_SERVICE) as DisplayManager?

//當前副屏的Display
 private var currentDisplay: Display? = null
 displayManger?.run {
     //取所有副屏對應(yīng)的Display列表
     val displays = getDisplays(DisplayManager.DISPLAY_CATEGORY_PRESENTATION)
     if (!displays.isEmpty()){
           val display = displays.find { it.isValid } //取第一個有效的Display
           //無副屏到接入新的副屏
           if (currentDisplay == null) {
                 //保存副屏的Display
                 currentDisplay = display
           }
     }
 }

第一步"設(shè)置Simulate secondary displays"中我們已經(jīng)設(shè)置過副屏了,所以currentDisplay不會為空。
3、初始化Context與WindowManager

//副屏Context
private var presentationContext: Context? = null 
//副屏窗口管理器
private var presentationWindowManager:WindowManager? = null
val displayContext: Context =  activity.createDisplayContext(display)
val wm = displayContext.getSystemService(WINDOW_SERVICE) as WindowManager

presentationContext = object :ContextThemeWrapper(displayContext, android.R.style.Theme){
    override fun getSystemService(name: String): Any {
        if (WINDOW_SERVICE == name) {
            return(wm)
        }

        return super.getSystemService(name)
    }
}
presentationWindowManager = 
(presentationContext as ContextThemeWrapper).getSystemService(Context.WINDOW_SERVICE) as WindowManager

4、向副屏添加View
實現(xiàn)一個只顯示純藍色背景的布局:default.xml

<?xml version="1.0" encoding="utf-8"?>
<View xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="@android:color/holo_blue_dark"/>

以下是向副屏窗口加入View的參考代碼:

//通過布局id生成View
val inflater = LayoutInflater.from(presentationContext!!)
val view = inflater.inflate(R.layout.default, null)
//最終副屏?xí)@示default.xml的內(nèi)容
presentationWindowManager?.addView(view,buildLayoutParams())

buildLayoutParams函數(shù):

@SuppressLint("InlinedApi")
private fun buildLayoutParams():WindowManager.LayoutParams {
    if(Build.VERSION.SDK_INT >= 26){
       return WindowManager.LayoutParams(
            WindowManager.LayoutParams.MATCH_PARENT,
            WindowManager.LayoutParams.MATCH_PARENT,
            0,
            0,
            TYPE_APPLICATION_OVERLAY,  //FIRST_SYSTEM_WINDOW + 38
            0, PixelFormat.TRANSPARENT
        )
    } else {
        return WindowManager.LayoutParams(
            WindowManager.LayoutParams.MATCH_PARENT,
            WindowManager.LayoutParams.MATCH_PARENT,
            0,
            0,
            WindowManager.LayoutParams.TYPE_SYSTEM_ALERT,
            0, PixelFormat.TRANSPARENT
        )
    }
 }

說明一下:
Android8.0及以后只能使用TYPE_APPLICATION_OVERLAY窗口類型來創(chuàng)建懸浮窗。(其它窗口類型在8.0已經(jīng)被廢棄掉)
看一下最終的效果:


副屏還可以顯示其它更復(fù)雜的布局,也可以顯示圖片與播放視頻,如下是播放視頻的截圖:

最后的問題:
副屏是否支持觸摸?
目前我了解所知,原生并不支持副屏觸摸動作,但是修改源碼是可以達到的(主要是修改觸控事件的向上分發(fā)邏輯,因為分發(fā)時只有一個主屏)。
可以參考:http://m.itdecent.cn/p/572eaa37ddd3

另外Android自帶一個系統(tǒng)組件Presentation,可以簡化多屏異顯,其實質(zhì)也是封裝了上面的過程。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容