Tag Archives: android

webview Access-Control-Allow-Origin Error At Android

最近做项目时,在三星手机上遇到了一个问题,webview下的zeptojs的ajax请求报错,具体错误信息如下: 查了后发现需要在Android上加入如下配置 参考文章:http://stackoverflow.com/questions/11318703/access-control-allow-origin-error-at-android-4-1 有关添加此配置后引起的安全性问题文章一篇:http://www.2cto.com/Article/201501/370287.html

android + javascript 相互通信实例分析(转)

开发是碰到在webview里面添加图片上传功能,一直没有处理好,最后决定采用JavaScript和Android通信,利用Android原生的完成,然后再把上传好的路径传过来。 根据功能实现找到了下面一篇文章,地址:http://www.cnblogs.com/yaozhongxiao/p/3408948.html 建议去原文地址阅读,原文样式更加的便于阅读,指鹤转载只为了将来查找方便。 转载内容: 1.  AndroidManifest.xml中必须使用许可 “android.permission.INTERNET”, 否则会出Web page not available错误。 <uses-permission android:name=”android.permission.INTERNET”/> 2.  如果访问的页面中有Javascript,则webview必须设置支持Javascript。 1   WebSettings webSetting = webview.getSettings(); 2   webSetting.setJavaScriptEnabled(true); 3.如果页面中链接,如果希望点击链接继续在当前browser中响应,而不是新开Android的系统browser中响应该链接,必须覆盖 webview的WebViewClient对象或者覆盖webview的 setWebChromeClient 1 mWebView.setWebViewClient(new WebViewClient(){ 2 public boolean shouldOverrideUrlLoading(WebView view, String url) { 3     view.loadUrl(url); 4     return true; 5    } 6 }); 1 mWebView.setWebChromeClient(new MyWebChromeClient() 2 @Override 3 public boolean onJsAlert(WebView view, String url, String message, JsResult result) { 4 Log.d(LOG_TAG, message); 5 result.confirm(); 6 return true; 7 }); 4.  如果不做任何处理,浏览网页,点击系统“Back”键,整个Browser会调用finish()而结束自身,如果希望浏览的网 页回退而不是推出浏览器,需要在当前Activity中处理并消费掉该Back事件。 1 public boolean onKeyDown(int keyCode, KeyEvent event) { 2   if ((keyCode == KeyEvent.KEYCODE_BACK) && mWebView.canGoBack()) { 3     mWebView.goBack(); 4     return true; 5   } 6   return super.onKeyDown(keyCode, event); 7 } 5.  javascript对象 与 android 对象绑定 WebView注入Java对象   对象注入即通过webview 建立 javascript对象 与 android 原生对象的绑定关系,下面代码中,obj1对象在android程序中可以操作,obj2在js程序中可以操作,两者操作的均为同一个内存对象,即可以理解为,两个绑定的对象是同一个对象在不同运行环境下的一个别名(仅个人理解,有误请大牛指正) 1 webview.getSetting().setJavaScriptEnable(true); 2 class JsObject { 3 @JavascriptInterface 4 public String toString() { return “injectedObject”; } 5 } 6 webView.addJavascriptInterface(new JsObject()obj1, “injectedObject”obj2); 上面的程序建立 javascript 与android 程序的绑定关系,android 4.2 之后版本提供给js调用的函数必须带有注释语句@JavascriptInterface ,4.2版本之前向webview注入的对象所暴露的接口不是必须带有@JavascriptInterface注释语句(需要注意,android adt,eclipse生成的工程,低版本中会自动带有 anotations.jar,支持@JavascriptInterface, 而高版本中工程中,不会自动带有anotations.jar包,所以要加入注释语句@JavascriptInterface,首先要自己手动加入anotations.jar包,不要忘记import 哦!本人就犯过这么低级的错误哦) 官方文档解释是因为这个接口允许JavaScript 控制宿主应用程序,这是个很强大的特性,但同时,在4.2的版本前存在重大安全隐患,因为JavaScript 可以使用反射访问注入webview的java对象的public fields,在一个包含不信任内容的WebView中使用这个方法,会允许攻击者去篡改宿主应用程序,使用宿主应用程序的权限执行java代码。因此4.2以后,任何为JS暴露的接口,都需要加 @JavascriptInterface 注释,这样,这个Java对象的fields 将不允许被JS访问。[2] 注:如果将targetSdkVersion 设置为17或者更高,但却没有给暴露的js接口加@JavascriptInterface注释,则logcat会报如下输出:    Console: Uncaught TypeError: Object [object Object] has no method ‘toString’   (需要特注意的一点,这里的限制是通过 targetSdkVersion 为标准,即如果工程采用了android sdk的版本是4.2以上,但是 targetSdkVersion 的版本在17之下,那么该状态下生成的应用,不过报错,如果targetSdkVersion 设置为>=17 就需要特别主意,要加上 @JavascriptInterface注释语句了, 所有建议在各种版本下都采用@JavascriptInterface注释,就万无一失了)   6.  在做webview开发是经常会加载本机的html文件如下: file:///android_asset/teste.html   加载项目assets下的文件teste.html […]

