引用: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代码
  1. <SPANstyle="FONT-SIZE:x-small"><head>
  2. <title>Exmaple</title>
  3. <metaname=”viewport”content=”width=device-width,user-scalable=no/>
  4. </head></SPAN>

meta中viewport的属性如下

Html代码
  1. <SPANstyle="FONT-SIZE:x-small"><metaname="viewport"
  2. content="
  3. height=[pixel_value|device-height],
  4. width=[pixel_value|device-width],
  5. initial-scale=float_value,
  6. minimum-scale=float_value,
  7. maximum-scale=float_value,
  8. user-scalable=[yes|no],
  9. target-densitydpi=[dpi_value|device-dpi|
  10. high-dpi|medium-dpi|low-dpi]
  11. "
  12. /></SPAN>

2 CSS控制设备密度

为每种密度创建独立的样式表(注意其中的webkit-device-pixel-ratio3个数值对应3种分辨率)

Html代码
  1. <linkrel="stylesheet"media="screenand(-webkit-device-pixel-ratio:1.5)"href="hdpi.css"/>
  2. <linkrel="stylesheet"media="screenand(-webkit-device-pixel-ratio:1.0)"href="mdpi.css"/>
  3. <linkrel="stylesheet"media="screenand(-webkit-device-pixel-ratio:0.75)"href="ldpi.css"/>

在一个样式表中,指定不同的样式

Html代码
  1. #header{
  2. <SPANstyle="WHITE-SPACE:pre"></SPAN>background:url(medium-density-image.png);
  3. }
  4. @mediascreenand(-webkit-device-pixel-ratio:1.5){
  5. //CSSforhigh-densityscreens
  6. #header{
  7. background:url(high-density-image.png);
  8. }
  9. }
  10. @mediascreenand(-webkit-device-pixel-ratio:0.75){
  11. //CSSforlow-densityscreens
  12. #header{
  13. background:url(low-density-image.png);
  14. }
  15. }

Html代码
  1. <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代码
  1. if(window.devicePixelRatio==1.5){
  2. alert("Thisisahigh-densityscreen");
  3. }elseif(window.devicePixelRation==0.75){
  4. alert("Thisisalow-densityscreen");
  5. }

● Android中构建HTML5应用

使用WebView控件 与其他控件的使用方法相同 在layout中使用一个<WebView>标签

WebView不包括导航栏,地址栏等完整浏览器功能,只用于显示一个网页

在WebView中加载Web页面,使用loadUrl()

Java代码
  1. WebViewmyWebView=(WebView)findViewById(R.id.webview);
  2. myWebView.loadUrl("http://www.example.com");

注意在manifest文件中加入访问互联网的权限:

Xml代码
  1. <uses-permissionandroid:name="android.permission.INTERNET"/>

在Android中点击一个链接,默认是调用应用程序来启动,因此WebView需要代为处理这个动作通过WebViewClient

Java代码
  1. //设置WebViewClient
  2. webView.setWebViewClient(newWebViewClient(){
  3. publicbooleanshouldOverrideUrlLoading(WebViewview,Stringurl){
  4. view.loadUrl(url);
  5. returntrue;
  6. }
  7. publicvoidonPageFinished(WebViewview,Stringurl){
  8. super.onPageFinished(view,url);
  9. }
  10. publicvoidonPageStarted(WebViewview,Stringurl,Bitmapfavicon){
  11. super.onPageStarted(view,url,favicon);
  12. }
  13. });

这个WebViewClient对象是可以自己扩展的,例如

Java代码
  1. privateclassMyWebViewClientextendsWebViewClient{
  2. publicbooleanshouldOverrideUrlLoading(WebViewview,Stringurl){
  3. if(Uri.parse(url).getHost().equals("www.example.com")){
  4. returnfalse;
  5. }
  6. Intentintent=newIntent(Intent.ACTION_VIEW,Uri.parse(url));
  7. startActivity(intent);
  8. returntrue;
  9. }
  10. }

之后:

Java代码
  1. WebViewmyWebView=(WebView)findViewById(R.id.webview);
  2. myWebView.setWebViewClient(newMyWebViewClient());

另外出于用户习惯上的考虑 需要将WebView表现得更像一个浏览器,也就是需要可以回退历史记录

因此需要覆盖系统的回退键goBack,goForward可向前向后浏览历史页面

