android 编写简单浏览器带下载 支持多触点 支持下载功能

转自:http://www.cmd59.com/html/2182.html

  1. packageorg.badboy.browser;
  2. importjava.io.ByteArrayOutputStream;
  3. importjava.io.File;
  4. importjava.io.FileInputStream;
  5. importjava.io.FileNotFoundException;
  6. importjava.io.FileOutputStream;
  7. importjava.io.InputStream;
  8. importjava.net.HttpURLConnection;
  9. importjava.net.MalformedURLException;
  10. importjava.net.URL;
  11. importjava.net.URLConnection;
  12. importorg.metalev.multitouch.controller.MultiTouchController;
  13. importorg.metalev.multitouch.controller.MultiTouchController.MultiTouchObjectCanvas;
  14. importorg.metalev.multitouch.controller.MultiTouchController.PointInfo;
  15. importorg.metalev.multitouch.controller.MultiTouchController.PositionAndScale;
  16. importandroid.app.Activity;
  17. importandroid.app.AlertDialog;
  18. importandroid.app.Dialog;
  19. importandroid.app.ProgressDialog;
  20. importandroid.app.SearchManager;
  21. importandroid.content.Context;
  22. importandroid.content.Intent;
  23. importandroid.content.res.Configuration;
  24. importandroid.net.Uri;
  25. importandroid.os.Bundle;
  26. importandroid.os.Environment;
  27. importandroid.util.Log;
  28. importandroid.view.KeyEvent;
  29. importandroid.view.Menu;
  30. importandroid.view.MenuItem;
  31. importandroid.view.MotionEvent;
  32. importandroid.view.View;
  33. importandroid.view.Window;
  34. importandroid.webkit.DownloadListener;
  35. importandroid.webkit.URLUtil;
  36. importandroid.webkit.WebChromeClient;
  37. importandroid.webkit.WebView;
  38. importandroid.webkit.WebViewClient;
  39. importandroid.widget.Button;
  40. importandroid.widget.EditText;
  41. importandroid.widget.ProgressBar;
  42. importandroid.widget.Toast;
  43. /***
  44. *使用WebView对象创建一个简单网页浏览器。
  45. *@authorBadBoy
  46. *
  47. */
  48. publicclassBrowserActivityextendsActivityimplementsMultiTouchObjectCanvas<Object>{
  49. privatefinalstaticintMENU_NEW_WEB=Menu.FIRST;
  50. privatefinalstaticintMENU_SET_MAIN_PAGE=MENU_NEW_WEB+1;
  51. privateStringdefaultGoogleUrl="";
  52. privateStringdefaultUCWebUrl="";
  53. privateStringdefaultUrl="";
  54. privateWebViewmWebView;
  55. //储存默认网址文件
  56. privateStringfileUrl="fileUrl.txt";
  57. //对话框标识
  58. privatefinalstaticintPROGRESS_DIALOG=110;
  59. privatefinalstaticintSET_DEFAULT_URL_DIALOG=111;
  60. //显示网页加载进度
  61. privateProgressDialogmDialog;
  62. privateProgressBarbar;
  63. //多点触摸
  64. privateMultiTouchController<Object>mMultiTouchController;
  65. @Override
  66. publicvoidonCreate(BundlesavedInstanceState){
  67. super.onCreate(savedInstanceState);
  68. //下面四条语句要在setContentView()方法之前调用,否则程序会出错,在本程序中,加入以下的语句貌似还没有什么影响,或者有我还没发现
  69. this.requestWindowFeature(Window.FEATURE_LEFT_ICON);
  70. this.requestWindowFeature(Window.FEATURE_RIGHT_ICON);
  71. this.requestWindowFeature(Window.FEATURE_PROGRESS);
  72. this.requestWindowFeature(Window.FEATURE_INDETERMINATE_PROGRESS);
  73. setContentView(R.layout.main);
  74. initWebView();
  75. performSearchIntent(getIntent());
  76. }
  77. @Override
  78. protectedvoidonNewIntent(Intentintent){
  79. setIntent(intent);
  80. performSearchIntent(intent);
  81. }
  82. /**
  83. *执行搜索,打开网页
  84. */
  85. privatevoidperformSearchIntent(Intentintent){
  86. if(Intent.ACTION_SEARCH.equals(intent.getAction())){
  87. Stringquery=intent.getStringExtra(SearchManager.QUERY);
  88. //还没有对网址进行严格的解析
  89. if(!query.startsWith("http://")){
  90. mWebView.loadUrl("http://"+query);
  91. }
  92. if(query.startsWith("http://")){
  93. mWebView.loadUrl(query);
  94. }
  95. /*else{
  96. Toast.makeText(this,R.string.url_error,Toast.LENGTH_SHORT).show();
  97. }*/
  98. }
  99. }
  100. privatevoidinitWebView(){
  101. defaultGoogleUrl=this.getResources().getString(R.string.default_google_url);
  102. defaultUCWebUrl=this.getResources().getString(R.string.default_ucweb_url);
  103. setDefaultURL();
  104. bar=(ProgressBar)findViewById(R.id.progress_bar);
  105. mMultiTouchController=newMultiTouchController<Object>(this,false);
  106. mWebView=(WebView)findViewById(R.id.webview);
  107. //使用mWebView的getSettings()方法设置支持JavaScript为true
  108. mWebView.getSettings().setJavaScriptEnabled(true);
  109. mWebView.setScrollBarStyle(0);
  110. //用loadUrl方法加载网址
  111. mWebView.loadUrl(defaultUrl);
  112. //对mWebView设置WebViewClient对象,如果不设置此对象那么当单击mWebView中的链接时将由系统
  113. //默认的Browser来响应链接,即由默认的Browser打开链接,而不是你自己写的Browser来打开
  114. //故为了mWebView自己处理页面中的所有链接,则要扩展WebViewClient类,重载shouldOverrideUrlLoading()方法
  115. mWebView.setWebViewClient(newMyWebViewClient());
  116. //
  117. mWebView.setWebChromeClient(newMyWebChromeClient());
  118. //实现下载监听
  119. mWebView.setDownloadListener(newDownloadListener(){
  120. publicvoidonDownloadStart(Stringurl,StringuserAgent,StringcontentDisposition,
  121. Stringmimetype,longcontentLength){
  122. /*Uriuri=Uri.parse(url);
  123. Intentintent=newIntent(Intent.ACTION_VIEW,uri);
  124. startActivity(intent);
  125. */
  126. downloadFile(url,mimetype,mimetype,mimetype,contentLength);
  127. }
  128. });
  129. }
  130. /*
  131. *下列代码实现网络文件下载功能,目前下载的文件时存储在/data/data/org.badboy.browser/files目录下的。
  132. *后续还会更新这个方法,将其下载到SDCard上来。思路是这样子的:下载文件时先检查是否由sdcard或udisk外存储设备,
  133. *若有则直接下载到外存储设备,否则存储到/data/data/org.badboy.browser/files目录中。最后还要增加一个功能:就是
  134. *列出已下载文件,以及对文件copy,delete等操作
  135. *2011-3-4
  136. */
  137. privatevoiddownloadFile(Stringurl,StringuserAgent,StringcontentDisposition,
  138. Stringmimetype,longcontentLength){
  139. /*Stringfilename=URLUtil.guessFileName(url,
  140. contentDisposition,mimetype);
  141. //ChecktoseeifwehaveanSDCard
  142. Stringstatus=Environment.getExternalStorageState();
  143. if(!status.equals(Environment.MEDIA_MOUNTED)){
  144. inttitle;
  145. Stringmsg;
  146. //ChecktoseeiftheSDCardisbusy,sameasthemusicapp
  147. if(status.equals(Environment.MEDIA_SHARED)){
  148. msg=getString(R.string.download_sdcard_busy_dlg_msg);
  149. title=R.string.download_sdcard_busy_dlg_title;
  150. }else{
  151. msg=getString(R.string.download_no_sdcard_dlg_msg,filename);
  152. title=R.string.download_no_sdcard_dlg_title;
  153. }
  154. newAlertDialog.Builder(this)
  155. .setTitle(title)
  156. .setIcon(android.R.drawable.ic_dialog_alert)
  157. .setMessage(msg)
  158. .setPositiveButton(R.string.ok,null)
  159. .show();
  160. return;
  161. }*/
  162. try{
  163. Stringfilename=URLUtil.guessFileName(url,
  164. contentDisposition,mimetype);
  165. URLurl2=newURL(url);
  166. HttpURLConnectionconn=(HttpURLConnection)url2.openConnection();
  167. conn.setDoInput(true);
  168. conn.connect();
  169. if(conn.getResponseCode()==HttpURLConnection.HTTP_OK){
  170. InputStreamis=conn.getInputStream();
  171. FileOutputStreamfos=this.openFileOutput(filename,Context.MODE_APPEND);
  172. intlen=0;
  173. byte[]buf=newbyte[1024];
  174. while((len=is.read(buf))!=-1){
  175. fos.write(buf,0,len);
  176. }
  177. is.close();
  178. fos.close();
  179. }else{
  180. Toast.makeText(this,R.string.net_error,Toast.LENGTH_SHORT).show();
  181. }
  182. }catch(Exceptione){
  183. e.printStackTrace();
  184. }
  185. }
  186. privatevoidsetDefaultURL(){
  187. try{
  188. //android中使用openFileInput()方法得到文件输入流
  189. FileInputStreamfis=this.openFileInput(fileUrl);
  190. ByteArrayOutputStreambaos=newByteArrayOutputStream();
  191. byte[]buffer=newbyte[1024];
  192. intlen=0;
  193. while((len=fis.read(buffer))!=-1){
  194. baos.write(buffer,0,len);
  195. }
  196. //defaultUrl=newString(buffer,0,len);
  197. defaultUrl=baos.toString();
  198. fis.close();
  199. baos.close();
  200. }catch(Exceptione){
  201. e.printStackTrace();
  202. }
  203. //如果还是为空,则使用defaultUCWebUrl
  204. if(defaultUrl.equals("")){
  205. defaultUrl=defaultUCWebUrl;
  206. }
  207. }
  208. /**
  209. *按键事件处理
  210. */
  211. @Override
  212. publicbooleanonKeyDown(intkeyCode,KeyEventevent){
  213. //按返回键可退回之前浏览过的网页
  214. if((keyCode==KeyEvent.KEYCODE_BACK)&&mWebView.canGoBack()){
  215. mWebView.goBack();
  216. returntrue;
  217. }
  218. //搜索按键
  219. if(keyCode==KeyEvent.KEYCODE_SEARCH){
  220. onSearchRequested();
  221. }
  222. returnsuper.onKeyDown(keyCode,event);
  223. }
  224. /**
  225. *重写WebChromeClient类
  226. */
  227. privateclassMyWebChromeClientextendsWebChromeClient{
  228. //设置网页加载进度条
  229. @Override
  230. publicvoidonProgressChanged(WebViewwebview,intnewProgress){
  231. BrowserActivity.this.getWindow().setFeatureInt(Window.FEATURE_PROGRESS,100);
  232. //以下注释代码是用来ProgressDialog显示网页加载进度的
  233. /*showDialog(PROGRESS_DIALOG);
  234. mDialog.setProgress(newProgress);
  235. if(newProgress==100){
  236. dismissDialog(PROGRESS_DIALOG);
  237. }*/
  238. //以下代码是用来ProgressBar显示网页加载进度的
  239. bar.setProgress(newProgress);
  240. bar.setVisibility(View.VISIBLE);
  241. if(bar.getProgress()==100){
  242. bar.setVisibility(View.GONE);
  243. }
  244. super.onProgressChanged(webview,newProgress);
  245. }
  246. }
  247. /**
  248. *重写WebViewClient类,由本Browser处理网页中的链接
  249. */
  250. privateclassMyWebViewClientextendsWebViewClient{
  251. @Override
  252. publicbooleanshouldOverrideUrlLoading(WebViewview,Stringurl){
  253. view.loadUrl(url);
  254. returntrue;
  255. }
  256. }
  257. /**
  258. *Menu按键的添加和事件处理
  259. */
  260. @Override
  261. publicbooleanonCreateOptionsMenu(Menumenu){
  262. //打开网址输入栏
  263. menu.add(0,MENU_NEW_WEB,0,R.string.new_web_page)
  264. .setIcon(R.drawable.search_icon);
  265. //设置默认网址
  266. menu.add(0,MENU_SET_MAIN_PAGE,0,R.string.set_default_url)
  267. .setIcon(R.drawable.browser_icon);
  268. returnsuper.onCreateOptionsMenu(menu);
  269. }
  270. @Override
  271. publicbooleanonMenuItemSelected(intfeatureId,MenuItemitem){
  272. switch(item.getItemId()){
  273. caseMENU_NEW_WEB:
  274. onSearchRequested();
  275. returntrue;
  276. caseMENU_SET_MAIN_PAGE:
  277. this.showDialog(SET_DEFAULT_URL_DIALOG);
  278. break;
  279. }
  280. returnsuper.onMenuItemSelected(featureId,item);
  281. }
  282. /**
  283. *重写onSearchRequested(),可实现调用SearchBar
  284. */
  285. @Override
  286. publicbooleanonSearchRequested(){
  287. //本程序还没处理Bundle对象传来的数据,注释下列三行代码
  288. /*BundleappData=newBundle();
  289. appData.putBoolean("search",true);
  290. this.startSearch(null,false,appData,false);*/
  291. this.startSearch(null,false,null,false);
  292. returntrue;
  293. }
  294. /**
  295. *当要调用this.showDialog(intid)方法来显示Dialog时,要重写下列方法
  296. */
  297. @Override
  298. protectedDialogonCreateDialog(intid){
  299. switch(id){
  300. casePROGRESS_DIALOG:
  301. mDialog=newProgressDialog(this);
  302. //mDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
  303. mDialog.setMessage("Pageisloading...");
  304. returnmDialog;
  305. caseSET_DEFAULT_URL_DIALOG:
  306. returncreateDefaultUrlDialog();
  307. default:
  308. returnsuper.onCreateDialog(id);
  309. }
  310. }
  311. privateDialogcreateDefaultUrlDialog(){
  312. finalDialogdialog=newDialog(this);
  313. dialog.setContentView(R.layout.default_url_dialog);
  314. dialog.setTitle(R.string.dialog_title);
  315. finalEditTexturl=(EditText)dialog.findViewById(R.id.url);
  316. ButtonbtnOK=(Button)dialog.findViewById(R.id.ok_btn);
  317. btnOK.setOnClickListener(newView.OnClickListener(){
  318. publicvoidonClick(Viewarg0){
  319. defaultUrl=url.getText().toString();
  320. try{
  321. FileOutputStreamfos=BrowserActivity.this.openFileOutput(fileUrl,Context.MODE_PRIVATE);
  322. byte[]buffer=defaultUrl.getBytes();
  323. fos.write(buffer);
  324. fos.close();
  325. }catch(Exceptione){
  326. e.printStackTrace();
  327. }
  328. dialog.dismiss();
  329. mWebView.loadUrl(defaultUrl);
  330. }
  331. });
  332. ButtonbtnCancel=(Button)dialog.findViewById(R.id.cancel_btn);
  333. btnCancel.setOnClickListener(newView.OnClickListener(){
  334. publicvoidonClick(Viewarg0){
  335. dialog.dismiss();
  336. }
  337. });
  338. returndialog;
  339. }
  340. /**
  341. *屏幕旋转时,程序会重新调用onCreate()方法,即重新加载程序。当不需要这么做时,
  342. *可在manifest文件中的Activity标签中加入android:configChanges="orientation|keyboardHidden"
  343. *属性,并且重写下列方法。该方法中可以处理屏幕旋转时发生的动作
  344. */
  345. @Override
  346. publicvoidonConfigurationChanged(ConfigurationnewConfig){
  347. /*if(this.getResources().getConfiguration().orientation==Configuration.ORIENTATION_LANDSCAPE){
  348. }elseif(this.getResources().getConfiguration().orientation==Configuration.ORIENTATION_PORTRAIT){
  349. }*/
  350. super.onConfigurationChanged(newConfig);
  351. }
  352. //-------------multitouchstuff------------------------------------
  353. privateintmCurrentZoom=0;
  354. privatestaticfinaldoubleZOOM_SENSITIVITY=1.6;
  355. privatestaticfinalfloatZOOM_LOG_BASE_INV=1.0f/(float)Math.log(2.0/ZOOM_SENSITIVITY);
  356. privatebooleanisMultiTouchScale=false;
  357. @Override
  358. publicbooleandispatchTouchEvent(MotionEventevent){
  359. if(mMultiTouchController.onTouchEvent(event)){
  360. if(!isMultiTouchScale){
  361. event.setAction(MotionEvent.ACTION_CANCEL);
  362. super.dispatchTouchEvent(event);
  363. }
  364. }else{
  365. isMultiTouchScale=true;
  366. if(super.dispatchTouchEvent(event)){
  367. returntrue;
  368. }
  369. returnfalse;
  370. }
  371. returntrue;
  372. }
  373. publicObjectgetDraggableObjectAtPoint(PointInfotouchPoint){
  374. returnnewObject();
  375. }
  376. publicvoidgetPositionAndScale(Objectobj,
  377. PositionAndScaleobjPosAndScaleOut){
  378. objPosAndScaleOut.set(0.0f,0.0f,true,1.0f,false,0.0f,0.0f,false,0.0f);
  379. mCurrentZoom=0;
  380. }
  381. publicvoidselectObject(Objectobj,PointInfotouchPoint){
  382. }
  383. publicbooleansetPositionAndScale(Objectobj,
  384. PositionAndScalenewObjPosAndScale,PointInfotouchPoint){
  385. floatnewRelativeScale=newObjPosAndScale.getScale();
  386. inttargetZoom=(int)Math.round(Math.log(newRelativeScale)
  387. *ZOOM_LOG_BASE_INV);
  388. while(mCurrentZoom>targetZoom){
  389. mCurrentZoom--;
  390. mWebView.zoomOut();
  391. }
  392. while(mCurrentZoom<targetZoom){
  393. mCurrentZoom++;
  394. mWebView.zoomIn();
  395. }
  396. returntrue;
  397. }
  398. }

更多相关文章

  1. 浅谈Java中Collections.sort对List排序的两种方法
  2. NPM 和webpack 的基础使用
  3. Python list sort方法的具体使用
  4. 【阿里云镜像】使用阿里巴巴DNS镜像源——DNS配置教程
  5. python list.sort()根据多个关键字排序的方法实现
  6. 收集整理的Android(安卓)color.xml文件的颜色配置
  7. Android(安卓)- Manifest 文件 详解
  8. Android--MediaPlayer(实现列表选歌,上一首,下一首,清空播放列表,搜
  9. Android(安卓)onSaveInstanceState和onRestoreInstanceState触发

随机推荐

  1. Android获取手机内存
  2. Android(安卓)xml解析实例详解
  3. Android(安卓)kotlin使用butterknife
  4. Event dispatching of Android
  5. Android(安卓)录音
  6. Eclipse 开发 Android, RelativeLayout (
  7. Android(安卓)监听系统音量
  8. Eclipse 开发 Android, TableLayout(学习4
  9. Android获取开机启动程序列表
  10. android host