/androidsays/src/com/google/marvin/androidsays/AndroidSays.java

http://eyes-free.googlecode.com/ · Java · 400 lines · 304 code · 71 blank · 25 comment · 20 complexity · d9158a2f85d26cffb6c520ec8dd14c10 MD5 · raw file

  1. /*
  2. * Copyright (C) 2008 Google Inc.
  3. *
  4. * Licensed under the Apache License, Version 2.0 (the "License"); you may not
  5. * use this file except in compliance with the License. You may obtain a copy of
  6. * 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, WITHOUT
  12. * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
  13. * License for the specific language governing permissions and limitations under
  14. * the License.
  15. */
  16. package com.google.marvin.androidsays;
  17. import com.scoreninja.adapter.ScoreNinjaAdapter;
  18. import android.app.Activity;
  19. import android.app.AlertDialog.Builder;
  20. import android.content.DialogInterface;
  21. import android.content.DialogInterface.OnClickListener;
  22. import android.content.ComponentName;
  23. import android.content.Intent;
  24. import android.content.SharedPreferences;
  25. import android.content.SharedPreferences.Editor;
  26. import android.media.AudioManager;
  27. import android.net.Uri;
  28. import android.os.Bundle;
  29. import android.preference.PreferenceManager;
  30. import android.view.Menu;
  31. import android.view.MenuItem;
  32. import android.view.View;
  33. import android.widget.Toast;
  34. import java.io.File;
  35. import java.io.FilenameFilter;
  36. import java.util.ArrayList;
  37. /**
  38. * mem A memory game for the Android Platform
  39. *
  40. * @author clchen@google.com (Charles L. Chen)
  41. */
  42. public class AndroidSays extends Activity {
  43. protected static final int PREFS_UPDATED = 42;
  44. private static final String THEME_FILE_EXTENSION = ".mem";
  45. private static final String THEMES_BASE_PATH = "/sdcard/mem/themes/";
  46. private GameView gView;
  47. public SfxController sfx;
  48. public int speedPrefDelay;
  49. public int gameMode;
  50. public int sequenceLength;
  51. public boolean halt;
  52. private String[] filenames;
  53. public String themeFilename;
  54. private ScoreNinjaAdapter scoreNinjaAdapter;
  55. private String appId = "androidsays";
  56. private String privateKey = "450CA446A7885E7F7B75F19E8F5A39E8";
  57. /** Called when the activity is first created. */
  58. @Override
  59. public void onCreate(Bundle icicle) {
  60. super.onCreate(icicle);
  61. halt = false;
  62. themeFilename = null;
  63. scoreNinjaAdapter = new ScoreNinjaAdapter(this, appId, privateKey);
  64. loadPrefs();
  65. setVolumeControlStream(AudioManager.STREAM_MUSIC);
  66. startApp();
  67. }
  68. private void startApp() {
  69. if (gView != null) {
  70. gView.setVisibility(View.GONE);
  71. gView = null;
  72. }
  73. sfx = new SfxController(this);
  74. gView = new GameView(this);
  75. setContentView(gView);
  76. }
  77. @Override
  78. public boolean onCreateOptionsMenu(Menu menu) {
  79. menu.add(0, R.string.settings, 0, R.string.settings).setIcon(
  80. android.R.drawable.ic_menu_preferences);
  81. menu.add(0, R.string.themes, 0, R.string.themes).setIcon(android.R.drawable.ic_menu_edit);
  82. menu.add(0, R.string.about, 0, R.string.about).setIcon(android.R.drawable.ic_menu_info_details);
  83. menu.add(0, R.string.hiscores, 0, R.string.hiscores).setIcon(
  84. android.R.drawable.btn_star_big_off);
  85. return super.onCreateOptionsMenu(menu);
  86. }
  87. @Override
  88. public boolean onOptionsItemSelected(MenuItem item) {
  89. Intent intent;
  90. switch (item.getItemId()) {
  91. case R.string.settings:
  92. intent = new Intent(this, PrefsActivity.class);
  93. startActivityForResult(intent, PREFS_UPDATED);
  94. break;
  95. case R.string.themes:
  96. displayThemeSelector();
  97. break;
  98. case R.string.about:
  99. displayAbout();
  100. break;
  101. case R.string.hiscores:
  102. displayHiscores();
  103. break;
  104. }
  105. return super.onOptionsItemSelected(item);
  106. }
  107. @Override
  108. protected void onActivityResult(int requestCode, int resultCode, Intent data) {
  109. if (requestCode == PREFS_UPDATED) {
  110. loadPrefs();
  111. }
  112. super.onActivityResult(requestCode, resultCode, data);
  113. scoreNinjaAdapter.onActivityResult(requestCode, resultCode, data);
  114. }
  115. private void loadPrefs() {
  116. SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this);
  117. // From the game mode setting
  118. String modeStr = prefs.getString("game_mode_pref", "1");
  119. gameMode = Integer.parseInt(modeStr);
  120. String sequenceLengthStr = prefs.getString("sequence_length_pref", "1");
  121. sequenceLength = Integer.parseInt(sequenceLengthStr);
  122. // From the speed setting
  123. String delayStr = prefs.getString("speed_pref", "-1");
  124. speedPrefDelay = Integer.parseInt(delayStr);
  125. // Load the theme
  126. themeFilename = prefs.getString("theme_pref", "");
  127. }
  128. @Override
  129. protected void onStop() {
  130. halt = true;
  131. sfx.stop();
  132. super.onStop();
  133. }
  134. @Override
  135. protected void onRestart() {
  136. reloadGameView();
  137. super.onRestart();
  138. }
  139. private void reloadGameView() {
  140. halt = false;
  141. if (gView != null) {
  142. gView.setVisibility(View.GONE);
  143. gView = null;
  144. }
  145. gView = new GameView(this);
  146. setContentView(gView);
  147. }
  148. private void displayThemeSelector() {
  149. Builder themeFilesDialog = new Builder(this);
  150. String titleText = "Select a theme";
  151. themeFilesDialog.setTitle(titleText);
  152. File androidSaysDir = new File(THEMES_BASE_PATH);
  153. filenames = androidSaysDir.list(new FilenameFilter() {
  154. public boolean accept(File dir, String filename) {
  155. return filename.endsWith(THEME_FILE_EXTENSION);
  156. }
  157. });
  158. // Read the available themes from the SD card
  159. ArrayList<String> filenamesArrayList = new ArrayList<String>();
  160. filenamesArrayList.add("Default");
  161. if (filenames != null) {
  162. for (int i = 0; i < filenames.length; i++) {
  163. filenamesArrayList.add(filenames[i].substring(0, filenames[i].length()
  164. - THEME_FILE_EXTENSION.length()));
  165. }
  166. } else {
  167. filenames = new String[0];
  168. }
  169. filenames = filenamesArrayList.toArray(filenames);
  170. themeFilesDialog.setSingleChoiceItems(filenames, -1, new OnClickListener() {
  171. public void onClick(DialogInterface dialog, int which) {
  172. if (which == 0) {
  173. themeFilename = null;
  174. } else {
  175. themeFilename = THEMES_BASE_PATH + filenames[which] + THEME_FILE_EXTENSION;
  176. }
  177. }
  178. });
  179. final Activity self = this;
  180. themeFilesDialog.setPositiveButton("Apply theme", new OnClickListener() {
  181. public void onClick(DialogInterface dialog, int which) {
  182. SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(self);
  183. Editor editor = prefs.edit();
  184. editor.putString("theme_pref", themeFilename);
  185. editor.commit();
  186. reloadGameView();
  187. dialog.dismiss();
  188. }
  189. });
  190. themeFilesDialog.setNeutralButton("Get new themes", new OnClickListener() {
  191. public void onClick(DialogInterface dialog, int which) {
  192. if (!new File("/sdcard/").canWrite()) {
  193. dialog.dismiss();
  194. displayMissingSdCardToast();
  195. } else {
  196. Intent i = new Intent();
  197. ComponentName comp =
  198. new ComponentName("com.android.browser", "com.android.browser.BrowserActivity");
  199. i.setComponent(comp);
  200. i.setAction("android.intent.action.VIEW");
  201. i.addCategory("android.intent.category.BROWSABLE");
  202. Uri uri = Uri.parse("http://groups.google.com/group/mem-game/files");
  203. i.setData(uri);
  204. self.startActivity(i);
  205. }
  206. }
  207. });
  208. themeFilesDialog.setNegativeButton("Cancel", new OnClickListener() {
  209. public void onClick(DialogInterface dialog, int which) {
  210. dialog.dismiss();
  211. }
  212. });
  213. themeFilesDialog.show();
  214. }
  215. private void displayMissingSdCardToast() {
  216. Toast.makeText(this, "Please insert an SD card before trying to download themes.",
  217. Toast.LENGTH_LONG).show();
  218. }
  219. private void displayAbout() {
  220. Builder about = new Builder(this);
  221. String titleText = "mem";
  222. about.setTitle(titleText);
  223. String message = "by Charles L. Chen (clchen@google.com)";
  224. about.setMessage(message);
  225. final Activity self = this;
  226. about.setPositiveButton("Visit website", new OnClickListener() {
  227. public void onClick(DialogInterface dialog, int which) {
  228. Intent i = new Intent();
  229. ComponentName comp =
  230. new ComponentName("com.android.browser", "com.android.browser.BrowserActivity");
  231. i.setComponent(comp);
  232. i.setAction("android.intent.action.VIEW");
  233. i.addCategory("android.intent.category.BROWSABLE");
  234. Uri uri = Uri.parse("http://groups.google.com/group/mem-game");
  235. i.setData(uri);
  236. self.startActivity(i);
  237. }
  238. });
  239. about.setNegativeButton("Close", new OnClickListener() {
  240. public void onClick(DialogInterface dialog, int which) {
  241. }
  242. });
  243. about.show();
  244. }
  245. public void recordScore(int score) {
  246. SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this);
  247. String modeStr = prefs.getString("game_mode_pref", "1");
  248. gameMode = Integer.parseInt(modeStr);
  249. String sequenceLengthStr = prefs.getString("sequence_length_pref", "1");
  250. String scorePrefStr = "";
  251. String subboard = " (" + sequenceLengthStr + ")";
  252. if (gameMode == 1) {
  253. scorePrefStr = "classic_";
  254. subboard = "Classic Mode" + subboard;
  255. } else {
  256. scorePrefStr = "challenge_";
  257. subboard = "Challenge Mode" + subboard;
  258. }
  259. scorePrefStr = scorePrefStr + sequenceLengthStr;
  260. int prevHiScore = Integer.parseInt(prefs.getString(scorePrefStr, "0"));
  261. int diff = score - prevHiScore;
  262. if (diff > 0) {
  263. Editor editor = prefs.edit();
  264. editor.putString(scorePrefStr, Integer.toString(score));
  265. editor.commit();
  266. Toast.makeText(this, "You beat your old record by " + diff + "!", Toast.LENGTH_LONG).show();
  267. }
  268. scoreNinjaAdapter.show(score, "Top Scores for " + subboard, subboard);
  269. }
  270. private void displayHiscores() {
  271. Builder hiscores = new Builder(this);
  272. String titleText = "High Scores";
  273. hiscores.setTitle(titleText);
  274. SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this);
  275. String message = "Classic mode (1): " + prefs.getString("classic_1", "0") + "\n";
  276. message = message + "Classic mode (5): " + prefs.getString("classic_5", "0") + "\n";
  277. message = message + "Classic mode (10): " + prefs.getString("classic_10", "0") + "\n";
  278. message = message + "Classic mode (20): " + prefs.getString("classic_20", "0") + "\n";
  279. message = message + "Classic mode (30): " + prefs.getString("classic_30", "0") + "\n" + "\n";
  280. message = message + "Challenge mode (1): " + prefs.getString("challenge_1", "0") + "\n";
  281. message = message + "Challenge mode (5): " + prefs.getString("challenge_5", "0") + "\n";
  282. message = message + "Challenge mode (10): " + prefs.getString("challenge_10", "0") + "\n";
  283. message = message + "Challenge mode (20): " + prefs.getString("challenge_20", "0") + "\n";
  284. message = message + "Challenge mode (30): " + prefs.getString("challenge_30", "0");
  285. hiscores.setMessage(message);
  286. hiscores.setPositiveButton("Erase high scores", new OnClickListener() {
  287. public void onClick(DialogInterface dialog, int which) {
  288. displayScoreResetConfirmation();
  289. dialog.dismiss();
  290. }
  291. });
  292. hiscores.setNegativeButton("Close", new OnClickListener() {
  293. public void onClick(DialogInterface dialog, int which) {
  294. }
  295. });
  296. hiscores.show();
  297. }
  298. private void displayScoreResetConfirmation() {
  299. Builder confirmation = new Builder(this);
  300. String titleText = "Erase high scores?";
  301. confirmation.setTitle(titleText);
  302. String message = "Are you sure you want to erase the high scores?";
  303. confirmation.setMessage(message);
  304. final Activity self = this;
  305. confirmation.setPositiveButton("Yes", new OnClickListener() {
  306. public void onClick(DialogInterface dialog, int which) {
  307. SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(self);
  308. Editor editor = prefs.edit();
  309. editor.putString("classic_1", "0");
  310. editor.putString("classic_5", "0");
  311. editor.putString("classic_10", "0");
  312. editor.putString("classic_20", "0");
  313. editor.putString("classic_30", "0");
  314. editor.putString("challenge_1", "0");
  315. editor.putString("challenge_5", "0");
  316. editor.putString("challenge_10", "0");
  317. editor.putString("challenge_20", "0");
  318. editor.putString("challenge_30", "0");
  319. editor.commit();
  320. dialog.dismiss();
  321. }
  322. });
  323. confirmation.setNegativeButton("No", new OnClickListener() {
  324. public void onClick(DialogInterface dialog, int which) {
  325. }
  326. });
  327. confirmation.show();
  328. }
  329. }