Android Open Source - AudioBook Main Activity






From Project

Back to project page AudioBook.

License

The source code is released under:

Creative Commons Legal Code Attribution-NonCommercial 3.0 Unported CREATIVE COMMONS CORPORATION IS NOT A LAW FIRM AND DOES NOT PROVIDE LEGAL SERVICES. DISTRIBUTION OF THIS LICENSE DOES NOT C...

If you think the Android project AudioBook listed in this page is inappropriate, such as containing malicious code/tools or violating the copyright, please email info at java2s dot com, thanks.

Java Source Code

/**
 *  This work is licensed under the Creative Commons Attribution-NonCommercial-
 *  NoDerivs 3.0 Unported License. To view a copy of this license, visit
 *  http://creativecommons.org/licenses/by-nc-nd/3.0/ or send a letter to 
 *  Creative Commons, 444 Castro Street, Suite 900, Mountain View, California, 
 *  94041, USA./*from www  . j  a  va  2s . co  m*/
 * 
 *  Use of this work is permitted only in accordance with license rights granted.
 *  Materials provided "AS IS"; no representations or warranties provided.
 * 
 *  Copyright ? 2012 Marcus Parkkinen, Aki K?kel?, Fredrik ?hs.
 **/

package edu.chalmers.dat255.audiobookplayer.view;

import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.util.ArrayList;
import java.util.List;

import android.content.Intent;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentActivity;
import android.support.v4.view.ViewPager;
import android.util.Log;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.widget.Toast;
import edu.chalmers.dat255.audiobookplayer.R;
import edu.chalmers.dat255.audiobookplayer.constants.Constants;
import edu.chalmers.dat255.audiobookplayer.constants.PlaybackStatus;
import edu.chalmers.dat255.audiobookplayer.ctrl.BookshelfController;
import edu.chalmers.dat255.audiobookplayer.ctrl.PlayerController;
import edu.chalmers.dat255.audiobookplayer.interfaces.IBookshelfEvents;
import edu.chalmers.dat255.audiobookplayer.interfaces.IBookshelfGUIEvents;
import edu.chalmers.dat255.audiobookplayer.interfaces.IPlayerEvents;
import edu.chalmers.dat255.audiobookplayer.model.Book;
import edu.chalmers.dat255.audiobookplayer.model.Bookshelf;
import edu.chalmers.dat255.audiobookplayer.util.BookCreator;
import edu.chalmers.dat255.audiobookplayer.util.BookshelfHandler;

/**
 * The main activity of the application.
 * 
 * @author Aki K?kel?, Marcus Parkkinen
 * @version 0.6
 * 
 */
