zoukankan      html  css  js  c++  java
  • 利用HTML5开发Android

    ● 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. <SPAN style="FONT-SIZE: x-small">   <head>    
    2.         <title>Exmaple</title>    
    3.         <meta name=”viewport” content=”width=device-width,user-scalable=no/>    
    4.     </head></SPAN>  

     

    meta中viewport的属性如下

    Html代码  
    1. <SPAN style="FONT-SIZE: x-small">   <meta name="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-ratio 3个数值对应3种分辨率)

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

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

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

     

    Html代码  
    1. <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代码 
    1. if (window.devicePixelRatio == 1.5) {   
    2.     alert("This is a high-density screen");   
    3. else if (window.devicePixelRation == 0.75) {   
    4.     alert("This is a low-density screen");   
    5. }  

     

    ● Android中构建HTML5应用

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

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

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

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

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

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

     

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

    Java代码  
    1. //设置WebViewClient   
    2. webView.setWebViewClient(new WebViewClient(){      
    3.     public boolean shouldOverrideUrlLoading(WebView view, String url) {      
    4.         view.loadUrl(url);      
    5.         return true;      
    6.     }     
    7.     public void onPageFinished(WebView view, String url) {   
    8.             super.onPageFinished(view, url);   
    9.     }   
    10.     public void onPageStarted(WebView view, String url, Bitmap favicon) {   
    11.         super.onPageStarted(view, url, favicon);   
    12.     }   
    13. });  

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

    Java代码  
    1. private class MyWebViewClient extends WebViewClient {   
    2.     public boolean shouldOverrideUrlLoading(WebView view, String url) {   
    3.         if (Uri.parse(url).getHost().equals("www.example.com")) {   
    4.             return false;   
    5.         }   
    6.         Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(url));   
    7.     startActivity(intent);   
    8.     return true;   
    9.     }   
    10. }  

     

    之后:

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

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

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

    Java代码  
    1. public boolean onKeyDown(int keyCode, KeyEvent event) {   
    2.     if ((keyCode == KeyEvent.KEYCODE_BACK) && myWebView.canGoBack() {   
    3.         myWebView.goBack();   
    4.         return true;   
    5.     }   
    6.     return super.onKeyDown(keyCode, event);   
    7. }  
    Java代码
    1. WebView myWebView = (WebView) findViewById(R.id.webview);   
    2. WebSettings webSettings = myWebView.getSettings();   
    3. webSettings.setJavaScriptEnabled(true);  

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

    1 在JS中调用Android的函数方法
     
    首先 需要在Android程序中建立接口
     
    Java代码
    1. final class InJavaScript {   
    2.        public void runOnAndroidJavaScript(final String str) {   
    3.         handler.post(new Runnable() {   
    4.                public void run() {    
    5.                    TextView show = (TextView) findViewById(R.id.textview);   
    6.                    show.setText(str);   
    7.                }   
    8.            });   
    9.        }   
    10.    }  
      
     
     
    Java代码
    1. //把本类的一个实例添加到js的全局对象window中,   
    2. //这样就可以使用windows.injs来调用它的方法   
    3. webView.addJavascriptInterface(new InJavaScript(), "injs");  

     
    在JavaScript中调用
    Js代码
    1. function sendToAndroid(){   
    2.         var str = "Cookie call the Android method from js";   
    3.         windows.injs.runOnAndroidJavaScript(str);//调用android的函数   
    4. }   
      
    2 在Android中调用JS的方法
     
    JS中的方法
    Js代码
    1. function getFromAndroid(str){   
    2.         document.getElementByIdx_x_x_x("android").innerHTML=str;   
    3. }  
      
    Android调用该方法
    Java代码
    1. Button button = (Button) findViewById(R.id.button);   
    2.        button.setOnClickListener(new OnClickListener() {   
    3.        public void onClick(View arg0) {   
    4.             //调用javascript中的方法   
    5.            webView.loadUrl("javascript:getFromAndroid('Cookie call the js function from Android')");   
    6.        }   
    7.    });  
      
    3 Android中处理JS的警告,对话框等
    在Android中处理JS的警告,对话框等需要对WebView设置WebChromeClient对象
    Java代码  
    1. //设置WebChromeClient   
    2. webView.setWebChromeClient(new WebChromeClient(){   
    3.     //处理javascript中的alert   
    4.     public boolean onJsAlert(WebView view, String url, String message, final JsResult result) {   
    5.         //构建一个Builder来显示网页中的对话框   
    6.         Builder builder = new Builder(MainActivity.this);   
    7.         builder.setTitle("Alert");   
    8.         builder.setMessage(message);   
    9.         builder.setPositiveButton(android.R.string.ok,   
    10.             new AlertDialog.OnClickListener() {   
    11.                 public void onClick(DialogInterface dialog, int which) {   
    12.                     result.confirm();   
    13.                 }   
    14.             });   
    15.         builder.setCancelable(false);   
    16.         builder.create();   
    17.         builder.show();   
    18.         return true;   
    19.     };   
    20.     //处理javascript中的confirm   
    21.     public boolean onJsConfirm(WebView view, String url, String message, final JsResult result) {   
    22.         Builder builder = new Builder(MainActivity.this);   
    23.         builder.setTitle("confirm");   
    24.         builder.setMessage(message);   
    25.         builder.setPositiveButton(android.R.string.ok,   
    26.             new AlertDialog.OnClickListener() {   
    27.                 public void onClick(DialogInterface dialog, int which) {   
    28.                     result.confirm();   
    29.                 }   
    30.             });   
    31.         builder.setNegativeButton(android.R.string.cancel,   
    32.             new DialogInterface.OnClickListener() {   
    33.                 public void onClick(DialogInterface dialog, int which) {   
    34.                     result.cancel();   
    35.                 }   
    36.             });   
    37.         builder.setCancelable(false);   
    38.         builder.create();   
    39.         builder.show();   
    40.         return true;   
    41.     };   
    42.            
    43.     @Override  
    44.     //设置网页加载的进度条   
    45.     public void onProgressChanged(WebView view, int newProgress) {   
    46.         MainActivity.this.getWindow().setFeatureInt(Window.FEATURE_PROGRESS, newProgress * 100);   
    47.         super.onProgressChanged(view, newProgress);   
    48.     }   
    49.   
    50.     //设置应用程序的标题title   
    51.     public void onReceivedTitle(WebView view, String title) {   
    52.         MainActivity.this.setTitle(title);   
    53.         super.onReceivedTitle(view, title);   
    54.     }   
    55. });  
      
    ● Android中的调试
    通过JS代码输出log信息
    Js代码  
    1. Js代码: console.log("Hello World");   
    2. Log信息: Console: Hello World http://www.example.com/hello.html :82   
      
    在WebChromeClient中实现onConsoleMesaage()回调方法,让其在LogCat中打印信息
    Java代码 复制代码 收藏代码
    1. WebView myWebView = (WebView) findViewById(R.id.webview);   
    2. myWebView.setWebChromeClient(new WebChromeClient() {   
    3.     public void onConsoleMessage(String message, int lineNumber, String sourceID) {   
    4.         Log.d("MyApplication", message + " -- From line "  
    5.             + lineNumber + " of "  
    6.             + sourceID);   
    7.     }   
    8. });  

    以及
    Java代码  
    1. WebView myWebView = (WebView) findViewById(R.id.webview);   
    2. myWebView.setWebChromeClient(new WebChromeClient() {   
    3.     public boolean onConsoleMessage(ConsoleMessage cm) {   
    4.         Log.d("MyApplication", cm.message() + " -- From line "  
    5.             + cm.lineNumber() + " of "  
    6.             + cm.sourceId() );   
    7.         return true;   
    8.     }   
    9. });  
      
    *ConsoleMessage 还包括一个 MessageLevel 表示控制台传递信息类型。 您可以用messageLevel()查询信息级别,以确定信息的严重程度,然后使用适当的Log方法或采取其他适当的措施。
     
    ● HTML5本地存储在Android中的应用
    HTML5提供了2种客户端存储数据新方法
    localStorage 没有时间限制
    sessionStorage 针对一个Session的数据存储
     
    Js代码
    1. <script type="text/javascript">    
    2.     localStorage.lastname="Smith";    
    3.     document.write(localStorage.lastname);    
    4. </script>    
    5. <script type="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. String dir = this.getApplicationContext().getDir("database", Context.MODE_PRIVATE).getPath();   
    4. //设置数据库路径   
    5. webSettings.setDatabasePath(dir);   
    6. //使用localStorage则必须打开   
    7. webSettings.setDomStorageEnabled(true);   
    8. //扩充数据库的容量(在WebChromeClinet中实现)   
    9. public void onExceededDatabaseQuota(String url, String databaseIdentifier, long currentQuota,    
    10.         long estimatedSize, long totalUsedQuota, WebStorage.QuotaUpdater quotaUpdater) {   
    11.     quotaUpdater.updateQuota(estimatedSize * 2);   
    12. }  

      
     
    JS中按常规进行数据库操作
     
    Js代码
    1. function initDatabase() {   
    2. try {   
    3.     if (!window.openDatabase) {   
    4.         alert('Databases are not supported by your browser');   
    5.     } else {   
    6.         var shortName = 'YARINDB';   
    7.         var version = '1.0';   
    8.         var displayName = 'yarin db';   
    9.         var maxSize = 100000; // in bytes   
    10.         YARINDB = openDatabase(shortName, version, displayName, maxSize);   
    11.         createTables();   
    12.         selectAll();   
    13.     }   
    14. catch(e) {   
    15.     if (e == 2) {   
    16.         // Version mismatch.   
    17.         console.log("Invalid database version.");   
    18.     } else {   
    19.         console.log("Unknown error "+ e +".");   
    20.     }   
    21.     return;   
    22. }    
    23. }   
    24.   
    25. function createTables(){   
    26.     YARINDB.transaction(   
    27.         function (transaction) {   
    28.             transaction.executeSql('CREATE TABLE IF NOT EXISTS yarin(id INTEGER NOT NULL PRIMARY KEY, name TEXT NOT NULL,desc TEXT NOT NULL);', [], nullDataHandler, errorHandler);   
    29.         }   
    30.     );   
    31.     insertData();   
    32. }   
    33.   
    34. function insertData(){   
    35.     YARINDB.transaction(   
    36.         function (transaction) {   
    37.         //Starter data when page is initialized   
    38.         var data = ['1','yarin yang','I am yarin'];     
    39.            
    40.         transaction.executeSql("INSERT INTO yarin(id, name, desc) VALUES (?, ?, ?)", [data[0], data[1], data[2]]);   
    41.         }   
    42.     );     
    43. }   
    44.   
    45. function errorHandler(transaction, error){   
    46.     if (error.code==1){   
    47.         // DB Table already exists   
    48.     } else {   
    49.         // Error is a human-readable string.   
    50.         console.log('Oops.  Error was '+error.message+' (Code '+error.code+')');   
    51.     }   
    52.     return false;   
    53. }   
    54.   
    55.   
    56. function nullDataHandler(){   
    57.     console.log("SQL Query Succeeded");   
    58. }   
    59.   
    60. function selectAll(){    
    61.     YARINDB.transaction(   
    62.         function (transaction) {   
    63.             transaction.executeSql("SELECT * FROM yarin;", [], dataSelectHandler, errorHandler);   
    64.         }   
    65.     );     
    66. }   
    67.   
    68. function dataSelectHandler(transaction, results){   
    69.     // Handle the results   
    70.     for (var i=0; i<results.rows.length; i++) {   
    71.         var row = results.rows.item(i);   
    72.         var newFeature = new Object();   
    73.         newFeature.name   = row['name'];   
    74.         newFeature.decs = row['desc'];   
    75.            
    76.         document.getElementByIdx_x_x_x("name").innerHTML="name:"+newFeature.name;   
    77.         document.getElementByIdx_x_x_x("desc").innerHTML="desc:"+newFeature.decs;   
    78.     }   
    79. }   
    80.   
    81. function updateData(){   
    82.     YARINDB.transaction(   
    83.         function (transaction) {   
    84.             var data = ['fengsheng yang','I am fengsheng'];    
    85.             transaction.executeSql("UPDATE yarin SET name=?, desc=? WHERE id = 1", [data[0], data[1]]);   
    86.         }   
    87.     );     
    88.     selectAll();   
    89. }   
    90.   
    91. function ddeleteTables(){   
    92.     YARINDB.transaction(   
    93.         function (transaction) {   
    94.             transaction.executeSql("DROP TABLE yarin;", [], nullDataHandler, errorHandler);   
    95.         }   
    96.     );   
    97.     console.log("Table 'page_settings' has been dropped.");   
    98. }   
    99. 注意onLoad中的初始化工作   
    100. function initLocalStorage(){   
    101.     if (window.localStorage) {   
    102.         textarea.addEventListener("keyup"function() {   
    103.             window.localStorage["value"] = this.value;   
    104.             window.localStorage["time"] = new Date().getTime();   
    105.         }, false);   
    106.     } else {   
    107.         alert("LocalStorage are not supported in this browser.");   
    108.     }   
    109. }   
    110.   
    111. window.onload = function() {   
    112.     initDatabase();   
    113.     initLocalStorage();   
    114. }  

      
     

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

     
     
    在Manifest中添加权限
     
    Xml代码
    1. <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />  
    2. <uses-permission android: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. function get_location() {   
    3.     if (navigator.geolocation) {   
    4.         navigator.geolocation.getCurrentPosition(show_map,handle_error,{enableHighAccuracy:false,maximumAge:1000,timeout:15000});   
    5.     } else {   
    6.         alert("Your browser does not support HTML5 geoLocation");   
    7.     }   
    8. }   
    9.        
    10. function show_map(position) {   
    11.     var latitude = position.coords.latitude;   
    12.     var longitude = position.coords.longitude;   
    13.     var city = position.coords.city;   
    14.     //telnet localhost 5554   
    15.     //geo fix -82.411629 28.054553   
    16.     //geo fix -121.45356 46.51119 4392   
    17.     //geo nmea $GPGGA,001431.092,0118.2653,N,10351.1359,E,0,00,,-19.6,M,4.1,M,,0000*5B   
    18.     document.getElementByIdx_x_x_x("Latitude").innerHTML="latitude:"+latitude;   
    19.     document.getElementByIdx_x_x_x("Longitude").innerHTML="longitude:"+longitude;   
    20.     document.getElementByIdx_x_x_x("City").innerHTML="city:"+city;   
    21. }   
    22.        
    23. function handle_error(err) {   
    24.     switch (err.code) {   
    25.     case 1:   
    26.         alert("permission denied");   
    27.         break;   
    28.     case 2:   
    29.         alert("the network is down or the position satellites can't be contacted");   
    30.         break;   
    31.     case 3:   
    32.         alert("time out");   
    33.         break;   
    34.     default:   
    35.         alert("unknown error");   
    36.         break;   
    37.     }   
    38. }  

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

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

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

    在Android中构建离线应用
    Java代码
    1. //开启应用程序缓存   
    2. webSettingssetAppCacheEnabled(true);   
    3. String dir = 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. //扩充缓存的容量   
    12. public void onReachedMaxAppCacheSize(long spaceNeeded,   
    13.             long totalUsedQuota, WebStorage.QuotaUpdater quotaUpdater) {   
    14.     quotaUpdater.updateQuota(spaceNeeded * 2);   
    15. }  

    转发: http://blog.sina.com.cn/s/blog_83940dfb0100yrfm.html

  • 相关阅读:
    webpack基础
    LeetCode232. 用栈实现队列做题笔记
    mysql 时间加减一个月
    leetcode 1381. 设计一个支持增量操作的栈 思路与算法
    LeetCode 141. 环形链表 做题笔记
    leetcode 707. 设计链表 做题笔记
    leetcode 876. 链表的中间结点 做题笔记
    leetcode 143. 重排链表 做题笔记
    leetcode 1365. 有多少小于当前数字的数字 做题笔记
    LeetCode1360. 日期之间隔几天 做题笔记
  • 原文地址:https://www.cnblogs.com/622698abc/p/3358520.html
Copyright © 2011-2022 走看看