做者:賀國睿、朱忠凱 騰訊移動客戶端開發 高級工程師
商業轉載請聯繫騰訊WeTest得到受權,非商業轉載請註明出處。
原文連接:http://wetest.qq.com/lab/view/376.htmlhtml
2018年3月8日,Google推出了Android P Preview版本,並提供官方鏡像下載。android
爲了讓廣大開發者可以及時瞭解Android P的新功能特性,提早爲您的app進行良好適配,WeTest決定限時免費開放Android P Preview版本的遠程調試及標準兼容功能,供開發者進行體驗。算法
即日起,針對WeTest平臺的Android P、Android Oreo專區,我的認證用戶可免費得到30分鐘/天遠程調試、3次/天標準兼容測試額度;企業帳戶可得到60分鐘/天遠程調試、6次/天標準兼容測試額度。canvas
此外,WeTest的技術專家就本次Android P的新特性,進行了一些簡單的開發體驗,供你們參考:
api
新功能特性搶先看
Android P的新功能特性集中在了UI、通知體驗、室內定位、圖像存儲幾個方面,解決了以前一直存在的痛點。例如WiFi RTT必定程度上彌補了蜂窩網絡在室內環境下的定位問題,HEIC圖像格式則重點解決了存儲容量問題。同時,Android P也在通知豐富度及操做便捷性等功能方面有所加強和提高。安全
WiFi RTT功能是Android P新引入的一個功能,從原理上來講與蜂窩網絡的定位原理一致,但這個功能極大的彌補了蜂窩網絡在室內定位的短板,WiFi RTT將可以在室內提供高精度的定位,這是蜂窩網絡很難作到的。網絡
WiFi RTT是全新的功能,在android.net.wifi包下增長了rtt包,用於存放WiFi RTT相關類和接口。app
WiFi RTT的API以WifiRttManager爲核心,藉助AP熱點或WiFi,利用RTT原理完成測距,經過三個以上的測距點就可以準確地定位到設備所在位置。框架
WiFiRTTManager提供了測距接口,是一個異步測距操做,根據 官方文檔 說明,其測距接口以下:異步
void startRanging(RangingRequest request, RangingResultCallback callback, Handler handler);
注: SDK Platforms Android P Preview Revision 1的相關接口定義與此不一樣,但實際的官方鏡像中接口與此一致,開發者須要更新最新的Android P Preview Revision 2,此版本中Google已經修正該接口。
接口中,RangingRequest經過RangingRequest.Builder構建,RangingRequest.Builder構建出RangingRequest所須要的參數能夠經過WiFiManager等系統服務獲取到相關的內容,如 List<ScanResult> scanResults = wifiManager.getScanResults();
如下提供一個簡單的測試Demo,以供參考:
private WifiRttManager wifiRttManager; private WifiManager wifiManager; @Override protected void onCreate(Bundle savedInstanceState) { // ... ... if(getPackageManager().hasSystemFeature(PackageManager.FEATURE_WIFI_RTT)) { Object service = this.getApplicationContext().getSystemService(Context.WIFI_RTT_RANGING_SERVICE); if(service instanceof WifiRttManager) { wifiRttManager= (WifiRttManager) service; Log.i(TAG, "Get WifiRttManager Succ."); } wifiManager = (WifiManager) this.getApplicationContext().getSystemService(Context.WIFI_SERVICE); IntentFilter wifiFileter = new IntentFilter(); wifiFileter.addAction(WifiManager.NETWORK_STATE_CHANGED_ACTION); wifiFileter.addAction(WifiManager.WIFI_STATE_CHANGED_ACTION); wifiFileter.addAction(WifiManager.SCAN_RESULTS_AVAILABLE_ACTION); registerReceiver(new WifiChangeReceiver(), wifiFileter); } // ... ... } private void startScanAPs() { wifiManager.setWifiEnabled(true); wifiManager.startScan(); } class WifiChangeReceiver extends BroadcastReceiver { @RequiresApi(api = 28) @Override public void onReceive(Context context, Intent intent) { if (intent.getAction().equals(WifiManager.SCAN_RESULTS_AVAILABLE_ACTION)) { List<ScanResult> scanResults = wifiManager.getScanResults(); Log.i(TAG, "Wifi Scan size:" + scanResults.size()); for(ScanResult scanResult: scanResults) { Log.i(TAG, scanResult.toString()); RangingRequest.Builder builder = new RangingRequest.Builder(); builder.addAccessPoint(scanResult); wifiRttManager.startRanging(builder.build(), new RangingResultCallback() { @SuppressLint("Override") @Override public void onRangingFailure(int i) { // TODO } @SuppressLint("Override") @Override public void onRangingResults(List<RangingResult> list) { // TODO get result from list for(RangingResult result : list) { Log.i(TAG, result.toString()); } } }, new Handler()); } } } }
使用WiFi RTT時,須要在AndroidManifest.xml中增長以下聲明:
<uses-feature android:name="android.hardware.wifi.rtt" />
經過上面的簡單代碼,就可以實現WiFi RTT的功能。
WiFi RTT功能適用於複雜地形的大型室內外場所,如商場、娛樂場所、大型休閒、遊樂場等等,提供場所內的局部區域精確化導航等功能。相信在很快的時間內,就可以在各大地圖應用內體驗到這項便利功能,對於路癡、地圖盲的夥伴們將是極大的福音。
隨着iPhone X的推出,「劉海屏」達到了空前的高潮。Android P裏提供了對異形屏幕的UI適配兼容方案,經過DisplayCutout類提供的相關接口,可以獲取到屏幕中Cutout區域的信息。
藉助DisplayCutout,能夠獲取到以下信息:
DisplayCutout displayCutout = view.getRootWindowInsets().getDisplayCutout(); if(displayCutout != null) { Region bounds = displayCutout.getBounds(); Log.d(TAG, String.format("Bounds:%s", bounds.toString())); int top = displayCutout.getSafeInsetTop(); int bottom = displayCutout.getSafeInsetBottom(); int left = displayCutout.getSafeInsetLeft(); int right = displayCutout.getSafeInsetRight(); Log.d(TAG, String.format("Cutout edge:[left:%d, top:%d,right:%d, bottom:%d]", left, top, right, bottom)); }
public Region getBounds()可以獲取到Cutout區域的全部信息,Region就是Cutout區域。
public int getSafeInsetTop() public int getSafeInsetBottom() public int getSafeInsetLeft() public int getSafeInsetRight()
以上四個接口,能夠獲取到去除Cutout區域後的安全區域邊界值。
經過上述數據,開發者可以精準的控制UI的繪製,避免將UI內容繪製到Cutout區域形成UI顯示異常。
Android機器裏,劉海屏目前仍是極爲罕見的Google爲了方便開發者調試,在Android P Preview鏡像中,特別提供了Cutout的支持,具體打開方式能夠參考Google提供的特性說明文檔cutout小節內容。
如圖所示,筆者使用手頭的Pixel 2 XL體驗了Android P的Cutout設置。
Android P在通知內容的豐富度和操做上作了優化。
最近的版本中,Android系統的通知管理方面一直優化升級,Android O提供了更細粒度的Channel功能,通知欄推送時須要指定NotificationChannel,用戶能夠對通知的Channel選擇,只容許感興趣的Channel推送的通知顯示。經過通道設置、免打擾優化等方式,極大加強了消息體驗。
加強消息體驗
Android P繼續改進和加強消息通知[v1] 。早在Android 7.0時,就提供了在通知中直接應答和輸入,Android P對這一功能作了更多的加強。
Android P的通知中支持圖像內容,能夠經過setData()方法,給出消息的圖像內容,在通知上展現給用戶。
Android P一樣簡化了通知的配置形式。Android P中增長了Notification.Person類,用於區分同一個對話的參與者信息,如參與者的頭像、URI等。根據官方說明,Android P中,通知消息的其餘一些API,也使用Person替代以前的CharSequence。
簡單的體驗下新的API的開發:
NotificationChannel channel = new NotificationChannel("WtTestChannel", "WtTestChannel", NotificationManager.IMPORTANCE_DEFAULT); channel.enableLights(true); // luncher icon right corner's point channel.setLightColor(Color.RED); // read point channel.setShowBadge(true); // whether show this channel notification on long press icon Notification.Builder builder = new Notification.Builder(MainActivity.this, "WtTestChannel"); Notification.Person p = new Notification.Person(); p.setName("WeTest"); p.setUri("http://cdn.wetest.qq.com/" + "ui/1.2.0/pc/static/image/newLogo-16042.png"); Notification.MessagingStyle messageStyle = new Notification.MessagingStyle(p); Notification.MessagingStyle.Message message = new Notification.MessagingStyle.Message("WeTestMessage", 2000, p); //show image Uri image = Uri.parse( "http://cdn.wetest.qq.com/ui/1.2.0/pc/static/image/newLogo-16042.png"); message.setData("image/png", image); messageStyle.addMessage(message); builder.setStyle(messageStyle); builder.setSmallIcon(R.mipmap.ic_launcher); Notification notification = builder.build(); NotificationManager notifyManager = (NotificationManager) getSystemService( MainActivity.this.getApplicationContext().NOTIFICATION_SERVICE); notifyManager.createNotificationChannel(channel); notifyManager.notify("WeTest", 1, notification);
通道設置、廣播和免打擾優化
Android P中,重點作了內容豐富上的工做,同時也對Channel的設置方面作了一些簡化處理。
Android O版本里,首次推出了NotificationChannel,開發者須要配置相應的Channel,纔可以推送通知給用戶。用戶可以更加細粒度[v1] 的針對App的Channel選擇,而不是禁止App的全部通知內容。
而在Android P中,對通知的管理作了進一步的優化,包括能夠屏蔽通道組、提供新的廣播類型和新的免打擾優先級。
屏蔽通道組: 用戶能夠在通知設置中屏蔽App的整個通道組。開發者能夠經過isBlocked()來判斷某個通道組是否被屏蔽了,並根據結果,不向已經被屏蔽的通道組發送任何通知。另外,開發者能夠在App中使用新接口getNotificationChannelGroup()來查詢當前的通道組設置。
新的廣播類型:新廣播類型是針對通道和通道組的功能增長的「通道(組)屏蔽狀態變化」廣播。開發者App中能夠對所擁有的通道(組)接收廣播,並根據具體廣播內容做出動做。開發者能夠經過NotificationManager,查看廣播相關的具體信息。針對廣播的動做能夠經過Broadcasts查看具體的方法和信息。
免打擾優先級: NotificationManager.Policy增長了兩個新的優先級常量,PRIORITY_CATEGORY_ALARMS(警告優先),PRIORITY_CATEGORY_MEDIA_SYSTEM_OTHER (媒體、系統和遊戲聲音優先)。
近一段時間,雙攝、多攝等機型紛紛面世。雙攝及多攝提供了單攝像頭所沒法完成的能力,如無縫縮放、散景和立體視覺。Android P在這方面也提供了系統級的API支持。
Android P提供了系統API,支持從兩個或者多個物理攝像頭同步獲取數據流。此前OEM廠商提供的雙攝設備可能是廠商自行定製系統實現,此時Android P推出了API,從系統層面上制定了API規範。
新的API提供了在不一樣相機之間切換邏輯數據流或混合數據流的調用能力。在捕捉延遲方面,提供新的會話參數,下降初始捕捉延遲。同時,提供相機共享能力,以解決在多種使用相機的場景下重複中止、開啓相機流。閃光燈方面,Android P增長基於顯示的閃光燈支持。光學防抖方面,Android P向開發者提供OIS時間戳,用於圖像穩定性優化以及其餘特效使用。
此外,Android P還支持外部USB/UVC相機,可使用更強大的外置攝像頭模組。
Android P引入了新的ImageDecoder,該類除了支持對各類圖片格式的解碼、縮放、裁剪以外,其強大之處在於支持對解碼後的圖像作後期處理(post-process),使用該功能能夠添加複雜的自定義特效,好比圓角,或是將圖片放在圓形像框中。編寫後期處理回調函數,你能夠添加任何繪圖指令實現須要的效果。
此外,Android P原生支持GIF和WebP格式的動圖,新增了AnimatedVectorDrawable類,並被新增的解碼器類ImageDecoder直接支持,用法跟矢量動畫類AnimatedVectorDrawable相似,實現方式也相似,經過新增渲染線程和工做線程,不須要在UI線程處理動圖更新,能夠說是無痛使用,很是省心。
下面經過編寫代碼,顯示一張gif圖,並利用後期處理機制,在圖像中間繪製一個綠色的實心圓。
final ImageView image = (ImageView) findViewById(R.id.image); File gifFile = new File("/data/local/tmp/test.gif"); if (!gifFile.exists()) { Log.d(TAG, "gifFile is not exsited!"); return; } ImageDecoder.Source source = ImageDecoder.createSource(gifFile); try { d = ImageDecoder.decodeDrawable(source, new ImageDecoder.OnHeaderDecodedListener() { @Override public void onHeaderDecoded(ImageDecoder imageDecoder, final ImageDecoder.ImageInfo imageInfo, ImageDecoder.Source source) { imageDecoder.setPostProcessor(new PostProcessor() { @Override public int onPostProcess(Canvas canvas) { int w = imageInfo.getSize().getWidth(); int h = imageInfo.getSize().getHeight(); Paint paint = new Paint(); paint.setAntiAlias(true); paint.setColor(Color.GREEN); canvas.drawCircle(w/2, h/2, h/4, new Paint(paint)); return 0; } }); } }); image.setVisibility(View.VISIBLE); image.setImageDrawable(d); } catch (IOException e){ Log.d(TAG, e.toString()); } Button button = (Button) findViewById(R.id.buttonText); button.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { if (d != null && d instanceof AnimatedImageDrawable) { AnimatedImageDrawable ad = (AnimatedImageDrawable) d; if (ad.isRunning()) { Log.d(TAG, "stop running"); ad.stop(); } else { Log.d(TAG, "start running"); ad.start(); } } } });
Android P內置了對HDR VP9和HEIF(heic)圖像編碼的支持。HEIF是蘋果在iOS11推出的一種高效壓縮格式,目前在IphoneX、Iphone 八、IPhone 8P上已經支持。該格式的壓縮率更高,可是編碼該格式須要硬件的支持,解碼並不須要。最新的支持庫中的HeifWriter支持從YUV字節緩衝區、Surface或是Bitmap類轉換爲HEIF格式的靜態圖像。
Android P新引入了MediaPlayer2,支持DataSourceDesc建立的播放列表。
功能優化提高一覽
1、神經網絡API 1.1
在前不久發佈的Android 8.1 (API level 27)上,Google首次在Android平臺上推出了神經網絡API,這意味着咱們的Android機器智能化水平又提升了一大步。而本次Android P,進一步豐富了神經網絡的支持,不只對以前的相關API進行了優化,而且提供了9個新的操做,爲具體的數據操做方面提供了更深刻的支持。
2、改進表單自動填充
Android 8.0(API等級26)中引入了自動填充框架,這使得在應用中填寫表單變得更加容易。 Android P引入了自動填充服務並實現了多項改進,得以在填寫表單時進一步加強用戶體驗。
3、安全加強
Android P引入了許多新的安全功能,包括統一的指紋驗證對話框和敏感交易的高確信度的用戶確認。應用程序內的指紋認證UI也將會更加一致。
統一的指紋驗證對話框
若是第三方APP想要使用指紋,Android系統框架爲應用提供了指紋認證對話框,該功能能夠提供統一的外觀和使用體驗,用戶使用起來更放心。若是您的程序還在使用FingerprintManager,如今改用FingerprintDialog替代吧,系統來提供對話框顯示。對了,在使用FingerprintDialog以前,別忘了調用hasSystemFeature()方法檢查手機設備是否支持指紋。
敏感交易的高確信度的用戶確認
Android P系統提供了受保護的確認API,藉助這組全新的API,應用可使用ConfirmationDialog對話框向用戶提示,請求用戶批准一條簡短的聲明, 該聲明容許應用提醒用戶,即將完成一筆敏感交易,例如支付。
若是用戶接受聲明,應用將會收到一條key-hash的消息認證碼(HMAC),該簽名由TEE產生,以保護用於輸入和認證對話框的顯示。該簽名表示用於已經看到了聲明並贊成了。
硬件安全模塊
Android P還提供了StrongBox Keymaster(強力沙盒祕鑰大師),一個存儲在硬件安全模塊的具體實現。在這個硬件安全模塊中有本身的CPU、安全存儲空間,真隨機數生成器,以及額外的機制抵禦應用被篡改或是未受權應用的惡意加載。當檢查存儲在StrongBox Keymaster中的密鑰時,系統經過可信執行環境(TEE)確認密鑰的完整性。爲了下降能耗,StrongBox支持了一組算法和不一樣長度的祕鑰:
● RSA 2048
● AES 128 and 256
● ECDSA P-256
● HMAC-SHA256 (支持8字節到64字節任意祕鑰長度)
● Triple DES 168
須要說明的是,這個機制須要硬件支持。
安全祕鑰導入KeyStore
使用新的ASN.1編碼的祕鑰格式添加導入祕鑰到Keystore,Android P提供了額外的密碼解密安全能力。以後KeyMaster就能夠解密KeyStore存儲的祕鑰,這種工做方式使得祕鑰明文永遠不會出如今設備內存中。這項特性要求設備支持Keymaster 4。
4、支持客戶端側Android備份加密
Android P支持使用客戶端密鑰對Android備份進行加密。 這項隱私措施,須要設備的PIN、圖案密碼或標準密碼才能從用戶設備備份的數據中恢復數據。
5、Accessibility優化
爲了使App使用更便捷,Android在多個方面爲開發者提供了易用性的優化。
Navigation semantics
Android P在App的場景切換和操做上爲開發者提供了不少的優化點。
Accessibility pane titles
Android P中對Section提供了新的機制,被稱爲accessibility pane titles, Accessibility services可以接收這些標題的變化,使得可以對一些變化提供更加細粒度的信息。
指定Section的標題,能夠經過android:accessibilityPaneTitle新屬性來設置,一樣運行時能夠經過setAccessibilityPaneTitle()來設置標題。
頂部欄導航
Android P提供了新的頂部欄導航機制,經過設置View實例的android:accessibilityHeading屬性爲true,來顯示邏輯標題。經過這些標題,用戶就能夠從一個標題導航到下一個標題,
羣組導航和輸出
針對屏幕閱讀器,Android P對View提供了新的屬性android:screenReaderFocusable代替原有的android:focusable來作標記,來解決在一些場景下爲了使屏幕閱讀器工做而設置View爲可獲取焦點的操做。這時,屏幕閱讀器須要同時關注android:screenReaderFocusable和android:focusable設置爲ture的View。
便捷操做
tooltips交互
Android P中,可使用getTooltipText()去讀取tooltips的文本內容。使用新的ACTION_SHOW_TOOLTIP和ACTION_HIDE_TOOLTIP控制View顯示或者隱藏tooltips。
新全局交互
Android P在AccessibilityService類中提供了兩個全新的操做。開發者的Service能夠經過GLOBAL_ACTION_LOCK_SCREEN幫助用戶鎖屏,經過GLOBAL_ACTION_TAKE_SCREENSHOT幫助用戶完成屏幕截圖。
窗體改變的一些細節
Android P優化了在App多窗體同步發生變化時的更新內容獲取。當出現TYPE_WINDOWS_CHANGED時,開發者能夠經過getWindowChanges()API獲取窗體變化狀況。
當多窗體發生改變時,每一個窗體都會發出本身的事件,開發者能夠經過getSource()獲取到事件窗體的根View。
若是你的App爲View定義了accessibility pane titles,UI更新時你的Service就可以識別到相應的改動。當出現TYPE_WINDOW_STATE_CHANGED事件時,使用新方法 getContentChangeTypes()返回的類型,就可以獲取到當前窗體的變化狀況。例如,如今就可以經過上述的機制,檢測到一個[v1] 窗格是否有了新標題,或者一個窗格的消失。
旋轉屏幕,是一些遊戲、視頻等場景必要的操做,但有一些場景,用戶旋轉屏幕並非爲了讓應用顯示從豎屏變成橫屏或反過來。爲了不這種誤操做,Android P提供了新的機制,開發者能夠指定屏幕不隨重力感應旋轉,而是用戶經過一個單獨的按鈕自行控制屏幕顯示轉向。
參考文檔:
https://developer.android.goo...
點擊連接:http://wetest.qq.com/cloud/help/AndroidP 便可限時免費體驗Android P Preview版本的遠程調試及標準兼容功能。
若有任何問題,或對系統的建議,請聯繫WeTest小助手(QQ:800024531)。
咱們會將與谷歌技術專家共同爲您解答。