引用: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. pandaboard ES学习之旅——4 Android源代码下载与编译
  2. Android中设置动画循环旋转的方法
  3. 向模拟器发短信打电话的方法
  4. android手机屏幕适配方法
  5. android百度地图标记点代码
  6. 更新android studio gradle 不成功解决方法
  7. Android使用代码模拟HOME键的功能

随机推荐

  1. 【流媒體】Android 实时视频采集/编码/传
  2. Android 之 退出的2种方式
  3. Android中的Surface和SurfaceView
  4. AsyncTask的使用方法(异步任务的处理)
  5. Android的 getSystemService
  6. Android(安卓)Camera HAL3 - MultiCamera
  7. js将一个数组传给android
  8. Android中设计具有背景图的按钮—ImageBu
  9. 【Android】adb常用指令整理
  10. Android SDK 中文 (56) ―― ViewFlipper