DaisyPlayer.java :  » UnTagged » android-daisy-epub-reader » com » ader » Android Open Source

Android Open Source » UnTagged » android daisy epub reader 
android daisy epub reader » com » ader » DaisyPlayer.java
package com.ader;

import android.app.Activity;
import android.app.AlertDialog;
import android.content.DialogInterface;
import android.media.MediaPlayer;
import android.media.MediaPlayer.OnCompletionListener;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.widget.FrameLayout;
import android.widget.TextView;
import android.widget.Toast;

import com.google.marvin.widget.TouchGestureControlOverlay;
import com.google.marvin.widget.TouchGestureControlOverlay.Gesture;
import com.google.marvin.widget.TouchGestureControlOverlay.GestureListener;

import java.io.FileNotFoundException;
import java.io.IOException;

public class DaisyPlayer extends Activity implements OnCompletionListener {

  private static final String AUDIO_OFFSET = "Offset";
  private static final String IS_THE_BOOK_PLAYING = "playing";
  private static final String TAG = "DaisyPlayer";
  private DaisyBook book;
  private MediaPlayer player;
  private TouchGestureControlOverlay gestureOverlay;
  private FrameLayout frameLayout;
  private TextView mainText;
  private TextView statusText;
  private TextView depthText;
  private int audioOffset ;

