问题分析:
成都创新互联公司坚持“要么做到,要么别承诺”的工作理念,服务领域包括:成都网站制作、网站设计、企业官网、英文网站、手机端网站、网站推广等服务,满足客户于互联网时代的阜阳网站设计、移动媒体设计的需求,帮助企业找到有效的互联网解决方案。努力成为您成熟可靠的网络建设合作伙伴!
html5网站主要由html+css+js的形式组成,需要使用浏览器进行展现。
Android需要使用Java语言来开发,对于前端工程师来说,无疑是增加了很大的难度。
随后出现了很多打包工具,来协助我们将网页元素打包成手机app,将我们编写的html转化为Java语言。
解决方案:
推荐一款我们常用的打包工具:HBuilder。
该工具不仅提供了Android应用打包,还可以直接连接手机进行调试,配合HTML5+可以实现很多Android原生的功能。比如:扫码二维码,拍照,摇一摇等等。
具体操作步骤:
1、真机调试
进入软件后,第一步点击“运行”,第二步点击“手机运行”,第三步选择已连接的手机,示例中我使用的是安卓模拟机进行连接的。市面上常用的几款安卓模拟机器都可以直接连接上。
按如上几个步骤操作后,会自动执行打包并将应用安装在链接的手机(模拟器)中,可以操作手机(模拟机)进行测试。
2、打包生成Android的安装格式apk文件
① 打开软件,选择发行-发行为原生安装包,随即打开下图窗口。
② 勾选Android复选框,如果使用Dcloud公用证书的话,可以直接进行打包,手机可以安装使用。如果需要上传发行到第三方应用平台的话,需要使用自有证书,自用证书可以使用JRE自带的创建和管理数字证书的工具Keytool来生成自有证书,生成过程是免费的。
勾选Android选项后,在下方表单中填写Android包名,为保证唯一性,可以使用自有网站域名的反写方式加上应用名称。如果使用自有证书的话,还需要填写证书别名,密钥密码,证书文件。
填写完毕后,点击打包,即可生成apk文件。
其他注意事项:
1、在开发过程中,不需要进行打包,应更多的使用真机调试,可以节约很多时间。
2、开发完毕后,尽可能在各种版本的android机器上做一下测试,因为一些网页的样式在不同的android版本中呈现的效果略有不同。
3、重新编辑一下html5网站代码,将一些网页功能转换为手机功能,比如网页元素的a标签跳转,就应该使用Webview来完成。可以解决页面切换白屏的问题,还可以提高网站在手机中的运行效率。
三种解决方式:1 viewport属性 2 CSS控制 3 JS控制
1 viewport属性放在HTML的meta中
SPAN style="FONT-SIZE: x-small" head
titleExmaple/title
meta name=”viewport” content=”width=device-width,user-scalable=no”/
/head/SPAN
meta中viewport的属性如下
SPAN style="FONT-SIZE: x-small" meta name="viewport"
content="
height = [pixel_value | device-height] ,
width = [pixel_value | device-width ] ,
initial-scale = float_value ,
minimum-scale = float_value ,
maximum-scale = float_value ,
user-scalable = [yes | no] ,
target-densitydpi = [dpi_value | device-dpi |
high-dpi | medium-dpi | low-dpi]
"
//SPAN
2 CSS控制设备密度
为每种密度创建独立的样式表(注意其中的webkit-device-pixel-ratio 3个数值对应3种分辨率)
link rel="stylesheet" media="screen and (-webkit-device-pixel-ratio: 1.5)" href="hdpi.css" /
link rel="stylesheet" media="screen and (-webkit-device-pixel-ratio: 1.0)" href="mdpi.css" /
link rel="stylesheet" media="screen and (-webkit-device-pixel-ratio: 0.75)" href="ldpi.css" /
在一个样式表中,指定不同的样式
WebView myWebView = (WebView) findViewById(R.id.webview);
myWebView.setWebViewClient(new MyWebViewClient());
另外出于用户习惯上的考虑 需要将WebView表现得更像一个浏览器,也就是需要可以回退历史记录
因此需要覆盖系统的回退键 goBack,goForward可向前向后浏览历史页面
Java代码
public boolean onKeyDown(int keyCode, KeyEvent event) {
if ((keyCode == KeyEvent.KEYCODE_BACK) myWebView.canGoBack() {
myWebView.goBack();
return true;
}
return super.onKeyDown(keyCode, event);
}
//处理javascript中的confirm
public boolean onJsConfirm(WebView view, String url, String message, final JsResult result) {
Builder builder = new Builder(MainActivity.this);
builder.setTitle("confirm");
builder.setMessage(message);
builder.setPositiveButton(android.R.string.ok,
new AlertDialog.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
result.confirm();
}
});
builder.setNegativeButton(android.R.string.cancel,
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
result.cancel();
}
});
builder.setCancelable(false);
builder.create();
builder.show();
return true;
};
@Override
//设置网页加载的进度条
public void onProgressChanged(WebView view, int newProgress) {
MainActivity.this.getWindow().setFeatureInt(Window.FEATURE_PROGRESS, newProgress * 100);
super.onProgressChanged(view, newProgress);
}
//设置应用程序的标题title
public void onReceivedTitle(WebView view, String title) {
MainActivity.this.setTitle(title);
super.onReceivedTitle(view, title);
}
});
● Android中的调试
通过JS代码输出log信息
Js代码
Js代码: console.log("Hello World");
Log信息: Console: Hello World :82
在WebChromeClient中实现onConsoleMesaage()回调方法,让其在LogCat中打印信息
Java代码 复制代码 收藏代码
WebView myWebView = (WebView) findViewById(R.id.webview);
myWebView.setWebChromeClient(new WebChromeClient() {
public void onConsoleMessage(String message, int lineNumber, String sourceID) {
Log.d("MyApplication", message + " -- From line "
+ lineNumber + " of "
+ sourceID);
}
});
以及
Java代码
WebView myWebView = (WebView) findViewById(R.id.webview);
myWebView.setWebChromeClient(new WebChromeClient() {
public boolean onConsoleMessage(ConsoleMessage cm) {
Log.d("MyApplication", cm.message() + " -- From line "
+ cm.lineNumber() + " of "
+ cm.sourceId() );
return true;
}
});
*ConsoleMessage 还包括一个 MessageLevel 表示控制台传递信息类型。 您可以用messageLevel()查询信息级别,以确定信息的严重程度,然后使用适当的Log方法或采取其他适当的措施。
● HTML5本地存储在Android中的应用
HTML5提供了2种客户端存储数据新方法:
localStorage 没有时间限制
sessionStorage 针对一个Session的数据存储
Js代码
script type="text/javascript"
localStorage.lastname="Smith";
document.write(localStorage.lastname);
/script
script type="text/javascript"
sessionStorage.lastname="Smith";
document.write(sessionStorage.lastname);
/script
WebStorage的API:
//清空storage
localStorage.clear();
//设置一个键值
localStorage.setItem(“yarin”,“yangfegnsheng”);
//获取一个键值
localStorage.getItem(“yarin”);
//获取指定下标的键的名称(如同Array)
localStorage.key(0);
//return “fresh” //删除一个键值
localStorage.removeItem(“yarin”);
注意一定要在设置中开启哦
setDomStorageEnabled(true)
在Android中进行操作
//启用数据库
webSettings.setDatabaseEnabled(true);
String dir = this.getApplicationContext().getDir("database", Context.MODE_PRIVATE).getPath();
//设置数据库路径
webSettings.setDatabasePath(dir);
//使用localStorage则必须打开
webSettings.setDomStorageEnabled(true);
//扩充数据库的容量(在WebChromeClinet中实现)
public void onExceededDatabaseQuota(String url, String databaseIdentifier, long currentQuota,
long estimatedSize, long totalUsedQuota, WebStorage.QuotaUpdater quotaUpdater) {
quotaUpdater.updateQuota(estimatedSize * 2);
}
在JS中按常规进行数据库操作
function initDatabase() {
try {
if (!window.openDatabase) {
alert('Databases are not supported by your browser');
} else {
var shortName = 'YARINDB';
var version = '1.0';
var displayName = 'yarin db';
var maxSize = 100000; // in bytes
YARINDB = openDatabase(shortName, version, displayName, maxSize);
createTables();
selectAll();
}
} catch(e) {
if (e == 2) {
// Version mismatch.
console.log("Invalid database version.");
} else {
console.log("Unknown error "+ e +".");
}
return;
}
}
function createTables(){
YARINDB.transaction(
function (transaction) {
transaction.executeSql('CREATE TABLE IF NOT EXISTS yarin(id INTEGER NOT NULL PRIMARY KEY, name TEXT NOT NULL,desc TEXT NOT NULL);', [], nullDataHandler, errorHandler);
}
);
insertData();
}
function insertData(){
YARINDB.transaction(
function (transaction) {
//Starter data when page is initialized
var data = ['1','yarin yang','I am yarin'];
transaction.executeSql("INSERT INTO yarin(id, name, desc) VALUES (?, ?, ?)", [data[0], data[1], data[2]]);
}
);
}
function errorHandler(transaction, error){
if (error.code==1){
// DB Table already exists
} else {
// Error is a human-readable string.
console.log('Oops. Error was '+error.message+' (Code '+error.code+')');
}
return false;
}
function nullDataHandler(){
console.log("SQL Query Succeeded");
}
function selectAll(){
YARINDB.transaction(
function (transaction) {
transaction.executeSql("SELECT * FROM yarin;", [], dataSelectHandler, errorHandler);
}
);
}
function dataSelectHandler(transaction, results){
// Handle the results
for (var i=0; iresults.rows.length; i++) {
var row = results.rows.item(i);
var newFeature = new Object();
newFeature.name = row['name'];
newFeature.decs = row['desc'];
document.getElementByIdx_x_x_x("name").innerHTML="name:"+newFeature.name;
document.getElementByIdx_x_x_x("desc").innerHTML="desc:"+newFeature.decs;
}
}
function updateData(){
YARINDB.transaction(
function (transaction) {
var data = ['fengsheng yang','I am fengsheng'];
transaction.executeSql("UPDATE yarin SET name=?, desc=? WHERE id = 1", [data[0], data[1]]);
}
);
selectAll();
}
function ddeleteTables(){
YARINDB.transaction(
function (transaction) {
transaction.executeSql("DROP TABLE yarin;", [], nullDataHandler, errorHandler);
}
);
console.log("Table 'page_settings' has been dropped.");
}
注意onLoad中的初始化工作
function initLocalStorage(){
if (window.localStorage) {
textarea.addEventListener("keyup", function() {
window.localStorage["value"] = this.value;
window.localStorage["time"] = new Date().getTime();
}, false);
} else {
alert("LocalStorage are not supported in this browser.");
}
}
window.onload = function() {
initDatabase();
initLocalStorage();
}
● HTML5地理位置服务在Android中的应用
//启用地理定位
webSettings.setGeolocationEnabled(true);
//设置定位的数据库路径
webSettings.setGeolocationDatabasePath(dir);
//配置权限(同样在WebChromeClient中实现)
public void onGeolocationPermissionsShowPrompt(String origin,
GeolocationPermissions.Callback callback) {
callback.invoke(origin, true, false);
super.onGeolocationPermissionsShowPrompt(origin, callback);
}
HTML5中 通过navigator.geolocation对象获取地理位置信息
常用的navigator.geolocation对象有以下三种方法:
Js代码
//获取当前地理位置
navigator.geolocation.getCurrentPosition(success_callback_function, error_callback_function, position_options)
//持续获取地理位置
navigator.geolocation.watchPosition(success_callback_function, error_callback_function, position_options)
//清除持续获取地理位置事件
navigator.geolocation.clearWatch(watch_position_id)
其中success_callback_function为成功之后处理的函数,error_callback_function为失败之后返回的处理函数,参数position_options是配置项
//定位
function get_location() {
if (navigator.geolocation) {
navigator.geolocation.getCurrentPosition(show_map,handle_error,{enableHighAccuracy:false,maximumAge:1000,timeout:15000});
} else {
alert("Your browser does not support HTML5 geoLocation");
}
}
工具/原料
MyEclipse2014
Android SDK
eclipse
java开发环境
方法/步骤
下载安装MyEclipse2014,Android SDK,eclipse(需配置Android开发环境)
Java和Android环境安装与配置,将另写经验分享,读者也可百度参考其他相关资料,自行安装
打开MyEclipse2014,新建一个HTML5 Mobile Application Project,命名,例如:hello
html5程序在工程www目录下编辑;
编辑好我们的html5程序,下面就要开始学习打包了
这里介绍两种打包方式:1、PhoneGap Build Service 打包
PhoneGap官网有相关教程可参考,不具体介绍
2、android SDK +eclispe 打包
android SDK +eclispe 打包(前提已配置好,android开发环境):
Step1、启动eclipse,新建Android Application Project,即Android工程,命名,例如:hello
Step2、将前面Myeclipse2014中编辑好的HTML5程序(www整个目录)拷至刚刚在eclipse新建hello工程对应assets目录下面
Step3、下面要做的就是如何将我们的HTML5程序在Android应用中启动,这里我们要使用Android系统自带的WebView控件(具体信息参考Adroid开发文档)---在工程下找到res-layout-activity_main.xml并打开,向里面插入WebView控件,编辑好自己想要的样式
Step4、在主程序入口,用刚刚编辑好的WebView控件将HTML5程序引入,此时,主体功能已实现,编译工程即可得到apk
Android浏览器默认预览模式浏览 会缩小页面 WebView中则会以原始大小显示
Android浏览器和WebView默认为mdpi。hdpi相当于mdpi的1.5倍 ldpi相当于0.75倍
三种解决方式:1 viewport属性 2 CSS控制 3 JS控制
1 viewport属性放在HTML的meta中
Html代码
SPAN style="FONT-SIZE: x-small" head
titleExmaple/title
meta name=”viewport” content=”width=device-width,user-scalable=no”/
/head/SPAN
meta中viewport的属性如下
Html代码
SPAN style="FONT-SIZE: x-small" meta name="viewport"
content="
height = [pixel_value | device-height] ,
width = [pixel_value | device-width ] ,
initial-scale = float_value ,
minimum-scale = float_value ,
maximum-scale = float_value ,
user-scalable = [yes | no] ,
target-densitydpi = [dpi_value | device-dpi |
high-dpi | medium-dpi | low-dpi]
"
//SPAN
2 CSS控制设备密度
为每种密度创建独立的样式表(注意其中的webkit-device-pixel-ratio 3个数值对应3种分辨率)
Html代码
link rel="stylesheet" media="screen and (-webkit-device-pixel-ratio: 1.5)" href="hdpi.css" /
link rel="stylesheet" media="screen and (-webkit-device-pixel-ratio: 1.0)" href="mdpi.css" /
link rel="stylesheet" media="screen and (-webkit-device-pixel-ratio: 0.75)" href="ldpi.css" /
在一个样式表中,指定不同的样式
Html代码
#header {
SPAN style="WHITE-SPACE: pre" /SPAN background:url(medium-density-image.png);
}
@media screen and (-webkit-device-pixel-ratio: 1.5) {
// CSS for high-density screens
#header {
background:url(high-density-image.png);
}
}
@media screen and (-webkit-device-pixel-ratio: 0.75) {
// CSS for low-density screens
#header {
background:url(low-density-image.png);
}
}
Html代码
meta name="viewport" content="target-densitydpi=device-dpi, width=device-width" /
3 JS控制
Android浏览器和WebView支持查询当前设别密度的DOM特性
window.devicePixelRatio 同样值有3个(0.75,1,1.5对应3种分辨率)
JS中查询设备密度的方法
Js代码
if (window.devicePixelRatio == 1.5) {
alert("This is a high-density screen");
} else if (window.devicePixelRation == 0.75) {
alert("This is a low-density screen");
}
● Android中构建HTML5应用
使用WebView控件 与其他控件的使用方法相同 在layout中使用一个WebView标签
WebView不包括导航栏,地址栏等完整浏览器功能,只用于显示一个网页
在WebView中加载Web页面,使用loadUrl()
Java代码
WebView myWebView = (WebView) findViewById(R.id.webview);
myWebView.loadUrl("");
注意在manifest文件中加入访问互联网的权限:
Xml代码
uses-permission android:name="android.permission.INTERNET" /
在Android中点击一个链接,默认是调用应用程序来启动,因此WebView需要代为处理这个动作 通过WebViewClient
Java代码
//设置WebViewClient
webView.setWebViewClient(new WebViewClient(){
public boolean shouldOverrideUrlLoading(WebView view, String url) {
view.loadUrl(url);
return true;
}
public void onPageFinished(WebView view, String url) {
super.onPageFinished(view, url);
}
public void onPageStarted(WebView view, String url, Bitmap favicon) {
super.onPageStarted(view, url, favicon);
}
});
这个WebViewClient对象是可以自己扩展的,例如
Java代码
private class MyWebViewClient extends WebViewClient {
public boolean shouldOverrideUrlLoading(WebView view, String url) {
if (Uri.parse(url).getHost().equals("")) {
return false;
}
Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(url));
startActivity(intent);
return true;
}
}
之后:
Java代码
WebView myWebView = (WebView) findViewById(R.id.webview);
myWebView.setWebViewClient(new MyWebViewClient());
另外出于用户习惯上的考虑 需要将WebView表现得更像一个浏览器,也就是需要可以回退历史记录
因此需要覆盖系统的回退键 goBack,goForward可向前向后浏览历史页面
Java代码
public boolean onKeyDown(int keyCode, KeyEvent event) {
if ((keyCode == KeyEvent.KEYCODE_BACK) myWebView.canGoBack() {
myWebView.goBack();
return true;
}
return super.onKeyDown(keyCode, event);
}
Java代码
WebView myWebView = (WebView) findViewById(R.id.webview);
WebSettings webSettings = myWebView.getSettings();
webSettings.setJavaScriptEnabled(true);