public class MainActivity extends FragmentActivity implements IPlayerEvents,
    IBookshelfEvents, IBookshelfGUIEvents, PropertyChangeListener {
  private static final String TAG = "MainActivity";
  private static final String USERNAME = "Default";
  private static final int PLAYER = 0;
  private static final int BOOKSHELF = 1;

  // ViewPager
  private ViewPager pager;

  // Fragments
  private PlayerFragment playerFragment = new PlayerFragment();
  private BookshelfFragment bookshelfFragment = new BookshelfFragment();

  // Controllers
  private BookshelfController bookshelfController;
  private PlayerController playerController;

  /*
   * (non-Javadoc)
   * 
   * @see android.support.v4.app.FragmentActivity#onCreate(android.os.Bundle)
   */
  @Override
  public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    setContentView(R.layout.activity_main);

    initPager();

    // Load a bookshelf specified by the username
    Bookshelf bs = BookshelfHandler.loadBookshelf(this, USERNAME);

    // Create controllers with the bookshelf reference
    playerController = new PlayerController(bs);
    bookshelfController = new BookshelfController(bs);

    BookCreator.getInstance().setBookshelf(bs);

    // Provide a reference to the bookshelf as an argument in the bundle
    Bundle bsReference = new Bundle();
    bsReference.putSerializable(Constants.Reference.BOOKSHELF, bs);
    bookshelfFragment.setArguments(bsReference);

  }

  /**
   * Initializes the ViewPager and its adapter.
   */
  private void initPager() {
    // create a list of our fragments
    List<Fragment> fragments = new ArrayList<Fragment>();
    fragments.add(playerFragment);
    fragments.add(bookshelfFragment);

    // create the adapter
    // NOTE: it is a local variable since it will not be used.
    ViewPagerAdapter adapter = new ViewPagerAdapter(
        super.getSupportFragmentManager(), fragments);

    // create the view pager and set the adapter
    pager = (ViewPager) super.findViewById(R.id.twopanelviewpager);
    pager.setAdapter(adapter);

    // default selected screen
    pager.setCurrentItem(BOOKSHELF);
  }

  /*
   * (non-Javadoc)
   * 
   * @see android.support.v4.app.FragmentActivity#onStop()
   */
  @Override
  protected void onStop() {
    Log.d(TAG, "onStop()");
    super.onStop();

    // Disable updates
    bookshelfController.removeListeners();
  }

  /*
   * (non-Javadoc)
   * 
   * @see android.support.v4.app.FragmentActivity#onResume()
   */
  @Override
  protected void onResume() {
    Log.d(TAG, "onResume()");
    super.onResume();
    /*
     * if the application is stopped, it will go through onStart() and then
     * onResume(), so just start the updates again here.
     */
    bookshelfController.addPropertyChangeListener(this);

    /*
     * This method is run every time the application is created, starts or
     * resumes. The updates should only start when returning from a paused
     * or stopped state.
     */
  }

  /*
   * (non-Javadoc)
   * 
   * @see android.support.v4.app.FragmentActivity#onStart()
   */
  @Override
  protected void onStart() {
    Log.d(TAG, "onStart()");
    super.onStart();
  }

  /*
   * (non-Javadoc)
   * 
   * @see android.support.v4.app.FragmentActivity#onDestroy()
   */
  @Override
  protected void onDestroy() {
    super.onDestroy();
    Log.d(TAG, "onDestroy()");

    // Stop the audio player
    playerController.stop();

    /*
     * Whenever the application is about to quit, save a bookmark.
     */
    save();
  }

  /*
   * (non-Javadoc)
   * 
   * @see android.app.Activity#onCreateOptionsMenu(android.view.Menu)
   */
  @Override
  public boolean onCreateOptionsMenu(Menu menu) {
    MenuInflater menuInflater = getMenuInflater();
    menuInflater.inflate(R.menu.main_menu, menu);
    return true;
  }

  /**
   * Saves a bookmark (the bookshelf).
   */
  private boolean save() {
    return bookshelfController.saveBookshelf(this, USERNAME);
  }

  /*
   * Handle the menu item selection. Every item has a unique id.
   * 
   * (non-Javadoc)
   * 
   * @see android.app.Activity#onOptionsItemSelected(android.view.MenuItem)
   */
  @Override
  public boolean onOptionsItemSelected(MenuItem item) {

    int id = item.getItemId();

    switch (id) {
    case R.id.menu_save:
      // save a bookmark and show whether it was successful
      if (save()) {
        Toast.makeText(this, "Saved", Toast.LENGTH_SHORT).show();
      } else {
        Toast.makeText(this, "Saving failed", Toast.LENGTH_SHORT);
      }
      return true;

    default:
      Toast.makeText(this, "Unknown", Toast.LENGTH_SHORT).show();
      return super.onOptionsItemSelected(item);
    }
  }

  /* IPlayerEvents */

  /*
   * The methods below relay user-initiated events from the fragments to
   * relevant controller methods.
   */

  /*
   * (non-Javadoc)
   * 
   * @see
   * edu.chalmers.dat255.audiobookplayer.interfaces.IPlayerEvents#previousTrack
   * ()
   */
  public void previousTrack() {
    playerController.previousTrack();
  }

  /*
   * (non-Javadoc)
   * 
   * @see
   * edu.chalmers.dat255.audiobookplayer.interfaces.IPlayerEvents#resume()
   */
  public void resume() {
    playerController.resume();
  }

  /*
   * (non-Javadoc)
   * 
   * @see edu.chalmers.dat255.audiobookplayer.interfaces.IPlayerEvents#pause()
   */
  public void pause() {
    playerController.pause();
  }

  /*
   * (non-Javadoc)
   * 
   * @see
   * edu.chalmers.dat255.audiobookplayer.interfaces.IPlayerEvents#nextTrack()
   */
  public void nextTrack() {
    playerController.nextTrack();
  }

  /*
   * (non-Javadoc)
   * 
   * @see
   * edu.chalmers.dat255.audiobookplayer.interfaces.IPlayerEvents#seekLeft
   * (boolean)
   */
  public void seekLeft(boolean seek) {
    playerController.seekLeft(seek);
  }

  /*
   * (non-Javadoc)
   * 
   * @see
   * edu.chalmers.dat255.audiobookplayer.interfaces.IPlayerEvents#seekRight
   * (boolean)
   */
  public void seekRight(boolean seek) {
    playerController.seekRight(seek);
  }

  /*
   * (non-Javadoc)
   * 
   * @see edu.chalmers.dat255.audiobookplayer.interfaces.IPlayerEvents#
   * seekToPercentageInBook(double)
   */
  public void seekToPercentageInBook(double percentage) {
    playerController.seekToPercentageInBook(percentage);
  }

  /*
   * (non-Javadoc)
   * 
   * @see edu.chalmers.dat255.audiobookplayer.interfaces.IPlayerEvents#
   * seekToPercentageInTrack(double)
   */
  public void seekToPercentageInTrack(double percentage) {
    playerController.seekToPercentageInTrack(percentage);
  }

  /*
   * (non-Javadoc)
   * 
   * @see
   * edu.chalmers.dat255.audiobookplayer.interfaces.IPlayerEvents#isPlaying()
   */
  public boolean isPlaying() {
    return playerController.isPlaying();
  }

  /*
   * (non-Javadoc)
   * 
   * @see
   * edu.chalmers.dat255.audiobookplayer.interfaces.IPlayerEvents#isStarted()
   */
  public boolean isStarted() {
    return playerController.isStarted();
  }

  /* End IPlayerEvents */

  /* BookshelfUIListener */
  public void setSelectedBook(int index) {
    // set the selected book to the new index
    bookshelfController.setSelectedBook(index);
  }

  /*
   * (non-Javadoc)
   * 
   * @see edu.chalmers.dat255.audiobookplayer.interfaces.IBookshelfGUIEvents#
   * addBookButtonPressed()
   */
  public void addBookButtonPressed() {
    Intent intent = new Intent(MainActivity.this, BrowserActivity.class);
    startActivity(intent);
  }

  /* End BookshelfUIListener */

  /*
   * (non-Javadoc)
   * 
   * @see android.support.v4.app.FragmentActivity#onBackPressed()
   */
  @Override
  public void onBackPressed() {
    super.onBackPressed();

    Log.i(TAG, "Back pressed in Main Activity");
    Intent intent = new Intent(Intent.ACTION_MAIN);

    // move to the home screen when pressing back
    intent.addCategory(Intent.CATEGORY_HOME);

    // start a new task
    intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
    startActivity(intent);
  }

  /**
   * Whenever the model component changes, an event is received here. The new
   * value property of the event contains a reference to a copy of the model.
   * 
   * @param event
   *            Event object that contains information about the change.
   */
  public void propertyChange(PropertyChangeEvent event) {
    if (event.getNewValue() instanceof Bookshelf) {
      // Get the model copy from the update
      Bookshelf bs = (Bookshelf) event.getNewValue();

      // Update the fragments
      updateFragments(event.getPropertyName(), bs);
    }
  }

  /**
   * Handles the updates of the fragments given a model to represent
   * graphically.
   * 
   * @param eventName
   *            The property name of the fired event.
   * @param bs
   *            Model copy.
   * @precondition The bookshelf instance must not be null.
   */
  private void updateFragments(String eventName, Bookshelf bs) {
    /*
     * Check which event was fired, and do relevant updates in the
     * fragments.
     */
    if (eventName.equals(Constants.Event.BOOK_LIST_CHANGED)) {
      // update the bookshelf GUI
      bookshelfFragment.bookshelfUpdated(bs);
    } else if (eventName.equals(Constants.Event.BOOK_SELECTED)) {
      if (bs.getSelectedBookIndex() != Constants.Value.NO_BOOK_SELECTED) {
        Book b = bs.getSelectedBook();

        // reset the player controls to standard values
        playerFragment.resetComponents();

        // update the player GUI components
        updatePlayerGUI(b);

        // make sure the player GUI knows it is playing
        playerFragment.setPlaybackStatus(PlaybackStatus.PLAYING);

        // show the player UI
        pager.setCurrentItem(PLAYER);

        // if a track is selected, start it
        if (bs.getSelectedTrackIndex() != Constants.Value.NO_TRACK_SELECTED) {
          // start at the saved time
          playerController.setStartPosition(b
              .getSelectedTrackElapsedTime());

          // select the stored track to start playing in
          bookshelfController.setSelectedTrack(
              bs.getSelectedBookIndex(),
              bs.getSelectedTrackIndex());
        } else {
          // if there is no track selected, start from the beginning.

          playerController.setStartPosition(0);
          bookshelfController.setSelectedTrack(
              bs.getSelectedBookIndex(), 0);

        }
      }
    } else if (eventName.equals(Constants.Event.ELAPSED_TIME_CHANGED)) {
      Book b = bs.getSelectedBook();

      // Bookshelf
      updateSelectedBookElapsedTime(b);

      // Player
      // recalculate the track seekbar
      updateTrackSeekbar(b);
      // recalculate the book seekbar
      updateBookSeekbar(b);
      // update time labels
      updateElapsedTimeLabels(b);

    } else if (eventName.equals(Constants.Event.TRACK_LIST_CHANGED)) {
      Book b = bs.getSelectedBook();

      // Update the bookshelf GUI.
      bookshelfFragment.bookshelfUpdated(bs);

      // Player
      // update book duration label
      updateBookDurationLabel(b);

      // show the correct number of tracks
      updateTrackCounterLabel(b);

      // Update book duration label
      updateBookDurationLabel(b);
    } else if (eventName.equals(Constants.Event.TRACK_INDEX_CHANGED)) {
      pager.setCurrentItem(PLAYER);
      if (bs.getSelectedTrackIndex() == Constants.Value.NO_TRACK_SELECTED) {
        /*
         * Do not play audio.
         */
        // reset the controls to 'stopped'
        playerFragment.resetComponents();

        // stop the audio player
        playerController.stop();
      } else {
        /*
         * Play audio.
         */

        // restart the player
        playerController.start();

        // set the status
        playerFragment.setPlaybackStatus(PlaybackStatus.PLAYING);
      }
      Book b = bs.getSelectedBook();

      // Player
      // update track title label
      updateTrackTitleLabel(b);

      // update track book duration label
      updateTrackDurationLabel(b);

      // show the correct number of tracks, illegal track index or not
      updateTrackCounterLabel(b);
    } else if (eventName.equals(Constants.Event.BOOK_TITLE_CHANGED)) {
      Book b = bs.getSelectedBook();
      // Bookshelf

      // Player
      // update the book title label
      updateBookTitleLabel(b);
    } else if (eventName.equals(Constants.Event.BOOKSHELF_UPDATED)) {
      bookshelfFragment.bookshelfUpdated(bs);
    }
    /*
     * Eventually tag updates would have been handled here as well, calling
     * the private method updateTags. Tags are, however, not implemented in
     * the GUI so they will not be written here, either.
     */
  }

  /**
   * Updates the book title/duration, track title/duration and track counter
   * (i.e. no changes to seek bars).
   * <p>
   * Does nothing if the given book is null.
   * 
   * @param b
   *            Book given with the data to be represented by the Player UI.
   */
  private void updatePlayerGUI(Book b) {
    if (b != null) {
      // show the title of the book
      updateBookTitleLabel(b);

      // display its duration
      updateBookDurationLabel(b);

      // show the title of the track
      updateTrackTitleLabel(b);

      // and display its duration
      updateTrackDurationLabel(b);

      // update the track counter
      updateTrackCounterLabel(b);
    }
  }

  /**
   * Updates the tags in the player UI (unimplemented in GUI).
   * 
   * @param selectedBook
   */
  @SuppressWarnings("unused")
  private void updateTags(final Book selectedBook) {
    playerFragment.getActivity().runOnUiThread(new Runnable() {
      public void run() {
        playerFragment.updateTagTimes(selectedBook.getTagTimes());
      }
    });
  }

  /**
   * Updates the count of the tracks in the player UI.
   * 
   * @param b
   */
  private void updateTrackCounterLabel(final Book b) {
    playerFragment.getActivity().runOnUiThread(new Runnable() {
      public void run() {
        int currentTrack = b.getSelectedTrackIndex();
        int numberOfTracks = b.getNumberOfTracks();
        playerFragment.updateTrackCounterLabel(currentTrack,
            numberOfTracks);
      }
    });
  }

  /*
   * Titles
   */
  /**
   * UI mutator method that updates the book title label in the player
   * fragment.
   * 
   * @param b
   *            Book that specifies the change
   */
  private void updateBookTitleLabel(final Book b) {
    playerFragment.getActivity().runOnUiThread(new Runnable() {
      public void run() {
        playerFragment.updateBookTitleLabel(b.getSelectedBookTitle());
      }
    });
  }

  /**
   * UI mutator method that updates the track title in the player fragment.
   * 
   * @param b
   *            Book that specifies the change
   */
  private void updateTrackTitleLabel(final Book b) {
    playerFragment.getActivity().runOnUiThread(new Runnable() {
      public void run() {
        if (b.getSelectedTrackIndex() != -1) {
          playerFragment.updateTrackTitleLabel(b.getTrackTitle());
        }
      }
    });
  }

  /*
   * Duration times
   */
  /**
   * UI mutator method that updates the book duration label in the player
   * fragment.
   * 
   * @param b
   *            Book that specifies the change
   */
  private void updateBookDurationLabel(final Book b) {
    playerFragment.getActivity().runOnUiThread(new Runnable() {
      public void run() {
        playerFragment.updateBookDurationLabel(b.getDuration());
      }
    });
  }

  /**
   * UI mutator method that updates the track duration label in the player
   * fragment.
   * 
   * @param b
   *            Book that specifies the change
   */
  private void updateTrackDurationLabel(final Book b) {
    playerFragment.getActivity().runOnUiThread(new Runnable() {
      public void run() {
        if (b.getSelectedTrackIndex() != -1) {
          int trackDur = 0;
          try {
            trackDur = b.getSelectedTrackDuration();
          } catch (IllegalArgumentException e) {
            Log.e(TAG, "No track selected when trying to update "
                + "track duration label. "
                + "Setting duration to 0.");
          }
          playerFragment.updateTrackDurationLabel(trackDur);
        }
      }
    });
  }

  /*
   * Elapsed times
   */
  /**
   * UI mutator method that updates the track duration label in the player
   * fragment.
   * 
   * @param b
   *            Book that specifies the change
   */
  private void updateElapsedTimeLabels(final Book b) {
    if (playerFragment.getActivity() != null) {
      playerFragment.getActivity().runOnUiThread(new Runnable() {
        public void run() {
          if (b.getSelectedTrackIndex() != -1) {
            playerFragment.updateTrackElapsedTimeLabel(b
                .getSelectedTrackElapsedTime());
            playerFragment.updateBookElapsedTimeLabel(b
                .getBookElapsedTime());
          }
        }
      });
    }
  }

  /**
   * UI mutator method that updates the book position of the selected book in
   * bookshelf fragment
   * 
   * @param b
   *            The selected book.
   */
  private void updateSelectedBookElapsedTime(final Book b) {
    if (b.getSelectedTrackIndex() != -1
        && bookshelfFragment.getActivity() != null) {
      bookshelfFragment.getActivity().runOnUiThread(new Runnable() {
        public void run() {
          // update
          bookshelfFragment.selectedBookElapsedTimeUpdated(b
              .getBookElapsedTime());
        }
      });
    }
  }

  /**
   * UI mutator method that updates the track seekbar in the player fragment.
   * 
   * @param b
   *            Book that specifies the change
   */
  private void updateTrackSeekbar(Book b) {
    if (b.getSelectedTrackIndex() != -1) {
      // elapsed time
      int trackElapsedTime = b.getSelectedTrackElapsedTime();

      // total duration
      int trackDuration = b.getSelectedTrackDuration();

      double progress = getProgress(trackElapsedTime, trackDuration);

      playerFragment.updateTrackSeekBar(progress);
    }
  }

  /**
   * UI mutator method that updates the book seekbar in the player fragment.
   * 
   * @param b
   *            Book that specifies the change
   */
  private void updateBookSeekbar(Book b) {
    // elapsed time
    int bookElapsedTime = b.getBookElapsedTime();

    // total duration
    int bookDuration = b.getDuration();

    double progress = getProgress(bookElapsedTime, bookDuration);

    playerFragment.updateBookSeekBar(progress);
  }

  /**
   * Private utility method that calculates the progress of a book or track.
   * 
   * @param int Elapsed time of the book or track in milliseconds.
   * @param int Duration of the book or track in milliseconds.
   * @return The ratio between the elapsed time and the duration.
   */
  private double getProgress(int elapsedTime, int duration) {
    return ((double) elapsedTime) / duration;
  }

  /*
   * (non-Javadoc)
   * 
   * @see edu.chalmers.dat255.audiobookplayer.interfaces.IBookshelfEvents#
   * setSelectedTrack(int, int)
   */
  public void setSelectedTrack(int bookIndex, int trackIndex) {

    bookshelfController.setSelectedTrack(bookIndex, trackIndex);

    // restart the player
    playerController.start();
  }

  /*
   * (non-Javadoc)
   * 
   * @see
   * edu.chalmers.dat255.audiobookplayer.interfaces.IBookshelfEvents#removeBook
   * (int)
   */
  public void removeBook(int bookIndex) {
    bookshelfController.removeBook(bookIndex);
  }

  /*
   * (non-Javadoc)
   * 
   * @see
   * edu.chalmers.dat255.audiobookplayer.interfaces.IBookshelfEvents#removeTrack
   * (int, int)
   */
  public void removeTrack(int bookIndex, int trackIndex) {
    bookshelfController.removeTrack(bookIndex, trackIndex);
  }

  /*
   * (non-Javadoc)
   * 
   * @see edu.chalmers.dat255.audiobookplayer.interfaces.IBookshelfEvents#
   * setBookTitleAt(int, java.lang.String)
   */
  public void setBookTitleAt(int bookIndex, String newTitle) {
    bookshelfController.setBookTitleAt(bookIndex, newTitle);
  }

  /*
   * (non-Javadoc)
   * 
   * @see
   * edu.chalmers.dat255.audiobookplayer.interfaces.IBookshelfEvents#removeTrack
   * (int)
   */
  public void removeTrack(int trackIndex) {
    bookshelfController.removeTrack(trackIndex);
  }

  /*
   * (non-Javadoc)
   * 
   * @see
   * edu.chalmers.dat255.audiobookplayer.interfaces.IBookshelfEvents#moveTrack
   * (int, int, int)
   */
  public void moveTrack(int bookIndex, int trackIndex, int offset) {
    bookshelfController.moveTrack(bookIndex, trackIndex, offset);
  }

}




