remi-andrake 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (503) hide show
  1. data/LICENSE +22 -0
  2. data/README.markdown +3 -0
  3. data/Rakefile +57 -0
  4. data/examples/andrake/HelloAndroid/HelloAndroid.java +22 -0
  5. data/examples/andrake/HelloAndroid/init.rb +44 -0
  6. data/examples/andrake/HelloAndroid/layout/main.xml +13 -0
  7. data/examples/android/BasicUI/AndroidManifest.xml +20 -0
  8. data/examples/android/BasicUI/build.xml +269 -0
  9. data/examples/android/BasicUI/reinstall-and-debug-on-default-device +6 -0
  10. data/examples/android/BasicUI/reinstall-and-run-on-default-device +6 -0
  11. data/examples/android/BasicUI/res/drawable/icon.png +0 -0
  12. data/examples/android/BasicUI/res/layout/main.xml +23 -0
  13. data/examples/android/BasicUI/res/layout/result.xml +12 -0
  14. data/examples/android/BasicUI/res/values/colors.xml +10 -0
  15. data/examples/android/BasicUI/res/values/strings.xml +6 -0
  16. data/examples/android/BasicUI/src/com/android/basicui/AnotherView.java +39 -0
  17. data/examples/android/BasicUI/src/com/android/basicui/BasicUI.java +102 -0
  18. data/examples/android/BasicUI/src/com/android/basicui/R.java +36 -0
  19. data/examples/android/BasicUI/src/com/android/basicui/UiResult.java +20 -0
  20. data/examples/android/COPYING +1 -0
  21. data/examples/android/HelloAndroid/AndroidManifest.xml +15 -0
  22. data/examples/android/HelloAndroid/build.xml +269 -0
  23. data/examples/android/HelloAndroid/res/drawable/icon.png +0 -0
  24. data/examples/android/HelloAndroid/res/layout/main.xml +12 -0
  25. data/examples/android/HelloAndroid/res/values/strings.xml +5 -0
  26. data/examples/android/HelloAndroid/src/com/android/hello/HelloAndroid.java +16 -0
  27. data/examples/android/HelloAndroid/src/com/android/hello/R.java +23 -0
  28. data/examples/android/LICENSE +1 -0
  29. data/examples/android/LolcatBuilder/AndroidManifest.xml +32 -0
  30. data/examples/android/LolcatBuilder/README.txt +90 -0
  31. data/examples/android/LolcatBuilder/build.xml +269 -0
  32. data/examples/android/LolcatBuilder/res/drawable/app_icon.png +0 -0
  33. data/examples/android/LolcatBuilder/res/drawable/photo_border.9.png +0 -0
  34. data/examples/android/LolcatBuilder/res/layout-land/lolcat_activity.xml +91 -0
  35. data/examples/android/LolcatBuilder/res/layout/lolcat_activity.xml +90 -0
  36. data/examples/android/LolcatBuilder/res/layout/lolcat_caption_dialog.xml +68 -0
  37. data/examples/android/LolcatBuilder/res/values/strings.xml +45 -0
  38. data/examples/android/LolcatBuilder/src/com/android/lolcat/LolcatActivity.java +808 -0
  39. data/examples/android/LolcatBuilder/src/com/android/lolcat/LolcatView.java +638 -0
  40. data/examples/android/LolcatBuilder/src/com/android/lolcat/R.java +60 -0
  41. data/examples/android/README.markdown +9 -0
  42. data/examples/android/Translate/AndroidManifest.xml +35 -0
  43. data/examples/android/Translate/CHANGELOG +9 -0
  44. data/examples/android/Translate/README +13 -0
  45. data/examples/android/Translate/TODO +1 -0
  46. data/examples/android/Translate/build.xml +269 -0
  47. data/examples/android/Translate/res/drawable/ad.png +0 -0
  48. data/examples/android/Translate/res/drawable/ae.png +0 -0
  49. data/examples/android/Translate/res/drawable/af.png +0 -0
  50. data/examples/android/Translate/res/drawable/ag.png +0 -0
  51. data/examples/android/Translate/res/drawable/ai.png +0 -0
  52. data/examples/android/Translate/res/drawable/al.png +0 -0
  53. data/examples/android/Translate/res/drawable/am.png +0 -0
  54. data/examples/android/Translate/res/drawable/an.png +0 -0
  55. data/examples/android/Translate/res/drawable/ao.png +0 -0
  56. data/examples/android/Translate/res/drawable/ar.png +0 -0
  57. data/examples/android/Translate/res/drawable/as.png +0 -0
  58. data/examples/android/Translate/res/drawable/at.png +0 -0
  59. data/examples/android/Translate/res/drawable/au.png +0 -0
  60. data/examples/android/Translate/res/drawable/aw.png +0 -0
  61. data/examples/android/Translate/res/drawable/ax.png +0 -0
  62. data/examples/android/Translate/res/drawable/az.png +0 -0
  63. data/examples/android/Translate/res/drawable/ba.png +0 -0
  64. data/examples/android/Translate/res/drawable/babelfish.png +0 -0
  65. data/examples/android/Translate/res/drawable/bb.png +0 -0
  66. data/examples/android/Translate/res/drawable/bd.png +0 -0
  67. data/examples/android/Translate/res/drawable/be.png +0 -0
  68. data/examples/android/Translate/res/drawable/bf.png +0 -0
  69. data/examples/android/Translate/res/drawable/bg.png +0 -0
  70. data/examples/android/Translate/res/drawable/bh.png +0 -0
  71. data/examples/android/Translate/res/drawable/bi.png +0 -0
  72. data/examples/android/Translate/res/drawable/bj.png +0 -0
  73. data/examples/android/Translate/res/drawable/bm.png +0 -0
  74. data/examples/android/Translate/res/drawable/bn.png +0 -0
  75. data/examples/android/Translate/res/drawable/bo.png +0 -0
  76. data/examples/android/Translate/res/drawable/br.png +0 -0
  77. data/examples/android/Translate/res/drawable/bs.png +0 -0
  78. data/examples/android/Translate/res/drawable/bt.png +0 -0
  79. data/examples/android/Translate/res/drawable/bv.png +0 -0
  80. data/examples/android/Translate/res/drawable/bw.png +0 -0
  81. data/examples/android/Translate/res/drawable/by.png +0 -0
  82. data/examples/android/Translate/res/drawable/bz.png +0 -0
  83. data/examples/android/Translate/res/drawable/ca.png +0 -0
  84. data/examples/android/Translate/res/drawable/catalonia.png +0 -0
  85. data/examples/android/Translate/res/drawable/cc.png +0 -0
  86. data/examples/android/Translate/res/drawable/cd.png +0 -0
  87. data/examples/android/Translate/res/drawable/cf.png +0 -0
  88. data/examples/android/Translate/res/drawable/cg.png +0 -0
  89. data/examples/android/Translate/res/drawable/ch.png +0 -0
  90. data/examples/android/Translate/res/drawable/ci.png +0 -0
  91. data/examples/android/Translate/res/drawable/ck.png +0 -0
  92. data/examples/android/Translate/res/drawable/cl.png +0 -0
  93. data/examples/android/Translate/res/drawable/cm.png +0 -0
  94. data/examples/android/Translate/res/drawable/cn.png +0 -0
  95. data/examples/android/Translate/res/drawable/co.png +0 -0
  96. data/examples/android/Translate/res/drawable/cr.png +0 -0
  97. data/examples/android/Translate/res/drawable/cs.png +0 -0
  98. data/examples/android/Translate/res/drawable/cu.png +0 -0
  99. data/examples/android/Translate/res/drawable/cv.png +0 -0
  100. data/examples/android/Translate/res/drawable/cx.png +0 -0
  101. data/examples/android/Translate/res/drawable/cy.png +0 -0
  102. data/examples/android/Translate/res/drawable/cz.png +0 -0
  103. data/examples/android/Translate/res/drawable/de.png +0 -0
  104. data/examples/android/Translate/res/drawable/dj.png +0 -0
  105. data/examples/android/Translate/res/drawable/dk.png +0 -0
  106. data/examples/android/Translate/res/drawable/dm.png +0 -0
  107. data/examples/android/Translate/res/drawable/dz.png +0 -0
  108. data/examples/android/Translate/res/drawable/ec.png +0 -0
  109. data/examples/android/Translate/res/drawable/ee.png +0 -0
  110. data/examples/android/Translate/res/drawable/eg.png +0 -0
  111. data/examples/android/Translate/res/drawable/eh.png +0 -0
  112. data/examples/android/Translate/res/drawable/england.png +0 -0
  113. data/examples/android/Translate/res/drawable/er.png +0 -0
  114. data/examples/android/Translate/res/drawable/es.png +0 -0
  115. data/examples/android/Translate/res/drawable/et.png +0 -0
  116. data/examples/android/Translate/res/drawable/europeanunion.png +0 -0
  117. data/examples/android/Translate/res/drawable/fam.png +0 -0
  118. data/examples/android/Translate/res/drawable/fi.png +0 -0
  119. data/examples/android/Translate/res/drawable/fj.png +0 -0
  120. data/examples/android/Translate/res/drawable/fk.png +0 -0
  121. data/examples/android/Translate/res/drawable/fm.png +0 -0
  122. data/examples/android/Translate/res/drawable/fo.png +0 -0
  123. data/examples/android/Translate/res/drawable/fr.png +0 -0
  124. data/examples/android/Translate/res/drawable/ga.png +0 -0
  125. data/examples/android/Translate/res/drawable/gb.png +0 -0
  126. data/examples/android/Translate/res/drawable/gd.png +0 -0
  127. data/examples/android/Translate/res/drawable/ge.png +0 -0
  128. data/examples/android/Translate/res/drawable/gf.png +0 -0
  129. data/examples/android/Translate/res/drawable/gh.png +0 -0
  130. data/examples/android/Translate/res/drawable/gi.png +0 -0
  131. data/examples/android/Translate/res/drawable/gl.png +0 -0
  132. data/examples/android/Translate/res/drawable/gm.png +0 -0
  133. data/examples/android/Translate/res/drawable/gn.png +0 -0
  134. data/examples/android/Translate/res/drawable/gp.png +0 -0
  135. data/examples/android/Translate/res/drawable/gq.png +0 -0
  136. data/examples/android/Translate/res/drawable/gr.png +0 -0
  137. data/examples/android/Translate/res/drawable/gs.png +0 -0
  138. data/examples/android/Translate/res/drawable/gt.png +0 -0
  139. data/examples/android/Translate/res/drawable/gu.png +0 -0
  140. data/examples/android/Translate/res/drawable/gw.png +0 -0
  141. data/examples/android/Translate/res/drawable/gy.png +0 -0
  142. data/examples/android/Translate/res/drawable/hk.png +0 -0
  143. data/examples/android/Translate/res/drawable/hm.png +0 -0
  144. data/examples/android/Translate/res/drawable/hn.png +0 -0
  145. data/examples/android/Translate/res/drawable/hr.png +0 -0
  146. data/examples/android/Translate/res/drawable/ht.png +0 -0
  147. data/examples/android/Translate/res/drawable/hu.png +0 -0
  148. data/examples/android/Translate/res/drawable/id.png +0 -0
  149. data/examples/android/Translate/res/drawable/ie.png +0 -0
  150. data/examples/android/Translate/res/drawable/il.png +0 -0
  151. data/examples/android/Translate/res/drawable/in.png +0 -0
  152. data/examples/android/Translate/res/drawable/io.png +0 -0
  153. data/examples/android/Translate/res/drawable/iq.png +0 -0
  154. data/examples/android/Translate/res/drawable/ir.png +0 -0
  155. data/examples/android/Translate/res/drawable/is.png +0 -0
  156. data/examples/android/Translate/res/drawable/it.png +0 -0
  157. data/examples/android/Translate/res/drawable/jm.png +0 -0
  158. data/examples/android/Translate/res/drawable/jo.png +0 -0
  159. data/examples/android/Translate/res/drawable/jp.png +0 -0
  160. data/examples/android/Translate/res/drawable/ke.png +0 -0
  161. data/examples/android/Translate/res/drawable/kg.png +0 -0
  162. data/examples/android/Translate/res/drawable/kh.png +0 -0
  163. data/examples/android/Translate/res/drawable/ki.png +0 -0
  164. data/examples/android/Translate/res/drawable/km.png +0 -0
  165. data/examples/android/Translate/res/drawable/kn.png +0 -0
  166. data/examples/android/Translate/res/drawable/kp.png +0 -0
  167. data/examples/android/Translate/res/drawable/kr.png +0 -0
  168. data/examples/android/Translate/res/drawable/kw.png +0 -0
  169. data/examples/android/Translate/res/drawable/ky.png +0 -0
  170. data/examples/android/Translate/res/drawable/kz.png +0 -0
  171. data/examples/android/Translate/res/drawable/la.png +0 -0
  172. data/examples/android/Translate/res/drawable/lb.png +0 -0
  173. data/examples/android/Translate/res/drawable/lc.png +0 -0
  174. data/examples/android/Translate/res/drawable/li.png +0 -0
  175. data/examples/android/Translate/res/drawable/lk.png +0 -0
  176. data/examples/android/Translate/res/drawable/lr.png +0 -0
  177. data/examples/android/Translate/res/drawable/ls.png +0 -0
  178. data/examples/android/Translate/res/drawable/lt.png +0 -0
  179. data/examples/android/Translate/res/drawable/lu.png +0 -0
  180. data/examples/android/Translate/res/drawable/lv.png +0 -0
  181. data/examples/android/Translate/res/drawable/ly.png +0 -0
  182. data/examples/android/Translate/res/drawable/ma.png +0 -0
  183. data/examples/android/Translate/res/drawable/mc.png +0 -0
  184. data/examples/android/Translate/res/drawable/md.png +0 -0
  185. data/examples/android/Translate/res/drawable/me.png +0 -0
  186. data/examples/android/Translate/res/drawable/mg.png +0 -0
  187. data/examples/android/Translate/res/drawable/mh.png +0 -0
  188. data/examples/android/Translate/res/drawable/mk.png +0 -0
  189. data/examples/android/Translate/res/drawable/ml.png +0 -0
  190. data/examples/android/Translate/res/drawable/mm.png +0 -0
  191. data/examples/android/Translate/res/drawable/mn.png +0 -0
  192. data/examples/android/Translate/res/drawable/mo.png +0 -0
  193. data/examples/android/Translate/res/drawable/mp.png +0 -0
  194. data/examples/android/Translate/res/drawable/mq.png +0 -0
  195. data/examples/android/Translate/res/drawable/mr.png +0 -0
  196. data/examples/android/Translate/res/drawable/ms.png +0 -0
  197. data/examples/android/Translate/res/drawable/mt.png +0 -0
  198. data/examples/android/Translate/res/drawable/mu.png +0 -0
  199. data/examples/android/Translate/res/drawable/mv.png +0 -0
  200. data/examples/android/Translate/res/drawable/mw.png +0 -0
  201. data/examples/android/Translate/res/drawable/mx.png +0 -0
  202. data/examples/android/Translate/res/drawable/my.png +0 -0
  203. data/examples/android/Translate/res/drawable/mz.png +0 -0
  204. data/examples/android/Translate/res/drawable/na.png +0 -0
  205. data/examples/android/Translate/res/drawable/nc.png +0 -0
  206. data/examples/android/Translate/res/drawable/ne.png +0 -0
  207. data/examples/android/Translate/res/drawable/nf.png +0 -0
  208. data/examples/android/Translate/res/drawable/ng.png +0 -0
  209. data/examples/android/Translate/res/drawable/ni.png +0 -0
  210. data/examples/android/Translate/res/drawable/nl.png +0 -0
  211. data/examples/android/Translate/res/drawable/no.png +0 -0
  212. data/examples/android/Translate/res/drawable/np.png +0 -0
  213. data/examples/android/Translate/res/drawable/nr.png +0 -0
  214. data/examples/android/Translate/res/drawable/nu.png +0 -0
  215. data/examples/android/Translate/res/drawable/nz.png +0 -0
  216. data/examples/android/Translate/res/drawable/om.png +0 -0
  217. data/examples/android/Translate/res/drawable/pa.png +0 -0
  218. data/examples/android/Translate/res/drawable/pe.png +0 -0
  219. data/examples/android/Translate/res/drawable/pf.png +0 -0
  220. data/examples/android/Translate/res/drawable/pg.png +0 -0
  221. data/examples/android/Translate/res/drawable/ph.png +0 -0
  222. data/examples/android/Translate/res/drawable/pk.png +0 -0
  223. data/examples/android/Translate/res/drawable/pl.png +0 -0
  224. data/examples/android/Translate/res/drawable/pm.png +0 -0
  225. data/examples/android/Translate/res/drawable/pn.png +0 -0
  226. data/examples/android/Translate/res/drawable/pr.png +0 -0
  227. data/examples/android/Translate/res/drawable/ps.png +0 -0
  228. data/examples/android/Translate/res/drawable/pt.png +0 -0
  229. data/examples/android/Translate/res/drawable/pw.png +0 -0
  230. data/examples/android/Translate/res/drawable/py.png +0 -0
  231. data/examples/android/Translate/res/drawable/qa.png +0 -0
  232. data/examples/android/Translate/res/drawable/re.png +0 -0
  233. data/examples/android/Translate/res/drawable/readme.txt +9 -0
  234. data/examples/android/Translate/res/drawable/ro.png +0 -0
  235. data/examples/android/Translate/res/drawable/rs.png +0 -0
  236. data/examples/android/Translate/res/drawable/ru.png +0 -0
  237. data/examples/android/Translate/res/drawable/rw.png +0 -0
  238. data/examples/android/Translate/res/drawable/sa.png +0 -0
  239. data/examples/android/Translate/res/drawable/sb.png +0 -0
  240. data/examples/android/Translate/res/drawable/sc.png +0 -0
  241. data/examples/android/Translate/res/drawable/scotland.png +0 -0
  242. data/examples/android/Translate/res/drawable/sd.png +0 -0
  243. data/examples/android/Translate/res/drawable/se.png +0 -0
  244. data/examples/android/Translate/res/drawable/sg.png +0 -0
  245. data/examples/android/Translate/res/drawable/sh.png +0 -0
  246. data/examples/android/Translate/res/drawable/si.png +0 -0
  247. data/examples/android/Translate/res/drawable/sj.png +0 -0
  248. data/examples/android/Translate/res/drawable/sk.png +0 -0
  249. data/examples/android/Translate/res/drawable/sl.png +0 -0
  250. data/examples/android/Translate/res/drawable/sm.png +0 -0
  251. data/examples/android/Translate/res/drawable/sn.png +0 -0
  252. data/examples/android/Translate/res/drawable/so.png +0 -0
  253. data/examples/android/Translate/res/drawable/sr.png +0 -0
  254. data/examples/android/Translate/res/drawable/st.png +0 -0
  255. data/examples/android/Translate/res/drawable/sv.png +0 -0
  256. data/examples/android/Translate/res/drawable/sy.png +0 -0
  257. data/examples/android/Translate/res/drawable/sz.png +0 -0
  258. data/examples/android/Translate/res/drawable/tc.png +0 -0
  259. data/examples/android/Translate/res/drawable/td.png +0 -0
  260. data/examples/android/Translate/res/drawable/tf.png +0 -0
  261. data/examples/android/Translate/res/drawable/tg.png +0 -0
  262. data/examples/android/Translate/res/drawable/th.png +0 -0
  263. data/examples/android/Translate/res/drawable/tj.png +0 -0
  264. data/examples/android/Translate/res/drawable/tk.png +0 -0
  265. data/examples/android/Translate/res/drawable/tl.png +0 -0
  266. data/examples/android/Translate/res/drawable/tm.png +0 -0
  267. data/examples/android/Translate/res/drawable/tn.png +0 -0
  268. data/examples/android/Translate/res/drawable/to.png +0 -0
  269. data/examples/android/Translate/res/drawable/tr.png +0 -0
  270. data/examples/android/Translate/res/drawable/tt.png +0 -0
  271. data/examples/android/Translate/res/drawable/tv.png +0 -0
  272. data/examples/android/Translate/res/drawable/tw.png +0 -0
  273. data/examples/android/Translate/res/drawable/tz.png +0 -0
  274. data/examples/android/Translate/res/drawable/ua.png +0 -0
  275. data/examples/android/Translate/res/drawable/ug.png +0 -0
  276. data/examples/android/Translate/res/drawable/um.png +0 -0
  277. data/examples/android/Translate/res/drawable/us.png +0 -0
  278. data/examples/android/Translate/res/drawable/uy.png +0 -0
  279. data/examples/android/Translate/res/drawable/uz.png +0 -0
  280. data/examples/android/Translate/res/drawable/va.png +0 -0
  281. data/examples/android/Translate/res/drawable/vc.png +0 -0
  282. data/examples/android/Translate/res/drawable/ve.png +0 -0
  283. data/examples/android/Translate/res/drawable/vg.png +0 -0
  284. data/examples/android/Translate/res/drawable/vi.png +0 -0
  285. data/examples/android/Translate/res/drawable/vn.png +0 -0
  286. data/examples/android/Translate/res/drawable/vu.png +0 -0
  287. data/examples/android/Translate/res/drawable/wales.png +0 -0
  288. data/examples/android/Translate/res/drawable/wf.png +0 -0
  289. data/examples/android/Translate/res/drawable/ws.png +0 -0
  290. data/examples/android/Translate/res/drawable/ye.png +0 -0
  291. data/examples/android/Translate/res/drawable/yt.png +0 -0
  292. data/examples/android/Translate/res/drawable/za.png +0 -0
  293. data/examples/android/Translate/res/drawable/zm.png +0 -0
  294. data/examples/android/Translate/res/drawable/zw.png +0 -0
  295. data/examples/android/Translate/res/layout/about_dialog.xml +15 -0
  296. data/examples/android/Translate/res/layout/history_activity.xml +21 -0
  297. data/examples/android/Translate/res/layout/history_record.xml +77 -0
  298. data/examples/android/Translate/res/layout/language_dialog.xml +30 -0
  299. data/examples/android/Translate/res/layout/language_entry.xml +25 -0
  300. data/examples/android/Translate/res/layout/main.xml +13 -0
  301. data/examples/android/Translate/res/layout/translate_activity.xml +114 -0
  302. data/examples/android/Translate/res/menu/history_activity_menu.xml +35 -0
  303. data/examples/android/Translate/res/menu/translate_activity_menu.xml +35 -0
  304. data/examples/android/Translate/res/raw/dictionary.txtgz +0 -0
  305. data/examples/android/Translate/res/values/strings.xml +50 -0
  306. data/examples/android/Translate/sign +11 -0
  307. data/examples/android/Translate/src/com/beust/android/translate/AboutDialog.java +39 -0
  308. data/examples/android/Translate/src/com/beust/android/translate/Entities.java +990 -0
  309. data/examples/android/Translate/src/com/beust/android/translate/History.java +164 -0
  310. data/examples/android/Translate/src/com/beust/android/translate/HistoryActivity.java +124 -0
  311. data/examples/android/Translate/src/com/beust/android/translate/HistoryRecord.java +83 -0
  312. data/examples/android/Translate/src/com/beust/android/translate/ITranslate.aidl +27 -0
  313. data/examples/android/Translate/src/com/beust/android/translate/ITranslate.java +139 -0
  314. data/examples/android/Translate/src/com/beust/android/translate/LanguageDialog.java +90 -0
  315. data/examples/android/Translate/src/com/beust/android/translate/Languages.java +220 -0
  316. data/examples/android/Translate/src/com/beust/android/translate/Lists.java +64 -0
  317. data/examples/android/Translate/src/com/beust/android/translate/Maps.java +33 -0
  318. data/examples/android/Translate/src/com/beust/android/translate/R.java +333 -0
  319. data/examples/android/Translate/src/com/beust/android/translate/Translate.java +117 -0
  320. data/examples/android/Translate/src/com/beust/android/translate/TranslateActivity.java +443 -0
  321. data/examples/android/Translate/src/com/beust/android/translate/TranslateService.java +63 -0
  322. data/examples/android/WikiNotes/AndroidManifest.xml +64 -0
  323. data/examples/android/WikiNotes/README.TXT +67 -0
  324. data/examples/android/WikiNotes/bin/WikiNotes.ap_ +0 -0
  325. data/examples/android/WikiNotes/build.xml +269 -0
  326. data/examples/android/WikiNotes/res/drawable/icon.png +0 -0
  327. data/examples/android/WikiNotes/res/drawable/icon_delete.png +0 -0
  328. data/examples/android/WikiNotes/res/drawable/icon_recent.png +0 -0
  329. data/examples/android/WikiNotes/res/drawable/icon_start.png +0 -0
  330. data/examples/android/WikiNotes/res/drawable/parchmentbase.png +0 -0
  331. data/examples/android/WikiNotes/res/layout/main.xml +33 -0
  332. data/examples/android/WikiNotes/res/layout/wiki_note_edit.xml +49 -0
  333. data/examples/android/WikiNotes/res/layout/wiki_search.xml +45 -0
  334. data/examples/android/WikiNotes/res/menu/notelist.xml +24 -0
  335. data/examples/android/WikiNotes/res/values/strings.xml +70 -0
  336. data/examples/android/WikiNotes/res/xml/searchable.xml +30 -0
  337. data/examples/android/WikiNotes/src/com/google/android/wikinotes/Eula.java +60 -0
  338. data/examples/android/WikiNotes/src/com/google/android/wikinotes/R.java +90 -0
  339. data/examples/android/WikiNotes/src/com/google/android/wikinotes/WikiActivityHelper.java +448 -0
  340. data/examples/android/WikiNotes/src/com/google/android/wikinotes/WikiNoteEditor.java +121 -0
  341. data/examples/android/WikiNotes/src/com/google/android/wikinotes/WikiNotes.java +282 -0
  342. data/examples/android/WikiNotes/src/com/google/android/wikinotes/WikiNotesList.java +159 -0
  343. data/examples/android/WikiNotes/src/com/google/android/wikinotes/db/WikiNote.java +100 -0
  344. data/examples/android/WikiNotes/src/com/google/android/wikinotes/db/WikiNotesProvider.java +331 -0
  345. data/examples/different_states_of_andrakeness/BasicUI_1/AndroidManifest.xml +20 -0
  346. data/examples/different_states_of_andrakeness/BasicUI_1/AnotherView.java +39 -0
  347. data/examples/different_states_of_andrakeness/BasicUI_1/BasicUI.java +102 -0
  348. data/examples/different_states_of_andrakeness/BasicUI_1/UiResult.java +20 -0
  349. data/examples/different_states_of_andrakeness/BasicUI_1/build.xml +269 -0
  350. data/examples/different_states_of_andrakeness/BasicUI_1/res/drawable/icon.png +0 -0
  351. data/examples/different_states_of_andrakeness/BasicUI_1/res/layout/main.xml +23 -0
  352. data/examples/different_states_of_andrakeness/BasicUI_1/res/layout/result.xml +12 -0
  353. data/examples/different_states_of_andrakeness/BasicUI_1/res/values/colors.xml +10 -0
  354. data/examples/different_states_of_andrakeness/BasicUI_1/res/values/strings.xml +6 -0
  355. data/examples/different_states_of_andrakeness/BasicUI_1/src/com/android/basicui/AnotherView.java +39 -0
  356. data/examples/different_states_of_andrakeness/BasicUI_1/src/com/android/basicui/BasicUI.java +102 -0
  357. data/examples/different_states_of_andrakeness/BasicUI_1/src/com/android/basicui/R.java +36 -0
  358. data/examples/different_states_of_andrakeness/BasicUI_1/src/com/android/basicui/UiResult.java +20 -0
  359. data/examples/different_states_of_andrakeness/BasicUI_2/AndroidManifest.xml +20 -0
  360. data/examples/different_states_of_andrakeness/BasicUI_2/build.xml +269 -0
  361. data/examples/different_states_of_andrakeness/BasicUI_2/reinstall-and-debug-on-default-device +6 -0
  362. data/examples/different_states_of_andrakeness/BasicUI_2/reinstall-and-run-on-default-device +6 -0
  363. data/examples/different_states_of_andrakeness/BasicUI_2/res/drawable/icon.png +0 -0
  364. data/examples/different_states_of_andrakeness/BasicUI_2/res/layout/main.xml +23 -0
  365. data/examples/different_states_of_andrakeness/BasicUI_2/res/layout/result.xml +12 -0
  366. data/examples/different_states_of_andrakeness/BasicUI_2/res/values/colors.xml +10 -0
  367. data/examples/different_states_of_andrakeness/BasicUI_2/res/values/strings.xml +6 -0
  368. data/examples/different_states_of_andrakeness/BasicUI_2/src/com/android/basicui/AnotherView.java +39 -0
  369. data/examples/different_states_of_andrakeness/BasicUI_2/src/com/android/basicui/BasicUI.java +102 -0
  370. data/examples/different_states_of_andrakeness/BasicUI_2/src/com/android/basicui/R.java +36 -0
  371. data/examples/different_states_of_andrakeness/BasicUI_2/src/com/android/basicui/UiResult.java +20 -0
  372. data/examples/different_states_of_andrakeness/BasicUI_3/AndroidManifest.xml +20 -0
  373. data/examples/different_states_of_andrakeness/BasicUI_3/app.css +4 -0
  374. data/examples/different_states_of_andrakeness/BasicUI_3/build.xml +269 -0
  375. data/examples/different_states_of_andrakeness/BasicUI_3/res/drawable/icon.png +0 -0
  376. data/examples/different_states_of_andrakeness/BasicUI_3/res/layout/main.xml +22 -0
  377. data/examples/different_states_of_andrakeness/BasicUI_3/res/layout/result.xml +12 -0
  378. data/examples/different_states_of_andrakeness/BasicUI_3/res/values/colors.xml +10 -0
  379. data/examples/different_states_of_andrakeness/BasicUI_3/res/values/strings.xml +6 -0
  380. data/examples/different_states_of_andrakeness/BasicUI_3/src/com/android/basicui/AnotherView.java +39 -0
  381. data/examples/different_states_of_andrakeness/BasicUI_3/src/com/android/basicui/BasicUI.java +102 -0
  382. data/examples/different_states_of_andrakeness/BasicUI_3/src/com/android/basicui/R.java +36 -0
  383. data/examples/different_states_of_andrakeness/BasicUI_3/src/com/android/basicui/UiResult.java +20 -0
  384. data/examples/different_states_of_andrakeness/BasicUI_4/AndroidManifest.xml +20 -0
  385. data/examples/different_states_of_andrakeness/BasicUI_4/app.sass +3 -0
  386. data/examples/different_states_of_andrakeness/BasicUI_4/build.xml +269 -0
  387. data/examples/different_states_of_andrakeness/BasicUI_4/res/drawable/icon.png +0 -0
  388. data/examples/different_states_of_andrakeness/BasicUI_4/res/layout/main.xml +22 -0
  389. data/examples/different_states_of_andrakeness/BasicUI_4/res/layout/result.xml +12 -0
  390. data/examples/different_states_of_andrakeness/BasicUI_4/res/values/colors.xml +10 -0
  391. data/examples/different_states_of_andrakeness/BasicUI_4/res/values/strings.xml +6 -0
  392. data/examples/different_states_of_andrakeness/BasicUI_4/src/com/android/basicui/AnotherView.java +39 -0
  393. data/examples/different_states_of_andrakeness/BasicUI_4/src/com/android/basicui/BasicUI.java +102 -0
  394. data/examples/different_states_of_andrakeness/BasicUI_4/src/com/android/basicui/R.java +36 -0
  395. data/examples/different_states_of_andrakeness/BasicUI_4/src/com/android/basicui/UiResult.java +20 -0
  396. data/examples/different_states_of_andrakeness/BasicUI_5/AndroidManifest.xml +20 -0
  397. data/examples/different_states_of_andrakeness/BasicUI_5/app.sass +3 -0
  398. data/examples/different_states_of_andrakeness/BasicUI_5/build.xml +269 -0
  399. data/examples/different_states_of_andrakeness/BasicUI_5/res/drawable/icon.png +0 -0
  400. data/examples/different_states_of_andrakeness/BasicUI_5/res/layout/main.xml +21 -0
  401. data/examples/different_states_of_andrakeness/BasicUI_5/res/layout/result.xml +12 -0
  402. data/examples/different_states_of_andrakeness/BasicUI_5/res/values/colors.xml +10 -0
  403. data/examples/different_states_of_andrakeness/BasicUI_5/res/values/strings.xml +6 -0
  404. data/examples/different_states_of_andrakeness/BasicUI_5/src/com/android/basicui/AnotherView.java +39 -0
  405. data/examples/different_states_of_andrakeness/BasicUI_5/src/com/android/basicui/BasicUI.java +102 -0
  406. data/examples/different_states_of_andrakeness/BasicUI_5/src/com/android/basicui/R.java +36 -0
  407. data/examples/different_states_of_andrakeness/BasicUI_5/src/com/android/basicui/UiResult.java +20 -0
  408. data/examples/different_states_of_andrakeness/BasicUI_6/AndroidManifest.xml +20 -0
  409. data/examples/different_states_of_andrakeness/BasicUI_6/app.sass +17 -0
  410. data/examples/different_states_of_andrakeness/BasicUI_6/build.xml +269 -0
  411. data/examples/different_states_of_andrakeness/BasicUI_6/res/drawable/icon.png +0 -0
  412. data/examples/different_states_of_andrakeness/BasicUI_6/res/layout/main.haml +4 -0
  413. data/examples/different_states_of_andrakeness/BasicUI_6/res/layout/result.xml +12 -0
  414. data/examples/different_states_of_andrakeness/BasicUI_6/res/values/colors.xml +10 -0
  415. data/examples/different_states_of_andrakeness/BasicUI_6/res/values/strings.xml +6 -0
  416. data/examples/different_states_of_andrakeness/BasicUI_6/src/com/android/basicui/AnotherView.java +39 -0
  417. data/examples/different_states_of_andrakeness/BasicUI_6/src/com/android/basicui/BasicUI.java +102 -0
  418. data/examples/different_states_of_andrakeness/BasicUI_6/src/com/android/basicui/R.java +36 -0
  419. data/examples/different_states_of_andrakeness/BasicUI_6/src/com/android/basicui/UiResult.java +20 -0
  420. data/examples/different_states_of_andrakeness/BasicUI_7/app.sass +17 -0
  421. data/examples/different_states_of_andrakeness/BasicUI_7/build.xml +269 -0
  422. data/examples/different_states_of_andrakeness/BasicUI_7/res/drawable/icon.png +0 -0
  423. data/examples/different_states_of_andrakeness/BasicUI_7/res/layout/main.haml +4 -0
  424. data/examples/different_states_of_andrakeness/BasicUI_7/res/layout/result.xml +12 -0
  425. data/examples/different_states_of_andrakeness/BasicUI_7/res/values/colors.xml +10 -0
  426. data/examples/different_states_of_andrakeness/BasicUI_7/res/values/strings.xml +6 -0
  427. data/examples/different_states_of_andrakeness/BasicUI_7/src/com/android/basicui/AnotherView.java +39 -0
  428. data/examples/different_states_of_andrakeness/BasicUI_7/src/com/android/basicui/BasicUI.java +102 -0
  429. data/examples/different_states_of_andrakeness/BasicUI_7/src/com/android/basicui/R.java +36 -0
  430. data/examples/different_states_of_andrakeness/BasicUI_7/src/com/android/basicui/UiResult.java +20 -0
  431. data/examples/different_states_of_andrakeness/BasicUI_8/app/activities/AnotherView.java +39 -0
  432. data/examples/different_states_of_andrakeness/BasicUI_8/app/activities/BasicUI.java +102 -0
  433. data/examples/different_states_of_andrakeness/BasicUI_8/app/activities/UiResult.java +20 -0
  434. data/examples/different_states_of_andrakeness/BasicUI_8/app/layouts/main.haml +4 -0
  435. data/examples/different_states_of_andrakeness/BasicUI_8/app/layouts/result.xml +12 -0
  436. data/examples/different_states_of_andrakeness/BasicUI_8/app/styles/app.sass +17 -0
  437. data/examples/different_states_of_andrakeness/BasicUI_8/init.rb +13 -0
  438. data/examples/different_states_of_andrakeness/BasicUI_8/res/drawable/icon.png +0 -0
  439. data/examples/more-apps/AnyCut/AndroidManifest.xml +58 -0
  440. data/examples/more-apps/AnyCut/NOTICE +190 -0
  441. data/examples/more-apps/AnyCut/res/drawable/app_icon.png +0 -0
  442. data/examples/more-apps/AnyCut/res/drawable/sym_action_call.png +0 -0
  443. data/examples/more-apps/AnyCut/res/drawable/sym_action_sms.png +0 -0
  444. data/examples/more-apps/AnyCut/res/layout/custom_shortcut_creator.xml +33 -0
  445. data/examples/more-apps/AnyCut/res/layout/front_door.xml +44 -0
  446. data/examples/more-apps/AnyCut/res/layout/list.xml +22 -0
  447. data/examples/more-apps/AnyCut/res/layout/shortcut_editor.xml +38 -0
  448. data/examples/more-apps/AnyCut/res/values/colors.xml +22 -0
  449. data/examples/more-apps/AnyCut/res/values/strings.xml +48 -0
  450. data/examples/more-apps/AnyCut/src/com/example/anycut/ActivityPickerActivity.java +171 -0
  451. data/examples/more-apps/AnyCut/src/com/example/anycut/CreateShortcutActivity.java +324 -0
  452. data/examples/more-apps/AnyCut/src/com/example/anycut/CustomShortcutCreatorActivity.java +83 -0
  453. data/examples/more-apps/AnyCut/src/com/example/anycut/FrontDoorActivity.java +75 -0
  454. data/examples/more-apps/AnyCut/src/com/example/anycut/ShortcutEditorDialog.java +171 -0
  455. data/examples/more-apps/AnyCut/src/com/google/android/photostream/UserTask.java +457 -0
  456. data/examples/more-apps/LolcatBuilder/AndroidManifest.xml +32 -0
  457. data/examples/more-apps/LolcatBuilder/README.txt +90 -0
  458. data/examples/more-apps/LolcatBuilder/build.xml +269 -0
  459. data/examples/more-apps/LolcatBuilder/res/drawable/app_icon.png +0 -0
  460. data/examples/more-apps/LolcatBuilder/res/drawable/photo_border.9.png +0 -0
  461. data/examples/more-apps/LolcatBuilder/res/layout-land/lolcat_activity.xml +91 -0
  462. data/examples/more-apps/LolcatBuilder/res/layout/lolcat_activity.xml +90 -0
  463. data/examples/more-apps/LolcatBuilder/res/layout/lolcat_caption_dialog.xml +68 -0
  464. data/examples/more-apps/LolcatBuilder/res/values/strings.xml +45 -0
  465. data/examples/more-apps/LolcatBuilder/src/com/android/lolcat/LolcatActivity.java +808 -0
  466. data/examples/more-apps/LolcatBuilder/src/com/android/lolcat/LolcatView.java +638 -0
  467. data/examples/more-apps/LolcatBuilder/src/com/android/lolcat/R.java +60 -0
  468. data/examples/simplegen/template-dir1/app/foo.xml._erb +1 -0
  469. data/examples/simplegen/template-dir1/dynamic_dirname/_%dynamic%_/foo +0 -0
  470. data/examples/simplegen/template-dir1/dynamic_filename/%dynamic%_file.rb.erb +1 -0
  471. data/examples/simplegen/template-dir1/many_dirs/many/dirs/hello.txt.erb +2 -0
  472. data/lib/andrake.rb +17 -0
  473. data/lib/andrake/activity.rb +32 -0
  474. data/lib/andrake/application.rb +202 -0
  475. data/lib/andrake/bin.rb +66 -0
  476. data/lib/andrake/hybrid.rb +87 -0
  477. data/lib/andrake/resource_manager.rb +42 -0
  478. data/lib/android.rb +21 -0
  479. data/lib/android/activity.rb +2 -0
  480. data/lib/android/application.rb +194 -0
  481. data/lib/android/bin.rb +75 -0
  482. data/lib/android/extensions.rb +9 -0
  483. data/lib/android/gen.rb +86 -0
  484. data/lib/android/javaclass.rb +26 -0
  485. data/lib/android/layout.rb +142 -0
  486. data/lib/javaclass.rb +50 -0
  487. data/lib/simplegen.rb +236 -0
  488. data/spec/andrake/basic_ui_spec.rb +12 -0
  489. data/spec/andrake/hello_android_spec.rb +36 -0
  490. data/spec/android/basic_ui_spec.rb +33 -0
  491. data/spec/android/hello_android_spec.rb +55 -0
  492. data/spec/custom_matcher.rb +51 -0
  493. data/spec/javaclass/examples/Eula.java +60 -0
  494. data/spec/javaclass/examples/WikiActivityHelper.java +448 -0
  495. data/spec/javaclass/examples/WikiNoteEditor.java +121 -0
  496. data/spec/javaclass/examples/WikiNotes.java +282 -0
  497. data/spec/javaclass/examples/WikiNotesList.java +159 -0
  498. data/spec/javaclass/javaclass_spec.rb +36 -0
  499. data/spec/rcov.opts +2 -0
  500. data/spec/simplegen/simplegen_spec.rb +139 -0
  501. data/spec/spec.opts +4 -0
  502. data/spec/spec_helper.rb +51 -0
  503. metadata +727 -0