  @Override
  protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    book = (DaisyBook) getIntent().getSerializableExtra(
        "com.ader.DaisyBook");
    activateGesture();
    player = new MediaPlayer();
    player.setOnCompletionListener(this);
    play();
  }

  @Override
  protected void onDestroy() {
    // Let's stop playing the book if the user presses back, etc.
    stop();
    player.release();
    super.onDestroy();
  }

  @Override
  public boolean onCreateOptionsMenu(Menu menu) {
    new MenuInflater(getApplication()).inflate(R.menu.playermenu, menu);
    return(super.onCreateOptionsMenu(menu));
  }
  
  
  @Override
  public boolean onOptionsItemSelected(MenuItem item) {
    switch (item.getItemId()) {
    case R.id.player_instructions:
      AlertDialog.Builder builder=new AlertDialog.Builder(this);
      
      builder
        .setTitle(R.string.player_instructions_description)
        .setMessage(R.string.player_instructions)
        .setPositiveButton(R.string.close_instructions, null)
        .show();
      break;
    }
    return true;
  }
  
  public void onCompletion(MediaPlayer mp) {
    Util.logInfo(TAG, "onCompletion called.");
    // stop();
    if (book.nextSection(false)) {
      Util.logInfo(TAG, "PLAYING section: " + book.getDisplayPosition() + " " +
          book.current().getText());
      mainText.setText(book.current().getText());
      // reset the audio Offset (used on device rotation)
      audioOffset = 0;
      play();
    }
  }

  public void play() {
    Util.logInfo(TAG, "play");
    player.reset();
    int duration = Toast.LENGTH_LONG;

    Toast toast; 
    try {
      book.openSmil();
      read();
    } catch (FileNotFoundException fnfe) {
      CharSequence text = getString(R.string.cannot_open_book_a_file_is_missing) + fnfe.getLocalizedMessage();
      toast = Toast.makeText(this, text, duration);
      toast.show();
      AlertDialog.Builder explainProblem = new AlertDialog.Builder(this);
      explainProblem
      .setCancelable(false)
      .setTitle(R.string.unable_to_open_file)
      .setMessage(fnfe.getLocalizedMessage())
      .setPositiveButton(R.string.close_instructions, new DialogInterface.OnClickListener() {
        public void onClick(DialogInterface dialog, int id) {
          DaisyPlayer.this.finish();
        }
      })
      .show();
    } catch (IOException ioe) {
      CharSequence text = getString(R.string.cannot_open_book) + ioe.getLocalizedMessage();
      toast = Toast.makeText(this, text, duration);
      toast.show();      
      
      AlertDialog.Builder explainProblem = new AlertDialog.Builder(this);
      explainProblem
      .setTitle(R.string.permission_problem_opening_a_file)
      .setMessage(ioe.getLocalizedMessage())
      .setPositiveButton(R.string.close_instructions, new DialogInterface.OnClickListener() {
        public void onClick(DialogInterface dialog, int id) {
          DaisyPlayer.this.finish();
        }
      })
      .show();
    } catch (RuntimeException re) {
      CharSequence text = getString(R.string.cannot_open_book) + " A Runtime error occured." 
        + re.getLocalizedMessage();
      toast = Toast.makeText(this, text, duration);
      toast.show();
      
      AlertDialog.Builder explainProblem = new AlertDialog.Builder(this);
      explainProblem
      .setTitle(R.string.serious_problem_found)
      .setMessage(re.getLocalizedMessage())
      .setPositiveButton(R.string.close_instructions, new DialogInterface.OnClickListener() {
        public void onClick(DialogInterface dialog, int id) {
          DaisyPlayer.this.finish();
        }
      })
      .show();
    }
  }

  /**
   * Start reading the current section of the book
   */
  private void read() {
    Bookmark bookmark = book.getBookmark();

    // TODO(jharty): Find a practical way to format these messages for i18n and l10n
    depthText.setText("Depth " + book.getCurrentDepthInDaisyBook() + " of " + book.getMaximumDepthInDaisyBook());
    
    if (book.hasAudioSegments()) {
      try {
        mainText.setText(getText(R.string.reading_message) + " " + book.current().getText());
        Util.logInfo(TAG, "Start playing " + bookmark.getFilename() + " " + bookmark.getPosition());
        player.setDataSource(bookmark.getFilename());
        player.prepare();
      } catch (IllegalArgumentException e) {
        throw new RuntimeException(e);
      } catch (IllegalStateException e) {
        throw new RuntimeException(e);
      } catch (IOException e) {
        throw new RuntimeException(bookmark.getFilename() 
            + "\n" + e.getLocalizedMessage());
      }
      // Part of my experiment to stop the player restarting the audio
      // when the device is rotated between landscape and portrait modes.
      // player.seekTo(bookmark.getPosition());
      player.seekTo(audioOffset);
      player.setScreenOnWhilePlaying(true);
      statusText.setText(getText(R.string.playing_message) + "...");
      player.start();
    } else if (book.hasTextSegments()) {
      // TODO(jharty): add TTS to speak the text section
      // Note: we need to decide how to handle things like \n
      // For now, perhaps we can simply display the text in a new view.
      Util.logInfo("We need to read the text from: ", bookmark.getFilename());
      
      // For now, here is some information for the user. Perhaps I could
      // add a way to automatically send a request e.g. by email?
      mainText.setText(bookmark.getFilename());
      // TODO(jharty): Test whether the status is visible at this size.
      statusText.setTextSize(10.0f);
      statusText.setText(R.string.text_content_not_supported_yet);
      depthText.setText("");  // Blank out the depth message.
    }
  }
    
  public void stop() {
    Util.logInfo(TAG, "stop");
    player.pause();
    Bookmark bookmark = book.getBookmark();
    bookmark.setPosition(player.getCurrentPosition());
    player.reset();
    if (bookmark.getFilename() != null) {
      // We only save the bookmark if there's a valid file, problems e.g.
      // reading a smil file might mean the bookmark hasn't been assigned.
      book.getBookmark().save(book.getPath() + "auto.bmk");
    }
  }

  public void togglePlay() {
    Util.logInfo(TAG, "togglePlay called.");
    if (player.isPlaying()) {
      statusText.setText(getText(R.string.paused_message));
      player.pause();
    } else {
      statusText.setText(getText(R.string.playing_message));
      player.start();
    }
  }

  @Override
  public void onSaveInstanceState(Bundle savedInstanceState) {
    audioOffset = player.getCurrentPosition();
    Util.logInfo(TAG, "Length in media player is: " + audioOffset);
    
    savedInstanceState.putBoolean(IS_THE_BOOK_PLAYING, player.isPlaying());
    savedInstanceState.putInt(AUDIO_OFFSET, audioOffset);
    if (player.isPlaying()) {
      // Try seeing if I can pause the player on rotation rather than stopping it
      // player.pause();
    }
    super.onSaveInstanceState(savedInstanceState);
  }
  
  @Override
  public void onRestoreInstanceState(Bundle savedInstanceState) {
    super.onRestoreInstanceState(savedInstanceState);
    Boolean isPlaying = savedInstanceState.getBoolean(IS_THE_BOOK_PLAYING, true);
    Util.logInfo(TAG, "Offset at start of onRestoreInstanceState is: " + audioOffset);
    audioOffset = savedInstanceState.getInt(AUDIO_OFFSET, 0);
    Util.logInfo(TAG, "Offset after retrieving saved offset value is: " + audioOffset);
    player.seekTo(audioOffset);
    if (!isPlaying) {
      // Try seeing if I can pause the player on rotation rather than stopping it
      statusText.setText(getText(R.string.paused_message) + "...");
      player.pause();
    } else {
      player.start();
    }
    

  }
  
  private void activateGesture() {
    setContentView(R.layout.daisyplayerframe);
    depthText = (TextView) findViewById(R.id.depthText);
    mainText = (TextView) findViewById(R.id.mainText);
        statusText = (TextView) findViewById(R.id.statusText);
    frameLayout = (FrameLayout) findViewById(R.id.daisyPlayerLayout);
    gestureOverlay = new TouchGestureControlOverlay(this, gestureListener);
    frameLayout.addView(gestureOverlay);
    setContentView(frameLayout);
  }

  private GestureListener gestureListener = new GestureListener() {

    public void onGestureStart(Gesture g) {

    }

    public void onGestureChange(Gesture g) {
    }

    public void onGestureFinish(Gesture g) {
      if (g == Gesture.CENTER) {
        togglePlay();
      } else if (g == Gesture.UP) {
        if (book.previousSection()) {
          audioOffset = 0;
          play();
        }
      } else if (g == Gesture.DOWN) {
        if (book.nextSection(true)) {
          audioOffset = 0;
          play();
        }
      } else if (g == Gesture.LEFT) {
        int levelSetTo = book.decrementSelectedLevel();
        Util.logInfo(TAG, "Decremented Level to: " + levelSetTo);
        depthText.setText("Depth " + levelSetTo + " of " + book.getMaximumDepthInDaisyBook());
      } else if (g == Gesture.RIGHT) {
        int levelSetTo = book.incrementSelectedLevel();
        Util.logInfo(TAG, "Incremented Level to: " + levelSetTo);
        // TODO(jharty): Localize all the recently added hardcoded text e.g. here!
        depthText.setText("Depth " + levelSetTo + " of " + book.getMaximumDepthInDaisyBook());
      }
    }
  };
}
java2s.com  | Contact Us | Privacy Policy
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.