aboutsummaryrefslogtreecommitdiffstats
path: root/src/cgeo/geocaching/cgMapImg.java
blob: 1ab8cdbe01aba8fb0473b1b9182c25cb25e4187b (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
package cgeo.geocaching;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;

import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.entity.BufferedHttpEntity;
import org.apache.http.impl.client.DefaultHttpClient;

import android.util.Log;

public class cgMapImg {
	/**
	 * in my tests the "no image available" image had 5470 bytes, while "street only" maps had at least 20000 bytes
	 */
	private static final int MIN_MAP_IMAGE_BYTES = 6000;
	private String geocode = null;

	public cgMapImg(String geocodeIn) {
		geocode = geocodeIn;

		if (geocode != null && geocode.length() > 0) {
			final String dirName = cgSettings.getStorage() + geocode + "/";

			File dir = null;
			dir = new File(cgSettings.getStorage());
			if (dir.exists() == false) {
				dir.mkdirs();
			}
			dir = new File(dirName);
			if (dir.exists() == false) {
				dir.mkdirs();
			}
			dir = null;
		}
	}

	public void getDrawable(String url, int level) {
		if (url == null || url.length() == 0) {
			return;
		}

		if (geocode == null || geocode.length() == 0) {
			return;
		}

		final String fileName = cgSettings.getStorage() + geocode + "/map_" + level;
		HttpClient client = null;
		HttpGet getMethod = null;
		HttpResponse httpResponse = null;
		HttpEntity entity = null;
		BufferedHttpEntity bufferedEntity = null;

		boolean ok = false;

		for (int i = 0; i < 3; i ++) {
			if (i > 0) Log.w(cgSettings.tag, "cgMapImg.getDrawable: Failed to download data, retrying. Attempt #" + (i + 1));

			try {
				client = new DefaultHttpClient();
				getMethod = new HttpGet(url);
				httpResponse = client.execute(getMethod);
				entity = httpResponse.getEntity();

				// if image is to small, don't download and save, there is no map data for this zoom level
				long contentSize = entity.getContentLength();
				if (contentSize > 0 && contentSize <= MIN_MAP_IMAGE_BYTES) {
					break;
				}

				bufferedEntity = new BufferedHttpEntity(entity);
				if (bufferedEntity != null) {
					InputStream is = (InputStream)bufferedEntity.getContent();
					FileOutputStream fos = new FileOutputStream(fileName);

					int fileSize = 0;
					try {
						byte[] buffer = new byte[4096];
						int bytesRead;
						while ((bytesRead = is.read(buffer)) != -1) {
							fos.write(buffer, 0, bytesRead);
							fileSize += bytesRead;
						}
						fos.flush();
						ok = true;
					} catch (IOException e) {
						Log.e(cgSettings.tag, "cgMapImg.getDrawable (saving to cache): " + e.toString());
					} finally {
						is.close();
						fos.close();
					}

					bufferedEntity = null;

					// delete image if it has no contents
					if (ok && fileSize < MIN_MAP_IMAGE_BYTES) {
						(new File(fileName)).delete();
					}
				}

				if (ok == true) {
					break;
				}
			} catch (Exception e) {
				Log.e(cgSettings.tag, "cgMapImg.getDrawable (downloading from web): " + e.toString());
			}
		}
	}
}