android 编写简单浏览器带下载 支持多触点 支持下载功能
1. package
2.
3. import
4. import
5. import
6. import
7. import
8. import
9. import
10. import
11. import
12. import
13.
14. import
15. import
16. import
17. import
18.
19. import
20. import
21. import
22. import
23. import
24. import
25. import
26. import
27. import
28. import
29. import
30. import
31. import
32. import
33. import
34. import
35. import
36. import
37. import
38. import
39. import
40. import
41. import
42. import
43. import
44. import
45. import
46.
47. /***
48. * 使用WebView对象创建一个简单网页浏览器。
49. * @author BadBoy
50. *
51. */
52. public class BrowserActivity extends Activity implements
53.
54. private final static int
55. private final static int MENU_SET_MAIN_PAGE = MENU_NEW_WEB + 1;
56.
57. private String defaultGoogleUrl = "";
58. private String defaultUCWebUrl = "";
59. private String defaultUrl = "";
60. private
61. //储存默认网址文件
62. private String fileUrl = "fileUrl.txt";
63. //对话框标识
64. private final static int PROGRESS_DIALOG = 110;
65. private final static int SET_DEFAULT_URL_DIALOG = 111;
66. //显示网页加载进度
67. private
68. private
69. //多点触摸
70. private
71. @Override
72. public void
73. super.onCreate(savedInstanceState);
74. //下面四条语句要在setContentView()方法之前调用,否则程序会出错,在本程序中,加入以下的语句貌似还没有什么影响,或者有我还没发现
75. this.requestWindowFeature(Window.FEATURE_LEFT_ICON);
76. this.requestWindowFeature(Window.FEATURE_RIGHT_ICON);
77. this.requestWindowFeature(Window.FEATURE_PROGRESS);
78. this.requestWindowFeature(Window.FEATURE_INDETERMINATE_PROGRESS);
79.
80. setContentView(R.layout.main);
81. initWebView();
82. performSearchIntent(getIntent());
83.
84.
85. }
86.
87. @Override
88. protected void
89. setIntent(intent);
90. performSearchIntent(intent);
91. }
92. /**
93. * 执行搜索,打开网页
94. */
95. private void
96. if(Intent.ACTION_SEARCH.equals(intent.getAction())){
97. String query = intent.getStringExtra(SearchManager.QUERY);
98. //还没有对网址进行严格的解析
99. if(!query.startsWith("http://")){
100. "http://"+query);
101. }
102. if(query.startsWith("http://")){
103. mWebView.loadUrl(query);
104. }
105. /*else{
106. Toast.makeText(this, R.string.url_error, Toast.LENGTH_SHORT).show();
107. }*/
108. }
109. }
110.
111. private void
112. this.getResources().getString(R.string.default_google_url);
113. this.getResources().getString(R.string.default_ucweb_url);
114. setDefaultURL();
115.
116. bar = (ProgressBar)findViewById(R.id.progress_bar);
117.
118. new MultiTouchController<Object>(this,false);
119.
120. mWebView = (WebView)findViewById(R.id.webview);
121. //使用mWebView的getSettings()方法设置支持JavaScript为true
122. true);
123. 0);
124. //用loadUrl方法加载网址
125. mWebView.loadUrl(defaultUrl);
126. //对mWebView设置WebViewClient对象,如果不设置此对象那么当单击mWebView中的链接时将由系统
127. //默认的Browser来响应链接,即由默认的Browser打开链接,而不是你自己写的Browser来打开
128. //故为了mWebView自己处理页面中的所有链接,则要扩展WebViewClient类,重载shouldOverrideUrlLoading()方法
129. new
130. //
131. new
132. //实现下载监听
133. new
134.
135. public void
136. long
137. /*Uri uri = Uri.parse(url);
138. Intent intent = new Intent(Intent.ACTION_VIEW,uri);
139. startActivity(intent);
140. */
141. downloadFile(url, mimetype, mimetype, mimetype, contentLength);
142. }
143.
144. });
145. }
146. /*
147. * 下列代码实现网络文件下载功能,目前下载的文件时存储在/data/data/org.badboy.browser/files目录下的。
148. * 后续还会更新这个方法,将其下载到SDCard上来。思路是这样子的:下载文件时先检查是否由sdcard或udisk外存储设备,
149. * 若有则直接下载到外存储设备,否则存储到/data/data/org.badboy.browser/files目录中。最后还要增加一个功能:就是
150. * 列出已下载文件,以及对文件copy,delete等操作
151. * 2011-3-4
152. */
153. private void
154. long
155.
156. /*String filename = URLUtil.guessFileName(url,
157. contentDisposition, mimetype);
158. // Check to see if we have an SDCard
159. String status = Environment.getExternalStorageState();
160. if (!status.equals(Environment.MEDIA_MOUNTED)) {
161. int title;
162. String msg;
163.
164. // Check to see if the SDCard is busy, same as the music app
165. if (status.equals(Environment.MEDIA_SHARED)) {
166. msg = getString(R.string.download_sdcard_busy_dlg_msg);
167. title = R.string.download_sdcard_busy_dlg_title;
168. } else {
169. msg = getString(R.string.download_no_sdcard_dlg_msg, filename);
170. title = R.string.download_no_sdcard_dlg_title;
171. }
172.
173. new AlertDialog.Builder(this)
174. .setTitle(title)
175. .setIcon(android.R.drawable.ic_dialog_alert)
176. .setMessage(msg)
177. .setPositiveButton(R.string.ok, null)
178. .show();
179. return;
180. }*/
181.
182. try
183. String filename = URLUtil.guessFileName(url,
184. contentDisposition, mimetype);
185. new
186. HttpURLConnection conn = (HttpURLConnection) url2.openConnection();
187. true);
188. conn.connect();
189. if
190. InputStream is = conn.getInputStream();
191. this.openFileOutput(filename, Context.MODE_APPEND);
192. int len = 0;
193. byte[] buf = new byte[1024];
194. while ((len = is.read(buf)) != -1) {
195. 0, len);
196. }
197. is.close();
198. fos.close();
199. else
200. this, R.string.net_error, Toast.LENGTH_SHORT).show();
201. }
202.
203. catch
204. e.printStackTrace();
205. }
206.
207. }
208.
209. private void
210. try
211. //android中使用openFileInput()方法得到文件输入流
212. this.openFileInput(fileUrl);
213. new
214. byte[] buffer = new byte[1024];
215. int len = 0;
216. while((len = fis.read(buffer))!=-1){
217. 0, len);
218. }
219. //defaultUrl = new String(buffer,0,len);
220. defaultUrl = baos.toString();
221. fis.close();
222. baos.close();
223. catch
224. e.printStackTrace();
225. }
226. //如果还是为空,则使用defaultUCWebUrl
227. if(defaultUrl.equals("")){
228. defaultUrl = defaultUCWebUrl;
229. }
230. }
231. /**
232. * 按键事件处理
233. */
234. @Override
235. public boolean onKeyDown(int
236. //按返回键可退回之前浏览过的网页
237. if((keyCode == KeyEvent.KEYCODE_BACK) && mWebView.canGoBack()){
238. mWebView.goBack();
239. return true;
240. }
241. //搜索按键
242. if(keyCode == KeyEvent.KEYCODE_SEARCH){
243. onSearchRequested();
244. }
245. return super.onKeyDown(keyCode, event);
246. }
247. /**
248. * 重写WebChromeClient类
249. */
250. private class MyWebChromeClient extends
251. //设置网页加载进度条
252. @Override
253. public void onProgressChanged(WebView webview, int
254. this.getWindow().setFeatureInt(Window.FEATURE_PROGRESS, 100);
255. //以下注释代码是用来ProgressDialog显示网页加载进度的
256. /*showDialog(PROGRESS_DIALOG);
257. mDialog.setProgress(newProgress);
258. if(newProgress==100){
259. dismissDialog(PROGRESS_DIALOG);
260. }*/
261. //以下代码是用来ProgressBar显示网页加载进度的
262. bar.setProgress(newProgress);
263. bar.setVisibility(View.VISIBLE);
264. if(bar.getProgress()==100){
265. bar.setVisibility(View.GONE);
266. }
267. super.onProgressChanged(webview, newProgress);
268. }
269. }
270. /**
271. * 重写 WebViewClient类,由本Browser处理网页中的链接
272. */
273. private class MyWebViewClient extends
274.
275. @Override
276. public boolean
277. view.loadUrl(url);
278. return true;
279. }
280.
281. }
282. /**
283. * Menu 按键的添加和事件处理
284. */
285. @Override
286. public boolean
287. //打开网址输入栏
288. 0,MENU_NEW_WEB,0,R.string.new_web_page)
289. .setIcon(R.drawable.search_icon);
290. //设置默认网址
291. 0,MENU_SET_MAIN_PAGE,0,R.string.set_default_url)
292. .setIcon(R.drawable.browser_icon);
293. return super.onCreateOptionsMenu(menu);
294. }
295. @Override
296. public boolean onMenuItemSelected(int
297. switch(item.getItemId()){
298. case
299. onSearchRequested();
300. return true;
301. case
302. this.showDialog(SET_DEFAULT_URL_DIALOG);
303. break;
304. }
305. return super.onMenuItemSelected(featureId, item);
306. }
307.
308. /**
309. * 重写onSearchRequested(),可实现调用Search Bar
310. */
311. @Override
312. public boolean
313. //本程序还没处理Bundle对象传来的数据,注释下列三行代码
314. /*Bundle appData = new Bundle();
315. appData.putBoolean("search",true);
316. this.startSearch(null, false, appData, false);*/
317. this.startSearch(null, false, null, false);
318. return true;
319. }
320. /**
321. * 当要调用this.showDialog(int id)方法来显示Dialog时,要重写下列方法
322. */
323. @Override
324. protected Dialog onCreateDialog(int
325. switch(id){
326. case
327. new ProgressDialog(this);
328. //mDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
329. "Page is loading...");
330. return
331. case
332. return
333. default:
334. return super.onCreateDialog(id);
335. }
336.
337. }
338. private
339. final Dialog dialog = new Dialog(this);
340. dialog.setContentView(R.layout.default_url_dialog);
341. dialog.setTitle(R.string.dialog_title);
342. final
343. Button btnOK = (Button)dialog.findViewById(R.id.ok_btn);
344. new
345.
346. public void
347. defaultUrl = url.getText().toString();
348. try
349. this.openFileOutput(fileUrl, Context.MODE_PRIVATE);
350. byte[] buffer = defaultUrl.getBytes();
351. fos.write(buffer);
352. fos.close();
353. catch
354. e.printStackTrace();
355. }
356. dialog.dismiss();
357. mWebView.loadUrl(defaultUrl);
358. }
359. });
360. Button btnCancel = (Button)dialog.findViewById(R.id.cancel_btn);
361. new
362.
363. public void
364. dialog.dismiss();
365. }
366. });
367. return
368. }
369.
370. /**
371. * 屏幕旋转时,程序会重新调用onCreate()方法,即重新加载程序。当不需要这么做时,
372. * 可在manifest文件中的Activity标签中加入android:configChanges="orientation|keyboardHidden"
373. * 属性,并且重写下列方法。该方法中可以处理屏幕旋转时发生的动作
374. */
375. @Override
376. public void
377.
378. /*if (this.getResources().getConfiguration().orientation == Configuration.ORIENTATION_LANDSCAPE) {
379.
380. } else if (this.getResources().getConfiguration().orientation == Configuration.ORIENTATION_PORTRAIT) {
381.
382. }*/
383.
384. super.onConfigurationChanged(newConfig);
385. }
386.
387. //-------------multitouch stuff ------------------------------------
388.
389. private int mCurrentZoom = 0;
390. private static final double ZOOM_SENSITIVITY = 1.6;
391. private static final float ZOOM_LOG_BASE_INV = 1.0f / (float) Math.log(2.0
392. private boolean isMultiTouchScale = false;
393. @Override
394. public boolean
395. if
396. if
397. event.setAction(MotionEvent.ACTION_CANCEL);
398. super.dispatchTouchEvent(event);
399. }
400. else{
401. true;
402. if (super.dispatchTouchEvent(event)) {
403. return true;
404. }
405. return false;
406. }
407. return true;
408. }
409. public
410. return new
411. }
412.
413. public void
414. PositionAndScale objPosAndScaleOut) {
415. 0.0f, 0.0f, true, 1.0f, false, 0.0f, 0.0f, false, 0.0f);
416. 0;
417. }
418.
419. public void
420.
421. }
422.
423. public boolean
424. PositionAndScale newObjPosAndScale, PointInfo touchPoint) {
425. float
426. int targetZoom = (int) Math.round(Math.log(newRelativeScale)
427. * ZOOM_LOG_BASE_INV);
428. while
429. mCurrentZoom--;
430. mWebView.zoomOut();
431. }
432. while
433. mCurrentZoom++;
434. mWebView.zoomIn();
435. }
436. return true;
437. }
438.
439. }