html5 开发android
引用:http://www.cnblogs.com/qianru/archive/2012/02/27/2369526.html
● Android设备多分辨率的问题
Android浏览器默认预览模式浏览 会缩小页面WebView中则会以原始大小显示
Android浏览器和WebView默认为mdpi。hdpi相当于mdpi的1.5倍ldpi相当于0.75倍
三种解决方式:1 viewport属性 2 CSS控制 3 JS控制
1 viewport属性放在HTML的<meta>中
Html代码- <SPANstyle="FONT-SIZE:x-small"><head>
- <title>Exmaple</title>
- <metaname=”viewport”content=”width=device-width,user-scalable=no”/>
- </head></SPAN>
meta中viewport的属性如下
Html代码- <SPANstyle="FONT-SIZE:x-small"><metaname="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-ratio3个数值对应3种分辨率)
Html代码- <linkrel="stylesheet"media="screenand(-webkit-device-pixel-ratio:1.5)"href="hdpi.css"/>
- <linkrel="stylesheet"media="screenand(-webkit-device-pixel-ratio:1.0)"href="mdpi.css"/>
- <linkrel="stylesheet"media="screenand(-webkit-device-pixel-ratio:0.75)"href="ldpi.css"/>
在一个样式表中,指定不同的样式
Html代码- #header{
- <SPANstyle="WHITE-SPACE:pre"></SPAN>background:url(medium-density-image.png);
- }
- @mediascreenand(-webkit-device-pixel-ratio:1.5){
- //CSSforhigh-densityscreens
- #header{
- background:url(high-density-image.png);
- }
- }
- @mediascreenand(-webkit-device-pixel-ratio:0.75){
- //CSSforlow-densityscreens
- #header{
- background:url(low-density-image.png);
- }
- }
Html代码
- <metaname="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("Thisisahigh-densityscreen");
- }elseif(window.devicePixelRation==0.75){
- alert("Thisisalow-densityscreen");
- }
● Android中构建HTML5应用
使用WebView控件 与其他控件的使用方法相同 在layout中使用一个<WebView>标签
WebView不包括导航栏,地址栏等完整浏览器功能,只用于显示一个网页
在WebView中加载Web页面,使用loadUrl()
Java代码- WebViewmyWebView=(WebView)findViewById(R.id.webview);
- myWebView.loadUrl("http://www.example.com");
注意在manifest文件中加入访问互联网的权限:
Xml代码- <uses-permissionandroid:name="android.permission.INTERNET"/>
在Android中点击一个链接,默认是调用应用程序来启动,因此WebView需要代为处理这个动作通过WebViewClient
Java代码- //设置WebViewClient
- webView.setWebViewClient(newWebViewClient(){
- publicbooleanshouldOverrideUrlLoading(WebViewview,Stringurl){
- view.loadUrl(url);
- returntrue;
- }
- publicvoidonPageFinished(WebViewview,Stringurl){
- super.onPageFinished(view,url);
- }
- publicvoidonPageStarted(WebViewview,Stringurl,Bitmapfavicon){
- super.onPageStarted(view,url,favicon);
- }
- });
这个WebViewClient对象是可以自己扩展的,例如
Java代码- privateclassMyWebViewClientextendsWebViewClient{
- publicbooleanshouldOverrideUrlLoading(WebViewview,Stringurl){
- if(Uri.parse(url).getHost().equals("www.example.com")){
- returnfalse;
- }
- Intentintent=newIntent(Intent.ACTION_VIEW,Uri.parse(url));
- startActivity(intent);
- returntrue;
- }
- }
之后:
Java代码- WebViewmyWebView=(WebView)findViewById(R.id.webview);
- myWebView.setWebViewClient(newMyWebViewClient());
另外出于用户习惯上的考虑 需要将WebView表现得更像一个浏览器,也就是需要可以回退历史记录
因此需要覆盖系统的回退键goBack,goForward可向前向后浏览历史页面
Java代码- publicbooleanonKeyDown(intkeyCode,KeyEventevent){
- if((keyCode==KeyEvent.KEYCODE_BACK)&&myWebView.canGoBack(){
- myWebView.goBack();
- returntrue;
- }
- returnsuper.onKeyDown(keyCode,event);
- }
- WebViewmyWebView=(WebView)findViewById(R.id.webview);
- WebSettingswebSettings=myWebView.getSettings();
- webSettings.setJavaScriptEnabled(true);
Java代码
(这里的webSetting用处非常大 可以开启很多设置 在之后的本地存储,地理位置等之中都会使用到)
1 在JS中调用Android的函数方法
首先 需要在Android程序中建立接口
- finalclassInJavaScript{
- publicvoidrunOnAndroidJavaScript(finalStringstr){
- handler.post(newRunnable(){
- publicvoidrun(){
- TextViewshow=(TextView)findViewById(R.id.textview);
- show.setText(str);
- }
- });
- }
- }
Java代码
- //把本类的一个实例添加到js的全局对象window中,
- //这样就可以使用windows.injs来调用它的方法
- webView.addJavascriptInterface(newInJavaScript(),"injs");
Js代码
在JavaScript中调用
- functionsendToAndroid(){
- varstr="CookiecalltheAndroidmethodfromjs";
- windows.injs.runOnAndroidJavaScript(str);//调用android的函数
- }
Js代码
2 在Android中调用JS的方法
在JS中的方法:
- functiongetFromAndroid(str){
- document.getElementByIdx_x_x_x("android").innerHTML=str;
- }
Java代码
在Android调用该方法
- Buttonbutton=(Button)findViewById(R.id.button);
- button.setOnClickListener(newOnClickListener(){
- publicvoidonClick(Viewarg0){
- //调用javascript中的方法
- webView.loadUrl("javascript:getFromAndroid('CookiecallthejsfunctionfromAndroid')");
- }
- });
Java代码
3 Android中处理JS的警告,对话框等
在Android中处理JS的警告,对话框等需要对WebView设置WebChromeClient对象
- //设置WebChromeClient
- webView.setWebChromeClient(newWebChromeClient(){
- //处理javascript中的alert
- publicbooleanonJsAlert(WebViewview,Stringurl,Stringmessage,finalJsResultresult){
- //构建一个Builder来显示网页中的对话框
- Builderbuilder=newBuilder(MainActivity.this);
- builder.setTitle("Alert");
- builder.setMessage(message);
- builder.setPositiveButton(android.R.string.ok,
- newAlertDialog.OnClickListener(){
- publicvoidonClick(DialogInterfacedialog,intwhich){
- result.confirm();
- }
- });
- builder.setCancelable(false);
- builder.create();
- builder.show();
- returntrue;
- };
- //处理javascript中的confirm
- publicbooleanonJsConfirm(WebViewview,Stringurl,Stringmessage,finalJsResultresult){
- Builderbuilder=newBuilder(MainActivity.this);
- builder.setTitle("confirm");
- builder.setMessage(message);
- builder.setPositiveButton(android.R.string.ok,
- newAlertDialog.OnClickListener(){
- publicvoidonClick(DialogInterfacedialog,intwhich){
- result.confirm();
- }
- });
- builder.setNegativeButton(android.R.string.cancel,
- newDialogInterface.OnClickListener(){
- publicvoidonClick(DialogInterfacedialog,intwhich){
- result.cancel();
- }
- });
- builder.setCancelable(false);
- builder.create();
- builder.show();
- returntrue;
- };
- @Override
- //设置网页加载的进度条
- publicvoidonProgressChanged(WebViewview,intnewProgress){
- MainActivity.this.getWindow().setFeatureInt(Window.FEATURE_PROGRESS,newProgress*100);
- super.onProgressChanged(view,newProgress);
- }
- //设置应用程序的标题title
- publicvoidonReceivedTitle(WebViewview,Stringtitle){
- MainActivity.this.setTitle(title);
- super.onReceivedTitle(view,title);
- }
- });
Js代码
● Android中的调试
通过JS代码输出log信息
- Js代码:console.log("HelloWorld");
- Log信息:Console:HelloWorldhttp://www.example.com/hello.html:82
Java代码
在WebChromeClient中实现onConsoleMesaage()回调方法,让其在LogCat中打印信息
- WebViewmyWebView=(WebView)findViewById(R.id.webview);
- myWebView.setWebChromeClient(newWebChromeClient(){
- publicvoidonConsoleMessage(Stringmessage,intlineNumber,StringsourceID){
- Log.d("MyApplication",message+"--Fromline"
- +lineNumber+"of"
- +sourceID);
- }
- });
Java代码
以及
- WebViewmyWebView=(WebView)findViewById(R.id.webview);
- myWebView.setWebChromeClient(newWebChromeClient(){
- publicbooleanonConsoleMessage(ConsoleMessagecm){
- Log.d("MyApplication",cm.message()+"--Fromline"
- +cm.lineNumber()+"of"
- +cm.sourceId());
- returntrue;
- }
- });
Js代码
*ConsoleMessage 还包括一个 MessageLevel 表示控制台传递信息类型。 您可以用messageLevel()查询信息级别,以确定信息的严重程度,然后使用适当的Log方法或采取其他适当的措施。
● HTML5本地存储在Android中的应用
HTML5提供了2种客户端存储数据新方法:
localStorage 没有时间限制
sessionStorage 针对一个Session的数据存储
- <scripttype="text/javascript">
- localStorage.lastname="Smith";
- document.write(localStorage.lastname);
- </script>
- <scripttype="text/javascript">
- sessionStorage.lastname="Smith";
- document.write(sessionStorage.lastname);
- </script>
Js代码
WebStorage的API:
- //清空storage
- localStorage.clear();
- //设置一个键值
- localStorage.setItem(“yarin”,“yangfegnsheng”);
- //获取一个键值
- localStorage.getItem(“yarin”);
- //获取指定下标的键的名称(如同Array)
- localStorage.key(0);
- //return“fresh”//删除一个键值
- localStorage.removeItem(“yarin”);
- 注意一定要在设置中开启哦
- setDomStorageEnabled(true)
Java代码
在Android中进行操作
- //启用数据库
- webSettings.setDatabaseEnabled(true);
- Stringdir=this.getApplicationContext().getDir("database",Context.MODE_PRIVATE).getPath();
- //设置数据库路径
- webSettings.setDatabasePath(dir);
- //使用localStorage则必须打开
- webSettings.setDomStorageEnabled(true);
- //扩充数据库的容量(在WebChromeClinet中实现)
- publicvoidonExceededDatabaseQuota(Stringurl,StringdatabaseIdentifier,longcurrentQuota,
- longestimatedSize,longtotalUsedQuota,WebStorage.QuotaUpdaterquotaUpdater){
- quotaUpdater.updateQuota(estimatedSize*2);
- }
Js代码
在JS中按常规进行数据库操作
- functioninitDatabase(){
- try{
- if(!window.openDatabase){
- alert('Databasesarenotsupportedbyyourbrowser');
- }else{
- varshortName='YARINDB';
- varversion='1.0';
- vardisplayName='yarindb';
- varmaxSize=100000;//inbytes
- YARINDB=openDatabase(shortName,version,displayName,maxSize);
- createTables();
- selectAll();
- }
- }catch(e){
- if(e==2){
- //Versionmismatch.
- console.log("Invaliddatabaseversion.");
- }else{
- console.log("Unknownerror"+e+".");
- }
- return;
- }
- }
- functioncreateTables(){
- YARINDB.transaction(
- function(transaction){
- transaction.executeSql('CREATETABLEIFNOTEXISTSyarin(idINTEGERNOTNULLPRIMARYKEY,nameTEXTNOTNULL,descTEXTNOTNULL);',[],nullDataHandler,errorHandler);
- }
- );
- insertData();
- }
- functioninsertData(){
- YARINDB.transaction(
- function(transaction){
- //Starterdatawhenpageisinitialized
- vardata=['1','yarinyang','Iamyarin'];
- transaction.executeSql("INSERTINTOyarin(id,name,desc)VALUES(?,?,?)",[data[0],data[1],data[2]]);
- }
- );
- }
- functionerrorHandler(transaction,error){
- if(error.code==1){
- //DBTablealreadyexists
- }else{
- //Errorisahuman-readablestring.
- console.log('Oops.Errorwas'+error.message+'(Code'+error.code+')');
- }
- returnfalse;
- }
- functionnullDataHandler(){
- console.log("SQLQuerySucceeded");
- }
- functionselectAll(){
- YARINDB.transaction(
- function(transaction){
- transaction.executeSql("SELECT*FROMyarin;",[],dataSelectHandler,errorHandler);
- }
- );
- }
- functiondataSelectHandler(transaction,results){
- //Handletheresults
- for(vari=0;i<results.rows.length;i++){
- varrow=results.rows.item(i);
- varnewFeature=newObject();
- 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;
- }
- }
- functionupdateData(){
- YARINDB.transaction(
- function(transaction){
- vardata=['fengshengyang','Iamfengsheng'];
- transaction.executeSql("UPDATEyarinSETname=?,desc=?WHEREid=1",[data[0],data[1]]);
- }
- );
- selectAll();
- }
- functionddeleteTables(){
- YARINDB.transaction(
- function(transaction){
- transaction.executeSql("DROPTABLEyarin;",[],nullDataHandler,errorHandler);
- }
- );
- console.log("Table'page_settings'hasbeendropped.");
- }
- 注意onLoad中的初始化工作
- functioninitLocalStorage(){
- if(window.localStorage){
- textarea.addEventListener("keyup",function(){
- window.localStorage["value"]=this.value;
- window.localStorage["time"]=newDate().getTime();
- },false);
- }else{
- alert("LocalStoragearenotsupportedinthisbrowser.");
- }
- }
- window.onload=function(){
- initDatabase();
- initLocalStorage();
- }
Java代码
● HTML5地理位置服务在Android中的应用
Android中
- //启用地理定位
- webSettings.setGeolocationEnabled(true);
- //设置定位的数据库路径
- webSettings.setGeolocationDatabasePath(dir);
- //配置权限(同样在WebChromeClient中实现)
- publicvoidonGeolocationPermissionsShowPrompt(Stringorigin,
- GeolocationPermissions.Callbackcallback){
- callback.invoke(origin,true,false);
- super.onGeolocationPermissionsShowPrompt(origin,callback);
- }
Xml代码
在Manifest中添加权限
- <uses-permissionandroid:name="android.permission.ACCESS_FINE_LOCATION"/>
- <uses-permissionandroid:name="android.permission.ACCESS_COARSE_LOCATION"/>
Js代码
HTML5中通过navigator.geolocation对象获取地理位置信息
常用的navigator.geolocation对象有以下三种方法:
- //获取当前地理位置
- 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)
Js代码
其中success_callback_function为成功之后处理的函数,error_callback_function为失败之后返回的处理函数,参数position_options是配置项
在JS中的代码
- //定位
- functionget_location(){
- if(navigator.geolocation){
- navigator.geolocation.getCurrentPosition(show_map,handle_error,{enableHighAccuracy:false,maximumAge:1000,timeout:15000});
- }else{
- alert("YourbrowserdoesnotsupportHTML5geoLocation");
- }
- }
- functionshow_map(position){
- varlatitude=position.coords.latitude;
- varlongitude=position.coords.longitude;
- varcity=position.coords.city;
- //telnetlocalhost5554
- //geofix-82.41162928.054553
- //geofix-121.4535646.511194392
- //geonmea$GPGGA,001431.092,0118.2653,N,10351.1359,E,0,00,,-19.6,M,4.1,M,,0000*5B
- document.getElementByIdx_x_x_x("Latitude").innerHTML="latitude:"+latitude;
- document.getElementByIdx_x_x_x("Longitude").innerHTML="longitude:"+longitude;
- document.getElementByIdx_x_x_x("City").innerHTML="city:"+city;
- }
- functionhandle_error(err){
- switch(err.code){
- case1:
- alert("permissiondenied");
- break;
- case2:
- alert("thenetworkisdownorthepositionsatellitescan'tbecontacted");
- break;
- case3:
- alert("timeout");
- break;
- default:
- alert("unknownerror");
- break;
- }
- }
Manifest代码
其中position对象包含很多数据 error代码及选项 可以查看文档
● 构建HTML5离线应用
需要提供一个cache manifest文件,理出所有需要在离线状态下使用的资源
例如
- CACHEMANIFEST
- #这是注释
- images/sound-icon.png
- images/background.png
- clock.html
- clock.css
- clock.js
- NETWORK:
- test.cgi
- CACHE:
- style/default.css
- FALLBACK:
- /files/projects/projects
Js代码
在html标签中声明<html manifest="clock.manifest">
HTML5离线应用更新缓存机制
分为手动更新和自动更新2种
自动更新:
在cache manifest文件本身发生变化时更新缓存 资源文件发生变化不会触发更新
手动更新:
使用window.applicationCache
- if(window.applicationCache.status==window.applicationCache.UPDATEREADY){
- window.applicationCache.update();
- }
Java代码
在线状态检测
HTML5 提供了两种检测是否在线的方式:navigator.online(true/false)和online/offline事件。
在Android中构建离线应用
- //开启应用程序缓存
- webSettingssetAppCacheEnabled(true);
- Stringdir=this.getApplicationContext().getDir("cache",Context.MODE_PRIVATE).getPath();
- //设置应用缓存的路径
- webSettings.setAppCachePath(dir);
- //设置缓存的模式
- webSettings.setCacheMode(WebSettings.LOAD_DEFAULT);
- //设置应用缓存的最大尺寸
- webSettings.setAppCacheMaxSize(1024*1024*8);
- //扩充缓存的容量
- publicvoidonReachedMaxAppCacheSize(longspaceNeeded,
- longtotalUsedQuota,WebStorage.QuotaUpdaterquotaUpdater){
- quotaUpdater.updateQuota(spaceNeeded*2);
- }
更多相关文章
- Android(安卓)滚动条属性
- EditText使用小结
- android EditText 全面阐述
- Android(安卓)EditText 属性汇总
- 在Eclipse中导入android sdk源码
- android Textview属性细节以及EditText属性
- 跟着做 Android(安卓)NDK学习入门如此简单(二)
- 在activity中调用Application 出现android java.lang.ClassCastE
- 设置TextView文字居中