有关WebView开发问题

转自:http://blog.sina.com.cn/s/blog_8241e8510101btvk.html 今天做webview时遇到了问题,由于未加上 localStorage配置导致页面无法使用 localStorage,按照文章中的第七条进行了设置就可以了。 1、添加权限:AndroidManifest.xml中必须使用许可”android.permission.INTERNET”,否则会出Web page not available错误。 2、在要Activity中生成一个WebView组件:WebView webView = new WebView(this); 3、设置WebView基本信息: 如果访问的页面中有Javascript,则webview必须设置支持Javascript。 webview.getSettings().setJavaScriptEnabled(true); 触摸焦点起作用 webview.requestFocus();//如果不设置,则在点击网页文本输入框时,不能弹出软键盘及不响应其他的一些事件。 取消滚动条 this.setScrollBarStyle(SCROLLBARS_OUTSIDE_OVERLAY); 4、设置WevView要显示的网页: 互联网用:webView.loadUrl(“http://www.google.com”); 本地文件用:webView.loadUrl(“file:///android_asset/XX.html”); 本地文件存放在:assets文件中 5、如果希望点击链接由自己处理,而不是新开Android的系统browser中响应该链接。 给WebView添加一个事件监听对象(WebViewClient) 并重写其中的一些方法 shouldOverrideUrlLoading:对网页中超链接按钮的响应。 当按下某个连接时WebViewClient会调用这个方法,并传递参数:按下的url onLoadResource onPageStart onPageFinish onReceiveError onReceivedHttpAuthRequest 6.listview,webview中滚动拖动到顶部或者底部时的阴影(滑动到项部或底部不固定) WebView.setOverScrollMode(View.OVER_SCROLL_NEVER); 7.//android 中 webview 使用 localStorage WebSettings settings = mWebView.getSettings(); // 设置可以使用localStorage settings.setDomStorageEnabled(true); // 应用可以有数据库 settings.setDatabaseEnabled(true); String dbPath = this.getApplicationContext().getDir(“database”, Context.MODE_PRIVATE).getPath(); settings.setDatabasePath(dbPath); // 应用可以有缓存 settings.setAppCacheEnabled(true); String appCaceDir = this.getApplicationContext().getDir(“cache”, Context.MODE_PRIVATE).getPath(); settings.setAppCachePath(appCaceDir); 8、如果用webview点链接看了很多页以后,如果不做任何处理,点击系统“Back”键,整个浏览器会调用finish()而结束自身,如果希望浏览的网页回退而不是退出浏览器,需要在当前Activity中处理并消费掉该Back事件。 覆盖Activity类的onKeyDown(int keyCoder,KeyEvent event)方法。 public boolean onKeyDown(int keyCoder,KeyEvent event){ if(webView.canGoBack() && keyCoder == KeyEvent.KEYCODE_BACK){ webview.goBack(); //goBack()表示返回webView的上一页面 return true; } return false; } WebView相关问题注意: Android的webView很强大,其实就是一个浏览器,你可以把它嵌入到你想要的位置,我这里遇到两个问题,就是怎么知道网页的加载进度和加载网页时, 点击网页里面的链接还是在当前的webview里跳转,不想跳到浏览器那边,解决办法如下: //此方法可以处理webview 在加载时和加载完成时一些操作 webView.setWebChromeClient(new WebChromeClient(){ @Override public void onProgressChanged(WebView view, int newProgress) { if(newProgress==100){ // 这里是设置activity的标题, 也可以根据自己的需求做一些其他的操作 title.setText(“加载完成”); }else{ title.setText(“加载中…….”); } } }); webView.setWebViewClient(new WebViewClient(){ @Override public boolean shouldOverrideUrlLoading(WebView view, String url) { //重写此方法表明点击网页里面的链接还是在当前的webview里跳转,不跳到浏览器那边 view.loadUrl(url); return true; } @Override public void onReceivedSslError(WebView view, SslErrorHandler handler, android.net.http.SslError error) { // 重写此方法可以让webview处理https请求 handler.proceed(); } });

android(安卓)Webview嵌入页面在大字号设置下样式错乱

