mobile_template 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (211) hide show
  1. data/.gitignore +17 -0
  2. data/Gemfile +4 -0
  3. data/LICENSE +22 -0
  4. data/README.md +28 -0
  5. data/Rakefile +3 -0
  6. data/bin/mobile_template +71 -0
  7. data/lib/mobile_template/version.rb +4 -0
  8. data/lib/mobile_template.rb +5 -0
  9. data/mobile_template.gemspec +21 -0
  10. data/templates/assets/Gemfile +4 -0
  11. data/templates/assets/config.rb +96 -0
  12. data/templates/assets/config.ru +4 -0
  13. data/templates/assets/source/images/vendor/ajax-loader.gif +0 -0
  14. data/templates/assets/source/images/vendor/ajax-loader.png +0 -0
  15. data/templates/assets/source/images/vendor/icons-18-black.png +0 -0
  16. data/templates/assets/source/images/vendor/icons-18-white.png +0 -0
  17. data/templates/assets/source/images/vendor/icons-36-black.png +0 -0
  18. data/templates/assets/source/images/vendor/icons-36-white.png +0 -0
  19. data/templates/assets/source/index.html.erb +2 -0
  20. data/templates/assets/source/javascripts/app/index.js.coffee +2 -0
  21. data/templates/assets/source/javascripts/application.js.coffee +5 -0
  22. data/templates/assets/source/javascripts/vendor/cordova.js +4841 -0
  23. data/templates/assets/source/javascripts/vendor/jquery.js +9267 -0
  24. data/templates/assets/source/javascripts/vendor/jquery.mobile.js +7410 -0
  25. data/templates/assets/source/layout.erb +24 -0
  26. data/templates/assets/source/stylesheets/application.css.scss +2 -0
  27. data/templates/assets/source/stylesheets/vendor/jquery.mobile.css.scss +1872 -0
  28. data/templates/cordova_android/.gitignore +18 -0
  29. data/templates/cordova_android/LICENSE +202 -0
  30. data/templates/cordova_android/NOTICE +5 -0
  31. data/templates/cordova_android/README.md +95 -0
  32. data/templates/cordova_android/VERSION +1 -0
  33. data/templates/cordova_android/bin/BOOM +4 -0
  34. data/templates/cordova_android/bin/autotest +2 -0
  35. data/templates/cordova_android/bin/bench +29 -0
  36. data/templates/cordova_android/bin/create +46 -0
  37. data/templates/cordova_android/bin/create.bat +1 -0
  38. data/templates/cordova_android/bin/create.js +88 -0
  39. data/templates/cordova_android/bin/create.xml +79 -0
  40. data/templates/cordova_android/bin/node_modules/.bin/cake +7 -0
  41. data/templates/cordova_android/bin/node_modules/.bin/coffee +7 -0
  42. data/templates/cordova_android/bin/node_modules/.bin/nodeunit +120 -0
  43. data/templates/cordova_android/bin/node_modules/coffee-script/.npmignore +11 -0
  44. data/templates/cordova_android/bin/node_modules/coffee-script/LICENSE +22 -0
  45. data/templates/cordova_android/bin/node_modules/coffee-script/README +48 -0
  46. data/templates/cordova_android/bin/node_modules/coffee-script/Rakefile +78 -0
  47. data/templates/cordova_android/bin/node_modules/coffee-script/bin/cake +7 -0
  48. data/templates/cordova_android/bin/node_modules/coffee-script/bin/coffee +7 -0
  49. data/templates/cordova_android/bin/node_modules/coffee-script/extras/jsl.conf +44 -0
  50. data/templates/cordova_android/bin/node_modules/coffee-script/lib/browser.js +75 -0
  51. data/templates/cordova_android/bin/node_modules/coffee-script/lib/cake.js +76 -0
  52. data/templates/cordova_android/bin/node_modules/coffee-script/lib/coffee-script.js +135 -0
  53. data/templates/cordova_android/bin/node_modules/coffee-script/lib/command.js +301 -0
  54. data/templates/cordova_android/bin/node_modules/coffee-script/lib/grammar.js +591 -0
  55. data/templates/cordova_android/bin/node_modules/coffee-script/lib/helpers.js +66 -0
  56. data/templates/cordova_android/bin/node_modules/coffee-script/lib/index.js +8 -0
  57. data/templates/cordova_android/bin/node_modules/coffee-script/lib/lexer.js +656 -0
  58. data/templates/cordova_android/bin/node_modules/coffee-script/lib/nodes.js +2289 -0
  59. data/templates/cordova_android/bin/node_modules/coffee-script/lib/optparse.js +111 -0
  60. data/templates/cordova_android/bin/node_modules/coffee-script/lib/parser.js +676 -0
  61. data/templates/cordova_android/bin/node_modules/coffee-script/lib/repl.js +123 -0
  62. data/templates/cordova_android/bin/node_modules/coffee-script/lib/rewriter.js +363 -0
  63. data/templates/cordova_android/bin/node_modules/coffee-script/lib/scope.js +120 -0
  64. data/templates/cordova_android/bin/node_modules/coffee-script/package.json +27 -0
  65. data/templates/cordova_android/bin/node_modules/nodeunit/.gitignore +5 -0
  66. data/templates/cordova_android/bin/node_modules/nodeunit/.npmignore +3 -0
  67. data/templates/cordova_android/bin/node_modules/nodeunit/CONTRIBUTORS.md +60 -0
  68. data/templates/cordova_android/bin/node_modules/nodeunit/LICENSE +19 -0
  69. data/templates/cordova_android/bin/node_modules/nodeunit/Makefile +126 -0
  70. data/templates/cordova_android/bin/node_modules/nodeunit/README.md +432 -0
  71. data/templates/cordova_android/bin/node_modules/nodeunit/bin/nodeunit +120 -0
  72. data/templates/cordova_android/bin/node_modules/nodeunit/bin/nodeunit.json +10 -0
  73. data/templates/cordova_android/bin/node_modules/nodeunit/deps/async.js +623 -0
  74. data/templates/cordova_android/bin/node_modules/nodeunit/deps/console.log.js +55 -0
  75. data/templates/cordova_android/bin/node_modules/nodeunit/deps/ejs.js +125 -0
  76. data/templates/cordova_android/bin/node_modules/nodeunit/deps/json2.js +483 -0
  77. data/templates/cordova_android/bin/node_modules/nodeunit/examples/browser/nodeunit.js +1757 -0
  78. data/templates/cordova_android/bin/node_modules/nodeunit/examples/browser/suite1.js +12 -0
  79. data/templates/cordova_android/bin/node_modules/nodeunit/examples/browser/suite2.js +13 -0
  80. data/templates/cordova_android/bin/node_modules/nodeunit/examples/browser/test.html +16 -0
  81. data/templates/cordova_android/bin/node_modules/nodeunit/img/example_fail.png +0 -0
  82. data/templates/cordova_android/bin/node_modules/nodeunit/img/example_pass.png +0 -0
  83. data/templates/cordova_android/bin/node_modules/nodeunit/index.js +3 -0
  84. data/templates/cordova_android/bin/node_modules/nodeunit/lib/assert.js +316 -0
  85. data/templates/cordova_android/bin/node_modules/nodeunit/lib/core.js +260 -0
  86. data/templates/cordova_android/bin/node_modules/nodeunit/lib/nodeunit.js +82 -0
  87. data/templates/cordova_android/bin/node_modules/nodeunit/lib/reporters/browser.js +119 -0
  88. data/templates/cordova_android/bin/node_modules/nodeunit/lib/reporters/default.js +123 -0
  89. data/templates/cordova_android/bin/node_modules/nodeunit/lib/reporters/html.js +107 -0
  90. data/templates/cordova_android/bin/node_modules/nodeunit/lib/reporters/index.js +9 -0
  91. data/templates/cordova_android/bin/node_modules/nodeunit/lib/reporters/junit.js +183 -0
  92. data/templates/cordova_android/bin/node_modules/nodeunit/lib/reporters/minimal.js +112 -0
  93. data/templates/cordova_android/bin/node_modules/nodeunit/lib/reporters/skip_passed.js +105 -0
  94. data/templates/cordova_android/bin/node_modules/nodeunit/lib/track.js +48 -0
  95. data/templates/cordova_android/bin/node_modules/nodeunit/lib/types.js +187 -0
  96. data/templates/cordova_android/bin/node_modules/nodeunit/lib/utils.js +209 -0
  97. data/templates/cordova_android/bin/node_modules/nodeunit/man1/nodeunit.1 +95 -0
  98. data/templates/cordova_android/bin/node_modules/nodeunit/nodelint.cfg +4 -0
  99. data/templates/cordova_android/bin/node_modules/nodeunit/package.json +56 -0
  100. data/templates/cordova_android/bin/node_modules/nodeunit/share/junit.xml.ejs +19 -0
  101. data/templates/cordova_android/bin/node_modules/nodeunit/share/license.js +11 -0
  102. data/templates/cordova_android/bin/node_modules/nodeunit/share/nodeunit.css +70 -0
  103. data/templates/cordova_android/bin/templates/project/.cordova/android/readme.md +1 -0
  104. data/templates/cordova_android/bin/templates/project/.cordova/readme.md +3 -0
  105. data/templates/cordova_android/bin/templates/project/cordova/create +36 -0
  106. data/templates/cordova_android/bin/templates/project/cordova/debug +9 -0
  107. data/templates/cordova_android/bin/templates/project/cordova/emulate +12 -0
  108. data/templates/cordova_android/bin/templates/project/cordova/log +3 -0
  109. data/templates/cordova_android/bin/templates/project/cordova/templates/Activity.java +16 -0
  110. data/templates/cordova_android/bin/templates/project/cordova/templates/project/AndroidManifest.xml +50 -0
  111. data/templates/cordova_android/bin/templates/project/cordova/templates/project/assets/www/index.html +42 -0
  112. data/templates/cordova_android/bin/templates/project/cordova/templates/project/assets/www/main.js +146 -0
  113. data/templates/cordova_android/bin/templates/project/cordova/templates/project/assets/www/master.css +96 -0
  114. data/templates/cordova_android/bin/templates/project/cordova/templates/project/res/drawable/icon.png +0 -0
  115. data/templates/cordova_android/bin/templates/project/cordova/templates/project/res/xml/cordova.xml +5 -0
  116. data/templates/cordova_android/bin/templates/project/cordova/templates/project/res/xml/plugins.xml +19 -0
  117. data/templates/cordova_android/bin/test +26 -0
  118. data/templates/cordova_android/bin/tests/autotest.coffee +4 -0
  119. data/templates/cordova_android/bin/tests/create.coffee +21 -0
  120. data/templates/cordova_android/bin/tests/debug.coffee +0 -0
  121. data/templates/cordova_android/bin/tests/test.coffee +0 -0
  122. data/templates/cordova_android/framework/.classpath +8 -0
  123. data/templates/cordova_android/framework/.project +33 -0
  124. data/templates/cordova_android/framework/AndroidManifest.xml +68 -0
  125. data/templates/cordova_android/framework/ant.properties +34 -0
  126. data/templates/cordova_android/framework/assets/js/accelerometer.js +137 -0
  127. data/templates/cordova_android/framework/assets/js/app.js +89 -0
  128. data/templates/cordova_android/framework/assets/js/battery.js +134 -0
  129. data/templates/cordova_android/framework/assets/js/camera.js +168 -0
  130. data/templates/cordova_android/framework/assets/js/capture.js +203 -0
  131. data/templates/cordova_android/framework/assets/js/compass.js +168 -0
  132. data/templates/cordova_android/framework/assets/js/contact.js +310 -0
  133. data/templates/cordova_android/framework/assets/js/cordova.android.js +4841 -0
  134. data/templates/cordova_android/framework/assets/js/cordova.js.base +924 -0
  135. data/templates/cordova_android/framework/assets/js/crypto.js +54 -0
  136. data/templates/cordova_android/framework/assets/js/device.js +83 -0
  137. data/templates/cordova_android/framework/assets/js/file.js +1082 -0
  138. data/templates/cordova_android/framework/assets/js/filetransfer.js +125 -0
  139. data/templates/cordova_android/framework/assets/js/geolocation.js +209 -0
  140. data/templates/cordova_android/framework/assets/js/header.txt +19 -0
  141. data/templates/cordova_android/framework/assets/js/media.js +233 -0
  142. data/templates/cordova_android/framework/assets/js/network.js +100 -0
  143. data/templates/cordova_android/framework/assets/js/notification.js +133 -0
  144. data/templates/cordova_android/framework/assets/js/position.js +100 -0
  145. data/templates/cordova_android/framework/assets/js/storage.js +439 -0
  146. data/templates/cordova_android/framework/assets/www/index.html +27 -0
  147. data/templates/cordova_android/framework/build.xml +216 -0
  148. data/templates/cordova_android/framework/libs/commons-codec-1.3.jar +0 -0
  149. data/templates/cordova_android/framework/proguard-project.txt +20 -0
  150. data/templates/cordova_android/framework/project.properties +14 -0
  151. data/templates/cordova_android/framework/res/drawable/icon.png +0 -0
  152. data/templates/cordova_android/framework/res/drawable/splash.png +0 -0
  153. data/templates/cordova_android/framework/res/layout/main.xml +29 -0
  154. data/templates/cordova_android/framework/res/values/strings.xml +23 -0
  155. data/templates/cordova_android/framework/res/xml/cordova.xml +37 -0
  156. data/templates/cordova_android/framework/res/xml/plugins.xml +37 -0
  157. data/templates/cordova_android/framework/src/com/phonegap/api/IPlugin.java +27 -0
  158. data/templates/cordova_android/framework/src/com/phonegap/api/LOG.java +28 -0
  159. data/templates/cordova_android/framework/src/com/phonegap/api/PhonegapActivity.java +28 -0
  160. data/templates/cordova_android/framework/src/com/phonegap/api/Plugin.java +27 -0
  161. data/templates/cordova_android/framework/src/com/phonegap/api/PluginManager.java +35 -0
  162. data/templates/cordova_android/framework/src/com/phonegap/api/PluginResult.java +53 -0
  163. data/templates/cordova_android/framework/src/org/apache/cordova/AccelListener.java +311 -0
  164. data/templates/cordova_android/framework/src/org/apache/cordova/App.java +198 -0
  165. data/templates/cordova_android/framework/src/org/apache/cordova/AudioHandler.java +364 -0
  166. data/templates/cordova_android/framework/src/org/apache/cordova/AudioPlayer.java +450 -0
  167. data/templates/cordova_android/framework/src/org/apache/cordova/AuthenticationToken.java +69 -0
  168. data/templates/cordova_android/framework/src/org/apache/cordova/BatteryListener.java +156 -0
  169. data/templates/cordova_android/framework/src/org/apache/cordova/CallbackServer.java +431 -0
  170. data/templates/cordova_android/framework/src/org/apache/cordova/CameraLauncher.java +500 -0
  171. data/templates/cordova_android/framework/src/org/apache/cordova/Capture.java +400 -0
  172. data/templates/cordova_android/framework/src/org/apache/cordova/CompassListener.java +308 -0
  173. data/templates/cordova_android/framework/src/org/apache/cordova/ContactAccessor.java +198 -0
  174. data/templates/cordova_android/framework/src/org/apache/cordova/ContactAccessorSdk5.java +1934 -0
  175. data/templates/cordova_android/framework/src/org/apache/cordova/ContactManager.java +113 -0
  176. data/templates/cordova_android/framework/src/org/apache/cordova/CordovaChromeClient.java +314 -0
  177. data/templates/cordova_android/framework/src/org/apache/cordova/CordovaWebViewClient.java +306 -0
  178. data/templates/cordova_android/framework/src/org/apache/cordova/Device.java +219 -0
  179. data/templates/cordova_android/framework/src/org/apache/cordova/DirectoryManager.java +161 -0
  180. data/templates/cordova_android/framework/src/org/apache/cordova/DroidGap.java +1417 -0
  181. data/templates/cordova_android/framework/src/org/apache/cordova/ExifHelper.java +165 -0
  182. data/templates/cordova_android/framework/src/org/apache/cordova/FileTransfer.java +458 -0
  183. data/templates/cordova_android/framework/src/org/apache/cordova/FileUploadResult.java +63 -0
  184. data/templates/cordova_android/framework/src/org/apache/cordova/FileUtils.java +1048 -0
  185. data/templates/cordova_android/framework/src/org/apache/cordova/GeoBroker.java +165 -0
  186. data/templates/cordova_android/framework/src/org/apache/cordova/GeoListener.java +133 -0
  187. data/templates/cordova_android/framework/src/org/apache/cordova/GpsListener.java +163 -0
  188. data/templates/cordova_android/framework/src/org/apache/cordova/HttpHandler.java +80 -0
  189. data/templates/cordova_android/framework/src/org/apache/cordova/LinearLayoutSoftKeyboardDetect.java +104 -0
  190. data/templates/cordova_android/framework/src/org/apache/cordova/NetworkListener.java +153 -0
  191. data/templates/cordova_android/framework/src/org/apache/cordova/NetworkManager.java +248 -0
  192. data/templates/cordova_android/framework/src/org/apache/cordova/Notification.java +366 -0
  193. data/templates/cordova_android/framework/src/org/apache/cordova/PreferenceNode.java +34 -0
  194. data/templates/cordova_android/framework/src/org/apache/cordova/PreferenceSet.java +62 -0
  195. data/templates/cordova_android/framework/src/org/apache/cordova/StandAlone.java +35 -0
  196. data/templates/cordova_android/framework/src/org/apache/cordova/Storage.java +239 -0
  197. data/templates/cordova_android/framework/src/org/apache/cordova/TempListener.java +112 -0
  198. data/templates/cordova_android/framework/src/org/apache/cordova/api/CordovaInterface.java +145 -0
  199. data/templates/cordova_android/framework/src/org/apache/cordova/api/IPlugin.java +116 -0
  200. data/templates/cordova_android/framework/src/org/apache/cordova/api/LOG.java +234 -0
  201. data/templates/cordova_android/framework/src/org/apache/cordova/api/Plugin.java +210 -0
  202. data/templates/cordova_android/framework/src/org/apache/cordova/api/PluginManager.java +359 -0
  203. data/templates/cordova_android/framework/src/org/apache/cordova/api/PluginResult.java +119 -0
  204. data/templates/cordova_android/framework/src/org/apache/cordova/file/EncodingException.java +28 -0
  205. data/templates/cordova_android/framework/src/org/apache/cordova/file/FileExistsException.java +28 -0
  206. data/templates/cordova_android/framework/src/org/apache/cordova/file/InvalidModificationException.java +29 -0
  207. data/templates/cordova_android/framework/src/org/apache/cordova/file/NoModificationAllowedException.java +28 -0
  208. data/templates/cordova_android/framework/src/org/apache/cordova/file/TypeMismatchException.java +29 -0
  209. data/templates/cordova_android/framework/test/org/apache/cordova/PreferenceNodeTest.java +53 -0
  210. data/templates/cordova_android/framework/test/org/apache/cordova/PreferenceSetTest.java +73 -0
  211. metadata +279 -0
