Android中处理Touch Icon的方案
苹果的Touch Icon相对我们都比较熟悉,是苹果为了支持网络应用(或者说网页)添加到桌面需要的图标,有了这些Touch Icon的网页链接更加和Native应用更相像了。由于苹果设备IPod,IPhone,IPad等设备广泛,很多网页都提供了touch icon这种图标资源。由于Android中并没有及早的有一份这样的标准,当我们想把网页添加到桌面时,仍然需要使用苹果的Touch Icon。
Touch Icon
当我们想让一个网页比较完美地添加到桌面,通常情况下我们需要设置一个png图片文件作为apple-touch-icon。比如
<span style="font-family:Arial;font-size:14px;"><link rel="apple-touch-icon" href="/custom_icon.png"></span>
如果想支持IPhone和IPad,我们需要使用sizes属性来制定多个图片,默认sizes的值为60 x 60。
<span style="font-family:Arial;font-size:14px;"><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"></span>
在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的顺序不规律
<span style="font-family:Arial;font-size:14px;"><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"></span>
加载网页,onReceivedTouchIconUrl输出的日志
<span style="font-family:Arial;font-size:14px;"><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"></span>
从上面的输出来看,基本上是后面(书写)的元素先打印出来,所以这个回调的缺陷如下
1.由于Touch Icon url地址没有硬性规定,不能根据url包含某些尺寸来判断使用哪个icon
2.由于网页编写touch icon元素相对随意,不能根据onReceivedTouchIconUrl调用先后来决定使用哪个icon
3.回调中没有sizes属性值,不好确定使用哪个icon
4.如果我们选取质量最高的图片,然后进行适当压缩处理或许可以解决问题,但是将全部icon下载下来或者根据Head头信息总感觉不怎么好。
改进方法
既然WebView没有现成的方法满足我们的需求,只好自己来实现。其实实现方法还是比较简单地就是js脚本注入检测网页元素中得touch icon,返回json数据。
JavaScript方法
下面的JS代码所做的功能为查找所有为touch icon的link元素,包含正常的还标记为precomposed。然后将这些link元素的属性存入json数据,最后返回给Java代码中对应的回调。
<span style="font-family:Arial;font-size:14px;">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();</span>
Java代码
这里为了便于理解还是全部贴出了demo的源码,demo中当网页加载完成之后注入上面的js代码获取touch icon信息,然后返回给java的回调方法中。如果不清楚Java代码如何实现改进方案的,可以点击Java代码编写的Android应用如何实现安全
<span style="font-family:Arial;font-size:14px;">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();
}
}</span>
返回的JSON数据
<span style="font-family:Arial;font-size:14px;">[
{
"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"
}
]</span>
我们可以对得到的JSON数据按照需要处理。
Google会改进么
答案是会,而且已经改进,但Google修改的不是onReceivedTouchIconUrl这个方法,而是Google正在推行自己的一套规则。
在Chrome上,Google增加了这样一个元素,这是Google提供的为网页程序定义元数据的方法。
<span style="font-family:Arial;font-size:14px;"><link rel="manifest" href="manifest.json"></span>
在元数据json中,你可以自定义title,起始页,程序是横屏还是竖屏展示。一个简单地json实例如下,这里我们可以看到其中icons中存在多个类似touch icon的图标,src代表图标路径,sizes代表大小,type就是mimetype,density指的是Android中的屏幕密度(这样更加Android化了)。
<span style="font-family:Arial;font-size:14px;">{
"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"
}</span>
但是由于目前,这种标准实施率相对比较低,所以我们还是需要使用苹果的touch icon。
源码下载:http://pan.baidu.com/s/1dDD3gZZ
Android中处理Touch Icon的方案的更多相关文章
- Android中的Touch事件
Android中的Touch事件处理 主要内容 Activity或View类的onTouchEvent()回调函数会接收到touch事件. 一个完整的手势是从ACTION_DOWN开始,到ACTION ...
- android中的Touch研究
android中的事件类型分为按键事件和屏幕触摸事件,Touch事件是屏幕触摸事件的基础事件,有必要对它进行深入的了解. 一个最简单的屏幕触摸动作触发了一系列Touch事件:ACTION_DOWN-& ...
- Android中Touch事件分析--解决HorizontalScrollView滑动和按钮事件触发问题
之前写过关于HorizontalScrollView滑动和按钮事件触发问题,但是不能所有的情况,最近几天一直在想这个问题,今天有一个比较好的解决思路,最终应用在项目里面效果也很好,首先说明一下功能: ...
- Android中线程间通信原理分析:Looper,MessageQueue,Handler
自问自答的两个问题 在我们去讨论Handler,Looper,MessageQueue的关系之前,我们需要先问两个问题: 1.这一套东西搞出来是为了解决什么问题呢? 2.如果让我们来解决这个问题该怎么 ...
- Android中的dispatchTouchEvent()、onInterceptTouchEvent()和onTouchEvent()
dispatchTouchEvent (分发TouchEvent) 处理触摸事件分发,事件(多数情况)是从Activity的dispatchTouchEvent开始的.执行super.dispatc ...
- Android 编程下 Touch 事件的分发和消费机制
Android 中与 Touch 事件相关的方法包括:dispatchTouchEvent(MotionEvent ev).onInterceptTouchEvent(MotionEvent ev). ...
- Android中直播视频技术探究之---桌面屏幕视频数据源采集功能分析
一.前言 之前介绍了Android直播视频中一种视频源数据采集:摄像头Camera视频数据采集分析 中介绍了利用Camera的回调机制,获取摄像头的每一帧数据,然后进行二次处理进行推流.现在我们在介绍 ...
- Android 根据规划 Touch 分配和消费机制的事件
Android 中与 Touch 事件相关的方法包含:dispatchTouchEvent(MotionEvent ev).onInterceptTouchEvent(MotionEvent ev). ...
- iOS / Android 移动设备中的 Touch Icons
上次转载了一篇<将你的网站打造成一个iOS Web App>,但偶然发现这篇文章的内容有些是错误的——准确来说也不是错误,只是不适合自半年前来的情况了(也可以说是iOS7 之后的时间)—— ...
随机推荐
- ubuntu12.04开启Framebuffer
一.framebuffer概述 Framebuffer在Linux中是作为设备来实现的,它是对图形硬件的一种抽象,代表着显卡中的帧缓冲区(Framebuffer).通过Framebuffer设备,上层 ...
- SQL在线学习网站
1.在线编写网页:http://sqlfiddle.com/ 2.SQL菜鸟教程:http://www.runoob.com/sql/sql-intro.html 3.SQL语句在线练习 http:/ ...
- 【【henuacm2016级暑期训练】动态规划专题 F】Physics Practical
[链接] 我是链接,点我呀:) [题意] 给你n个数字 让你删掉最小的数字 使得: 剩余的数字中 "最大的数字"小于等于"最小的数字*2" [题解] 把数据从小 ...
- 查看系统的I/O使用iostat命令而使用iotop能够依据I/O统计信息排序,追踪到详细的进程
当看到I/O等待时间所占CPU时间的比重非常高的时候,首先要检查的就是机器是否正在大量使用交换空间,由于硬盘操作的速度远远低于RAM.所以当系统内存耗尽,開始使用交换空间的时候.系统的性能会受到严重影 ...
- php给图片加入文字水印
PHP对图片的操作用到GD库.这里我们介绍怎样给图片加入文字水印. 大致分为四步: 1.打开图片 2.操作图片 3.输出图片 4.销毁图片 以下我们上代码来详细解说每步的实现过程: <? php ...
- CC2540/CC2541 : Set the Peripheral Being Advertising while It is Being Connected
There is possible to set your CC254X be scanable when it is in connection. But, based on my test,the ...
- .Net MVC的学习(一)
套种间作,也挺有意思的--近来学习感悟.DRP学习的同一时候,折腾了点曾经不曾学习可是却非常多次耳闻过的东西--Asp.Net中的MVC架构模式. 一.是什么? MVC,即(Model-View-Co ...
- Vuejs2.0学习之二(Render函数,createElement,vm.$slots,函数化组件,模板编译,JSX)
时隔一周多,因为一些别的事情绊住了,下面接着写.中间这段时间也有看官方文档,发现正如他所说90%的基础内容都一样,所以这里直接跳到我比较关注的东东上,要是想看看哪些不一样,可以参考这个http://v ...
- gpg 的使用
GPG入门教程 GpG使用指南 1. 安装 源码编译安装:源码下载地址 ./configure make make install 直接安装编译好的二进制文件 # Debian / Ubuntu 环境 ...
- angular4过滤器
Angular4中过滤器 一.大小写转换过滤器 uppercase将字符串转换为大写 lowercase将字符串转换为小写 <p>将字符串转换为大写{{str | uppercase}}& ...