采用安卓原生加html页面的方式开发应用,结果发现嵌入的页面在用户设置了大字号后样式错乱(设置大字号的方式,设置->显示->字体大小)。 遇到问题,由于Webview是调用的安卓原生浏览器,所以首先直接打开原生浏览器访问网址,发现同样的问题,然后又测试发现chrome以及UC均不会出现此问题。原生浏览器用的人少,可以忽略,但嵌入的页面出现问题必须要解决啊,于是开始寻找解决方案。总算找到了一个可以解决此问题的方法,在安卓应用中设置默认字体。 具体设置方法如下: mWebView.getSettings().setDefaultFontSize(16); 设置默认的字体大小,默认为16,有效值区间在1-72之间。 目前测试暂为发现问题,时间2014.12.8,若是拟采用此方式出现问题,欢迎留言交流。 参考文章链接,点击这里,以下为摘抄过来的内容,建议去看原文,样式更加便于阅读。 摘要 WebView是安卓中用来显示html文本内容的的控件,对html5也有很好的支持,ios的控件UIWebView差不多。网上对WebView的解释很多,但都是零星的介绍,导致到现在为止webview给我的印象都是,貌似很强大,其实很鸡肋,于是决定总结一下webview的开发经验。 使用W WebView是安卓中用来显示html文本内容的的控件,对html5也有很好的支持,ios的控件UIWebView差不多。网上对WebView的解释很多,但都是零星的介绍,导致到现在为止webview给我的印象都是,貌似很强大,其实很鸡肋,于是决定总结一下webview的开发经验。 使用WebView并不需要开通网络权限 网上有文章说webview需要开通internet权限,否则会出Web page not available错误,这是不对的,出现Web page not available并不是因为使用了webview,而是webview访问了网络,如果webview只是加载本地html(比如assets目录中的文件),或者只是加载带有html文本的字符串,即使没有internet权限,也不会报错。 如何调用webview xml中 1 2 3 4 5 <WebView     android:id=”@+id/blog_detail_webview”     android:layout_width=”fill_parent”     android:layout_height=”wrap_content”     android:background=”#FFFFFF”/> activity中 1 2 3 4 5 6 mWebView = (WebView)findViewById(R.id.blog_detail_webview); mWebView.getSettings().setJavaScriptEnabled(false); mWebView.getSettings().setSupportZoom(false); mWebView.getSettings().setBuiltInZoomControls(false); mWebView.getSettings().setLayoutAlgorithm(LayoutAlgorithm.SINGLE_COLUMN); mWebView.getSettings().setDefaultFontSize(18); 基本设置 上面的java代码部分相信大家都懂,可以看到WebView 和其他控件不同的地方在于其属性设置是调用mWebView.getSettings()来完成的,不知道谷歌这样设计的用意,其中: mWebView.getSettings().setJavaScriptEnabled(false); 表示不支持js,如果想让java和js交互或者本身希望js完成一定的功能请把false改为true。 mWebView.getSettings().setSupportZoom(false); 设置是否支持缩放,我这里为false,默认为true。 mWebView.getSettings().setBuiltInZoomControls(false); 设置是否显示缩放工具,默认为false。 mWebView.getSettings().setLayoutAlgorithm(LayoutAlgorithm.SINGLE_COLUMN); 一般很少会用到这个,用WebView组件显示普通网页时一般会出现横向滚动条,这样会导致页面查看起来非常不方便。LayoutAlgorithm是一个枚举,用来控制html的布局,总共有三种类型: NORMAL:正常显示,没有渲染变化。 SINGLE_COLUMN:把所有内容放到WebView组件等宽的一列中。 NARROW_COLUMNS:可能的话,使所有列的宽度不超过屏幕宽度。 mWebView.getSettings().setDefaultFontSize(18); 设置默认的字体大小,默认为16,有效值区间在1-72之间。 加载内容 (1)加载assets目录下的本地网页 一般我们都是把html文件放在assets目录下, WebView调用assets目录下的本地网页和图片等资源非常方便,使用形如 1 mWebView.loadUrl(“file:///android_asset/html/test1.html”); 的调用方法即可。 (2)加载远程网页 1 mWebView.loadUrl(“http://www.google.com”); (3)使用 LoadData 或者 loadDataWithBaseURL方法加载内容 有时候我们的webview可能只是html片段,而不是一个完整的网页,事实上绝大多数时候都是如此,完整的网页无需做成应用,而直接在浏览器访问。 这种情况我们使用 LoadData 或者 loadDataWithBaseURL方法,后者用的最多: void loadDataWithBaseURL (String baseUrl, String data, String mimeType, String encoding, String historyUrl) loadDataWithBaseURL()比loadData()多两个参数,可以指定HTML代码片段中相关资源的相对根路径,也可以指定历史Url,其余三个参数相同。 这里主要注意参数baseUrl,baseUrl指定了你的data参数中数据是以什么地址为基准的,因为data中的数据可能会有超链接或者是image元素,而很多网站的地址都是用的相对路径,如果没有baseUrl,webview将访问不到这些资源。 举个例子: 1 2 String body =”示例:这里有个img标签,地址是相对路径<img src=’/uploads/allimg/130923/1FP02V7-0.png’ />”; mWebView.loadDataWithBaseURL(“http://www.jcodecraeer.com”, body, “text/html”, “utf-8”,null); 如果baseUrl没有指定为http://www.jcodecraeer.com,那么这张图片将显示不出来。 上面的例子其实演示了loadDataWithBaseURL的用法,我们直接加载一个字符串里面的html内容,而有些时候这些内容是从assets目录下的本地网页文件中读取,下面我们将html/test1.html中的内容通过LoadData来加载: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 String data = “”; try {     // 读取assets目录下的文件需要用到AssetManager对象的Open方法打开文件     InputStream is = getAssets().open(“html/test2.html”);     // loadData()方法需要的是一个字符串数据所以我们需要把文件转成字符串     ByteArrayBuffer baf = new ByteArrayBuffer(500);     int count = 0;     while ((count = is.read()) != -1) {         baf.append(count);     }     data = EncodingUtils.getString(baf.toByteArray(), “utf-8”); } catch (IOException e) {     e.printStackTrace(); } // […]

