成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

為 TV 開發的 App,你說要運行在手機上?

企業動態
Android 智能電視,不知道你接觸過沒有?近兩年生產的電視,基本上都屬于智能電視,而因為 Android 的開放性,這些電視很大一部分都是搭載的 Android 系統。

[[219110]]

一、前言

Android 智能電視,不知道你接觸過沒有?近兩年生產的電視,基本上都屬于智能電視,而因為 Android 的開放性,這些電視很大一部分都是搭載的 Android 系統。

而除了 Android 智能電視之外,還有一些智能盒子,例如:小米盒子、天貓魔盒等,其實都是屬于 Android 陣營的,接上一臺顯示器,就可以當一個智能電視使用。

在國內的環境下,開發 TV App 其實并沒有遵循標準的 Google TV 的開發規范,而是把它當成一個普通的橫屏 Android App 來開發。可是在這個過程中,是需要額外處理一些手機和電視的差異的,例如:焦點的控制、選中態的控制、屏幕的適配等等。

如果這些適配都已經做的非常好了的話,是可以在 Android 手機上,不需要做任何改動和配置,就***的運行一個原本為 Android TV 而開發的 App 的。

而在某些場景下,你可能需要對你原本想為 TV 開發的 App,做一些手機上的適配,讓它在運行在手機上的時候,呈現出另外的 UI 效果或者執行分支的邏輯。

舉個比較實際的例子:簡單的微信登錄功能,TV App 來實現這個功能,一般是展示一個登錄二維碼,讓用戶通過手機掃碼登錄,但是如果這個 App 運行在手機上的話,你可能需要的是一個按鈕,點擊吊起微信去登錄。

你別問為什么用戶要在手機上安裝一個 TV App?為什么不能讓用戶截圖然后去微信里掃描截圖登錄?

需求下來了,就問你能不能實現?

那么,本文就來討論一下,如何在運行時,通過一些標識來區分當前 App 是運行在手機上還是 TV 上。

二、如何區分

既然這是一個運行時的區分,肯定是需要獲取一些設備上的差異值,來判定當前的運行環境。

那么首先提個問題給自己,手機和 TV 到底存在哪些差異?

手機和電視的差異性:

  • 屏幕物理尺寸不同。
  • 布局尺寸不同。
  • SIM 卡的支持不同。
  • 電源接入的方式不同。
  • 系統參數不同。

差不多就這些差異了,接下來我們進行詳細分析。

1、屏幕物理尺寸

手機和電視的屏幕物理尺寸是完全不一樣的,但是我們也不能完全使用買電視的時候介紹的 Xx寸 來區分屏幕物理尺寸。實際上完全可以將 Android TV 當成一個大號的平板。