@@ -0,0 +1,165 @@
1
+ /*
2
+ Licensed to the Apache Software Foundation (ASF) under one
3
+ or more contributor license agreements. See the NOTICE file
4
+ distributed with this work for additional information
5
+ regarding copyright ownership. The ASF licenses this file
6
+ to you under the Apache License, Version 2.0 (the
7
+ "License"); you may not use this file except in compliance
8
+ with the License. You may obtain a copy of the License at
9
+
10
+ http://www.apache.org/licenses/LICENSE-2.0
11
+
12
+ Unless required by applicable law or agreed to in writing,
13
+ software distributed under the License is distributed on an
14
+ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15
+ KIND, either express or implied. See the License for the
16
+ specific language governing permissions and limitations
17
+ under the License.
18
+ */
19
+ package org.apache.cordova;
20
+
21
+ import java.io.IOException;
22
+
23
+ import android.media.ExifInterface;
24
+
25
+ public class ExifHelper {
26
+ private String aperature = null;
27
+ private String datetime = null;
28
+ private String exposureTime = null;
29
+ private String flash = null;
30
+ private String focalLength = null;
31
+ private String gpsAltitude = null;
32
+ private String gpsAltitudeRef = null;
33
+ private String gpsDateStamp = null;
34
+ private String gpsLatitude = null;
35
+ private String gpsLatitudeRef = null;
36
+ private String gpsLongitude = null;
37
+ private String gpsLongitudeRef = null;
38
+ private String gpsProcessingMethod = null;
39
+ private String gpsTimestamp = null;
40
+ private String iso = null;
41
+ private String make = null;
42
+ private String model = null;
43
+ private String orientation = null;
44
+ private String whiteBalance = null;
45
+
46
+ private ExifInterface inFile = null;
47
+ private ExifInterface outFile = null;
48
+
49
+ /**
50
+ * The file before it is compressed
51
+ *
52
+ * @param filePath
53
+ * @throws IOException
54
+ */
55
+ public void createInFile(String filePath) throws IOException {
56
+ this.inFile = new ExifInterface(filePath);
57
+ }
58
+
59
+ /**
60
+ * The file after it has been compressed
61
+ *
62
+ * @param filePath
63
+ * @throws IOException
64
+ */
65
+ public void createOutFile(String filePath) throws IOException {
66
+ this.outFile = new ExifInterface(filePath);
67
+ }
68
+
69
+ /**
70
+ * Reads all the EXIF data from the input file.
71
+ */
72
+ public void readExifData() {
73
+ this.aperature = inFile.getAttribute(ExifInterface.TAG_APERTURE);
74
+ this.datetime = inFile.getAttribute(ExifInterface.TAG_DATETIME);
75
+ this.exposureTime = inFile.getAttribute(ExifInterface.TAG_EXPOSURE_TIME);
76
+ this.flash = inFile.getAttribute(ExifInterface.TAG_FLASH);
77
+ this.focalLength = inFile.getAttribute(ExifInterface.TAG_FOCAL_LENGTH);
78
+ this.gpsAltitude = inFile.getAttribute(ExifInterface.TAG_GPS_ALTITUDE);
79
+ this.gpsAltitudeRef = inFile.getAttribute(ExifInterface.TAG_GPS_ALTITUDE_REF);
80
+ this.gpsDateStamp = inFile.getAttribute(ExifInterface.TAG_GPS_DATESTAMP);
81
+ this.gpsLatitude = inFile.getAttribute(ExifInterface.TAG_GPS_LATITUDE);
82
+ this.gpsLatitudeRef = inFile.getAttribute(ExifInterface.TAG_GPS_LATITUDE_REF);
83
+ this.gpsLongitude = inFile.getAttribute(ExifInterface.TAG_GPS_LONGITUDE);
84
+ this.gpsLongitudeRef = inFile.getAttribute(ExifInterface.TAG_GPS_LONGITUDE_REF);
85
+ this.gpsProcessingMethod = inFile.getAttribute(ExifInterface.TAG_GPS_PROCESSING_METHOD);
86
+ this.gpsTimestamp = inFile.getAttribute(ExifInterface.TAG_GPS_TIMESTAMP);
87
+ this.iso = inFile.getAttribute(ExifInterface.TAG_ISO);
88
+ this.make = inFile.getAttribute(ExifInterface.TAG_MAKE);
89
+ this.model = inFile.getAttribute(ExifInterface.TAG_MODEL);
90
+ this.orientation = inFile.getAttribute(ExifInterface.TAG_ORIENTATION);
91
+ this.whiteBalance = inFile.getAttribute(ExifInterface.TAG_WHITE_BALANCE);
92
+ }
93
+
94
+ /**
95
+ * Writes the previously stored EXIF data to the output file.
96
+ *
97
+ * @throws IOException
98
+ */
99
+ public void writeExifData() throws IOException {
100
+ // Don't try to write to a null file
101
+ if (this.outFile == null) {
102
+ return;
103
+ }
104
+
105
+ if (this.aperature != null) {
106
+ this.outFile.setAttribute(ExifInterface.TAG_APERTURE, this.aperature);
107
+ }
108
+ if (this.datetime != null) {
109
+ this.outFile.setAttribute(ExifInterface.TAG_DATETIME, this.datetime);
110
+ }
111
+ if (this.exposureTime != null) {
112
+ this.outFile.setAttribute(ExifInterface.TAG_EXPOSURE_TIME, this.exposureTime);
113
+ }
114
+ if (this.flash != null) {
115
+ this.outFile.setAttribute(ExifInterface.TAG_FLASH, this.flash);
116
+ }
117
+ if (this.focalLength != null) {
118
+ this.outFile.setAttribute(ExifInterface.TAG_FOCAL_LENGTH, this.focalLength);
119
+ }
120
+ if (this.gpsAltitude != null) {
121
+ this.outFile.setAttribute(ExifInterface.TAG_GPS_ALTITUDE, this.gpsAltitude);
122
+ }
123
+ if (this.gpsAltitudeRef != null) {
124
+ this.outFile.setAttribute(ExifInterface.TAG_GPS_ALTITUDE_REF, this.gpsAltitudeRef);
125
+ }
126
+ if (this.gpsDateStamp != null) {
127
+ this.outFile.setAttribute(ExifInterface.TAG_GPS_DATESTAMP, this.gpsDateStamp);
128
+ }
129
+ if (this.gpsLatitude != null) {
130
+ this.outFile.setAttribute(ExifInterface.TAG_GPS_LATITUDE, this.gpsLatitude);
131
+ }
132
+ if (this.gpsLatitudeRef != null) {
133
+ this.outFile.setAttribute(ExifInterface.TAG_GPS_LATITUDE_REF, this.gpsLatitudeRef);
134
+ }
135
+ if (this.gpsLongitude != null) {
136
+ this.outFile.setAttribute(ExifInterface.TAG_GPS_LONGITUDE, this.gpsLongitude);
137
+ }
138
+ if (this.gpsLongitudeRef != null) {
139
+ this.outFile.setAttribute(ExifInterface.TAG_GPS_LONGITUDE_REF, this.gpsLongitudeRef);
140
+ }
141
+ if (this.gpsProcessingMethod != null) {
142
+ this.outFile.setAttribute(ExifInterface.TAG_GPS_PROCESSING_METHOD, this.gpsProcessingMethod);
143
+ }
144
+ if (this.gpsTimestamp != null) {
145
+ this.outFile.setAttribute(ExifInterface.TAG_GPS_TIMESTAMP, this.gpsTimestamp);
146
+ }
147
+ if (this.iso != null) {
148
+ this.outFile.setAttribute(ExifInterface.TAG_ISO, this.iso);
149
+ }
150
+ if (this.make != null) {
151
+ this.outFile.setAttribute(ExifInterface.TAG_MAKE, this.make);
152
+ }
153
+ if (this.model != null) {
154
+ this.outFile.setAttribute(ExifInterface.TAG_MODEL, this.model);
155
+ }
156
+ if (this.orientation != null) {
157
+ this.outFile.setAttribute(ExifInterface.TAG_ORIENTATION, this.orientation);
158
+ }
159
+ if (this.whiteBalance != null) {
160
+ this.outFile.setAttribute(ExifInterface.TAG_WHITE_BALANCE, this.whiteBalance);
161
+ }
162
+
163
+ this.outFile.saveAttributes();
164
+ }
165
+ }
@@ -0,0 +1,458 @@
1
+ /*
2
+ Licensed to the Apache Software Foundation (ASF) under one
3
+ or more contributor license agreements. See the NOTICE file
4
+ distributed with this work for additional information
5
+ regarding copyright ownership. The ASF licenses this file
6
+ to you under the Apache License, Version 2.0 (the
7
+ "License"); you may not use this file except in compliance
8
+ with the License. You may obtain a copy of the License at
9
+
10
+ http://www.apache.org/licenses/LICENSE-2.0
11
+
12
+ Unless required by applicable law or agreed to in writing,
13
+ software distributed under the License is distributed on an
14
+ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15
+ KIND, either express or implied. See the License for the
16
+ specific language governing permissions and limitations
17
+ under the License.
18
+ */
19
+ package org.apache.cordova;
20
+
21
+ import java.io.DataInputStream;
22
+ import java.io.DataOutputStream;
23
+ import java.io.File;
24
+ import java.io.FileInputStream;
25
+ import java.io.FileNotFoundException;
26
+ import java.io.FileOutputStream;
27
+ import java.io.IOException;
28
+ import java.io.InputStream;
29
+ import java.net.HttpURLConnection;
30
+ import java.net.URL;
31
+ import java.security.cert.CertificateException;
32
+ import java.security.cert.X509Certificate;
33
+ import java.util.Iterator;
34
+
35
+ import javax.net.ssl.HostnameVerifier;
36
+ import javax.net.ssl.HttpsURLConnection;
37
+ import javax.net.ssl.SSLContext;
38
+ import javax.net.ssl.SSLException;
39
+ import javax.net.ssl.SSLSession;
40
+ import javax.net.ssl.SSLSocketFactory;
41
+ import javax.net.ssl.TrustManager;
42
+ import javax.net.ssl.X509TrustManager;
43
+
44
+ import org.apache.cordova.api.Plugin;
45
+ import org.apache.cordova.api.PluginResult;
46
+ import org.json.JSONArray;
47
+ import org.json.JSONException;
48
+ import org.json.JSONObject;
49
+
50
+ import android.net.Uri;
51
+ import android.util.Log;
52
+ import android.webkit.CookieManager;
53
+
54
+
55
+ public class FileTransfer extends Plugin {
56
+
57
+ private static final String LOG_TAG = "FileTransfer";
58
+ private static final String LINE_START = "--";
59
+ private static final String LINE_END = "\r\n";
60
+ private static final String BOUNDRY = "*****";
61
+
62
+ public static int FILE_NOT_FOUND_ERR = 1;
63
+ public static int INVALID_URL_ERR = 2;
64
+ public static int CONNECTION_ERR = 3;
65
+
66
+ private SSLSocketFactory defaultSSLSocketFactory = null;
67
+ private HostnameVerifier defaultHostnameVerifier = null;
68
+
69
+ /* (non-Javadoc)
70
+ * @see org.apache.cordova.api.Plugin#execute(java.lang.String, org.json.JSONArray, java.lang.String)
71
+ */
72
+ @Override
73
+ public PluginResult execute(String action, JSONArray args, String callbackId) {
74
+ String source = null;
75
+ String target = null;
76
+ try {
77
+ source = args.getString(0);
78
+ target = args.getString(1);
79
+ }
80
+ catch (JSONException e) {
81
+ Log.d(LOG_TAG, "Missing source or target");
82
+ return new PluginResult(PluginResult.Status.JSON_EXCEPTION, "Missing source or target");
83
+ }
84
+
85
+ try {
86
+ if (action.equals("upload")) {
87
+ // Setup the options
88
+ String fileKey = null;
89
+ String fileName = null;
90
+ String mimeType = null;
91
+
92
+ fileKey = getArgument(args, 2, "file");
93
+ fileName = getArgument(args, 3, "image.jpg");
94
+ mimeType = getArgument(args, 4, "image/jpeg");
95
+ JSONObject params = args.optJSONObject(5);
96
+ boolean trustEveryone = args.optBoolean(6);
97
+ boolean chunkedMode = args.optBoolean(7);
98
+ FileUploadResult r = upload(source, target, fileKey, fileName, mimeType, params, trustEveryone, chunkedMode);
99
+ Log.d(LOG_TAG, "****** About to return a result from upload");
100
+ return new PluginResult(PluginResult.Status.OK, r.toJSONObject());
101
+ } else if (action.equals("download")) {
102
+ JSONObject r = download(source, target);
103
+ Log.d(LOG_TAG, "****** About to return a result from download");
104
+ return new PluginResult(PluginResult.Status.OK, r);
105
+ } else {
106
+ return new PluginResult(PluginResult.Status.INVALID_ACTION);
107
+ }
108
+ } catch (FileNotFoundException e) {
109
+ Log.e(LOG_TAG, e.getMessage(), e);
110
+ JSONObject error = createFileTransferError(FILE_NOT_FOUND_ERR, source, target);
111
+ return new PluginResult(PluginResult.Status.IO_EXCEPTION, error);
112
+ } catch (IllegalArgumentException e) {
113
+ Log.e(LOG_TAG, e.getMessage(), e);
114
+ JSONObject error = createFileTransferError(INVALID_URL_ERR, source, target);
115
+ return new PluginResult(PluginResult.Status.IO_EXCEPTION, error);
116
+ } catch (SSLException e) {
117
+ Log.e(LOG_TAG, e.getMessage(), e);
118
+ Log.d(LOG_TAG, "Got my ssl exception!!!");
119
+ JSONObject error = createFileTransferError(CONNECTION_ERR, source, target);
120
+ return new PluginResult(PluginResult.Status.IO_EXCEPTION, error);
121
+ } catch (IOException e) {
122
+ Log.e(LOG_TAG, e.getMessage(), e);
123
+ JSONObject error = createFileTransferError(CONNECTION_ERR, source, target);
124
+ return new PluginResult(PluginResult.Status.IO_EXCEPTION, error);
125
+ } catch (JSONException e) {
126
+ Log.e(LOG_TAG, e.getMessage(), e);
127
+ return new PluginResult(PluginResult.Status.JSON_EXCEPTION);
128
+ }
129
+ }
130
+
131
+ // always verify the host - don't check for certificate
132
+ final static HostnameVerifier DO_NOT_VERIFY = new HostnameVerifier() {
133
+ public boolean verify(String hostname, SSLSession session) {
134
+ return true;
135
+ }
136
+ };
137
+
138
+ /**
139
+ * This function will install a trust manager that will blindly trust all SSL
140
+ * certificates. The reason this code is being added is to enable developers
141
+ * to do development using self signed SSL certificates on their web server.
142
+ *
143
+ * The standard HttpsURLConnection class will throw an exception on self
144
+ * signed certificates if this code is not run.
145
+ */
146
+ private void trustAllHosts() {
147
+ // Create a trust manager that does not validate certificate chains
148
+ TrustManager[] trustAllCerts = new TrustManager[] { new X509TrustManager() {
149
+ public java.security.cert.X509Certificate[] getAcceptedIssuers() {
150
+ return new java.security.cert.X509Certificate[] {};
151
+ }
152
+
153
+ public void checkClientTrusted(X509Certificate[] chain,
154
+ String authType) throws CertificateException {
155
+ }
156
+
157
+ public void checkServerTrusted(X509Certificate[] chain,
158
+ String authType) throws CertificateException {
159
+ }
160
+ } };
161
+
162
+ // Install the all-trusting trust manager
163
+ try {
164
+ // Backup the current SSL socket factory
165
+ defaultSSLSocketFactory = HttpsURLConnection.getDefaultSSLSocketFactory();
166
+ // Install our all trusting manager
167
+ SSLContext sc = SSLContext.getInstance("TLS");
168
+ sc.init(null, trustAllCerts, new java.security.SecureRandom());
169
+ HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory());
170
+ } catch (Exception e) {
171
+ Log.e(LOG_TAG, e.getMessage(), e);
172
+ }
173
+ }
174
+
175
+ /**
176
+ * Create an error object based on the passed in errorCode
177
+ * @param errorCode the error
178
+ * @return JSONObject containing the error
179
+ */
180
+ private JSONObject createFileTransferError(int errorCode, String source, String target) {
181
+ JSONObject error = null;
182
+ try {
183
+ error = new JSONObject();
184
+ error.put("code", errorCode);
185
+ error.put("source", source);
186
+ error.put("target", target);
187
+ } catch (JSONException e) {
188
+ Log.e(LOG_TAG, e.getMessage(), e);
189
+ }
190
+ return error;
191
+ }
192
+
193
+ /**
194
+ * Convenience method to read a parameter from the list of JSON args.
195
+ * @param args the args passed to the Plugin
196
+ * @param position the position to retrieve the arg from
197
+ * @param defaultString the default to be used if the arg does not exist
198
+ * @return String with the retrieved value
199
+ */
200
+ private String getArgument(JSONArray args, int position, String defaultString) {
201
+ String arg = defaultString;
202
+ if(args.length() >= position) {
203
+ arg = args.optString(position);
204
+ if (arg == null || "null".equals(arg)) {
205
+ arg = defaultString;
206
+ }
207
+ }
208
+ return arg;
209
+ }
210
+
211
+ /**
212
+ * Uploads the specified file to the server URL provided using an HTTP
213
+ * multipart request.
214
+ * @param file Full path of the file on the file system
215
+ * @param server URL of the server to receive the file
216
+ * @param fileKey Name of file request parameter
217
+ * @param fileName File name to be used on server
218
+ * @param mimeType Describes file content type
219
+ * @param params key:value pairs of user-defined parameters
220
+ * @return FileUploadResult containing result of upload request
221
+ */
222
+ public FileUploadResult upload(String file, String server, final String fileKey, final String fileName,
223
+ final String mimeType, JSONObject params, boolean trustEveryone, boolean chunkedMode) throws IOException, SSLException {
224
+ // Create return object
225
+ FileUploadResult result = new FileUploadResult();
226
+
227
+ // Get a input stream of the file on the phone
228
+ InputStream fileInputStream = getPathFromUri(file);
229
+
230
+ HttpURLConnection conn = null;
231
+ DataOutputStream dos = null;
232
+
233
+ int bytesRead, bytesAvailable, bufferSize;
234
+ long totalBytes;
235
+ byte[] buffer;
236
+ int maxBufferSize = 8096;
237
+
238
+ //------------------ CLIENT REQUEST
239
+ // open a URL connection to the server
240
+ URL url = new URL(server);
241
+
242
+ // Open a HTTP connection to the URL based on protocol
243
+ if (url.getProtocol().toLowerCase().equals("https")) {
244
+ // Using standard HTTPS connection. Will not allow self signed certificate
245
+ if (!trustEveryone) {
246
+ conn = (HttpsURLConnection) url.openConnection();
247
+ }
248
+ // Use our HTTPS connection that blindly trusts everyone.
249
+ // This should only be used in debug environments
250
+ else {
251
+ // Setup the HTTPS connection class to trust everyone
252
+ trustAllHosts();
253
+ HttpsURLConnection https = (HttpsURLConnection) url.openConnection();
254
+ // Save the current hostnameVerifier
255
+ defaultHostnameVerifier = https.getHostnameVerifier();
256
+ // Setup the connection not to verify hostnames
257
+ https.setHostnameVerifier(DO_NOT_VERIFY);
258
+ conn = https;
259
+ }
260
+ }
261
+ // Return a standard HTTP connection
262
+ else {
263
+ conn = (HttpURLConnection) url.openConnection();
264
+ }
265
+
266
+ // Allow Inputs
267
+ conn.setDoInput(true);
268
+
269
+ // Allow Outputs
270
+ conn.setDoOutput(true);
271
+
272
+ // Don't use a cached copy.
273
+ conn.setUseCaches(false);
274
+
275
+ // Use a post method.
276
+ conn.setRequestMethod("POST");
277
+ conn.setRequestProperty("Connection", "Keep-Alive");
278
+ conn.setRequestProperty("Content-Type", "multipart/form-data;boundary="+BOUNDRY);
279
+
280
+ // Handle the other headers
281
+ try {
282
+ JSONObject headers = params.getJSONObject("headers");
283
+ for (Iterator iter = headers.keys(); iter.hasNext();)
284
+ {
285
+ String headerKey = iter.next().toString();
286
+ conn.setRequestProperty(headerKey, headers.getString(headerKey));
287
+ }
288
+ } catch (JSONException e1) {
289
+ // No headers to be manipulated!
290
+ }
291
+
292
+ // Set the cookies on the response
293
+ String cookie = CookieManager.getInstance().getCookie(server);
294
+ if (cookie != null) {
295
+ conn.setRequestProperty("Cookie", cookie);
296
+ }
297
+
298
+ // Should set this up as an option
299
+ if (chunkedMode) {
300
+ conn.setChunkedStreamingMode(maxBufferSize);
301
+ }
302
+
303
+ dos = new DataOutputStream( conn.getOutputStream() );
304
+
305
+ // Send any extra parameters
306
+ try {
307
+ for (Iterator iter = params.keys(); iter.hasNext();) {
308
+ Object key = iter.next();
309
+ if(key.toString() != "headers")
310
+ {
311
+ dos.writeBytes(LINE_START + BOUNDRY + LINE_END);
312
+ dos.writeBytes("Content-Disposition: form-data; name=\"" + key.toString() + "\";");
313
+ dos.writeBytes(LINE_END + LINE_END);
314
+ dos.write(params.getString(key.toString()).getBytes());
315
+ dos.writeBytes(LINE_END);
316
+ }
317
+ }
318
+ } catch (JSONException e) {
319
+ Log.e(LOG_TAG, e.getMessage(), e);
320
+ }
321
+
322
+ dos.writeBytes(LINE_START + BOUNDRY + LINE_END);
323
+ dos.writeBytes("Content-Disposition: form-data; name=\"" + fileKey + "\";" + " filename=\"" + fileName +"\"" + LINE_END);
324
+ dos.writeBytes("Content-Type: " + mimeType + LINE_END);
325
+ dos.writeBytes(LINE_END);
326
+
327
+ // create a buffer of maximum size
328
+ bytesAvailable = fileInputStream.available();
329
+ bufferSize = Math.min(bytesAvailable, maxBufferSize);
330
+ buffer = new byte[bufferSize];
331
+
332
+ // read file and write it into form...
333
+ bytesRead = fileInputStream.read(buffer, 0, bufferSize);
334
+ totalBytes = 0;
335
+
336
+ while (bytesRead > 0) {
337
+ totalBytes += bytesRead;
338
+ result.setBytesSent(totalBytes);
339
+ dos.write(buffer, 0, bufferSize);
340
+ bytesAvailable = fileInputStream.available();
341
+ bufferSize = Math.min(bytesAvailable, maxBufferSize);
342
+ bytesRead = fileInputStream.read(buffer, 0, bufferSize);
343
+ }
344
+
345
+ // send multipart form data necesssary after file data...
346
+ dos.writeBytes(LINE_END);
347
+ dos.writeBytes(LINE_START + BOUNDRY + LINE_START + LINE_END);
348
+
349
+ // close streams
350
+ fileInputStream.close();
351
+ dos.flush();
352
+ dos.close();
353
+
354
+ //------------------ read the SERVER RESPONSE
355
+ StringBuffer responseString = new StringBuffer("");
356
+ DataInputStream inStream;
357
+ try {
358
+ inStream = new DataInputStream ( conn.getInputStream() );
359
+ } catch(FileNotFoundException e) {
360
+ throw new IOException("Received error from server");
361
+ }
362
+
363
+ String line;
364
+ while (( line = inStream.readLine()) != null) {
365
+ responseString.append(line);
366
+ }
367
+ Log.d(LOG_TAG, "got response from server");
368
+ Log.d(LOG_TAG, responseString.toString());
369
+
370
+ // send request and retrieve response
371
+ result.setResponseCode(conn.getResponseCode());
372
+ result.setResponse(responseString.toString());
373
+
374
+ inStream.close();
375
+ conn.disconnect();
376
+
377
+ // Revert back to the proper verifier and socket factories
378
+ if (trustEveryone && url.getProtocol().toLowerCase().equals("https")) {
379
+ ((HttpsURLConnection)conn).setHostnameVerifier(defaultHostnameVerifier);
380
+ HttpsURLConnection.setDefaultSSLSocketFactory(defaultSSLSocketFactory);
381
+ }
382
+
383
+ return result;
384
+ }
385
+
386
+ /**
387
+ * Downloads a file form a given URL and saves it to the specified directory.
388
+ *
389
+ * @param source URL of the server to receive the file
390
+ * @param target Full path of the file on the file system
391
+ * @return JSONObject the downloaded file
392
+ */
393
+ public JSONObject download(String source, String target) throws IOException {
394
+ try {
395
+ File file = new File(target);
396
+
397
+ // create needed directories
398
+ file.getParentFile().mkdirs();
399
+
400
+ // connect to server
401
+ URL url = new URL(source);
402
+ HttpURLConnection connection = (HttpURLConnection) url.openConnection();
403
+ connection.setRequestMethod("GET");
404
+ connection.connect();
405
+
406
+ Log.d(LOG_TAG, "Download file:" + url);
407
+
408
+ InputStream inputStream = connection.getInputStream();
409
+ byte[] buffer = new byte[1024];
410
+ int bytesRead = 0;
411
+
412
+ FileOutputStream outputStream = new FileOutputStream(file);
413
+
414
+ // write bytes to file
415
+ while ( (bytesRead = inputStream.read(buffer)) > 0 ) {
416
+ outputStream.write(buffer,0, bytesRead);
417
+ }
418
+
419
+ outputStream.close();
420
+
421
+ Log.d(LOG_TAG, "Saved file: " + target);
422
+
423
+ // create FileEntry object
424
+ FileUtils fileUtil = new FileUtils();
425
+
426
+ return fileUtil.getEntry(file);
427
+ } catch (Exception e) {
428
+ Log.d(LOG_TAG, e.getMessage(), e);
429
+ throw new IOException("Error while downloading");
430
+ }
431
+ }
432
+
433
+ /**
434
+ * Get an input stream based on file path or content:// uri
435
+ *
436
+ * @param path
437
+ * @return an input stream
438
+ * @throws FileNotFoundException
439
+ */
440
+ private InputStream getPathFromUri(String path) throws FileNotFoundException {
441
+ if (path.startsWith("content:")) {
442
+ Uri uri = Uri.parse(path);
443
+ return ctx.getContentResolver().openInputStream(uri);
444
+ }
445
+ else if (path.startsWith("file://")) {
446
+ int question = path.indexOf("?");
447
+ if (question == -1) {
448
+ return new FileInputStream(path.substring(7));
449
+ } else {
450
+ return new FileInputStream(path.substring(7, question));
451
+ }
452
+ }
453
+ else {
454
+ return new FileInputStream(path);
455
+ }
456
+ }
457
+
458
+ }
@@ -0,0 +1,63 @@
1
+ /*
2
+ Licensed to the Apache Software Foundation (ASF) under one
3
+ or more contributor license agreements. See the NOTICE file
4
+ distributed with this work for additional information
5
+ regarding copyright ownership. The ASF licenses this file
6
+ to you under the Apache License, Version 2.0 (the
7
+ "License"); you may not use this file except in compliance
8
+ with the License. You may obtain a copy of the License at
9
+
10
+ http://www.apache.org/licenses/LICENSE-2.0
11
+
12
+ Unless required by applicable law or agreed to in writing,
13
+ software distributed under the License is distributed on an
14
+ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15
+ KIND, either express or implied. See the License for the
16
+ specific language governing permissions and limitations
17
+ under the License.
18
+ */
19
+ package org.apache.cordova;
20
+
21
+ import org.json.JSONException;
22
+ import org.json.JSONObject;
23
+
24
+ /**
25
+ * Encapsulates the result and/or status of uploading a file to a remote server.
26
+ */
27
+ public class FileUploadResult {
28
+
29
+ private long bytesSent = 0; // bytes sent
30
+ private int responseCode = -1; // HTTP response code
31
+ private String response = null; // HTTP response
32
+
33
+ public long getBytesSent() {
34
+ return bytesSent;
35
+ }
36
+
37
+ public void setBytesSent(long bytes) {
38
+ this.bytesSent = bytes;
39
+ }
40
+
41
+ public int getResponseCode() {
42
+ return responseCode;
43
+ }
44
+
45
+ public void setResponseCode(int responseCode) {
46
+ this.responseCode = responseCode;
47
+ }
48
+
49
+ public String getResponse() {
50
+ return response;
51
+ }
52
+
53
+ public void setResponse(String response) {
54
+ this.response = response;
55
+ }
56
+
57
+ public JSONObject toJSONObject() throws JSONException {
58
+ return new JSONObject(
59
+ "{bytesSent:" + bytesSent +
60
+ ",responseCode:" + responseCode +
61
+ ",response:" + JSONObject.quote(response) + "}");
62
+ }
63
+ }