@@ -0,0 +1,91 @@
1
+ <?xml version="1.0" encoding="utf-8"?>
2
+ <!--
3
+ /*
4
+ * Copyright (c) 2008 Google Inc.
5
+ *
6
+ * Licensed under the Apache License, Version 2.0 (the "License");
7
+ * you may not use this file except in compliance with the License.
8
+ * 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, software
13
+ * distributed under the License is distributed on an "AS IS" BASIS,
14
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15
+ * See the License for the specific language governing permissions and
16
+ * limitations under the License.
17
+ */
18
+ -->
19
+
20
+ <!-- LANDSCAPE MODE layout for LolcatActivity. -->
21
+ <LinearLayout
22
+ xmlns:android="http://schemas.android.com/apk/res/android"
23
+ android:orientation="horizontal"
24
+ android:gravity="top"
25
+ android:layout_width="fill_parent"
26
+ android:layout_height="fill_parent">
27
+
28
+ <!-- Main image -->
29
+ <com.android.lolcat.LolcatView android:id="@+id/main_image"
30
+ android:layout_height="fill_parent"
31
+ android:layout_width="1dip"
32
+ android:layout_weight="30"
33
+ android:scaleType="centerInside"
34
+ android:padding="10dip"
35
+ android:background="@drawable/photo_border"
36
+ />
37
+
38
+ <!-- Control buttons -->
39
+ <LinearLayout
40
+ android:orientation="vertical"
41
+ android:layout_width="1dip"
42
+ android:layout_weight="11"
43
+ android:layout_height="fill_parent"
44
+ android:layout_marginTop="4dip"
45
+ android:layout_marginLeft="-4dip"
46
+ android:layout_marginRight="-4dip"
47
+ >
48
+ <Button android:id="@+id/pick_button"
49
+ android:text="@string/lolcat_pick"
50
+ android:layout_width="fill_parent"
51
+ android:layout_height="wrap_content"
52
+ android:singleLine="true"
53
+ />
54
+
55
+ <Button android:id="@+id/caption_button"
56
+ android:text="@string/lolcat_add_captions"
57
+ android:layout_width="fill_parent"
58
+ android:layout_height="wrap_content"
59
+ android:singleLine="true"
60
+ />
61
+
62
+ <Button android:id="@+id/save_button"
63
+ android:text="@string/lolcat_save"
64
+ android:layout_width="fill_parent"
65
+ android:layout_height="wrap_content"
66
+ android:singleLine="true"
67
+ />
68
+
69
+ <!-- Placeholder view to separate the upper and lower buttons -->
70
+ <View
71
+ android:layout_width="fill_parent"
72
+ android:layout_height="1dip"
73
+ android:layout_weight="1" />
74
+
75
+ <Button android:id="@+id/clear_caption_button"
76
+ android:text="@string/lolcat_clear_caption"
77
+ android:layout_width="fill_parent"
78
+ android:layout_height="wrap_content"
79
+ android:singleLine="true"
80
+ />
81
+
82
+ <Button android:id="@+id/clear_photo_button"
83
+ android:text="@string/lolcat_clear_photo"
84
+ android:layout_width="fill_parent"
85
+ android:layout_height="wrap_content"
86
+ android:singleLine="true"
87
+ />
88
+
89
+ </LinearLayout>
90
+
91
+ </LinearLayout>
@@ -0,0 +1,90 @@
1
+ <?xml version="1.0" encoding="utf-8"?>
2
+ <!--
3
+ /*
4
+ * Copyright (c) 2008 Google Inc.
5
+ *
6
+ * Licensed under the Apache License, Version 2.0 (the "License");
7
+ * you may not use this file except in compliance with the License.
8
+ * 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, software
13
+ * distributed under the License is distributed on an "AS IS" BASIS,
14
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15
+ * See the License for the specific language governing permissions and
16
+ * limitations under the License.
17
+ */
18
+ -->
19
+
20
+ <!-- PORTRAIT MODE layout for LolcatActivity. -->
21
+ <LinearLayout
22
+ xmlns:android="http://schemas.android.com/apk/res/android"
23
+ android:orientation="vertical"
24
+ android:gravity="center_horizontal"
25
+ android:layout_width="fill_parent"
26
+ android:layout_height="fill_parent">
27
+
28
+ <!-- Main image -->
29
+ <com.android.lolcat.LolcatView android:id="@+id/main_image"
30
+ android:layout_width="fill_parent"
31
+ android:layout_height="1dip"
32
+ android:layout_weight="1"
33
+ android:scaleType="centerInside"
34
+ android:padding="10dip"
35
+ android:background="@drawable/photo_border"
36
+ />
37
+
38
+ <!-- Control buttons -->
39
+ <LinearLayout
40
+ android:orientation="horizontal"
41
+ android:layout_width="fill_parent"
42
+ android:layout_height="wrap_content"
43
+ >
44
+
45
+ <Button android:id="@+id/pick_button"
46
+ android:text="@string/lolcat_pick"
47
+ android:layout_width="1dip"
48
+ android:layout_weight="4"
49
+ android:layout_height="wrap_content"
50
+ />
51
+
52
+ <Button android:id="@+id/caption_button"
53
+ android:text="@string/lolcat_add_captions"
54
+ android:layout_width="1dip"
55
+ android:layout_weight="4"
56
+ android:layout_height="wrap_content"
57
+ />
58
+
59
+ <Button android:id="@+id/save_button"
60
+ android:text="@string/lolcat_save"
61
+ android:layout_width="1dip"
62
+ android:layout_weight="4"
63
+ android:layout_height="wrap_content"
64
+ />
65
+
66
+ <!-- Placeholder view to separate the left-side and right-side buttons -->
67
+ <View
68
+ android:layout_height="fill_parent"
69
+ android:layout_width="1dip"
70
+ android:layout_weight="1" />
71
+
72
+ <!-- Not enough room for this button in portrait mode!
73
+ <Button android:id="@+id/clear_caption_button"
74
+ android:text="@string/lolcat_clear_caption"
75
+ android:layout_width="1dip"
76
+ android:layout_weight="4"
77
+ android:layout_height="wrap_content"
78
+ />
79
+ -->
80
+
81
+ <Button android:id="@+id/clear_photo_button"
82
+ android:text="@string/lolcat_clear_photo"
83
+ android:layout_width="1dip"
84
+ android:layout_weight="4"
85
+ android:layout_height="wrap_content"
86
+ />
87
+
88
+ </LinearLayout>
89
+
90
+ </LinearLayout>
@@ -0,0 +1,68 @@
1
+ <?xml version="1.0" encoding="utf-8"?>
2
+ <!--
3
+ /*
4
+ * Copyright (C) 2008 Google Inc.
5
+ *
6
+ * Licensed under the Apache License, Version 2.0 (the "License");
7
+ * you may not use this file except in compliance with the License.
8
+ * 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, software
13
+ * distributed under the License is distributed on an "AS IS" BASIS,
14
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15
+ * See the License for the specific language governing permissions and
16
+ * limitations under the License.
17
+ */
18
+ -->
19
+ <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
20
+ android:layout_width="fill_parent"
21
+ android:layout_height="wrap_content"
22
+ android:orientation="vertical">
23
+
24
+ <TextView
25
+ android:id="@+id/top_label"
26
+ android:layout_height="wrap_content"
27
+ android:layout_width="wrap_content"
28
+ android:layout_marginLeft="20dip"
29
+ android:layout_marginRight="20dip"
30
+ android:text="@string/lolcat_caption_dialog_top_label"
31
+ android:gravity="left"
32
+ android:singleLine="true"
33
+ android:textAppearance="?android:attr/textAppearanceMedium" />
34
+
35
+ <EditText
36
+ android:id="@+id/top_edittext"
37
+ android:layout_height="wrap_content"
38
+ android:layout_width="fill_parent"
39
+ android:layout_marginLeft="20dip"
40
+ android:layout_marginRight="20dip"
41
+ android:scrollHorizontally="true"
42
+ android:gravity="fill_horizontal"
43
+ android:singleLine="true"
44
+ android:textAppearance="?android:attr/textAppearanceMedium" />
45
+
46
+ <TextView
47
+ android:id="@+id/buttom_label"
48
+ android:layout_height="wrap_content"
49
+ android:layout_width="wrap_content"
50
+ android:layout_marginLeft="20dip"
51
+ android:layout_marginRight="20dip"
52
+ android:text="@string/lolcat_caption_dialog_bottom_label"
53
+ android:gravity="left"
54
+ android:singleLine="true"
55
+ android:textAppearance="?android:attr/textAppearanceMedium" />
56
+
57
+ <EditText
58
+ android:id="@+id/bottom_edittext"
59
+ android:layout_height="wrap_content"
60
+ android:layout_width="fill_parent"
61
+ android:layout_marginLeft="20dip"
62
+ android:layout_marginRight="20dip"
63
+ android:scrollHorizontally="true"
64
+ android:gravity="fill_horizontal"
65
+ android:singleLine="true"
66
+ android:textAppearance="?android:attr/textAppearanceMedium" />
67
+
68
+ </LinearLayout>
@@ -0,0 +1,45 @@
1
+ <?xml version="1.0" encoding="utf-8"?>
2
+ <!--
3
+ /*
4
+ * Copyright (c) 2008 Google Inc.
5
+ *
6
+ * Licensed under the Apache License, Version 2.0 (the "License");
7
+ * you may not use this file except in compliance with the License.
8
+ * 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, software
13
+ * distributed under the License is distributed on an "AS IS" BASIS,
14
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15
+ * See the License for the specific language governing permissions and
16
+ * limitations under the License.
17
+ */
18
+ -->
19
+
20
+ <resources>
21
+ <!-- lolcat_activity.xml / LolcatActivity.java -->
22
+ <string name="lolcat_pick">Pick photo</string>
23
+ <string name="lolcat_nothing_picked">No photo picked!</string>
24
+ <string name="lolcat_clear_caption">Clear captions</string>
25
+ <string name="lolcat_clear_photo">Clear photo</string>
26
+ <string name="lolcat_add_captions">Add captions</string>
27
+ <string name="lolcat_change_captions">Change captions</string>
28
+ <string name="lolcat_save">Save &amp; share</string>
29
+ <string name="lolcat_caption_dialog_title">Captions</string>
30
+ <string name="lolcat_caption_dialog_top_label">Top:</string>
31
+ <string name="lolcat_caption_dialog_bottom_label">Bottom:</string>
32
+ <string name="lolcat_caption_dialog_ok">OK</string>
33
+ <string name="lolcat_caption_dialog_cancel">Cancel</string>
34
+ <string name="lolcat_saving">Saving...</string>
35
+ <string name="lolcat_save_failed">Couldn't save photo</string>
36
+ <string name="lolcat_scan_failed">Couldn't scan photo on SD card</string>
37
+ <string name="lolcat_share_failed">Couldn't share photo</string>
38
+ <string name="lolcat_scanning">Scanning...</string>
39
+ <string name="lolcat_sendImage_label">Share picture via</string>
40
+ <string name="lolcat_save_succeeded_dialog_title">Image saved!</string>
41
+ <string name="lolcat_save_succeeded_dialog_body_format">"Lolcat image successfully saved:\n Filename: %s\n Uri: %s"</string>
42
+ <string name="lolcat_save_succeeded_dialog_view">View in gallery</string>
43
+ <string name="lolcat_save_succeeded_dialog_share">Share</string>
44
+ <string name="lolcat_save_succeeded_dialog_cancel">Cancel</string>
45
+ </resources>
@@ -0,0 +1,808 @@
1
+ /*
2
+ * Copyright (C) 2008 Google Inc.
3
+ *
4
+ * Licensed under the Apache License, Version 2.0 (the "License");
5
+ * you may not use this file except in compliance with the License.
6
+ * You may obtain a copy of the License at
7
+ *
8
+ * http://www.apache.org/licenses/LICENSE-2.0
9
+ *
10
+ * Unless required by applicable law or agreed to in writing, software
11
+ * distributed under the License is distributed on an "AS IS" BASIS,
12
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ * See the License for the specific language governing permissions and
14
+ * limitations under the License.
15
+ */
16
+
17
+ package com.android.lolcat;
18
+
19
+ import android.app.Activity;
20
+ import android.app.AlertDialog;
21
+ import android.app.Dialog;
22
+ import android.app.ProgressDialog;
23
+ import android.content.DialogInterface;
24
+ import android.content.Intent;
25
+ import android.graphics.Bitmap;
26
+ import android.graphics.drawable.Drawable;
27
+ import android.media.MediaScannerConnection;
28
+ import android.net.Uri;
29
+ import android.os.Bundle;
30
+ import android.os.Environment;
31
+ import android.os.Handler;
32
+ import android.text.TextUtils;
33
+ import android.util.Log;
34
+ import android.view.LayoutInflater;
35
+ import android.view.View;
36
+ import android.widget.Button;
37
+ import android.widget.EditText;
38
+ import android.widget.Toast;
39
+
40
+ import java.io.File;
41
+ import java.io.FileNotFoundException;
42
+ import java.io.FileOutputStream;
43
+ import java.io.IOException;
44
+ import java.io.OutputStream;
45
+
46
+ /**
47
+ * Lolcat builder activity.
48
+ *
49
+ * Instructions:
50
+ * (1) Take photo of cat using Camera
51
+ * (2) Run LolcatActivity
52
+ * (3) Pick photo
53
+ * (4) Add caption(s)
54
+ * (5) Save and share
55
+ *
56
+ * See README.txt for a list of currently-missing features and known bugs.
57
+ */
58
+ public class LolcatActivity extends Activity
59
+ implements View.OnClickListener {
60
+ private static final String TAG = "LolcatActivity";
61
+
62
+ // Location on the SD card for saving lolcat images
63
+ private static final String LOLCAT_SAVE_DIRECTORY = "lolcats/";
64
+
65
+ // Mime type / format / extension we use (must be self-consistent!)
66
+ private static final String SAVED_IMAGE_EXTENSION = ".png";
67
+ private static final Bitmap.CompressFormat SAVED_IMAGE_COMPRESS_FORMAT =
68
+ Bitmap.CompressFormat.PNG;
69
+ private static final String SAVED_IMAGE_MIME_TYPE = "image/png";
70
+
71
+ // UI Elements
72
+ private Button mPickButton;
73
+ private Button mCaptionButton;
74
+ private Button mSaveButton;
75
+ private Button mClearCaptionButton;
76
+ private Button mClearPhotoButton;
77
+ private LolcatView mLolcatView;
78
+
79
+ private AlertDialog mCaptionDialog;
80
+ private ProgressDialog mSaveProgressDialog;
81
+ private AlertDialog mSaveSuccessDialog;
82
+
83
+ private Handler mHandler;
84
+
85
+ private Uri mPhotoUri;
86
+
87
+ private String mSavedImageFilename;
88
+ private Uri mSavedImageUri;
89
+
90
+ private MediaScannerConnection mMediaScannerConnection;
91
+
92
+ // Request codes used with startActivityForResult()
93
+ private static final int PHOTO_PICKED = 1;
94
+
95
+ // Dialog IDs
96
+ private static final int DIALOG_CAPTION = 1;
97
+ private static final int DIALOG_SAVE_PROGRESS = 2;
98
+ private static final int DIALOG_SAVE_SUCCESS = 3;
99
+
100
+ // Keys used with onSaveInstanceState()
101
+ private static final String PHOTO_URI_KEY = "photo_uri";
102
+ private static final String SAVED_IMAGE_FILENAME_KEY = "saved_image_filename";
103
+ private static final String SAVED_IMAGE_URI_KEY = "saved_image_uri";
104
+ private static final String TOP_CAPTION_KEY = "top_caption";
105
+ private static final String BOTTOM_CAPTION_KEY = "bottom_caption";
106
+ private static final String CAPTION_POSITIONS_KEY = "caption_positions";
107
+
108
+
109
+ @Override
110
+ protected void onCreate(Bundle icicle) {
111
+ Log.i(TAG, "onCreate()... icicle = " + icicle);
112
+
113
+ super.onCreate(icicle);
114
+
115
+ setContentView(R.layout.lolcat_activity);
116
+
117
+ // Look up various UI elements
118
+
119
+ mPickButton = (Button) findViewById(R.id.pick_button);
120
+ mPickButton.setOnClickListener(this);
121
+
122
+ mCaptionButton = (Button) findViewById(R.id.caption_button);
123
+ mCaptionButton.setOnClickListener(this);
124
+
125
+ mSaveButton = (Button) findViewById(R.id.save_button);
126
+ mSaveButton.setOnClickListener(this);
127
+
128
+ mClearCaptionButton = (Button) findViewById(R.id.clear_caption_button);
129
+ // This button doesn't exist in portrait mode.
130
+ if (mClearCaptionButton != null) mClearCaptionButton.setOnClickListener(this);
131
+
132
+ mClearPhotoButton = (Button) findViewById(R.id.clear_photo_button);
133
+ mClearPhotoButton.setOnClickListener(this);
134
+
135
+ mLolcatView = (LolcatView) findViewById(R.id.main_image);
136
+
137
+ // Need one of these to call back to the UI thread
138
+ // (and run AlertDialog.show(), for that matter)
139
+ mHandler = new Handler();
140
+
141
+ mMediaScannerConnection = new MediaScannerConnection(this, mMediaScanConnClient);
142
+
143
+ if (icicle != null) {
144
+ Log.i(TAG, "- reloading state from icicle!");
145
+ restoreStateFromIcicle(icicle);
146
+ }
147
+ }
148
+
149
+ @Override
150
+ protected void onResume() {
151
+ Log.i(TAG, "onResume()...");
152
+ super.onResume();
153
+
154
+ updateButtons();
155
+ }
156
+
157
+ @Override
158
+ protected void onSaveInstanceState(Bundle outState) {
159
+ Log.i(TAG, "onSaveInstanceState()...");
160
+ super.onSaveInstanceState(outState);
161
+
162
+ // State from the Activity:
163
+ outState.putParcelable(PHOTO_URI_KEY, mPhotoUri);
164
+ outState.putString(SAVED_IMAGE_FILENAME_KEY, mSavedImageFilename);
165
+ outState.putParcelable(SAVED_IMAGE_URI_KEY, mSavedImageUri);
166
+
167
+ // State from the LolcatView:
168
+ // (TODO: Consider making Caption objects, or even the LolcatView
169
+ // itself, Parcelable? Probably overkill, though...)
170
+ outState.putString(TOP_CAPTION_KEY, mLolcatView.getTopCaption());
171
+ outState.putString(BOTTOM_CAPTION_KEY, mLolcatView.getBottomCaption());
172
+ outState.putIntArray(CAPTION_POSITIONS_KEY, mLolcatView.getCaptionPositions());
173
+ }
174
+
175
+ /**
176
+ * Restores the activity state from the specified icicle.
177
+ * @see onCreate()
178
+ * @see onSaveInstanceState()
179
+ */
180
+ private void restoreStateFromIcicle(Bundle icicle) {
181
+ Log.i(TAG, "restoreStateFromIcicle()...");
182
+
183
+ // State of the Activity:
184
+
185
+ Uri photoUri = icicle.getParcelable(PHOTO_URI_KEY);
186
+ Log.i(TAG, " - photoUri: " + photoUri);
187
+ if (photoUri != null) {
188
+ loadPhoto(photoUri);
189
+ }
190
+
191
+ mSavedImageFilename = icicle.getString(SAVED_IMAGE_FILENAME_KEY);
192
+ mSavedImageUri = icicle.getParcelable(SAVED_IMAGE_URI_KEY);
193
+
194
+ // State of the LolcatView:
195
+
196
+ String topCaption = icicle.getString(TOP_CAPTION_KEY);
197
+ String bottomCaption = icicle.getString(BOTTOM_CAPTION_KEY);
198
+ int[] captionPositions = icicle.getIntArray(CAPTION_POSITIONS_KEY);
199
+ Log.i(TAG, " - captions: '" + topCaption + "', '" + bottomCaption + "'");
200
+ if (!TextUtils.isEmpty(topCaption) || !TextUtils.isEmpty(bottomCaption)) {
201
+ mLolcatView.setCaptions(topCaption, bottomCaption);
202
+ mLolcatView.setCaptionPositions(captionPositions);
203
+ }
204
+ }
205
+
206
+ @Override
207
+ protected void onDestroy() {
208
+ Log.i(TAG, "onDestroy()...");
209
+ super.onDestroy();
210
+ clearPhoto(); // Free up some resources, and force a GC
211
+ }
212
+
213
+ // View.OnClickListener implementation
214
+ public void onClick(View view) {
215
+ int id = view.getId();
216
+ Log.i(TAG, "onClick(View " + view + ", id " + id + ")...");
217
+
218
+ switch (id) {
219
+ case R.id.pick_button:
220
+ Log.i(TAG, "onClick: pick_button...");
221
+ Intent intent = new Intent(Intent.ACTION_GET_CONTENT, null);
222
+ intent.setType("image/*");
223
+
224
+ // Note: we could have the "crop" UI come up here by
225
+ // default by doing this:
226
+ // intent.putExtra("crop", "true");
227
+ // (But watch out: if you do that, the Intent that comes
228
+ // back to onActivityResult() will have the URI (of the
229
+ // cropped image) in the "action" field, not the "data"
230
+ // field!)
231
+
232
+ startActivityForResult(intent, PHOTO_PICKED);
233
+ break;
234
+
235
+ case R.id.caption_button:
236
+ Log.i(TAG, "onClick: caption_button...");
237
+ showCaptionDialog();
238
+ break;
239
+
240
+ case R.id.save_button:
241
+ Log.i(TAG, "onClick: save_button...");
242
+ saveImage();
243
+ break;
244
+
245
+ case R.id.clear_caption_button:
246
+ Log.i(TAG, "onClick: clear_caption_button...");
247
+ clearCaptions();
248
+ updateButtons();
249
+ break;
250
+
251
+ case R.id.clear_photo_button:
252
+ Log.i(TAG, "onClick: clear_photo_button...");
253
+ clearPhoto(); // Also does clearCaptions()
254
+ updateButtons();
255
+ break;
256
+
257
+ default:
258
+ Log.w(TAG, "Click from unexpected source: " + view + ", id " + id);
259
+ break;
260
+ }
261
+ }
262
+
263
+ @Override
264
+ protected void onActivityResult(int requestCode, int resultCode, Intent data) {
265
+ Log.i(TAG, "onActivityResult(request " + requestCode
266
+ + ", result " + resultCode + ", data " + data + ")...");
267
+
268
+ if (resultCode != RESULT_OK) {
269
+ Log.i(TAG, "==> result " + resultCode + " from subactivity! Ignoring...");
270
+ Toast t = Toast.makeText(this, R.string.lolcat_nothing_picked, Toast.LENGTH_SHORT);
271
+ t.show();
272
+ return;
273
+ }
274
+
275
+ if (requestCode == PHOTO_PICKED) {
276
+ // "data" is an Intent containing (presumably) a URI like
277
+ // "content://media/external/images/media/3".
278
+
279
+ if (data == null) {
280
+ Log.w(TAG, "Null data, but RESULT_OK, from image picker!");
281
+ Toast t = Toast.makeText(this, R.string.lolcat_nothing_picked,
282
+ Toast.LENGTH_SHORT);
283
+ t.show();
284
+ return;
285
+ }
286
+
287
+ if (data.getData() == null) {
288
+ Log.w(TAG, "'data' intent from image picker contained no data!");
289
+ Toast t = Toast.makeText(this, R.string.lolcat_nothing_picked,
290
+ Toast.LENGTH_SHORT);
291
+ t.show();
292
+ return;
293
+ }
294
+
295
+ loadPhoto(data.getData());
296
+ updateButtons();
297
+ }
298
+ }
299
+
300
+ /**
301
+ * Updates the enabled/disabled state of the onscreen buttons.
302
+ */
303
+ private void updateButtons() {
304
+ Log.i(TAG, "updateButtons()...");
305
+
306
+ // mPickButton is always enabled.
307
+
308
+ // Do we have a valid photo and/or caption(s) yet?
309
+ Drawable d = mLolcatView.getDrawable();
310
+ // Log.i(TAG, "===> current mLolcatView drawable: " + d);
311
+ boolean validPhoto = (d != null);
312
+ boolean validCaption = mLolcatView.hasValidCaption();
313
+
314
+ mCaptionButton.setText(validCaption
315
+ ? R.string.lolcat_change_captions : R.string.lolcat_add_captions);
316
+ mCaptionButton.setEnabled(validPhoto);
317
+
318
+ mSaveButton.setEnabled(validPhoto && validCaption);
319
+
320
+ if (mClearCaptionButton != null) {
321
+ mClearCaptionButton.setEnabled(validPhoto && validCaption);
322
+ }
323
+
324
+ mClearPhotoButton.setEnabled(validPhoto);
325
+ }
326
+
327
+ /**
328
+ * Clears out any already-entered captions for this lolcat.
329
+ */
330
+ private void clearCaptions() {
331
+ mLolcatView.clearCaptions();
332
+
333
+ // Clear the text fields in the caption dialog too.
334
+ if (mCaptionDialog != null) {
335
+ EditText topText = (EditText) mCaptionDialog.findViewById(R.id.top_edittext);
336
+ topText.setText("");
337
+ EditText bottomText = (EditText) mCaptionDialog.findViewById(R.id.bottom_edittext);
338
+ bottomText.setText("");
339
+ topText.requestFocus();
340
+ }
341
+
342
+ // This also invalidates any image we've previously written to the
343
+ // SD card...
344
+ mSavedImageFilename = null;
345
+ mSavedImageUri = null;
346
+ }
347
+
348
+ /**
349
+ * Completely resets the UI to its initial state, with no photo
350
+ * loaded, and no captions.
351
+ */
352
+ private void clearPhoto() {
353
+ mLolcatView.clear();
354
+
355
+ mPhotoUri = null;
356
+ mSavedImageFilename = null;
357
+ mSavedImageUri = null;
358
+
359
+ clearCaptions();
360
+
361
+ // Force a gc (to be sure to reclaim the memory used by our
362
+ // potentially huge bitmap):
363
+ System.gc();
364
+ }
365
+
366
+ /**
367
+ * Loads the image with the specified Uri into the UI.
368
+ */
369
+ private void loadPhoto(Uri uri) {
370
+ Log.i(TAG, "loadPhoto: uri = " + uri);
371
+
372
+ clearPhoto(); // Be sure to release the previous bitmap
373
+ // before creating another one
374
+ mPhotoUri = uri;
375
+
376
+ // A new photo always starts out uncaptioned.
377
+ clearCaptions();
378
+
379
+ // Load the selected photo into our ImageView.
380
+ mLolcatView.loadFromUri(mPhotoUri);
381
+ }
382
+
383
+ private void showCaptionDialog() {
384
+ // If the dialog already exists, always reset focus to the top
385
+ // item each time it comes up.
386
+ if (mCaptionDialog != null) {
387
+ EditText topText = (EditText) mCaptionDialog.findViewById(R.id.top_edittext);
388
+ topText.requestFocus();
389
+ }
390
+
391
+ showDialog(DIALOG_CAPTION);
392
+ }
393
+
394
+ private void showSaveSuccessDialog() {
395
+ // If the dialog already exists, update the body text based on the
396
+ // current values of mSavedImageFilename and mSavedImageUri
397
+ // (otherwise the dialog will still have the body text from when
398
+ // it was first created!)
399
+
400
+ if (mSaveSuccessDialog != null) {
401
+ updateSaveSuccessDialogBody();
402
+ }
403
+ showDialog(DIALOG_SAVE_SUCCESS);
404
+ }
405
+
406
+ private void updateSaveSuccessDialogBody() {
407
+ if (mSaveSuccessDialog == null) {
408
+ throw new IllegalStateException(
409
+ "updateSaveSuccessDialogBody: mSaveSuccessDialog hasn't been created yet");
410
+ }
411
+ String dialogBody = String.format(
412
+ getResources().getString(R.string.lolcat_save_succeeded_dialog_body_format),
413
+ mSavedImageFilename, mSavedImageUri);
414
+ mSaveSuccessDialog.setMessage(dialogBody);
415
+ }
416
+
417
+ @Override
418
+ protected Dialog onCreateDialog(int id) {
419
+ Log.i(TAG, "onCreateDialog(id " + id + ")...");
420
+
421
+ // This is only run once (per dialog), the very first time
422
+ // a given dialog needs to be shown.
423
+
424
+ switch (id) {
425
+ case DIALOG_CAPTION:
426
+ LayoutInflater factory = LayoutInflater.from(this);
427
+ final View textEntryView = factory.inflate(R.layout.lolcat_caption_dialog, null);
428
+ mCaptionDialog = new AlertDialog.Builder(this)
429
+ .setTitle(R.string.lolcat_caption_dialog_title)
430
+ .setIcon(0)
431
+ .setView(textEntryView)
432
+ .setPositiveButton(
433
+ R.string.lolcat_caption_dialog_ok,
434
+ new DialogInterface.OnClickListener() {
435
+ public void onClick(DialogInterface dialog, int whichButton) {
436
+ Log.i(TAG, "Caption dialog: OK...");
437
+ updateCaptionsFromDialog();
438
+ }
439
+ })
440
+ .setNegativeButton(
441
+ R.string.lolcat_caption_dialog_cancel,
442
+ new DialogInterface.OnClickListener() {
443
+ public void onClick(DialogInterface dialog, int whichButton) {
444
+ Log.i(TAG, "Caption dialog: CANCEL...");
445
+ // Nothing to do here (for now at least)
446
+ }
447
+ })
448
+ .create();
449
+ return mCaptionDialog;
450
+
451
+ case DIALOG_SAVE_PROGRESS:
452
+ mSaveProgressDialog = new ProgressDialog(this);
453
+ mSaveProgressDialog.setMessage(getResources().getString(R.string.lolcat_saving));
454
+ mSaveProgressDialog.setIndeterminate(true);
455
+ mSaveProgressDialog.setCancelable(false);
456
+ return mSaveProgressDialog;
457
+
458
+ case DIALOG_SAVE_SUCCESS:
459
+ mSaveSuccessDialog = new AlertDialog.Builder(this)
460
+ .setTitle(R.string.lolcat_save_succeeded_dialog_title)
461
+ .setIcon(0)
462
+ .setPositiveButton(
463
+ R.string.lolcat_save_succeeded_dialog_view,
464
+ new DialogInterface.OnClickListener() {
465
+ public void onClick(DialogInterface dialog, int whichButton) {
466
+ Log.i(TAG, "Save dialog: View...");
467
+ viewSavedImage();
468
+ }
469
+ })
470
+ .setNeutralButton(
471
+ R.string.lolcat_save_succeeded_dialog_share,
472
+ new DialogInterface.OnClickListener() {
473
+ public void onClick(DialogInterface dialog, int whichButton) {
474
+ Log.i(TAG, "Save dialog: Share...");
475
+ shareSavedImage();
476
+ }
477
+ })
478
+ .setNegativeButton(
479
+ R.string.lolcat_save_succeeded_dialog_cancel,
480
+ new DialogInterface.OnClickListener() {
481
+ public void onClick(DialogInterface dialog, int whichButton) {
482
+ Log.i(TAG, "Save dialog: CANCEL...");
483
+ // Nothing to do here...
484
+ }
485
+ })
486
+ .create();
487
+ updateSaveSuccessDialogBody();
488
+ return mSaveSuccessDialog;
489
+
490
+ default:
491
+ Log.w(TAG, "Request for unexpected dialog id: " + id);
492
+ break;
493
+ }
494
+ return null;
495
+ }
496
+
497
+ private void updateCaptionsFromDialog() {
498
+ Log.i(TAG, "updateCaptionsFromDialog()...");
499
+
500
+ if (mCaptionDialog == null) {
501
+ Log.w(TAG, "updateCaptionsFromDialog: null mCaptionDialog!");
502
+ return;
503
+ }
504
+
505
+ // Get the two caption strings:
506
+
507
+ EditText topText = (EditText) mCaptionDialog.findViewById(R.id.top_edittext);
508
+ Log.i(TAG, "- Top editText: " + topText);
509
+ String topString = topText.getText().toString();
510
+ Log.i(TAG, " - String: '" + topString + "'");
511
+
512
+ EditText bottomText = (EditText) mCaptionDialog.findViewById(R.id.bottom_edittext);
513
+ Log.i(TAG, "- Bottom editText: " + bottomText);
514
+ String bottomString = bottomText.getText().toString();
515
+ Log.i(TAG, " - String: '" + bottomString + "'");
516
+
517
+ mLolcatView.setCaptions(topString, bottomString);
518
+ updateButtons();
519
+ }
520
+
521
+
522
+ /**
523
+ * Kicks off the process of saving the LolcatView's working Bitmap to
524
+ * the SD card, in preparation for viewing it later and/or sharing it.
525
+ */
526
+ private void saveImage() {
527
+ Log.i(TAG, "saveImage()...");
528
+
529
+ // First of all, bring up a progress dialog.
530
+ showDialog(DIALOG_SAVE_PROGRESS);
531
+
532
+ // We now need to save the bitmap to the SD card, and then ask the
533
+ // MediaScanner to scan it. Do the actual work of all this in a
534
+ // helper thread, since it's fairly slow (and will occasionally
535
+ // ANR if we do it here in the UI thread.)
536
+
537
+ Thread t = new Thread() {
538
+ public void run() {
539
+ Log.i(TAG, "Running worker thread...");
540
+ saveImageInternal();
541
+ }
542
+ };
543
+ t.start();
544
+ // Next steps:
545
+ // - saveImageInternal()
546
+ // - onMediaScannerConnected()
547
+ // - onScanCompleted
548
+ }
549
+
550
+ /**
551
+ * Saves the LolcatView's working Bitmap to the SD card, in
552
+ * preparation for viewing it later and/or sharing it.
553
+ *
554
+ * The bitmap will be saved as a new file in the directory
555
+ * LOLCAT_SAVE_DIRECTORY, with an automatically-generated filename
556
+ * based on the current time. It also connects to the
557
+ * MediaScanner service, since we'll need to scan that new file (in
558
+ * order to get a Uri we can then VIEW or share.)
559
+ *
560
+ * This method is run in a worker thread; @see saveImage().
561
+ */
562
+ private void saveImageInternal() {
563
+ Log.i(TAG, "saveImageInternal()...");
564
+
565
+ // TODO: Currently we save the bitmap to a file on the sdcard,
566
+ // then ask the MediaScanner to scan it (which gives us a Uri we
567
+ // can then do an ACTION_VIEW on.) But rather than doing these
568
+ // separate steps, maybe there's some easy way (given an
569
+ // OutputStream) to directly talk to the MediaProvider
570
+ // (i.e. com.android.provider.MediaStore) and say "here's an
571
+ // image, please save it somwhere and return the URI to me"...
572
+
573
+ // Save the bitmap to a file on the sdcard.
574
+ // (Based on similar code in MusicUtils.java.)
575
+ // TODO: Make this filename more human-readable? Maybe "Lolcat-YYYY-MM-DD-HHMMSS.png"?
576
+ String filename = Environment.getExternalStorageDirectory()
577
+ + "/" + LOLCAT_SAVE_DIRECTORY
578
+ + String.valueOf(System.currentTimeMillis() + SAVED_IMAGE_EXTENSION);
579
+ Log.i(TAG, "- filename: '" + filename + "'");
580
+
581
+ if (ensureFileExists(filename)) {
582
+ try {
583
+ OutputStream outstream = new FileOutputStream(filename);
584
+ Bitmap bitmap = mLolcatView.getWorkingBitmap();
585
+ boolean success = bitmap.compress(SAVED_IMAGE_COMPRESS_FORMAT,
586
+ 100, outstream);
587
+ Log.i(TAG, "- success code from Bitmap.compress: " + success);
588
+ outstream.close();
589
+
590
+ if (success) {
591
+ Log.i(TAG, "- Saved! filename = " + filename);
592
+ mSavedImageFilename = filename;
593
+
594
+ // Ok, now we need to get the MediaScanner to scan the
595
+ // file we just wrote. Step 1 is to get our
596
+ // MediaScannerConnection object to connect to the
597
+ // MediaScanner service.
598
+ mMediaScannerConnection.connect();
599
+ // See onMediaScannerConnected() for the next step
600
+ } else {
601
+ Log.w(TAG, "Bitmap.compress failed: bitmap " + bitmap
602
+ + ", filename '" + filename + "'");
603
+ onSaveFailed(R.string.lolcat_save_failed);
604
+ }
605
+ } catch (FileNotFoundException e) {
606
+ Log.w(TAG, "error creating file", e);
607
+ onSaveFailed(R.string.lolcat_save_failed);
608
+ } catch (IOException e) {
609
+ Log.w(TAG, "error creating file", e);
610
+ onSaveFailed(R.string.lolcat_save_failed);
611
+ }
612
+ } else {
613
+ Log.w(TAG, "ensureFileExists failed for filename '" + filename + "'");
614
+ onSaveFailed(R.string.lolcat_save_failed);
615
+ }
616
+ }
617
+
618
+
619
+ //
620
+ // MediaScanner-related code
621
+ //
622
+
623
+ /**
624
+ * android.media.MediaScannerConnection.MediaScannerConnectionClient implementation.
625
+ */
626
+ private MediaScannerConnection.MediaScannerConnectionClient mMediaScanConnClient =
627
+ new MediaScannerConnection.MediaScannerConnectionClient() {
628
+ /**
629
+ * Called when a connection to the MediaScanner service has been established.
630
+ */
631
+ public void onMediaScannerConnected() {
632
+ Log.i(TAG, "MediaScannerConnectionClient.onMediaScannerConnected...");
633
+ // The next step happens in the UI thread:
634
+ mHandler.post(new Runnable() {
635
+ public void run() {
636
+ LolcatActivity.this.onMediaScannerConnected();
637
+ }
638
+ });
639
+ }
640
+
641
+ /**
642
+ * Called when the media scanner has finished scanning a file.
643
+ * @param path the path to the file that has been scanned.
644
+ * @param uri the Uri for the file if the scanning operation succeeded
645
+ * and the file was added to the media database, or null if scanning failed.
646
+ */
647
+ public void onScanCompleted(final String path, final Uri uri) {
648
+ Log.i(TAG, "MediaScannerConnectionClient.onScanCompleted: path "
649
+ + path + ", uri " + uri);
650
+ // Just run the "real" onScanCompleted() method in the UI thread:
651
+ mHandler.post(new Runnable() {
652
+ public void run() {
653
+ LolcatActivity.this.onScanCompleted(path, uri);
654
+ }
655
+ });
656
+ }
657
+ };
658
+
659
+ /**
660
+ * This method is called when our MediaScannerConnection successfully
661
+ * connects to the MediaScanner service. At that point we fire off a
662
+ * request to scan the lolcat image we just saved.
663
+ *
664
+ * This needs to run in the UI thread, so it's called from
665
+ * mMediaScanConnClient's onMediaScannerConnected() method via our Handler.
666
+ */
667
+ private void onMediaScannerConnected() {
668
+ Log.i(TAG, "onMediaScannerConnected()...");
669
+
670
+ // Update the message in the progress dialog...
671
+ mSaveProgressDialog.setMessage(getResources().getString(R.string.lolcat_scanning));
672
+
673
+ // Fire off a request to the MediaScanner service to scan this
674
+ // file; we'll get notified when the scan completes.
675
+ Log.i(TAG, "- Requesting scan for file: " + mSavedImageFilename);
676
+ mMediaScannerConnection.scanFile(mSavedImageFilename,
677
+ null /* mimeType */);
678
+
679
+ // Next step: mMediaScanConnClient will get an onScanCompleted() callback,
680
+ // which calls our own onScanCompleted() method via our Handler.
681
+ }
682
+
683
+ /**
684
+ * Updates the UI after the media scanner finishes the scanFile()
685
+ * request we issued from onMediaScannerConnected().
686
+ *
687
+ * This needs to run in the UI thread, so it's called from
688
+ * mMediaScanConnClient's onScanCompleted() method via our Handler.
689
+ */
690
+ private void onScanCompleted(String path, final Uri uri) {
691
+ Log.i(TAG, "onScanCompleted: path " + path + ", uri " + uri);
692
+ mMediaScannerConnection.disconnect();
693
+
694
+ if (uri == null) {
695
+ Log.w(TAG, "onScanCompleted: scan failed.");
696
+ mSavedImageUri = null;
697
+ onSaveFailed(R.string.lolcat_scan_failed);
698
+ return;
699
+ }
700
+
701
+ // Success!
702
+
703
+ dismissDialog(DIALOG_SAVE_PROGRESS);
704
+
705
+ // We can now access the saved lolcat image using the specified Uri.
706
+ mSavedImageUri = uri;
707
+
708
+ // Bring up a success dialog, giving the user the option to go to
709
+ // the pictures app (so you can share the image).
710
+ showSaveSuccessDialog();
711
+ }
712
+
713
+
714
+ //
715
+ // Other misc utility methods
716
+ //
717
+
718
+ /**
719
+ * Ensure that the specified file exists on the SD card, creating it
720
+ * if necessary.
721
+ *
722
+ * Copied from MediaProvider / MusicUtils.
723
+ *
724
+ * @return true if the file already exists, or we
725
+ * successfully created it.
726
+ */
727
+ private static boolean ensureFileExists(String path) {
728
+ File file = new File(path);
729
+ if (file.exists()) {
730
+ return true;
731
+ } else {
732
+ // we will not attempt to create the first directory in the path
733
+ // (for example, do not create /sdcard if the SD card is not mounted)
734
+ int secondSlash = path.indexOf('/', 1);
735
+ if (secondSlash < 1) return false;
736
+ String directoryPath = path.substring(0, secondSlash);
737
+ File directory = new File(directoryPath);
738
+ if (!directory.exists())
739
+ return false;
740
+ file.getParentFile().mkdirs();
741
+ try {
742
+ return file.createNewFile();
743
+ } catch (IOException ioe) {
744
+ Log.w(TAG, "File creation failed", ioe);
745
+ }
746
+ return false;
747
+ }
748
+ }
749
+
750
+ /**
751
+ * Updates the UI after a failure anywhere in the bitmap saving / scanning
752
+ * sequence.
753
+ */
754
+ private void onSaveFailed(int errorMessageResId) {
755
+ dismissDialog(DIALOG_SAVE_PROGRESS);
756
+ Toast.makeText(this, errorMessageResId, Toast.LENGTH_SHORT).show();
757
+ }
758
+
759
+ /**
760
+ * Goes to the Pictures app for the specified URI.
761
+ */
762
+ private void viewSavedImage(Uri uri) {
763
+ Log.i(TAG, "viewSavedImage(" + uri + ")...");
764
+
765
+ if (uri == null) {
766
+ Log.w(TAG, "viewSavedImage: null uri!");
767
+ return;
768
+ }
769
+
770
+ Intent intent = new Intent(Intent.ACTION_VIEW, uri);
771
+ Log.i(TAG, "- running startActivity... Intent = " + intent);
772
+ startActivity(intent);
773
+ }
774
+
775
+ private void viewSavedImage() {
776
+ viewSavedImage(mSavedImageUri);
777
+ }
778
+
779
+ /**
780
+ * Shares the image with the specified URI.
781
+ */
782
+ private void shareSavedImage(Uri uri) {
783
+ Log.i(TAG, "shareSavedImage(" + uri + ")...");
784
+
785
+ if (uri == null) {
786
+ Log.w(TAG, "shareSavedImage: null uri!");
787
+ return;
788
+ }
789
+
790
+ Intent intent = new Intent();
791
+ intent.setAction(Intent.ACTION_SEND);
792
+ intent.setType(SAVED_IMAGE_MIME_TYPE);
793
+ intent.putExtra(Intent.EXTRA_STREAM, uri);
794
+ try {
795
+ startActivity(
796
+ Intent.createChooser(
797
+ intent,
798
+ getResources().getString(R.string.lolcat_sendImage_label)));
799
+ } catch (android.content.ActivityNotFoundException ex) {
800
+ Log.w(TAG, "shareSavedImage: startActivity failed", ex);
801
+ Toast.makeText(this, R.string.lolcat_share_failed, Toast.LENGTH_SHORT).show();
802
+ }
803
+ }
804
+
805
+ private void shareSavedImage() {
806
+ shareSavedImage(mSavedImageUri);
807
+ }
808
+ }