這里以一個電視英寸數的計算公式,計算屏幕對角線的長度,來做一個參考的數值。

  1. /** 
  2.  * 檢查當前屏幕的物理尺寸 
  3.  * 小于 6.4 人為是手機,否則人為是電視 
  4.  * 
  5.  * @return true 手機,false TV 
  6.  */ 
  7. private static boolean checkScreenIsPhone(Context ctx) { 
  8.     WindowManager wm = (WindowManager) ctx.getSystemService(Context.WINDOW_SERVICE); 
  9.     Display display = wm.getDefaultDisplay(); 
  10.     DisplayMetrics dm = new DisplayMetrics(); 
  11.     display.getMetrics(dm); 
  12.     double x = Math.pow(dm.widthPixels / dm.xdpi, 2); 
  13.     double y = Math.pow(dm.heightPixels / dm.ydpi, 2); 
  14.     // 屏幕尺寸 
  15.     double screenInches = Math.sqrt(x + y); 
  16.     return screenInches < 6.5; 

對于智能電視而言,我想最小應該都在 32 英寸,而這里的 6.4英寸以下,主要是基于手機的一個參數判斷。

不過手機的屏幕尺寸越做越大,各大廠商現在也都在上線全面屏的產品,隨手找了小米 Mix2 的參數,尺寸為 5.99 英寸,霸么就這個 6.4 英寸的判斷條件,在現階段來看是合理的。

2、布局尺寸

既然屏幕的尺寸有差異,那么從不同的布局中獲取布局文件也是不一樣的,可以通過 screenLayout 參數來區分出當前運行環境下***那一套。

規則如下:

截圖來自官方文檔,有興趣的可以通篇閱讀一下。

https://developer.android.com/guide/practices/screens_support.html?hl=zh-cn

而代碼如下:

  1. /** 
  2.  * 檢查當前設備的局部尺寸 
  3.  * 如果是 SIZE_LARGE 就人為是大屏幕的 
  4.  */ 
  5. private static boolean checkScreenLayoutIsPhone(Context ctx) { 
  6.     return (ctx.getResources().getConfiguration().screenLayout 
  7.             & Configuration.SCREENLAYOUT_LAYOUTDIR_MASK) 
  8.             <= Configuration.SCREENLAYOUT_SIZE_LARGE; 

3、SIM 支持的模式

對于電視而言,就現在所了解到的,還沒有一款智能電視或者智能盒子,是可以插 SIM 卡的,所以判斷 SIM 支持的模式,基本上就可以區分出電視還是手機了。

SIM 卡支持的模式可以使用 TelephonyManager 來獲取當前的狀態。

  1. /** 
  2.  * 檢查 SIM 卡的狀態,如果沒有檢查到,認為是電視 
  3.  * 
  4.  * @param ctx 
  5.  * @return 
  6.  */ 
  7. private static boolean checkTelephonyIsPhone(Context ctx) { 
  8.     TelephonyManager telecomManager = (TelephonyManager) ctx.getSystemService(Context.TELEPHONY_SERVICE); 
  9.     return telecomManager.getPhoneType() != TelephonyManager.PHONE_TYPE_NONE; 

可以看到 getPhoneType() 可以獲取當前設備支持的 Radio 的模式。

  1. /** No phone radio. */ 
  2.     public static final int PHONE_TYPE_NONE = PhoneConstants.PHONE_TYPE_NONE; 
  3.     /** Phone radio is GSM. */ 
  4.     public static final int PHONE_TYPE_GSM = PhoneConstants.PHONE_TYPE_GSM; 
  5.     /** Phone radio is CDMA. */ 
  6.     public static final int PHONE_TYPE_CDMA = PhoneConstants.PHONE_TYPE_CDMA; 
  7.     /** Phone is via SIP. */ 
  8.     public static final int PHONE_TYPE_SIP = PhoneConstants.PHONE_TYPE_SIP; 

一般而言,識別不到 SIM 的模式,就可以認為是一款不支持 SIM 插卡的設備了。

4、電源的接入方式

對于電視的電源,有什么特點?

  1. 永遠沒有耗電的變動,獲取到的電量永遠是滿的。
  2. 電源接入的方式,使用 AC 交流電,而非 USB(充電) 或者電池。

獲取當前電源和充電的接入方式,沒什么好說的,基本上依據這兩個條件,就可以區分出當前到底是電視還是手機/平板了。

  1. /** 
  2.  * 檢查當前電源的接入狀態,電視一定是 AC 交流電 
  3.  * 
  4.  * @param ctx 
  5.  * @return 
  6.  */ 
  7. private static boolean checkBatteryIsPhone(Context ctx) { 
  8.     IntentFilter filter = new IntentFilter(Intent.ACTION_BATTERY_CHANGED); 
  9.     Intent batteryStatus = ctx.registerReceiver(null, filter); 
  10.     // 當前電池的狀態 
  11.     int status = batteryStatus.getIntExtra(BatteryManager.EXTRA_STATUS, -1); 
  12.     boolean isChanging = status == BatteryManager.BATTERY_STATUS_FULL; 
  13.     // 當前充電的狀態 
  14.     int chargePlug = batteryStatus.getIntExtra(BatteryManager.EXTRA_PLUGGED, -1); 
  15.     boolean acCharge = chargePlug == BatteryManager.BATTERY_PLUGGED_AC; 
  16.     // 電視的狀態 當前點亮一定是滿的 兵器是 AC 交流電接入 才認為是電視 
  17.     return !(isChanging && acCharge); 

這種方式去判斷也有缺陷,因為對于智能電視類的設備來說,還有一種設備容易被忽略,那就是投影,對于投影而言,有一些是會內置電池的。

5、UI Mode

使用 UI Mode 的方式去判斷,就需要用到一個系統服務 UIModeManager,它和一般的系統服務一樣,需要我們通過 Context.getSystemService() 方法獲取到。

這是一個官方給出的判斷方式,但是在國內的環境下,并不可取。因為大部分廠商的智能電視,只是拿普通的 Android 系統改了改,其實并沒有遵循 Google TV 的標準,所以這種方式在某些設備上可能會判斷出錯。

既然文檔介紹了,這里還是簡單介紹一下。沒什么好說的,直接上代碼就好了。

  1. /** 
  2.  * 檢查當前設備的 UI MODE 來判定運行環境是 TV 還是 Phone 
  3.  */ 
  4. private static boolean checkUIModeIsPhone(Context ctx) { 
  5.     UiModeManager uiModeManager = (UiModeManager) ctx.getSystemService(Context.UI_MODE_SERVICE); 
  6.     return uiModeManager.getCurrentModeType() != Configuration.UI_MODE_TYPE_TELEVISION; 

有興趣可以直接閱讀完整的官方文檔中的相關部分。

https://developer.android.com/training/tv/start/hardware.html#runtime-check

三、設計原則

這里提供的幾種方法,其實都是猜測,都是有缺陷的。例如可能出現某些廠商的奇葩設備,出貨屏幕尺寸就是大的手機,或者有一些奇葩的電視或者盒子,就是可以支持插 SIM 卡,再或者有其實還有一些智能投影的設備,其實是內帶電池的,是有電量的消耗的。

所以最穩妥的方式,就是組合起來判斷。

  1. private static boolean sIsChecked = false
  2. private static boolean sIsPhoneRunCache = false
  3. public static boolean isPhoneRunning(Context ctx) { 
  4.     if (!sIsChecked) { 
  5.         sIsPhoneRunCache = checkScreenIsPhone(ctx) 
  6.                 && checkScreenLayoutIsPhone(ctx) 
  7.                 && checkTelephonyIsPhone(ctx) 
  8.                 && checkBatteryIsPhone(ctx); 
  9.         sIsChecked = true
  10.     } 
  11.     return sIsPhoneRunCache; 

這里的判斷,是基于當前 App 是主要發布在 Android 電視的應用市場中,所以這里的判斷條件是對手機進行嚴格判斷,其他的都認為是 Android TV 。這樣即便是誤判了,影響也不會太大。

【本文為51CTO專欄作者“張旸”的原創稿件,轉載請通過微信公眾號聯系作者獲取授權】

戳這里,看該作者更多好文

責任編輯:武曉燕 來源: 51CTO專欄
相關推薦

2021-04-21 10:22:56

Python 開發編程語言

2012-02-22 09:09:04

Ubuntu for UbuntuAndroid

2011-01-24 15:04:01

Windows Pho

2011-10-21 10:26:51

Howdy明信片

2014-09-18 09:20:18

WPS高德地圖美圖秀秀

2023-02-14 15:04:00

Linux虛擬機物理機

2020-09-27 10:13:53

Windows 功能系統

2012-12-26 10:29:02

2021-01-28 10:12:02

鴻蒙JSJava

2016-11-24 08:59:10

LinuxTOP500計算機

2012-05-10 09:34:27

TV

2020-09-05 16:35:20

AndroidPython軟件開發

2015-07-20 17:01:12

APP崩潰云智慧

2022-03-14 17:35:55

數據中心

2013-07-05 13:48:47

App

2023-03-28 15:48:39

開源模型

2023-07-04 13:50:21

自然語言手機

2014-06-11 13:22:44

2018-01-18 16:17:05

Android TVApp工具

2015-11-06 14:40:41

網速wifi
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 欧美第一区 | 中文字幕精品一区久久久久 | 翔田千里一区二区 | 男人影音 | 美女人人操 | 亚洲福利一区二区 | 成人欧美一区二区三区色青冈 | 日韩精品一区二区三区在线播放 | 少妇久久久 | 欧美不卡一区二区三区 | 中文字幕亚洲视频 | 欧美性jizz18性欧美 | 久久精品日产第一区二区三区 | 岛国av免费在线观看 | 伊人网综合| 国产成人在线一区 | 日韩影院在线 | 国产精品视频久久久久久 | 国产一区二区三区视频在线观看 | 欧美天堂在线观看 | 国产亚洲网站 | 色婷婷综合久久久中字幕精品久久 | 一区二区三区欧美 | 亚洲 中文 欧美 日韩 在线观看 | 国产在线高清 | 国产伊人精品 | 欧美激情一区 | 亚洲成人自拍 | 亚洲一区二区成人 | 免费精品 | 精品亚洲一区二区三区四区五区 | 91在线视频一区 | 欧美日韩精品在线一区 | 成人免费视频网 | 久久手机视频 | 欧美一级欧美三级在线观看 | 污免费网站 | 中文字幕在线第一页 | 国产精品99久久久久久久久 | 欧美va大片 | 国产精品国产三级国产aⅴ无密码 |