diff --git a/app/src/main/java/com/example/android/classicalmusicquiz/QuizActivity.java b/app/src/main/java/com/example/android/classicalmusicquiz/QuizActivity.java index 0e47cf46..1de123cd 100644 --- a/app/src/main/java/com/example/android/classicalmusicquiz/QuizActivity.java +++ b/app/src/main/java/com/example/android/classicalmusicquiz/QuizActivity.java @@ -17,15 +17,30 @@ package com.example.android.classicalmusicquiz; import android.content.Intent; +import android.graphics.BitmapFactory; import android.graphics.Color; import android.graphics.PorterDuff; +import android.net.Uri; import android.os.Bundle; import android.os.Handler; import android.support.v4.content.ContextCompat; import android.support.v7.app.AppCompatActivity; import android.view.View; import android.widget.Button; -import android.widget.ImageView; +import android.widget.Toast; + +import com.google.android.exoplayer2.DefaultLoadControl; +import com.google.android.exoplayer2.ExoPlayerFactory; +import com.google.android.exoplayer2.LoadControl; +import com.google.android.exoplayer2.SimpleExoPlayer; +import com.google.android.exoplayer2.extractor.DefaultExtractorsFactory; +import com.google.android.exoplayer2.source.ExtractorMediaSource; +import com.google.android.exoplayer2.source.MediaSource; +import com.google.android.exoplayer2.trackselection.DefaultTrackSelector; +import com.google.android.exoplayer2.trackselection.TrackSelector; +import com.google.android.exoplayer2.ui.SimpleExoPlayerView; +import com.google.android.exoplayer2.upstream.DefaultDataSourceFactory; +import com.google.android.exoplayer2.util.Util; import java.util.ArrayList; @@ -40,6 +55,8 @@ public class QuizActivity extends AppCompatActivity implements View.OnClickListe private int mCurrentScore; private int mHighScore; private Button[] mButtons; + private SimpleExoPlayer mExoPlayer; + private SimpleExoPlayerView mPlayerView; @Override @@ -47,8 +64,9 @@ protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_quiz); - // TODO (2): Replace the ImageView with the SimpleExoPlayerView, and remove the method calls on the composerView. - ImageView composerView = (ImageView) findViewById(R.id.composerView); + + // Initialize the player view. + mPlayerView = (SimpleExoPlayerView) findViewById(R.id.playerView); boolean isNewGame = !getIntent().hasExtra(REMAINING_SONGS_KEY); @@ -69,9 +87,9 @@ protected void onCreate(Bundle savedInstanceState) { mQuestionSampleIDs = QuizUtils.generateQuestion(mRemainingSampleIDs); mAnswerSampleID = QuizUtils.getCorrectAnswerID(mQuestionSampleIDs); - // TODO (3): Replace the default artwork in the SimpleExoPlayerView with the question mark drawable. - // Load the image of the composer for the answer into the ImageView. - composerView.setImageBitmap(Sample.getComposerArtBySampleID(this, mAnswerSampleID)); + // Load the question mark as the background image until the user answers the question. + mPlayerView.setDefaultArtwork(BitmapFactory.decodeResource + (getResources(), R.drawable.question_mark)); // If there is only one answer left, end the game. if (mQuestionSampleIDs.size() < 2) { @@ -81,17 +99,17 @@ protected void onCreate(Bundle savedInstanceState) { // Initialize the buttons with the composers names. mButtons = initializeButtons(mQuestionSampleIDs); - - // TODO (4): Create a Sample object using the Sample.getSampleByID() method and passing in mAnswerSampleID; - // TODO (5): Create a method called initializePlayer() that takes a Uri as an argument and call it here, passing in the Sample URI. - + + Sample answerSample = Sample.getSampleByID(this, mAnswerSampleID); + if (answerSample == null) { + Toast.makeText(this, getString(R.string.sample_not_found_error), + Toast.LENGTH_SHORT).show(); + return; } - - // In initializePayer - // TODO (6): Instantiate a SimpleExoPlayer object using DefaultTrackSelector and DefaultLoadControl. - // TODO (7): Prepare the MediaSource using DefaultDataSourceFactory and DefaultExtractorsFactory, as well as the Sample URI you passed in. - // TODO (8): Prepare the ExoPlayer with the MediaSource, start playing the sample and set the SimpleExoPlayer to the SimpleExoPlayerView. + // Initialize the player. + initializePlayer(Uri.parse(answerSample.getUri())); + } /** @@ -116,6 +134,37 @@ private Button[] initializeButtons(ArrayList answerSampleIDs) { } + /** + * Initialize ExoPlayer. + * @param mediaUri The URI of the sample to play. + */ + private void initializePlayer(Uri mediaUri) { + if (mExoPlayer == null) { + // Create an instance of the ExoPlayer. + TrackSelector trackSelector = new DefaultTrackSelector(); + LoadControl loadControl = new DefaultLoadControl(); + mExoPlayer = ExoPlayerFactory.newSimpleInstance(this, trackSelector, loadControl); + mPlayerView.setPlayer(mExoPlayer); + // Prepare the MediaSource. + String userAgent = Util.getUserAgent(this, "ClassicalMusicQuiz"); + MediaSource mediaSource = new ExtractorMediaSource(mediaUri, new DefaultDataSourceFactory( + this, userAgent), new DefaultExtractorsFactory(), null, null); + mExoPlayer.prepare(mediaSource); + mExoPlayer.setPlayWhenReady(true); + } + } + + + /** + * Release ExoPlayer. + */ + private void releasePlayer() { + mExoPlayer.stop(); + mExoPlayer.release(); + mExoPlayer = null; + } + + /** * The OnClick method for all of the answer buttons. The method uses the index of the button * in button array to to get the ID of the sample from the array of question IDs. It also @@ -161,25 +210,26 @@ public void onClick(View v) { handler.postDelayed(new Runnable() { @Override public void run() { - // TODO (9): Stop the playback when you go to the next question. + mExoPlayer.stop(); Intent nextQuestionIntent = new Intent(QuizActivity.this, QuizActivity.class); nextQuestionIntent.putExtra(REMAINING_SONGS_KEY, mRemainingSampleIDs); finish(); startActivity(nextQuestionIntent); } }, CORRECT_ANSWER_DELAY_MILLIS); - } /** - * Disables the buttons and changes the background colors to show the correct answer. + * Disables the buttons and changes the background colors and player art to + * show the correct answer. */ private void showCorrectAnswer() { + mPlayerView.setDefaultArtwork(Sample.getComposerArtBySampleID(this, mAnswerSampleID)); for (int i = 0; i < mQuestionSampleIDs.size(); i++) { int buttonSampleID = mQuestionSampleIDs.get(i); - // TODO (10): Change the default artwork in the SimpleExoPlayerView to show the picture of the composer, when the user has answered the question. mButtons[i].setEnabled(false); + if (buttonSampleID == mAnswerSampleID) { mButtons[i].getBackground().setColorFilter(ContextCompat.getColor (this, android.R.color.holo_green_light), @@ -190,10 +240,17 @@ private void showCorrectAnswer() { (this, android.R.color.holo_red_light), PorterDuff.Mode.MULTIPLY); mButtons[i].setTextColor(Color.WHITE); - } } } - // TODO (11): Override onDestroy() to stop and release the player when the Activity is destroyed. + + /** + * Release the player when the activity is destroyed. + */ + @Override + protected void onDestroy() { + super.onDestroy(); + releasePlayer(); + } } diff --git a/app/src/main/java/com/example/android/classicalmusicquiz/QuizUtils.java b/app/src/main/java/com/example/android/classicalmusicquiz/QuizUtils.java index e8e6c6cb..3ca7cbc6 100644 --- a/app/src/main/java/com/example/android/classicalmusicquiz/QuizUtils.java +++ b/app/src/main/java/com/example/android/classicalmusicquiz/QuizUtils.java @@ -134,5 +134,4 @@ static void endGame(Context context){ endGame.putExtra(GAME_FINISHED, true); context.startActivity(endGame); } - } diff --git a/app/src/main/res/layout/activity_quiz.xml b/app/src/main/res/layout/activity_quiz.xml index db8287d0..29c580ce 100644 --- a/app/src/main/res/layout/activity_quiz.xml +++ b/app/src/main/res/layout/activity_quiz.xml @@ -21,6 +21,19 @@ tools:layout_editor_absoluteX="0dp" tools:layout_editor_absoluteY="81dp"> + + - - - + diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 0bcf88fb..bbc7dd31 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -21,4 +21,5 @@ Can you guess the composer? Press play to hear the piece! Error loading one or more samples! + Sample not found!