Java Source Code List

edu.chalmers.dat255.audiobookplayer.constants.Constants.java
edu.chalmers.dat255.audiobookplayer.constants.PlaybackStatus.java
edu.chalmers.dat255.audiobookplayer.ctrl.BookshelfControllerTest.java
edu.chalmers.dat255.audiobookplayer.ctrl.BookshelfController.java
edu.chalmers.dat255.audiobookplayer.ctrl.PlayerControllerTest.java
edu.chalmers.dat255.audiobookplayer.ctrl.PlayerController.java
edu.chalmers.dat255.audiobookplayer.instrumentation.AllTests.java
edu.chalmers.dat255.audiobookplayer.interfaces.IBookUpdates.java
edu.chalmers.dat255.audiobookplayer.interfaces.IBookshelfEvents.java
edu.chalmers.dat255.audiobookplayer.interfaces.IBookshelfGUIEvents.java
edu.chalmers.dat255.audiobookplayer.interfaces.IPlayerEvents.java
edu.chalmers.dat255.audiobookplayer.interfaces.ITrackUpdates.java
edu.chalmers.dat255.audiobookplayer.model.BookTest.java
edu.chalmers.dat255.audiobookplayer.model.Book.java
edu.chalmers.dat255.audiobookplayer.model.BookshelfTest.java
edu.chalmers.dat255.audiobookplayer.model.Bookshelf.java
edu.chalmers.dat255.audiobookplayer.model.TagTest.java
edu.chalmers.dat255.audiobookplayer.model.Tag.java
edu.chalmers.dat255.audiobookplayer.model.TrackTest.java
edu.chalmers.dat255.audiobookplayer.model.Track.java
edu.chalmers.dat255.audiobookplayer.util.BookCreatorTest.java
edu.chalmers.dat255.audiobookplayer.util.BookCreator.java
edu.chalmers.dat255.audiobookplayer.util.BookshelfHandlerTest.java
edu.chalmers.dat255.audiobookplayer.util.BookshelfHandler.java
edu.chalmers.dat255.audiobookplayer.util.FileParserTest.java
edu.chalmers.dat255.audiobookplayer.util.FileParser.java
edu.chalmers.dat255.audiobookplayer.util.JsonParserTest.java
edu.chalmers.dat255.audiobookplayer.util.JsonParser.java
edu.chalmers.dat255.audiobookplayer.util.TextFormatterTest.java
edu.chalmers.dat255.audiobookplayer.util.TextFormatter.java
edu.chalmers.dat255.audiobookplayer.util.TrackCreatorTest.java
edu.chalmers.dat255.audiobookplayer.util.TrackCreator.java
edu.chalmers.dat255.audiobookplayer.view.BookshelfFragment.java
edu.chalmers.dat255.audiobookplayer.view.BrowserActivityTest.java
edu.chalmers.dat255.audiobookplayer.view.BrowserActivity.java
edu.chalmers.dat255.audiobookplayer.view.MainActivity.java
edu.chalmers.dat255.audiobookplayer.view.PlayerFragment.java
edu.chalmers.dat255.audiobookplayer.view.ViewPagerAdapter.java