Hiển thị ứng dụng của bạn trên nhiều màn hình cùng một lúc bằng cách sử dụng đa màn hình trong Android.
Tổng quat
Phiên bản Android 10 trở lên được hỗ trợ để hiển thị các hoạt động khác trên nhiều màn hình ngoài và chúng được đặt tên là đa màn hình được sử dụng cho điện thoại có thể gập lại cũng như màn hình phụ được kết nối với thiết bị của bạn.
Hôm nay, tôi sẽ giới thiệu với bạn về cách hiển thị một hoạt động trên một màn hình khác và LG của LG cho LG V50 để theo dõi sự kiện cho điện thoại có thể gập lại này với màn hình phụ của nó.
Hiển thị hoạt động của bạn trên một màn hình khác
Khai báo hoạt động thứ cấp của bạn trong bảng kê khai
1 2 3 4 5 6 7 8 9 10 11 | <span class="token tag"><span class="token tag"><span class="token punctuation"><</span> manifest</span> <span class="token attr-name"><span class="token namespace">xmlns:</span> android</span> <span class="token attr-value"><span class="token punctuation">=</span> <span class="token punctuation">"</span> http://schemas.android.com/apk/res/android <span class="token punctuation">"</span></span> <span class="token attr-name">package</span> <span class="token attr-value"><span class="token punctuation">=</span> <span class="token punctuation">"</span> com.android.multiplescreens <span class="token punctuation">"</span></span> <span class="token punctuation">></span></span> <application <span class="token comment"><!-- See about the taskAffinity attribute at http://bit.ly/34RKvzC --></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span> activity</span> <span class="token attr-name"><span class="token namespace">android:</span> name</span> <span class="token attr-value"><span class="token punctuation">=</span> <span class="token punctuation">"</span> .SecondActivity <span class="token punctuation">"</span></span> <span class="token attr-name"><span class="token namespace">android:</span> launchMode</span> <span class="token attr-value"><span class="token punctuation">=</span> <span class="token punctuation">"</span> singleTask <span class="token punctuation">"</span></span> <span class="token attr-name"><span class="token namespace">android:</span> taskAffinity</span> <span class="token attr-value"><span class="token punctuation">=</span> <span class="token punctuation">"</span> cover.container <span class="token punctuation">"</span></span> <span class="token punctuation">/></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"></</span> application</span> <span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"></</span> manifest</span> <span class="token punctuation">></span></span> |
launchMode
là một singleTask
kết hợp giữa FLAG_ACTIVITY_CLEAR_TOP
và FLAG_ACTIVITY_NEW_TASK
đặt trong ý định của bạn khi bạn bắt đầu một hoạt động. Nguyên nhân của việc sử dụng các cờ này là để chạy hoạt động của bạn trên tác vụ mới.
Ngoài ra, tôi có một thuộc tính đó là taskAffinity
. Nếu hoạt động của bạn chỉ sử dụng cờ FLAG_ACTIVITY_NEW_TASK
mà taskAffinity
không được đặt, nó sẽ bắt đầu cùng một nhiệm vụ với các hoạt động khác. Tuy nhiên, nếu bạn đặt taskAffinity
cho hoạt động của mình, nó sẽ chạy trên tác vụ mới và các hoạt động có cùng một nhiệm vụ. taskAffinity
sẽ chạy cùng nhau.
Bắt đầu hoạt động của bạn
Trước tiên, bạn cần một DisplayManager
quản lý hiển thị quản lý các thuộc tính của màn hình đính kèm.
1 2 | <span class="token keyword">val</span> displayManager <span class="token operator">=</span> <span class="token function">getSystemService</span> <span class="token punctuation">(</span> Context <span class="token punctuation">.</span> DISPLAY_SERVICE <span class="token punctuation">)</span> <span class="token keyword">as</span> DisplayManager |
Tiếp theo, bạn sử dụng nó để lấy tất cả màn hình kết nối với thiết bị.
1 2 | <span class="token keyword">val</span> displays <span class="token operator">=</span> displayManager <span class="token punctuation">.</span> displays |
Đảm bảo rằng thiết bị của bạn có nhiều hơn hai màn hình, sau đó tạo các tùy chọn hoạt động theo lớp ActivityOptions
để chỉ ra ID hiển thị mà bạn muốn hiển thị hoạt động của mình.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | <span class="token keyword">if</span> <span class="token punctuation">(</span> displays <span class="token punctuation">.</span> size <span class="token operator">></span> <span class="token number">1</span> <span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">if</span> <span class="token punctuation">(</span> Build <span class="token punctuation">.</span> VERSION <span class="token punctuation">.</span> SDK_INT <span class="token operator">>=</span> Build <span class="token punctuation">.</span> VERSION_CODES <span class="token punctuation">.</span> O <span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token comment">// Activity options are used to select the display screen.</span> <span class="token keyword">val</span> options <span class="token operator">=</span> ActivityOptions <span class="token punctuation">.</span> <span class="token function">makeBasic</span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token comment">// Select the display screen that you want to show the second activity</span> options <span class="token punctuation">.</span> launchDisplayId <span class="token operator">=</span> displays <span class="token punctuation">[</span> <span class="token number">1</span> <span class="token punctuation">]</span> <span class="token punctuation">.</span> displayId <span class="token comment">// To display on the second screen that your intent must be set flag to make</span> <span class="token comment">// single task (combine FLAG_ACTIVITY_CLEAR_TOP and FLAG_ACTIVITY_NEW_TASK)</span> <span class="token comment">// or you also set it in the manifest (see more at the manifest file)</span> <span class="token function">startActivity</span> <span class="token punctuation">(</span> <span class="token function">Intent</span> <span class="token punctuation">(</span> <span class="token keyword">this</span> <span class="token label symbol">@MainActivity</span> <span class="token punctuation">,</span> SecondActivity <span class="token operator">::</span> <span class="token keyword">class</span> <span class="token punctuation">.</span> java <span class="token punctuation">)</span> <span class="token punctuation">,</span> options <span class="token punctuation">.</span> <span class="token function">toBundle</span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token punctuation">)</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> |
Bây giờ, bạn có thể chạy hoạt động của mình trên một màn hình khác.
SDK màn hình kép của LG
Màn hình kép LG là gì?
LG Dual Screen là một chiếc điện thoại di động có hai màn hình. Các ứng dụng độc lập có thể được chạy trên màn hình cùng một lúc.
Nó có SDK để hỗ trợ theo dõi các sự kiện gấp.
Gọi lại
SDK này có hai cuộc gọi lại chính:
-
CoverDisplayCallback
: Xử lý các sự kiện liên quan đến các trạng thái như nắp được bật, tắt hoặc gỡ bỏ.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | <span class="token keyword">private</span> <span class="token keyword">inner</span> <span class="token keyword">class</span> MainCoverDisplayCallback <span class="token operator">:</span> DisplayManagerHelper <span class="token punctuation">.</span> <span class="token function">CoverDisplayCallback</span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">override</span> <span class="token keyword">fun</span> <span class="token function">onCoverDisplayEnabledChangedCallback</span> <span class="token punctuation">(</span> state <span class="token operator">:</span> Int <span class="token punctuation">)</span> <span class="token punctuation">{</span> displayManagerHelper <span class="token operator">?</span> <span class="token punctuation">.</span> coverDisplayState <span class="token operator">?</span> <span class="token punctuation">.</span> <span class="token function">let</span> <span class="token punctuation">{</span> Log <span class="token punctuation">.</span> <span class="token function">i</span> <span class="token punctuation">(</span> TAG <span class="token punctuation">,</span> <span class="token string">"Current DualScreen Callback state: <span class="token interpolation"><span class="token delimiter variable">${</span> <span class="token function">coverDisplayStateToString</span> <span class="token punctuation">(</span> it <span class="token punctuation">)</span> <span class="token delimiter variable">}</span></span> "</span> <span class="token punctuation">)</span> <span class="token punctuation">}</span> <span class="token keyword">if</span> <span class="token punctuation">(</span> prevDualScreenState <span class="token operator">!=</span> state <span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">when</span> <span class="token punctuation">(</span> state <span class="token punctuation">)</span> <span class="token punctuation">{</span> DisplayManagerHelper <span class="token punctuation">.</span> STATE_UNMOUNT <span class="token operator">-></span> <span class="token punctuation">{</span> Log <span class="token punctuation">.</span> <span class="token function">i</span> <span class="token punctuation">(</span> TAG <span class="token punctuation">,</span> <span class="token string">"Changed DualScreen State to STATE_UNMOUNT"</span> <span class="token punctuation">)</span> <span class="token punctuation">}</span> DisplayManagerHelper <span class="token punctuation">.</span> STATE_DISABLED <span class="token operator">-></span> <span class="token punctuation">{</span> Log <span class="token punctuation">.</span> <span class="token function">i</span> <span class="token punctuation">(</span> TAG <span class="token punctuation">,</span> <span class="token string">"Changed DualScreen State to STATE_DISABLED"</span> <span class="token punctuation">)</span> <span class="token punctuation">}</span> DisplayManagerHelper <span class="token punctuation">.</span> STATE_ENABLED <span class="token operator">-></span> <span class="token punctuation">{</span> <span class="token function">toSecondScreen</span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> Log <span class="token punctuation">.</span> <span class="token function">i</span> <span class="token punctuation">(</span> TAG <span class="token punctuation">,</span> <span class="token string">"Changed DualScreen State to STATE_ENABLED"</span> <span class="token punctuation">)</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> prevDualScreenState <span class="token operator">=</span> state <span class="token punctuation">}</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> |
-
SmartCoverCallback
: Trợ giúp gọi lại này cho biết khi nào nắp của bạn được mở, đóng hoặc lật.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | <span class="token keyword">private</span> <span class="token keyword">inner</span> <span class="token keyword">class</span> MainSmartCoverCallback <span class="token operator">:</span> DisplayManagerHelper <span class="token punctuation">.</span> <span class="token function">SmartCoverCallback</span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">override</span> <span class="token keyword">fun</span> <span class="token function">onTypeChanged</span> <span class="token punctuation">(</span> type <span class="token operator">:</span> Int <span class="token punctuation">)</span> <span class="token punctuation">{</span> Log <span class="token punctuation">.</span> <span class="token function">i</span> <span class="token punctuation">(</span> TAG <span class="token punctuation">,</span> <span class="token string">"SmartCoverCallback type: <span class="token interpolation"><span class="token delimiter variable">${</span> displayManagerHelper <span class="token operator">?</span> <span class="token punctuation">.</span> coverType <span class="token delimiter variable">}</span></span> "</span> <span class="token punctuation">)</span> <span class="token punctuation">}</span> <span class="token keyword">override</span> <span class="token keyword">fun</span> <span class="token function">onStateChanged</span> <span class="token punctuation">(</span> state <span class="token operator">:</span> Int <span class="token punctuation">)</span> <span class="token punctuation">{</span> displayManagerHelper <span class="token operator">?</span> <span class="token punctuation">.</span> coverState <span class="token operator">?</span> <span class="token punctuation">.</span> <span class="token function">let</span> <span class="token punctuation">{</span> Log <span class="token punctuation">.</span> <span class="token function">i</span> <span class="token punctuation">(</span> TAG <span class="token punctuation">,</span> <span class="token string">"Current SmartCoverCallback state: <span class="token interpolation"><span class="token delimiter variable">${</span> <span class="token function">smartCoverStateToString</span> <span class="token punctuation">(</span> it <span class="token punctuation">)</span> <span class="token delimiter variable">}</span></span> "</span> <span class="token punctuation">)</span> <span class="token punctuation">}</span> <span class="token keyword">when</span> <span class="token punctuation">(</span> state <span class="token punctuation">)</span> <span class="token punctuation">{</span> DisplayManagerHelper <span class="token punctuation">.</span> STATE_COVER_OPENED <span class="token operator">-></span> <span class="token punctuation">{</span> Log <span class="token punctuation">.</span> <span class="token function">i</span> <span class="token punctuation">(</span> TAG <span class="token punctuation">,</span> <span class="token string">"Received SmartCoverCallback is STATE_COVER_OPENED"</span> <span class="token punctuation">)</span> <span class="token punctuation">}</span> DisplayManagerHelper <span class="token punctuation">.</span> STATE_COVER_CLOSED <span class="token operator">-></span> <span class="token punctuation">{</span> Log <span class="token punctuation">.</span> <span class="token function">i</span> <span class="token punctuation">(</span> TAG <span class="token punctuation">,</span> <span class="token string">"Received SmartCoverCallback is STATE_COVER_CLOSED"</span> <span class="token punctuation">)</span> <span class="token punctuation">}</span> DisplayManagerHelper <span class="token punctuation">.</span> STATE_COVER_FLIPPED_OVER <span class="token operator">-></span> <span class="token punctuation">{</span> Log <span class="token punctuation">.</span> <span class="token function">i</span> <span class="token punctuation">(</span> TAG <span class="token punctuation">,</span> <span class="token string">"Received SmartCoverCallback is STATE_COVER_FLIPPED_OVER"</span> <span class="token punctuation">)</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> |
DisplayManagerHelper
DisplayManagerHelper
được cung cấp bởi SDK được sử dụng để đăng ký các cuộc gọi lại phía trên cũng như xác định thiết bị của bạn có phải là màn hình kép của LG hay không.
Bạn có thể xây dựng lớp này với bối cảnh hiện tại. Nếu thành công, hoạt động của bạn không phải là thiết bị màn hình kép của LG. Mặt khác, bạn có thể đăng ký cuộc gọi lại của mình thông qua hai chức năng là registerCoverDisplayEnabledCallback(key: String, callback: CoverDisplayCallback)
và registerSmartCoverCallback(callback: SmartCoverCallback)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | <span class="token keyword">try</span> <span class="token punctuation">{</span> <span class="token comment">// Try to construct the DisplayMangerHelper.</span> <span class="token comment">// If it isn't successful, this device isn't LG dual screens</span> displayManagerHelper <span class="token operator">=</span> <span class="token function">DisplayManagerHelper</span> <span class="token punctuation">(</span> applicationContext <span class="token punctuation">)</span> coverDisplayCallback <span class="token operator">=</span> <span class="token function">MainCoverDisplayCallback</span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> smartCoverCallback <span class="token operator">=</span> <span class="token function">MainSmartCoverCallback</span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token comment">// Register the callbacks for covers</span> displayManagerHelper <span class="token operator">?</span> <span class="token punctuation">.</span> <span class="token function">registerCoverDisplayEnabledCallback</span> <span class="token punctuation">(</span> applicationContext <span class="token punctuation">.</span> packageName <span class="token punctuation">,</span> coverDisplayCallback <span class="token punctuation">)</span> displayManagerHelper <span class="token operator">?</span> <span class="token punctuation">.</span> <span class="token function">registerSmartCoverCallback</span> <span class="token punctuation">(</span> smartCoverCallback <span class="token punctuation">)</span> isLGDualScreen <span class="token operator">=</span> <span class="token boolean">true</span> <span class="token punctuation">}</span> <span class="token keyword">catch</span> <span class="token punctuation">(</span> e <span class="token operator">:</span> Exception <span class="token punctuation">)</span> <span class="token punctuation">{</span> isLGDualScreen <span class="token operator">=</span> <span class="token boolean">false</span> Log <span class="token punctuation">.</span> <span class="token function">e</span> <span class="token punctuation">(</span> TAG <span class="token punctuation">,</span> <span class="token string">"This device isn't LG dual screens"</span> <span class="token punctuation">,</span> e <span class="token punctuation">)</span> <span class="token punctuation">}</span> |
Cuối cùng, bạn nên xóa tất cả các cuộc gọi lại khi hoạt động hoặc đoạn của bạn bị hủy để chắc chắn không xảy ra rò rỉ bộ nhớ.
1 2 3 4 5 6 7 | <span class="token keyword">override</span> <span class="token keyword">fun</span> <span class="token function">onDestroy</span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token comment">// Remove all callbacks when this activity is destroyed</span> displayManagerHelper <span class="token operator">?</span> <span class="token punctuation">.</span> <span class="token function">unregisterCoverDisplayEnabledCallback</span> <span class="token punctuation">(</span> applicationContext <span class="token punctuation">.</span> packageName <span class="token punctuation">)</span> displayManagerHelper <span class="token operator">?</span> <span class="token punctuation">.</span> <span class="token function">unregisterSmartCoverCallback</span> <span class="token punctuation">(</span> smartCoverCallback <span class="token punctuation">)</span> <span class="token keyword">super</span> <span class="token punctuation">.</span> <span class="token function">onDestroy</span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token punctuation">}</span> |
Bản giới thiệu
Bạn có thể xem bản demo đa màn hình của tôi trên GitHub . Nếu nó hữu ích với bạn, hãy để một ngôi sao cho tôi.