Java代码
  1. publicbooleanonKeyDown(intkeyCode,KeyEventevent){
  2. if((keyCode==KeyEvent.KEYCODE_BACK)&&myWebView.canGoBack(){
  3. myWebView.goBack();
  4. returntrue;
  5. }
  6. returnsuper.onKeyDown(keyCode,event);
  7. }
Java代码
  1. WebViewmyWebView=(WebView)findViewById(R.id.webview);
  2. WebSettingswebSettings=myWebView.getSettings();
  3. webSettings.setJavaScriptEnabled(true);


(这里的webSetting用处非常大 可以开启很多设置 在之后的本地存储,地理位置等之中都会使用到)

1 在JS中调用Android的函数方法

首先 需要在Android程序中建立接口
Java代码
  1. finalclassInJavaScript{
  2. publicvoidrunOnAndroidJavaScript(finalStringstr){
  3. handler.post(newRunnable(){
  4. publicvoidrun(){
  5. TextViewshow=(TextView)findViewById(R.id.textview);
  6. show.setText(str);
  7. }
  8. });
  9. }
  10. }


Java代码
  1. //把本类的一个实例添加到js的全局对象window中,
  2. //这样就可以使用windows.injs来调用它的方法
  3. webView.addJavascriptInterface(newInJavaScript(),"injs");


在JavaScript中调用
Js代码
  1. functionsendToAndroid(){
  2. varstr="CookiecalltheAndroidmethodfromjs";
  3. windows.injs.runOnAndroidJavaScript(str);//调用android的函数
  4. }

2 在Android中调用JS的方法

JS中的方法
Js代码
  1. functiongetFromAndroid(str){
  2. document.getElementByIdx_x_x_x("android").innerHTML=str;
  3. }

Android调用该方法
Java代码
  1. Buttonbutton=(Button)findViewById(R.id.button);
  2. button.setOnClickListener(newOnClickListener(){
  3. publicvoidonClick(Viewarg0){
  4. //调用javascript中的方法
  5. webView.loadUrl("javascript:getFromAndroid('CookiecallthejsfunctionfromAndroid')");
  6. }
  7. });

3 Android中处理JS的警告,对话框等
在Android中处理JS的警告,对话框等需要对WebView设置WebChromeClient对象
Java代码
  1. //设置WebChromeClient
  2. webView.setWebChromeClient(newWebChromeClient(){
  3. //处理javascript中的alert
  4. publicbooleanonJsAlert(WebViewview,Stringurl,Stringmessage,finalJsResultresult){
  5. //构建一个Builder来显示网页中的对话框
  6. Builderbuilder=newBuilder(MainActivity.this);
  7. builder.setTitle("Alert");
  8. builder.setMessage(message);
  9. builder.setPositiveButton(android.R.string.ok,
  10. newAlertDialog.OnClickListener(){
  11. publicvoidonClick(DialogInterfacedialog,intwhich){
  12. result.confirm();
  13. }
  14. });
  15. builder.setCancelable(false);
  16. builder.create();
  17. builder.show();
  18. returntrue;
  19. };
  20. //处理javascript中的confirm
  21. publicbooleanonJsConfirm(WebViewview,Stringurl,Stringmessage,finalJsResultresult){
  22. Builderbuilder=newBuilder(MainActivity.this);
  23. builder.setTitle("confirm");
  24. builder.setMessage(message);
  25. builder.setPositiveButton(android.R.string.ok,
  26. newAlertDialog.OnClickListener(){
  27. publicvoidonClick(DialogInterfacedialog,intwhich){
  28. result.confirm();
  29. }
  30. });
  31. builder.setNegativeButton(android.R.string.cancel,
  32. newDialogInterface.OnClickListener(){
  33. publicvoidonClick(DialogInterfacedialog,intwhich){
  34. result.cancel();
  35. }
  36. });
  37. builder.setCancelable(false);
  38. builder.create();
  39. builder.show();
  40. returntrue;
  41. };
  42. @Override
  43. //设置网页加载的进度条
  44. publicvoidonProgressChanged(WebViewview,intnewProgress){
  45. MainActivity.this.getWindow().setFeatureInt(Window.FEATURE_PROGRESS,newProgress*100);
  46. super.onProgressChanged(view,newProgress);
  47. }
  48. //设置应用程序的标题title
  49. publicvoidonReceivedTitle(WebViewview,Stringtitle){
  50. MainActivity.this.setTitle(title);
  51. super.onReceivedTitle(view,title);
  52. }
  53. });

● Android中的调试
通过JS代码输出log信息
Js代码
  1. Js代码:console.log("HelloWorld");
  2. Log信息:Console:HelloWorldhttp://www.example.com/hello.html:82

在WebChromeClient中实现onConsoleMesaage()回调方法,让其在LogCat中打印信息
Java代码
  1. WebViewmyWebView=(WebView)findViewById(R.id.webview);
  2. myWebView.setWebChromeClient(newWebChromeClient(){
  3. publicvoidonConsoleMessage(Stringmessage,intlineNumber,StringsourceID){
  4. Log.d("MyApplication",message+"--Fromline"
  5. +lineNumber+"of"
  6. +sourceID);
  7. }
  8. });

以及
Java代码
  1. WebViewmyWebView=(WebView)findViewById(R.id.webview);
  2. myWebView.setWebChromeClient(newWebChromeClient(){
  3. publicbooleanonConsoleMessage(ConsoleMessagecm){
  4. Log.d("MyApplication",cm.message()+"--Fromline"
  5. +cm.lineNumber()+"of"
  6. +cm.sourceId());
  7. returntrue;
  8. }
  9. });

*ConsoleMessage 还包括一个 MessageLevel 表示控制台传递信息类型。 您可以用messageLevel()查询信息级别,以确定信息的严重程度,然后使用适当的Log方法或采取其他适当的措施。

● HTML5本地存储在Android中的应用
HTML5提供了2种客户端存储数据新方法
localStorage 没有时间限制
sessionStorage 针对一个Session的数据存储
Js代码
  1. <scripttype="text/javascript">
  2. localStorage.lastname="Smith";
  3. document.write(localStorage.lastname);
  4. </script>
  5. <scripttype="text/javascript">
  6. sessionStorage.lastname="Smith";
  7. document.write(sessionStorage.lastname);
  8. </script>


WebStorage的API:
Js代码
  1. //清空storage
  2. localStorage.clear();
  3. //设置一个键值
  4. localStorage.setItem(“yarin”,“yangfegnsheng”);
  5. //获取一个键值
  6. localStorage.getItem(“yarin”);
  7. //获取指定下标的键的名称(如同Array)
  8. localStorage.key(0);
  9. //return“fresh”//删除一个键值
  10. localStorage.removeItem(“yarin”);
  11. 注意一定要在设置中开启哦
  12. setDomStorageEnabled(true


Android中进行操作
Java代码
  1. //启用数据库
  2. webSettings.setDatabaseEnabled(true);
  3. Stringdir=this.getApplicationContext().getDir("database",Context.MODE_PRIVATE).getPath();
  4. //设置数据库路径
  5. webSettings.setDatabasePath(dir);
  6. //使用localStorage则必须打开
  7. webSettings.setDomStorageEnabled(true);
  8. //扩充数据库的容量(在WebChromeClinet中实现)
  9. publicvoidonExceededDatabaseQuota(Stringurl,StringdatabaseIdentifier,longcurrentQuota,
  10. longestimatedSize,longtotalUsedQuota,WebStorage.QuotaUpdaterquotaUpdater){
  11. quotaUpdater.updateQuota(estimatedSize*2);
  12. }



JS中按常规进行数据库操作
Js代码
  1. functioninitDatabase(){
  2. try{
  3. if(!window.openDatabase){
  4. alert('Databasesarenotsupportedbyyourbrowser');
  5. }else{
  6. varshortName='YARINDB';
  7. varversion='1.0';
  8. vardisplayName='yarindb';
  9. varmaxSize=100000;//inbytes
  10. YARINDB=openDatabase(shortName,version,displayName,maxSize);
  11. createTables();
  12. selectAll();
  13. }
  14. }catch(e){
  15. if(e==2){
  16. //Versionmismatch.
  17. console.log("Invaliddatabaseversion.");
  18. }else{
  19. console.log("Unknownerror"+e+".");
  20. }
  21. return;
  22. }
  23. }
  24. functioncreateTables(){
  25. YARINDB.transaction(
  26. function(transaction){
  27. transaction.executeSql('CREATETABLEIFNOTEXISTSyarin(idINTEGERNOTNULLPRIMARYKEY,nameTEXTNOTNULL,descTEXTNOTNULL);',[],nullDataHandler,errorHandler);
  28. }
  29. );
  30. insertData();
  31. }
  32. functioninsertData(){
  33. YARINDB.transaction(
  34. function(transaction){
  35. //Starterdatawhenpageisinitialized
  36. vardata=['1','yarinyang','Iamyarin'];
  37. transaction.executeSql("INSERTINTOyarin(id,name,desc)VALUES(?,?,?)",[data[0],data[1],data[2]]);
  38. }
  39. );
  40. }
  41. functionerrorHandler(transaction,error){
  42. if(error.code==1){
  43. //DBTablealreadyexists
  44. }else{
  45. //Errorisahuman-readablestring.
  46. console.log('Oops.Errorwas'+error.message+'(Code'+error.code+')');
  47. }
  48. returnfalse;
  49. }
  50. functionnullDataHandler(){
  51. console.log("SQLQuerySucceeded");
  52. }
  53. functionselectAll(){
  54. YARINDB.transaction(
  55. function(transaction){
  56. transaction.executeSql("SELECT*FROMyarin;",[],dataSelectHandler,errorHandler);
  57. }
  58. );
  59. }
  60. functiondataSelectHandler(transaction,results){
  61. //Handletheresults
  62. for(vari=0;i<results.rows.length;i++){
  63. varrow=results.rows.item(i);
  64. varnewFeature=newObject();
  65. newFeature.name=row['name'];
  66. newFeature.decs=row['desc'];
  67. document.getElementByIdx_x_x_x("name").innerHTML="name:"+newFeature.name;
  68. document.getElementByIdx_x_x_x("desc").innerHTML="desc:"+newFeature.decs;
  69. }
  70. }
  71. functionupdateData(){
  72. YARINDB.transaction(
  73. function(transaction){
  74. vardata=['fengshengyang','Iamfengsheng'];
  75. transaction.executeSql("UPDATEyarinSETname=?,desc=?WHEREid=1",[data[0],data[1]]);
  76. }
  77. );
  78. selectAll();
  79. }
  80. functionddeleteTables(){
  81. YARINDB.transaction(
  82. function(transaction){
  83. transaction.executeSql("DROPTABLEyarin;",[],nullDataHandler,errorHandler);
  84. }
  85. );
  86. console.log("Table'page_settings'hasbeendropped.");
  87. }
  88. 注意onLoad中的初始化工作
  89. functioninitLocalStorage(){
  90. if(window.localStorage){
  91. textarea.addEventListener("keyup",function(){
  92. window.localStorage["value"]=this.value;
  93. window.localStorage["time"]=newDate().getTime();
  94. },false);
  95. }else{
  96. alert("LocalStoragearenotsupportedinthisbrowser.");
  97. }
  98. }
  99. window.onload=function(){
  100. initDatabase();
  101. initLocalStorage();
  102. }




● HTML5地理位置服务在Android中的应用
Android中
Java代码
  1. //启用地理定位
  2. webSettings.setGeolocationEnabled(true);
  3. //设置定位的数据库路径
  4. webSettings.setGeolocationDatabasePath(dir);
  5. //配置权限(同样在WebChromeClient中实现)
  6. publicvoidonGeolocationPermissionsShowPrompt(Stringorigin,
  7. GeolocationPermissions.Callbackcallback){
  8. callback.invoke(origin,true,false);
  9. super.onGeolocationPermissionsShowPrompt(origin,callback);
  10. }



在Manifest中添加权限
Xml代码
  1. <uses-permissionandroid:name="android.permission.ACCESS_FINE_LOCATION"/>
  2. <uses-permissionandroid:name="android.permission.ACCESS_COARSE_LOCATION"/>



HTML5中通过navigator.geolocation对象获取地理位置信息
常用的navigator.geolocation对象有以下三种方法:
Js代码
  1. //获取当前地理位置
  2. navigator.geolocation.getCurrentPosition(success_callback_function,error_callback_function,position_options)
  3. //持续获取地理位置
  4. navigator.geolocation.watchPosition(success_callback_function,error_callback_function,position_options)
  5. //清除持续获取地理位置事件
  6. navigator.geolocation.clearWatch(watch_position_id)


其中success_callback_function为成功之后处理的函数,error_callback_function为失败之后返回的处理函数,参数position_options是配置项

JS中的代码
Js代码
  1. //定位
  2. functionget_location(){
  3. if(navigator.geolocation){
  4. navigator.geolocation.getCurrentPosition(show_map,handle_error,{enableHighAccuracy:false,maximumAge:1000,timeout:15000});
  5. }else{
  6. alert("YourbrowserdoesnotsupportHTML5geoLocation");
  7. }
  8. }
  9. functionshow_map(position){
  10. varlatitude=position.coords.latitude;
  11. varlongitude=position.coords.longitude;
  12. varcity=position.coords.city;
  13. //telnetlocalhost5554
  14. //geofix-82.41162928.054553
  15. //geofix-121.4535646.511194392
  16. //geonmea$GPGGA,001431.092,0118.2653,N,10351.1359,E,0,00,,-19.6,M,4.1,M,,0000*5B
  17. document.getElementByIdx_x_x_x("Latitude").innerHTML="latitude:"+latitude;
  18. document.getElementByIdx_x_x_x("Longitude").innerHTML="longitude:"+longitude;
  19. document.getElementByIdx_x_x_x("City").innerHTML="city:"+city;
  20. }
  21. functionhandle_error(err){
  22. switch(err.code){
  23. case1:
  24. alert("permissiondenied");
  25. break;
  26. case2:
  27. alert("thenetworkisdownorthepositionsatellitescan'tbecontacted");
  28. break;
  29. case3:
  30. alert("timeout");
  31. break;
  32. default:
  33. alert("unknownerror");
  34. break;
  35. }
  36. }


其中position对象包含很多数据 error代码及选项 可以查看文档

● 构建HTML5离线应用
需要提供一个cache manifest文件,理出所有需要在离线状态下使用的资源
例如
Manifest代码
  1. CACHEMANIFEST
  2. #这是注释
  3. images/sound-icon.png
  4. images/background.png
  5. clock.html
  6. clock.css
  7. clock.js
  8. NETWORK:
  9. test.cgi
  10. CACHE:
  11. style/default.css
  12. FALLBACK:
  13. /files/projects/projects


在html标签中声明<html manifest="clock.manifest">

HTML5离线应用更新缓存机制
分为手动更新和自动更新2种
自动更新:
在cache manifest文件本身发生变化时更新缓存 资源文件发生变化不会触发更新
手动更新:
使用window.applicationCache
Js代码
  1. if(window.applicationCache.status==window.applicationCache.UPDATEREADY){
  2. window.applicationCache.update();

在线状态检测
HTML5 提供了两种检测是否在线的方式:navigator.online(true/false)online/offline事件。

在Android中构建离线应用
Java代码
  1. //开启应用程序缓存
  2. webSettingssetAppCacheEnabled(true);
  3. Stringdir=this.getApplicationContext().getDir("cache",Context.MODE_PRIVATE).getPath();
  4. //设置应用缓存的路径
  5. webSettings.setAppCachePath(dir);
  6. //设置缓存的模式
  7. webSettings.setCacheMode(WebSettings.LOAD_DEFAULT);
  8. //设置应用缓存的最大尺寸
  9. webSettings.setAppCacheMaxSize(1024*1024*8);
  10. //扩充缓存的容量
  11. publicvoidonReachedMaxAppCacheSize(longspaceNeeded,
  12. longtotalUsedQuota,WebStorage.QuotaUpdaterquotaUpdater){
  13. quotaUpdater.updateQuota(spaceNeeded*2);
  14. }

更多相关文章

  1. Android(安卓)滚动条属性
  2. EditText使用小结
  3. android EditText 全面阐述
  4. Android(安卓)EditText 属性汇总
  5. 在Eclipse中导入android sdk源码
  6. android Textview属性细节以及EditText属性
  7. 跟着做 Android(安卓)NDK学习入门如此简单(二)
  8. 在activity中调用Application 出现android java.lang.ClassCastE
  9. 设置TextView文字居中

随机推荐

  1. Android(安卓)事件处理
  2. Android(安卓)AsyncTask解析
  3. android日志分析与记录.
  4. 理解Android的菜单
  5. Android高手进阶教程(四)之----Android(
  6. .net程序员转战android第二篇---牛刀小试
  7. Android(安卓)NFS文件系统挂载遇到的问题
  8. Android应用程序启动过程源代码分析(1)
  9. android读取keystore证书文件
  10. 分析脚本文件AndroidInitProcess分析心得