17 */ |
17 */ |
18 |
18 |
19 |
19 |
20 package org.hedgewars.hedgeroid; |
20 package org.hedgewars.hedgeroid; |
21 |
21 |
22 import java.io.BufferedOutputStream; |
22 import java.io.Closeable; |
23 import java.io.File; |
23 import java.io.File; |
|
24 import java.io.FileNotFoundException; |
24 import java.io.FileOutputStream; |
25 import java.io.FileOutputStream; |
25 import java.io.IOException; |
26 import java.io.IOException; |
26 import java.io.InputStream; |
27 import java.io.InputStream; |
|
28 import java.io.OutputStream; |
27 import java.util.ArrayList; |
29 import java.util.ArrayList; |
28 import java.util.List; |
30 import java.util.List; |
29 |
31 |
30 import android.annotation.TargetApi; |
32 import android.annotation.TargetApi; |
31 import android.content.Context; |
33 import android.content.Context; |
|
34 import android.content.res.Resources; |
32 import android.content.res.TypedArray; |
35 import android.content.res.TypedArray; |
33 import android.os.Build; |
36 import android.os.Build; |
34 import android.os.Environment; |
37 import android.os.Environment; |
35 import android.util.Log; |
38 import android.util.Log; |
36 |
39 |
37 public class Utils { |
40 public class Utils { |
38 |
41 private static final String ROOT_DIR = "Data"; |
39 private static final String ROOT_DIR = "Data/"; |
42 private static final String TAG = "org.hedgewars.hedgeroid"; |
40 |
43 |
|
44 /** |
|
45 * @return true if the data path is currently available. However, it can vanish at any time so |
|
46 * normally you should just try to use it and rely on the exceptions. |
|
47 */ |
|
48 public static boolean isDataPathAvailable() { |
|
49 return Environment.MEDIA_MOUNTED.equals(Environment.getExternalStorageState()); |
|
50 } |
|
51 |
41 /** |
52 /** |
42 * get the path to which we should download all the data files |
53 * get the path to which we should download all the data files |
43 * @param c context |
54 * @param c context |
44 * @return absolute path |
55 * @return The directory |
45 */ |
56 * @throws FileNotFoundException if external storage is not avaliable at the moment |
46 public static String getCachePath(Context c){ |
57 */ |
|
58 public static File getCachePath(Context c) throws FileNotFoundException { |
|
59 File cachePath = null; |
47 if(Build.VERSION.SDK_INT < 8){//8 == Build.VERSION_CODES.FROYO |
60 if(Build.VERSION.SDK_INT < 8){//8 == Build.VERSION_CODES.FROYO |
48 return PreFroyoSDCardDir.getDownloadPath(c) + '/'; |
61 cachePath = PreFroyoSDCardDir.getDownloadPath(c); |
49 }else{ |
62 } else { |
50 return FroyoSDCardDir.getDownloadPath(c) + '/'; |
63 cachePath = FroyoSDCardDir.getDownloadPath(c); |
51 } |
64 } |
52 } |
65 if(cachePath==null) { |
53 |
66 throw new FileNotFoundException("External storage is currently unavailable"); |
54 public static String getDataPath(Context c){ |
67 } else { |
55 return getCachePath(c) + ROOT_DIR; |
68 return cachePath; |
|
69 } |
|
70 } |
|
71 |
|
72 public static File getDataPathFile(Context c) throws FileNotFoundException { |
|
73 return new File(getCachePath(c), ROOT_DIR); |
|
74 } |
|
75 |
|
76 // TODO Several callers are unaware that this may fail, so it throws an RTE now. |
|
77 // Should be handled better though. |
|
78 @Deprecated |
|
79 public static String getDataPath(Context c) { |
|
80 try { |
|
81 return getDataPathFile(c).getAbsolutePath()+"/"; |
|
82 } catch(FileNotFoundException e) { |
|
83 throw new RuntimeException(e); |
|
84 } |
56 } |
85 } |
57 |
86 |
58 @TargetApi(8) |
87 @TargetApi(8) |
59 static class FroyoSDCardDir{ |
88 private static class FroyoSDCardDir{ |
60 public static String getDownloadPath(Context c){ |
89 public static File getDownloadPath(Context c){ |
61 File f = c.getExternalCacheDir(); |
90 return c.getExternalCacheDir(); |
62 if(f != null){ |
91 } |
63 return f.getAbsolutePath(); |
92 } |
64 }else{ |
93 |
65 return null; |
94 private static class PreFroyoSDCardDir{ |
66 } |
95 public static File getDownloadPath(Context c){ |
67 } |
|
68 } |
|
69 |
|
70 static class PreFroyoSDCardDir{ |
|
71 public static String getDownloadPath(Context c){ |
|
72 if(Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)){ |
96 if(Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)){ |
73 if(Environment.getExternalStorageDirectory() != null) |
97 File extStorageDir = Environment.getExternalStorageDirectory(); |
74 return Environment.getExternalStorageDirectory().getAbsolutePath() + "/Hedgewars/"; |
98 if(extStorageDir != null) { |
|
99 return new File(extStorageDir, "Hedgewars"); |
|
100 } |
75 } |
101 } |
76 return null; |
102 return null; |
77 } |
103 } |
78 } |
104 } |
79 |
105 |
164 } |
190 } |
165 return ret; |
191 return ret; |
166 } |
192 } |
167 |
193 |
168 /** |
194 /** |
|
195 * Close a resource (possibly null), ignoring any IOException. |
|
196 */ |
|
197 public static void closeQuietly(Closeable c) { |
|
198 if(c!=null) { |
|
199 try { |
|
200 c.close(); |
|
201 } catch(IOException e) { |
|
202 Log.w(TAG, e); |
|
203 } |
|
204 } |
|
205 } |
|
206 |
|
207 /** |
|
208 * Write all data from the input stream to the file, creating or overwriting it. |
|
209 * The input stream will be closed. |
|
210 * |
|
211 * @throws IOException |
|
212 */ |
|
213 public static void writeStreamToFile(InputStream is, File file) throws IOException { |
|
214 OutputStream os = null; |
|
215 byte[] buffer = new byte[8192]; |
|
216 try { |
|
217 os = new FileOutputStream(file); |
|
218 int size; |
|
219 while((size=is.read(buffer)) != -1) { |
|
220 os.write(buffer, 0, size); |
|
221 } |
|
222 os.close(); // Important to close this non-quietly, in case of exceptions when flushing |
|
223 } finally { |
|
224 Utils.closeQuietly(is); |
|
225 Utils.closeQuietly(os); |
|
226 } |
|
227 } |
|
228 |
|
229 /** |
169 * Moves resources pointed to by sourceResId (from @res/raw/) to the app's private data directory |
230 * Moves resources pointed to by sourceResId (from @res/raw/) to the app's private data directory |
170 * @param c |
231 * @param c |
171 * @param sourceResId |
232 * @param sourceResId |
172 * @param directory |
233 * @param directory |
173 */ |
234 */ |
174 public static void resRawToFilesDir(Context c, int sourceResId, String directory){ |
235 public static void resRawToFilesDir(Context c, int sourceResId, String directory) throws IOException { |
175 byte[] buffer = new byte[1024]; |
236 File targetDir = new File(c.getFilesDir(), directory); |
176 InputStream bis = null; |
237 targetDir.mkdirs(); |
177 BufferedOutputStream bos = null; |
|
178 File schemesDirFile = new File(c.getFilesDir().getAbsolutePath() + '/' + directory); |
|
179 schemesDirFile.mkdirs(); |
|
180 String schemesDirPath = schemesDirFile.getAbsolutePath() + '/'; |
|
181 |
238 |
182 //Get an array with the resource files ID |
239 //Get an array with the resource files ID |
183 TypedArray ta = c.getResources().obtainTypedArray(sourceResId); |
240 Resources resources = c.getResources(); |
184 int[] resIds = new int[ta.length()]; |
241 TypedArray ta = resources.obtainTypedArray(sourceResId); |
185 for(int i = 0; i < ta.length(); i++){ |
242 for(int i = 0; i < ta.length(); i++){ |
186 resIds[i] = ta.getResourceId(i, 0); |
243 int resId = ta.getResourceId(i, 0); |
187 } |
244 String fileName = resources.getResourceEntryName(resId); |
188 |
245 File f = new File(targetDir, fileName); |
189 for(int id : resIds){ |
246 writeStreamToFile(resources.openRawResource(resId), f); |
190 String fileName = c.getResources().getResourceEntryName(id); |
|
191 File f = new File(schemesDirPath + fileName); |
|
192 try { |
|
193 if(!f.createNewFile()){ |
|
194 f.delete(); |
|
195 f.createNewFile(); |
|
196 } |
|
197 |
|
198 bis = c.getResources().openRawResource(id); |
|
199 bos = new BufferedOutputStream(new FileOutputStream(f), 1024); |
|
200 int read = 0; |
|
201 while((read = bis.read(buffer)) != -1){ |
|
202 bos.write(buffer, 0, read); |
|
203 } |
|
204 |
|
205 } catch (IOException e) { |
|
206 e.printStackTrace(); |
|
207 }finally{ |
|
208 if(bis != null) |
|
209 try { |
|
210 bis.close(); |
|
211 } catch (IOException e) { |
|
212 e.printStackTrace(); |
|
213 } |
|
214 if(bos != null) |
|
215 try { |
|
216 bos.close(); |
|
217 } catch (IOException e) { |
|
218 e.printStackTrace(); |
|
219 } |
|
220 } |
|
221 } |
247 } |
222 } |
248 } |
223 } |
249 } |