Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 11 additions & 11 deletions app/build.gradle
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
apply plugin: 'com.android.application'

android {
compileSdkVersion 25
buildToolsVersion "25.0.2"
compileSdkVersion 31
buildToolsVersion "30.0.3"
defaultConfig {
applicationId "com.example.android.classicalmusicquiz"
minSdkVersion 15
targetSdkVersion 25
minSdkVersion 17
targetSdkVersion 31
versionCode 1
versionName "1.0"
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
testInstrumentationRunner 'androidx.test.runner.AndroidJUnitRunner'
}
buildTypes {
release {
Expand All @@ -20,12 +20,12 @@ android {
}

dependencies {
compile fileTree(dir: 'libs', include: ['*.jar'])
androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2', {
implementation fileTree(dir: 'libs', include: ['*.jar'])
androidTestImplementation('androidx.test.espresso:espresso-core:3.1.0', {
exclude group: 'com.android.support', module: 'support-annotations'
})
compile 'com.google.android.exoplayer:exoplayer:r2.2.0'
compile 'com.android.support:appcompat-v7:25.3.0'
testCompile 'junit:junit:4.12'
compile 'com.android.support.constraint:constraint-layout:1.0.2'
implementation 'com.google.android.exoplayer:exoplayer:2.16.1'
implementation 'androidx.appcompat:appcompat:1.4.1'
testImplementation 'junit:junit:4.13.2'
implementation 'androidx.constraintlayout:constraintlayout:2.1.3'
}
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
package com.example.android.classicalmusicquiz;

import android.content.Context;
import android.support.test.InstrumentationRegistry;
import android.support.test.runner.AndroidJUnit4;
import androidx.test.platform.app.InstrumentationRegistry;
import androidx.test.ext.junit.runners.AndroidJUnit4;

import org.junit.Test;
import org.junit.runner.RunWith;
Expand Down
6 changes: 4 additions & 2 deletions app/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,8 @@
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/AppTheme">
<activity android:name=".MainActivity">
<activity android:name=".MainActivity"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.MAIN" />

Expand All @@ -31,7 +32,8 @@
</activity>
<activity android:name=".QuizActivity"
android:launchMode="singleTop"/>
<receiver android:name=".QuizActivity$MediaReceiver">
<receiver android:name=".QuizActivity$MediaReceiver"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.MEDIA_BUTTON" />
</intent-filter>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@

import android.content.Intent;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import androidx.appcompat.app.AppCompatActivity;
import android.view.View;
import android.widget.TextView;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,58 +21,57 @@
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Color;
import android.graphics.PorterDuff;
import android.graphics.drawable.BitmapDrawable;
import android.net.Uri;
import android.os.Bundle;
import android.os.Handler;
import android.support.v4.content.ContextCompat;
import android.support.v4.media.session.MediaButtonReceiver;
import android.support.v4.media.session.MediaSessionCompat;
import android.support.v4.media.session.PlaybackStateCompat;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.app.NotificationCompat;
import android.view.View;
import android.widget.Button;
import android.widget.Toast;

import androidx.core.content.ContextCompat;
import androidx.appcompat.app.AppCompatActivity;
import androidx.media.app.NotificationCompat;
import androidx.media.session.MediaButtonReceiver;
import androidx.core.app.NotificationCompat.Builder;

import com.google.android.exoplayer2.DefaultLoadControl;
import com.google.android.exoplayer2.ExoPlaybackException;
import com.google.android.exoplayer2.ExoPlayer;
import com.google.android.exoplayer2.ExoPlayerFactory;
import com.google.android.exoplayer2.LoadControl;
import com.google.android.exoplayer2.SimpleExoPlayer;
import com.google.android.exoplayer2.Timeline;
import com.google.android.exoplayer2.Player;
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.source.TrackGroupArray;
import com.google.android.exoplayer2.source.ProgressiveMediaSource;
import com.google.android.exoplayer2.trackselection.DefaultTrackSelector;
import com.google.android.exoplayer2.trackselection.TrackSelectionArray;
import com.google.android.exoplayer2.trackselection.TrackSelector;
import com.google.android.exoplayer2.ui.SimpleExoPlayerView;
import com.google.android.exoplayer2.ui.PlayerView;
import com.google.android.exoplayer2.upstream.DefaultDataSourceFactory;
import com.google.android.exoplayer2.util.Util;

import java.util.ArrayList;

public class QuizActivity extends AppCompatActivity implements View.OnClickListener, ExoPlayer.EventListener {
public class QuizActivity extends AppCompatActivity implements View.OnClickListener, Player.Listener {

private static final int CORRECT_ANSWER_DELAY_MILLIS = 1000;
private static final String REMAINING_SONGS_KEY = "remaining_songs";
private static final String TAG = QuizActivity.class.getSimpleName();
private int[] mButtonIDs = {R.id.buttonA, R.id.buttonB, R.id.buttonC, R.id.buttonD};
private ArrayList<Integer> mRemainingSampleIDs;
private ArrayList<Integer> mQuestionSampleIDs;
private static final String TAG = QuizActivity.class.getSimpleName();
private int mAnswerSampleID;
private int mCurrentScore;
private int mHighScore;
private Button[] mButtons;
private SimpleExoPlayer mExoPlayer;
private SimpleExoPlayerView mPlayerView;
private ExoPlayer mExoPlayer;
private PlayerView mPlayerView;
private static MediaSessionCompat mMediaSession;
private PlaybackStateCompat.Builder mStateBuilder;
public static PlaybackStateCompat.Builder mStateBuilder;
private NotificationManager mNotificationManager;


Expand All @@ -83,8 +82,7 @@ protected void onCreate(Bundle savedInstanceState) {


// Initialize the player view.
mPlayerView = (SimpleExoPlayerView) findViewById(R.id.playerView);

mPlayerView = (PlayerView) findViewById(R.id.playerView);

boolean isNewGame = !getIntent().hasExtra(REMAINING_SONGS_KEY);

Expand All @@ -106,8 +104,7 @@ protected void onCreate(Bundle savedInstanceState) {
mAnswerSampleID = QuizUtils.getCorrectAnswerID(mQuestionSampleIDs);

// Load the question mark as the background image until the user answers the question.
mPlayerView.setDefaultArtwork(BitmapFactory.decodeResource
(getResources(), R.drawable.question_mark));
mPlayerView.setDefaultArtwork(new BitmapDrawable(BitmapFactory.decodeResource(getResources(), R.drawable.question_mark)));

// If there is only one answer left, end the game.
if (mQuestionSampleIDs.size() < 2) {
Expand All @@ -118,7 +115,6 @@ protected void onCreate(Bundle savedInstanceState) {
// Initialize the buttons with the composers names.
mButtons = initializeButtons(mQuestionSampleIDs);

// Initialize the Media Session.
initializeMediaSession();

Sample answerSample = Sample.getSampleByID(this, mAnswerSampleID);
Expand All @@ -133,6 +129,7 @@ protected void onCreate(Bundle savedInstanceState) {
initializePlayer(Uri.parse(answerSample.getUri()));
}


/**
* Initializes the Media Session to be enabled with media buttons, transport controls, callbacks
* and media controller.
Expand Down Expand Up @@ -169,6 +166,7 @@ private void initializeMediaSession() {

}


/**
* Initializes the button to the correct views, and sets the text to the composers names,
* and set's the OnClick listener to the buttons.
Expand All @@ -192,12 +190,13 @@ private Button[] initializeButtons(ArrayList<Integer> answerSampleIDs) {


/**
* Shows Media Style notification, with actions that depend on the current MediaSession
* Shows Media Style notification, with an action that depends on the current MediaSession
* PlaybackState.
* @param state The PlaybackState of the MediaSession.
*/
private void showNotification(PlaybackStateCompat state) {
NotificationCompat.Builder builder = new NotificationCompat.Builder(this);
//no channelId created as it's not part of our course
androidx.core.app.NotificationCompat.Builder builder = new Builder(this,"");

int icon;
String play_pause;
Expand All @@ -210,12 +209,12 @@ private void showNotification(PlaybackStateCompat state) {
}


NotificationCompat.Action playPauseAction = new NotificationCompat.Action(
androidx.core.app.NotificationCompat.Action playPauseAction =new androidx.core.app.NotificationCompat.Action(
icon, play_pause,
MediaButtonReceiver.buildMediaButtonPendingIntent(this,
PlaybackStateCompat.ACTION_PLAY_PAUSE));

NotificationCompat.Action restartAction = new android.support.v4.app.NotificationCompat
androidx.core.app.NotificationCompat.Action restartAction =new androidx.core.app.NotificationCompat
.Action(R.drawable.exo_controls_previous, getString(R.string.restart),
MediaButtonReceiver.buildMediaButtonPendingIntent
(this, PlaybackStateCompat.ACTION_SKIP_TO_PREVIOUS));
Expand All @@ -227,7 +226,7 @@ private void showNotification(PlaybackStateCompat state) {
.setContentText(getString(R.string.notification_text))
.setContentIntent(contentPendingIntent)
.setSmallIcon(R.drawable.ic_music_note)
.setVisibility(NotificationCompat.VISIBILITY_PUBLIC)
.setVisibility(androidx.core.app.NotificationCompat.VISIBILITY_PUBLIC)
.addAction(restartAction)
.addAction(playPauseAction)
.setStyle(new NotificationCompat.MediaStyle()
Expand All @@ -249,16 +248,22 @@ private void initializePlayer(Uri mediaUri) {
// Create an instance of the ExoPlayer.
TrackSelector trackSelector = new DefaultTrackSelector();
LoadControl loadControl = new DefaultLoadControl();
mExoPlayer = ExoPlayerFactory.newSimpleInstance(this, trackSelector, loadControl);
mExoPlayer = new ExoPlayer.Builder(this)
.setTrackSelector(trackSelector)
.setLoadControl(loadControl).build();
mPlayerView.setPlayer(mExoPlayer);

// Set the ExoPlayer.EventListener to this activity.
mExoPlayer.addListener(this);

// Prepare the MediaSource.
String userAgent = Util.getUserAgent(this, "ClassicalMusicQuiz");
MediaSource mediaSource = new ExtractorMediaSource(mediaUri, new DefaultDataSourceFactory(
this, userAgent), new DefaultExtractorsFactory(), null, null);

DefaultDataSourceFactory defaultDataSourceFactory = new DefaultDataSourceFactory(this, userAgent);
DefaultExtractorsFactory defaultExtractorsFactory = new DefaultExtractorsFactory();
MediaSource mediaSource = new ProgressiveMediaSource.Factory(defaultDataSourceFactory,
defaultExtractorsFactory).createMediaSource(mediaUri);

mExoPlayer.prepare(mediaSource);
mExoPlayer.setPlayWhenReady(true);
}
Expand Down Expand Up @@ -330,12 +335,14 @@ public void run() {
}, CORRECT_ANSWER_DELAY_MILLIS);
}


/**
* 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));
Bitmap bitmap=Sample.getComposerArtBySampleID(this, mAnswerSampleID);
mPlayerView.setDefaultArtwork(new BitmapDrawable(bitmap));
for (int i = 0; i < mQuestionSampleIDs.size(); i++) {
int buttonSampleID = mQuestionSampleIDs.get(i);

Expand Down Expand Up @@ -366,21 +373,8 @@ protected void onDestroy() {
mMediaSession.setActive(false);
}


// ExoPlayer Event Listeners

@Override
public void onTimelineChanged(Timeline timeline, Object manifest) {
}

@Override
public void onTracksChanged(TrackGroupArray trackGroups, TrackSelectionArray trackSelections) {
}

@Override
public void onLoadingChanged(boolean isLoading) {
}

// ExoPlayer Event Listener
/**
* Method that is called when the ExoPlayer state changes. Used to update the MediaSession
* PlayBackState to keep in sync, and post the media notification.
Expand All @@ -390,29 +384,21 @@ public void onLoadingChanged(boolean isLoading) {
*/
@Override
public void onPlayerStateChanged(boolean playWhenReady, int playbackState) {
if((playbackState == ExoPlayer.STATE_READY) && playWhenReady){
if ((playbackState == ExoPlayer.STATE_READY) && playWhenReady) {
mStateBuilder.setState(PlaybackStateCompat.STATE_PLAYING,
mExoPlayer.getCurrentPosition(), 1f);
} else if((playbackState == ExoPlayer.STATE_READY)){
} else if ((playbackState == ExoPlayer.STATE_READY)) {
mStateBuilder.setState(PlaybackStateCompat.STATE_PAUSED,
mExoPlayer.getCurrentPosition(), 1f);
}
mMediaSession.setPlaybackState(mStateBuilder.build());
showNotification(mStateBuilder.build());
}

@Override
public void onPlayerError(ExoPlaybackException error) {
}

@Override
public void onPositionDiscontinuity() {
}

/**
* Media Session Callbacks, where all external clients control the player.
*/
private class MySessionCallback extends MediaSessionCompat.Callback {
public class MySessionCallback extends MediaSessionCompat.Callback {
@Override
public void onPlay() {
mExoPlayer.setPlayWhenReady(true);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@
* limitations under the License.
*/

import static com.google.android.exoplayer2.upstream.DataSourceUtil.closeQuietly;

import android.content.Context;
import android.content.res.AssetManager;
import android.graphics.Bitmap;
Expand All @@ -30,6 +32,7 @@
import com.google.android.exoplayer2.upstream.DefaultDataSource;
import com.google.android.exoplayer2.util.Util;

import java.io.Closeable;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
Expand Down Expand Up @@ -182,15 +185,15 @@ private static JsonReader readJSONFile(Context context) throws IOException {
}

String userAgent = Util.getUserAgent(context, "ClassicalMusicQuiz");
DataSource dataSource = new DefaultDataSource(context, null, userAgent, false);
DataSource dataSource = new DefaultDataSource(context, userAgent,1000,1000, false);
DataSpec dataSpec = new DataSpec(Uri.parse(uri));
InputStream inputStream = new DataSourceInputStream(dataSource, dataSpec);

JsonReader reader = null;
try {
reader = new JsonReader(new InputStreamReader(inputStream, "UTF-8"));
} finally {
Util.closeQuietly(dataSource);
closeQuietly(dataSource);
}

return reader;
Expand Down
10 changes: 5 additions & 5 deletions app/src/main/res/drawable/ic_music_note.xml
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24.0"
android:viewportHeight="24.0">
android:width="24dp"
android:height="24dp"
android:viewportWidth="24.0"
android:viewportHeight="24.0">
<path
android:fillColor="#FF000000"
android:pathData="M12,3v10.55c-0.59,-0.34 -1.27,-0.55 -2,-0.55 -2.21,0 -4,1.79 -4,4s1.79,4 4,4 4,-1.79 4,-4V7h4V3h-6z"/>
</vector>
</vector>
Loading