在 iOS 設備普及的今天,用戶習慣將常用網頁「添加到主屏幕」。Apple 為此定義了 apple-touch-icon 標準,讓網頁能像原生 App 一樣擁有精美的桌面圖標。然而,Android 系統早期缺乏統一標準,開發者在 WebView 中往往只能依賴解析 Apple 的 Touch Icon 來實現類似功能。
網頁通常在 <head> 中聲明多種尺寸的圖標,以適配不同設備:
<link rel="apple-touch-icon" href="/custom_icon.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">
若不希望 iOS 自動添加光澤與圓角,可使用 apple-touch-icon-precomposed。
WebView 提供 onReceivedTouchIconUrl(WebView view, String url, boolean precomposed) 回調,但在實戰中存在四大痛點:
sizes,難以選擇最適圖標;既然 WebView 內建 API 不足,我們可以注入 JS 腳本,主動掃描 <link> 標籤,提取完整屬性並以 JSON 回傳給 Java 層。
var touchIcons = [];
function gatherTouchIcons(elements) {
for (var i = 0; i < elements.length; i++) {
var el = elements[i];
var size = el.hasAttribute('sizes') ? el.sizes[0] : '';
touchIcons.push({ sizes: size, rel: el.rel, href: el.href });
}
}
function obtainTouchIcons() {
var normal = document.querySelectorAll("link[rel='apple-touch-icon']");
var precomposed = document.querySelectorAll("link[rel='apple-touch-icon-precomposed']");
gatherTouchIcons(normal);
gatherTouchIcons(precomposed);
window.app_native.onReceivedTouchIcons(document.URL, JSON.stringify(touchIcons));
}
obtainTouchIcons();
webView.getSettings().setJavaScriptEnabled(true);
webView.addJavascriptInterface(new JsObject(), "app_native");
webView.setWebViewClient(new WebViewClient() {
@Override
public void onPageFinished(WebView view, String url) {
String js = loadJsFromAssets("touchicon.js"); // 從 assets 讀取上述 JS
view.loadUrl("javascript:" + js);
}
});
private class JsObject {
@JavascriptInterface
public void onReceivedTouchIcons(String url, String json) {
Log.i(TAG, "TouchIcons: " + json);
// 解析 JSON,按尺寸/設備像素比選擇最佳圖標
}
}
[
{"sizes":"72x72", "rel":"apple-touch-icon-precomposed", "href":"https://.../H5-72x72.png"},
{"sizes":"114x114", "rel":"apple-touch-icon-precomposed", "href":"https://.../H5-114x114.png"},
{"sizes":"57x57", "rel":"apple-touch-icon-precomposed", "href":"https://.../H5-57x57.png"},
{"sizes":"", "rel":"apple-touch-icon-precomposed", "href":"https://.../H5-0x0.png"}
]
拿到結構化數據後,即可根據設備密度、首選尺寸邏輯挑選最優圖標,避免盲目下載。
Google 已推出 <link rel="manifest" href="manifest.json"> 標準,在 JSON 中統一定義圖標、啟動頁、顯示模式等:
{
"name": "My Web App",
"icons": [
{"src": "icon-48.png", "sizes": "48x48", "type": "image/png", "density": "1.0"},
{"src": "icon-192.png", "sizes": "192x192", "type": "image/png", "density": "4.0"}
],
"start_url": "index.html",
"display": "standalone"
}
但受限於普及率,短期內仍需兼容 Apple Touch Icon。採用「JS 注入 + JSON 回傳」方案,可在過渡期優雅解決 Android 端圖標獲取難題。