/documentation/tutorial/MusicFileBrowser/MusicFileBrowser_Tutorial1/src/com/google/marvin/tutorials/musicFileBrowser1/MusicFileBrowser.java

http://eyes-free.googlecode.com/ · Java · 222 lines · 184 code · 23 blank · 15 comment · 36 complexity · 50de681669c86300767f99dbeb0b7920 MD5 · raw file

  1. package com.google.marvin.tutorials.musicFileBrowser1;
  2. /**
  3. * Music File Browser with speech added; no gestures yet.
  4. *
  5. * File browsing code is based on a tutorial from anddev.org by Nicolas Gramlich
  6. * http://www.anddev.org/building_an_android_filebrowser_list-based_ -t67.html
  7. *
  8. * @author clchen@google.com (Charles L. Chen)
  9. */
  10. import com.google.tts.TTS;
  11. import java.io.File;
  12. import java.util.ArrayList;
  13. import java.util.Collections;
  14. import java.util.List;
  15. import android.app.Activity;
  16. import android.content.Context;
  17. import android.media.MediaPlayer;
  18. import android.net.Uri;
  19. import android.os.Bundle;
  20. import android.os.Vibrator;
  21. import android.view.KeyEvent;
  22. import android.view.MotionEvent;
  23. import android.view.View;
  24. import android.widget.AdapterView;
  25. import android.widget.ArrayAdapter;
  26. import android.widget.ListView;
  27. import android.widget.Toast;
  28. import android.widget.AdapterView.OnItemClickListener;
  29. public class MusicFileBrowser extends Activity {
  30. private static final long[] VIBE_PATTERN = {0, 10, 70, 80};
  31. private Vibrator vibe;
  32. private List<String> directoryEntries = new ArrayList<String>();
  33. private File currentDirectory = new File("/sdcard/");
  34. private MediaPlayer mp = new MediaPlayer();
  35. private int lastPosition;
  36. private String lastPlayedFilename = "";
  37. private TTS tts;
  38. private ListView myList;
  39. private TTS.InitListener ttsInitListener = new TTS.InitListener() {
  40. public void onInit(int version) {
  41. lastPosition = 0;
  42. vibe = (Vibrator) getSystemService(Context.VIBRATOR_SERVICE);
  43. browseTo(new File("/sdcard/"));
  44. tts.speak("Music File Browser started.", 0, null);
  45. }
  46. };
  47. /** Called when the activity is first created. */
  48. @Override
  49. public void onCreate(Bundle icicle) {
  50. super.onCreate(icicle);
  51. myList = new ListView(this);
  52. myList.setOnItemClickListener(new OnItemClickListener() {
  53. public void onItemClick(AdapterView<?> l, View v, int position, long id) {
  54. if (position == 0) {
  55. playNext();
  56. } else if (position == 1) {
  57. upOneLevel();
  58. } else {
  59. lastPosition = position;
  60. File clickedFile =
  61. new File(currentDirectory.getAbsolutePath() + directoryEntries.get(position));
  62. if (clickedFile != null) {
  63. browseTo(clickedFile);
  64. }
  65. }
  66. }
  67. });
  68. setContentView(myList);
  69. tts = new TTS(this, ttsInitListener, true);
  70. }
  71. /**
  72. * This function browses up one level according to the field: currentDirectory
  73. * Returns whether or not navigation occurred.
  74. */
  75. private boolean upOneLevel() {
  76. String parent = this.currentDirectory.getParent();
  77. if (parent.equals("/")) {
  78. browseTo(new File("/sdcard/"));
  79. return false;
  80. } else if (this.currentDirectory.getParent() != null) {
  81. this.browseTo(this.currentDirectory.getParentFile());
  82. }
  83. return true;
  84. }
  85. private void browseTo(final File aDirectory) {
  86. if (aDirectory.isDirectory()) {
  87. this.currentDirectory = aDirectory;
  88. fill(aDirectory.listFiles());
  89. lastPosition = 0;
  90. myList.setSelection(0);
  91. } else {
  92. togglePlaying(aDirectory);
  93. }
  94. }
  95. private void togglePlaying(final File aFile) {
  96. if (mp.isPlaying()) {
  97. mp.stop();
  98. } else {
  99. lastPlayedFilename = aFile.getAbsolutePath();
  100. mp = MediaPlayer.create(this, Uri.parse(lastPlayedFilename));
  101. mp.start();
  102. }
  103. }
  104. private void playNext() {
  105. if (mp.isPlaying()) {
  106. mp.stop();
  107. }
  108. int i = lastPosition;
  109. i++;
  110. String path = this.currentDirectory.getAbsolutePath();
  111. while (i < this.directoryEntries.size()) {
  112. String filename = this.directoryEntries.get(i);
  113. File currentFile = new File(path + filename);
  114. if (currentFile.isFile()) {
  115. lastPosition = i;
  116. togglePlaying(currentFile);
  117. return;
  118. }
  119. i++;
  120. }
  121. i = 0;
  122. while (i <= lastPosition) {
  123. String filename = this.directoryEntries.get(i);
  124. File currentFile = new File(path + filename);
  125. if (currentFile.isFile()) {
  126. lastPosition = i;
  127. togglePlaying(currentFile);
  128. return;
  129. }
  130. i++;
  131. }
  132. Toast.makeText(this, R.string.no_files, 1).show();
  133. tts.speak(getString(R.string.no_files), 0, null);
  134. }
  135. private void fill(File[] files) {
  136. this.directoryEntries.clear();
  137. // Add the top two choices
  138. this.directoryEntries.add(currentDirectory.getAbsolutePath());
  139. if (this.currentDirectory.getParent() != null) {
  140. this.directoryEntries.add(" up one level");
  141. }
  142. int currentPathStringLength = this.currentDirectory.getAbsolutePath().length();
  143. List<String> directories = new ArrayList<String>();
  144. for (File file : files) {
  145. if (file.isDirectory()) {
  146. String filename = file.getAbsolutePath().substring(currentPathStringLength);
  147. if (!filename.startsWith("/.")) {
  148. directories.add(filename);
  149. }
  150. }
  151. }
  152. Collections.sort(directories);
  153. this.directoryEntries.addAll(directories);
  154. List<String> audioFiles = new ArrayList<String>();
  155. for (File file : files) {
  156. if (file.getPath().endsWith(".mp3")) {
  157. String filename = file.getAbsolutePath().substring(currentPathStringLength);
  158. if (!filename.startsWith("/.")) {
  159. audioFiles.add(filename);
  160. }
  161. }
  162. }
  163. Collections.sort(audioFiles);
  164. this.directoryEntries.addAll(audioFiles);
  165. ArrayAdapter<String> directoryList =
  166. new ArrayAdapter<String>(this, R.layout.file_row, this.directoryEntries);
  167. myList.setAdapter(directoryList);
  168. }
  169. @Override
  170. public boolean onTrackballEvent(MotionEvent event) {
  171. int selectedId = myList.getSelectedItemPosition();
  172. if (selectedId == -1) {
  173. selectedId = 0;
  174. }
  175. if (lastPosition != selectedId) {
  176. lastPosition = selectedId;
  177. vibe.vibrate(VIBE_PATTERN, -1);
  178. String filename = directoryEntries.get(selectedId);
  179. tts.speak(filename.substring(1), 0, null);
  180. }
  181. return super.onTrackballEvent(event);
  182. }
  183. @Override
  184. public boolean onKeyDown(int keyCode, KeyEvent event) {
  185. if (keyCode == KeyEvent.KEYCODE_BACK) {
  186. // Pressing back should go up a level, not quit the app
  187. if (upOneLevel()) {
  188. return true;
  189. }
  190. }
  191. return super.onKeyDown(keyCode, event);
  192. }
  193. @Override
  194. public void onDestroy(){
  195. tts.shutdown();
  196. mp.stop();
  197. super.onDestroy();
  198. }
  199. }