Android中處理Touch Icon的方案
蘋果的Touch Icon相對我們都比較熟悉,是蘋果為了支援網路應用(或者說網頁)新增到桌面需要的圖示,有了這些Touch Icon的網頁連結更加和Native應用更相像了。由於蘋果裝置IPod,IPhone,IPad等裝置廣泛,很多網頁都提供了touch icon這種圖示資源。由於Android中並沒有及早的有一份這樣的標準,當我們想把網頁新增到桌面時,仍然需要使用蘋果的Touch Icon。
Touch Icon
當我們想讓一個網頁比較完美地新增到桌面,通常情況下我們需要設定一個png圖片檔案作為apple-touch-icon。比如
<link rel="apple-touch-icon" href="/custom_icon.png">
如果想支援IPhone和IPad,我們需要使用sizes屬性來制定多個圖片,預設sizes的值為60 x 60。
<link rel="apple-touch-icon" href="touch-icon-iphone.png"> <link rel="apple-touch-icon" sizes="76x76" href="touch-icon-ipad.png"> <link rel="apple-touch-icon" sizes="120x120" href="touch-icon-iphone-retina.png"> <link rel="apple-touch-icon" sizes="152x152" href="touch-icon-ipad-retina.png">
在IOS7之前,蘋果系統會對新增到桌面的圖示進行圓角化等視覺上的處理,為了不讓其處理,我們可以使用apple-touch-icon-precomposed來作為rel的值實現。
更多關於Touch Icon的資訊,可以訪問水果開發者網站瞭解更多。
Android中有缺陷的實現
在Android WebView提供了處理Touch Icon的回撥,onReceivedTouchIconUrl(WebView view, String url,boolean precomposed)
該方法返回了對我們有用的touch icon的url,和是否為預組合(在IOS中不需要進行視覺處理)。雖然有這些資料,我們可以進行處理,但是這其中是有問題的,就是我們不好確定檔案的大小,來選擇適合的圖片。
舉個例子,如下一個網頁的原始碼,其中sizes的順序不規律
<link rel="apple-touch-icon-precomposed" sizes="72x72" href="http://www.qiyipic.com/20130423143600/fix/H5-72x72.png"> <link rel="apple-touch-icon-precomposed" sizes="114x114" href="http://www.qiyipic.com/20130423143600/fix/H5-114x114.png"> <link rel="apple-touch-icon-precomposed" sizes="57x57" href="http://www.qiyipic.com/20130423143600/fix/H5-57x57.png"> <link rel="apple-touch-icon-precomposed" href="http://www.qiyipic.com/20130423143600/fix/H5-0x0.png">
載入網頁,onReceivedTouchIconUrl輸出的日誌
I/MainActivity( 6995): onReceivedTouchIconUrl url=http://www.qiyipic.com/20130423143600/fix/H5-0x0.png;precomposed=true I/MainActivity( 6995): onReceivedTouchIconUrl url=http://www.qiyipic.com/20130423143600/fix/H5-57x57.png;precomposed=true I/MainActivity( 6995): onReceivedTouchIconUrl url=http://www.qiyipic.com/20130423143600/fix/H5-114x114.png;precomposed=true I/MainActivity( 6995): onReceivedTouchIconUrl url=http://www.qiyipic.com/20130423143600/fix/H5-72x72.png;precomposed=true
從上面的輸出來看,基本上是後面(書寫)的元素先列印出來,所以這個回撥的缺陷如下
- 由於Touch Icon url地址沒有硬性規定,不能根據url包含某些尺寸來判斷使用哪個icon
- 由於網頁編寫touch icon元素相對隨意,不能根據onReceivedTouchIconUrl呼叫先後來決定使用哪個icon
- 回撥中沒有sizes屬性值,不好確定使用哪個icon
- 如果我們選取質量最高的圖片,然後進行適當壓縮處理或許可以解決問題,但是將全部icon下載下來或者根據Head頭資訊總感覺不怎麼好。
改進方法
既然WebView沒有現成的方法滿足我們的需求,只好自己來實現。其實實現方法還是比較簡單地就是js指令碼注入檢測網頁元素中得touch icon,返回json資料。
JavaScript方法
下面的JS程式碼所做的功能為查詢所有為touch icon的link元素,包含正常的還標記為precomposed。然後將這些link元素的屬性存入json資料,最後返回給Java程式碼中對應的回撥。
var touchIcons = []; function gatherTouchIcons(elements) { var normalTouchIconLength = elements.length; var currentElement; for (var i =0; i < normalTouchIconLength;i++) { currentElement = elements[i]; var size; if (currentElement.hasAttribute('sizes')) { size = currentElement.sizes[0]; } else { size = ''; } var info = {'sizes':size, 'rel': currentElement.rel, 'href': currentElement.href}; touchIcons.push(info); } } function obtainTouchIcons() { normalElements = document.querySelectorAll("link[rel='apple-touch-icon']"); precomposedElements = document.querySelectorAll("link[rel='apple-touch-icon-precomposed']"); gatherTouchIcons(normalElements); gatherTouchIcons(precomposedElements); var info = JSON.stringify(touchIcons); window.app_native.onReceivedTouchIcons(document.URL, info); } obtainTouchIcons();
Java程式碼
這裡為了便於理解還是全部貼出了demo的原始碼,demo中當網頁載入完成之後注入上面的js程式碼獲取touch icon資訊,然後返回給java的回撥方法中。如果不清楚Java和JavaScript互動,可以訪問Android中Java和JavaScript互動瞭解更多。
package com.example.obtaintouchicon; import java.io.BufferedReader; import java.io.FileNotFoundException; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import android.app.Activity; import android.os.Bundle; import android.util.Log; import android.webkit.JavascriptInterface; import android.webkit.WebChromeClient; import android.webkit.WebView; import android.webkit.WebViewClient; public class MainActivity extends Activity { protected String LOGTAG = "MainActivity"; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); WebView webView = new WebView(this); webView.getSettings().setJavaScriptEnabled(true); webView.setWebViewClient(new WebViewClient() { @Override public void onPageFinished(WebView view, String url) { super.onPageFinished(view, url); final String touchIconJsCode = getTouchIconJsCode(); Log.i(LOGTAG , "onPageFinished url = " + url + ";touchIconJsCode=" + touchIconJsCode); view.loadUrl("javascript:" + touchIconJsCode); } }); webView.addJavascriptInterface(new JsObject(), "app_native"); webView.loadUrl("http://192.168.1.5:8000/html/touchicon.html"); } private class JsObject { @JavascriptInterface public void onReceivedTouchIcons(String url, String json) { Log.i(LOGTAG, "onReceivedTouchIcons url=" + url + ";json=" + json); } } private String getTouchIconJsCode() { StringBuilder total = new StringBuilder(); InputStream inputStream = null; BufferedReader bufferReader = null; try { inputStream = getAssets().open("touchicon.js"); bufferReader = new BufferedReader(new InputStreamReader(inputStream)); String line; while ((line = bufferReader.readLine()) != null) { total.append(line); } } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } finally { if (null != inputStream) { try { inputStream.close(); } catch (IOException e) { e.printStackTrace(); } } } return total.toString(); } }
返回的JSON資料
[ { "sizes":"72x72", "rel":"apple-touch-icon-precomposed", "href":"http://www.qiyipic.com/20130423143600/fix/H5-72x72.png" }, { "sizes":"114x114", "rel":"apple-touch-icon-precomposed", "href":"http://www.qiyipic.com/20130423143600/fix/H5-114x114.png" }, { "sizes":"57x57", "rel":"apple-touch-icon-precomposed", "href":"http://www.qiyipic.com/20130423143600/fix/H5-57x57.png" }, { "sizes":"", "rel":"apple-touch-icon-precomposed", "href":"http://www.qiyipic.com/20130423143600/fix/H5-0x0.png" } ]
我們可以對得到的JSON資料按照需要處理。
Google會改進麼
答案是會,而且已經改進,但Google修改的不是onReceivedTouchIconUrl這個方法,而是Google正在推行自己的一套規則。
在Chrome上,Google增加了這樣一個元素,這是Google提供的為網頁程式定義後設資料的方法。
<link rel="manifest" href="manifest.json">
在後設資料json中,你可以自定義title,起始頁,程式是橫屏還是豎屏展示。一個簡單地json例項如下,這裡我們可以看到其中icons中存在多個類似touch icon的圖示,src代表圖示路徑,sizes代表大小,type就是mimetype,density指的是Android中的螢幕密度(這樣更加Android化了)。
{ "name": "Web Application Manifest Sample", "icons": [ { "src": "launcher-icon-0-75x.png", "sizes": "36x36", "type": "image/png", "density": "0.75" }, { "src": "launcher-icon-1x.png", "sizes": "48x48", "type": "image/png", "density": "1.0" }, { "src": "launcher-icon-1-5x.png", "sizes": "72x72", "type": "image/png", "density": "1.5" }, { "src": "launcher-icon-2x.png", "sizes": "96x96", "type": "image/png", "density": "2.0" }, { "src": "launcher-icon-3x.png", "sizes": "144x144", "type": "image/png", "density": "3.0" }, { "src": "launcher-icon-4x.png", "sizes": "192x192", "type": "image/png", "density": "4.0" } ], "start_url": "index.html", "display": "standalone", "orientation": "landscape" }
關於Google這套新的標準,可以參考Add to Homescreen
但是由於目前,這種標準實施率相對比較低,所以我們還是需要使用蘋果的touch icon。
相關文章
- Android的Touch事件處理機制介紹Android事件
- Android中的icon適配Android
- python圖片處理類之~PIL.Image模組(ios android icon圖示自動生成處理)PythoniOSAndroid
- web專案中圖示的前端處理方案Web前端
- Missing required icon file. The bundle does not contain an app icon for iPhone / iPod Touch of ex...UIAIAPPiPhone
- Android 中的轉場動畫及相容處理Android動畫
- Android 多使用者多快取的簡單處理方案Android快取
- 分散式事務處理方案,微服事務處理方案分散式
- Android中處理崩潰異常Android
- Android中的非同步訊息處理機制Android非同步
- 小程式中 icon 顏色自定義解決方案
- Cocoa Touch事件處理流程--響應者鏈(轉載)事件
- Android中AVD的使用以及錯誤處理方法Android
- 分散式系統中處理引數配置的 4 種方案分散式
- 分散式系統中處理引數配置的4種方案分散式
- reactnative 中關於小米文案的被截斷的處理方案React
- android處理webserviceAndroidWeb
- Oracle非法日期 處理方案Oracle
- ORACLE 11G DATAGUARD 日誌中斷處理方案Oracle
- 基於Vue & SVG 的 icon 解決方案VueSVG
- Android 中 EventBus 的使用(3):多執行緒事件處理Android執行緒事件
- asp.net ashx處理程式中switch case的替代方案總結ASP.NET
- hbase 故障的處理方案。 (轉載文章)
- java中的事件處理Java事件
- 影像處理或其他多媒體處理中的值溢位處理
- CSS > 關於雪碧圖預處理和後處理方案的討論CSS
- Android鍵盤皮膚衝突 佈局閃動處理方案Android
- Android中OpenGL濾鏡和RenderScript圖片處理Android
- 多功能視訊處理方案
- 頁面彈窗處理方案
- GOLANG錯誤處理最佳方案Golang
- 【譯】系統的學習 Android TouchAndroid
- Android和iOS開發中的非同步處理(一)——開篇AndroidiOS非同步
- java當中的批處理Java
- JDBC當中的批處理JDBC
- Java 中的並行處理Java並行
- JavaScript 中的引數處理JavaScript
- 影象中的畫素處理