android(安卓)webView访问页面404,删掉应用的title栏

1.android(安卓)webView访问页面404 今天开始试着将HTML页面嵌入到安卓应用里,也就是常说的WebView,访问的是HTTP资源。代码写好后问题来了,提示无法访问到页面,我手机是联网的啊?后面一查原来是没有申请网络权限。加上就可以了。具体添加方法如下(不知道还有没有更好的方法,若是你知道的麻烦告知一下指鹤)。 在AndroidManifest.xml文件的manifest标签下添加下面的代码,注意下不要填错了,指鹤填在了application,若是不知道填哪里合适,可以和指鹤一样填在那里。 2.去掉安卓应用的title标题栏,参考文章,点击这里。 有两种方法,一种是在java代码中修改,一种是在AndroidManifest.xml文件中,具体方法如下。 ->在代码中添加 ->在清单文件AndroidManifest.xml中添加,添加在application标签里

安卓开发学习小记

1、命令行创建、删除和浏览AVD android create avd -n <avd名称> -t <android版本> -b <cpu架构> -p <avd 保存位置> -s <选择AVD皮肤>; android list avd命令可以列出已安装的avd设备,去掉avd(android list)列出的是创建avd时可选的avd设备,相关的命令还有; list target列出机器上所有已经安装的android版本; move avd 移动或重名一个AVD设备; delete avd 删除一个AVD设备; update 升级一个AVD设备使之符合新的SDK环境。 2、使用Android模拟器 启动模拟器的模拟器的命令行方式:emulator -avd crazyit //运行名为crazyit的AVD设备 3、使用DDMS进行调试 命令行输入ddms.bat 4、Android debug bridge(ADB)的用法 查看正在运行的模拟器 adb -devices 电脑与手机之间文件的相互复制 adb push d:/abc.txt /sdcard/ 将D盘目录下的abc.txt文件复制到sdcard目录下; adb pull /sdcard/xyz.txt d:/ 将模拟器的/sdcard目录下的xyz.txt复制到d盘; 启动模拟器的shell窗口 adb shell 5、安装、卸载apk程序 adb install [-r] [-s] <file> 上面的命令格式指定安装<file>代表的apk包。其中-r表示重新安装apk包,-s表示将apk包安装到sd卡上,,偶人试讲APk包安装到内部存储器上。实例:adb install text.apk 卸载命令:adb uninstall [-k] <file> ,file代表指定删除的apk包,-k表示只删除该应用,但保留该程序所用的数据和缓存目录。 6、使用dx编译Android应用 dx –dex [–dump-to=<file>] [–core–library] [–core-library] [file.class | <file>.{zip,jar,apk} | <directory>] 上面的命令中 [–dump-to=<file>]指定生成的*.dex文件的文件名;而–core-library指定需要转换的*.class、*.zip、*.jar文件或者目录,实例如下: dx –dex –dump-to=g:\a.dex –core –library d:\helloworld\bin 7、使用Android Asset Packaging Tool(AAPT)打包资源(暂时不记了) 8、使用mksdcard管理虚拟sd卡 命令行:mksdcard [-l label] <size> <file>,<size>指定虚拟sd卡的大小,<file>指定保存虚拟sd卡的文件镜像,实例如下: mksdcard 64M D:\sdcard.img,命令创建了一个64M的虚拟sd卡,该卡对应的镜像文件为D:sdcard.img,若是希望启动模拟器是使用指定的SD卡,则在启动模拟器时增加-sdcard <file>选项,其中file代表了虚拟sd卡的文件镜像。如: emulator -avd crazyit -sdcard d:sdcard.img 小记到此为止,算是给自己记了一份笔记,同时也希望能够帮助到他人。 日记时间:2014.11.18