Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save udacityandroid/5808ce6e0c0b816bcf9a3125e8eeced0 to your computer and use it in GitHub Desktop.
Save udacityandroid/5808ce6e0c0b816bcf9a3125e8eeced0 to your computer and use it in GitHub Desktop.
After fixing 4 errors in NumbersFragment.java
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.word_list);
// Create and setup the {@link AudioManager} to request audio focus
mAudioManager = (AudioManager) getSystemService(Context.AUDIO_SERVICE);
// Create a list of words
final ArrayList<Word> words = new ArrayList<Word>();
words.add(new Word(R.string.number_one, R.string.miwok_number_one,
R.drawable.number_one, R.raw.number_one));
words.add(new Word(R.string.number_two, R.string.miwok_number_two,
R.drawable.number_two, R.raw.number_two));
words.add(new Word(R.string.number_three, R.string.miwok_number_three,
R.drawable.number_three, R.raw.number_three));
words.add(new Word(R.string.number_four, R.string.miwok_number_four,
R.drawable.number_four, R.raw.number_four));
words.add(new Word(R.string.number_five, R.string.miwok_number_five,
R.drawable.number_five, R.raw.number_five));
words.add(new Word(R.string.number_six, R.string.miwok_number_six,
R.drawable.number_six, R.raw.number_six));
words.add(new Word(R.string.number_seven, R.string.miwok_number_seven,
R.drawable.number_seven, R.raw.number_seven));
words.add(new Word(R.string.number_eight, R.string.miwok_number_eight,
R.drawable.number_eight, R.raw.number_eight));
words.add(new Word(R.string.number_nine, R.string.miwok_number_nine,
R.drawable.number_nine, R.raw.number_nine));
words.add(new Word(R.string.number_ten, R.string.miwok_number_ten,
R.drawable.number_ten, R.raw.number_ten));
// Create an {@link WordAdapter}, whose data source is a list of {@link Word}s. The
// adapter knows how to create list items for each item in the list.
WordAdapter adapter = new WordAdapter(this, words, R.color.category_numbers);
// Find the {@link ListView} object in the view hierarchy of the {@link Activity}.
// There should be a {@link ListView} with the view ID called list, which is declared in the
// word_list.xml layout file.
ListView listView = (ListView) findViewById(R.id.list);
// Make the {@link ListView} use the {@link WordAdapter} we created above, so that the
// {@link ListView} will display list items for each {@link Word} in the list.
listView.setAdapter(adapter);
// Set a click listener to play the audio when the list item is clicked on
listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> adapterView, View view, int position, long l) {
// Release the media player if it currently exists because we are about to
// play a different sound file
releaseMediaPlayer();
// Get the {@link Word} object at the given position the user clicked on
Word word = words.get(position);
// Request audio focus so in order to play the audio file. The app needs to play a
// short audio file, so we will request audio focus with a short amount of time
// with AUDIOFOCUS_GAIN_TRANSIENT.
int result = mAudioManager.requestAudioFocus(mOnAudioFocusChangeListener,
AudioManager.STREAM_MUSIC, AudioManager.AUDIOFOCUS_GAIN_TRANSIENT);
if (result == AudioManager.AUDIOFOCUS_REQUEST_GRANTED) {
// We have audio focus now.
// Create and setup the {@link MediaPlayer} for the audio resource associated
// with the current word
mMediaPlayer = MediaPlayer.create(NumbersActivity.this, word.getAudioResourceId());
// Start the audio file
mMediaPlayer.start();
// Setup a listener on the media player, so that we can stop and release the
// media player once the sound has finished playing.
mMediaPlayer.setOnCompletionListener(mCompletionListener);
}
}
});
}
@stef2dotoh
Copy link

stef2dotoh commented Dec 4, 2017

@27angel, I see no one has responded to your issue which is likely resolved by now. But for those who, like me, are just now taking this course and coming here for answers, here it is. Yes, you are correct. It seems at some point the hard-coded strings were moved to the strings.xml file and so now the code reflects that. I would really like to know when that happened because I don't recall being instructed to make those changes. Did I miss it somehow? After you make these changes for all of the fragment files, you have to then go into Word.java and change all references to String defaultTranslation and String miwokTranslation to int defaultTranslation and int miwokTranslation because you are now using resource IDs in the fragments instead of the hard-coded strings. If you want to be more accurate and consistent with the other variables, change defaultTranslation to defaultTranslationId and miwokTranslation to miwokTranslationId.

Just one of the short-comings of this course. Most frustrating experience ever.

Copy link

ghost commented Jan 12, 2018

After making the 4 adjustments I still face the following problem with the adapter. Anyone has the same problems?

Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'void android.widget.ListView.setAdapter(android.widget.ListAdapter)' on a null object reference at com.example.android.miwok.NumbersFragment.onCreateView(NumbersFragment.java:86)

My code for the WordAdapter adapter

        WordAdapter adapter = new WordAdapter(getActivity(), numberEnglishArray, R.color.category_numbers);

        ListView listView = (ListView) rootView.findViewById(R.id.list);

        listView.setAdapter(adapter);

Edit:

I found my problem is that I haven't created a new layout word_list.xml and then mistook that the instructor is talking about list_item.xml when she mentions word_list.xml . Create it and copy the code snippet for word_list.xml and everthing is fixed. Yet I can't recall when the instructor mentioned about creating word_list.xml , I must have missed it, do anyone remember which lesson?

@alexrooot
Copy link

Very important to add theView type in beingin of the overide method onCreateView
View rootView = inflater.inflate(R.layout.word_list, container, false);

@speedemon35
Copy link

@stef2dotoh thank you for existing and sharing the fix

@coding-catie
Copy link

@stef2dotoh Thanks from me as well!

@asadnawaz126
Copy link

I'm getting an error that says

Caused by: java.lang.RuntimeException: com.example.android.RomanPashto.FamilyActivity@277c150 must implement OnFragmentInteractionListener at com.example.android.RomanPashto.FamilyFragment.onAttach(FamilyFragment.java:239)

@Override public void onAttach(Context context) { super.onAttach(context); if (context instanceof OnFragmentInteractionListener) { mListener = (OnFragmentInteractionListener) context; } else { throw new RuntimeException(context.toString() + " must implement OnFragmentInteractionListener"); } }

The RuntimeException in the else statement seems to be triggered. Any help?

@kwonines
Copy link

Anyone who missed the comment of @sfgueller, if you are having a problem with this line
mAudioManager = (AudioManager) getActivity().getSystemService(Context.AUDIO_SERVICE);
Make sure that the return rootView; statement is at the bottom of your onCreateView method. I moved it and worked perfectly.

@mohammad-o
Copy link

@27angel, I see no one has responded to your issue which is likely resolved by now. But for those who, like me, are just now taking this course and coming here for answers, here it is. Yes, you are correct. It seems at some point the hard-coded strings were moved to the strings.xml file and so now the code reflects that. I would really like to know when that happened because I don't recall being instructed to make those changes. Did I miss it somehow? After you make these changes for all of the fragment files, you have to then go into Word.java and change all references to String defaultTranslation and String miwokTranslation to int defaultTranslation and int miwokTranslation because you are now using resource IDs in the fragments instead of the hard-coded strings. If you want to be more accurate and consistent with the other variables, change defaultTranslation to defaultTranslationId and miwokTranslation to miwokTranslationId.

Just one of the short-comings of this course. Most frustrating experience ever.

Couldn't agree more with that.

@FTW-Khushal
Copy link

`package com.example.android.miwok;

import android.content.Context;
import android.media.AudioManager;
import android.media.MediaPlayer;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.ListView;
import android.widget.TextView;

import java.util.ArrayList;

/**

  • A simple {@link Fragment} subclass.
    */
    public class NumbersFragment extends Fragment {

    private MediaPlayer mMediaPlayer;
    private AudioManager mAudioManager;
    private AudioManager.OnAudioFocusChangeListener mOnAudioFocusChangeListener = new AudioManager.OnAudioFocusChangeListener() {
    @OverRide
    public void onAudioFocusChange(int focusChange) {
    if (focusChange == AudioManager.AUDIOFOCUS_LOSS_TRANSIENT ||
    focusChange == AudioManager.AUDIOFOCUS_LOSS_TRANSIENT_CAN_DUCK) {
    // The AUDIOFOCUS_LOSS_TRANSIENT case means that we've lost audio focus for a
    // short amount of time. The AUDIOFOCUS_LOSS_TRANSIENT_CAN_DUCK case means that
    // our app is allowed to continue playing sound but at a lower volume. We'll treat
    // both cases the same way because our app is playing short sound files.

             // Pause playback and reset player to the start of the file. That way, we can
             // play the word from the beginning when we resume playback.
             mMediaPlayer.pause();
             mMediaPlayer.seekTo(0);
         } else if (focusChange == AudioManager.AUDIOFOCUS_GAIN) {
             // The AUDIOFOCUS_GAIN case means we have regained focus and can resume playback.
             mMediaPlayer.start();
         } else if (focusChange == AudioManager.AUDIOFOCUS_LOSS) {
             // The AUDIOFOCUS_LOSS case means we've lost audio focus and
             // Stop playback and clean up resources
             releaseMediaPlayer();
         }
     }
    

    };
    /**

    • This listener gets triggered when the {@link MediaPlayer} has completed

    • playing the audio file.
      */
      private MediaPlayer.OnCompletionListener mCompletionListener = new MediaPlayer.OnCompletionListener() {
      @OverRide
      public void onCompletion(MediaPlayer mediaPlayer) {
      // Now that the sound file has finished playing, release the media player resources.
      releaseMediaPlayer();

      }
      };
      public NumbersFragment() {
      // Required empty public constructor
      }

    @OverRide
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
    Bundle savedInstanceState) {
    View rootView = inflater.inflate(R.layout.word_list, container, false);

     /** TODO: Insert all the code from the NumberActivity’s onCreate() method after the setContentView method call */
    

// getSupportActionBar().setDisplayHomeAsUpEnabled(true);

    mAudioManager = (AudioManager) getActivity().getSystemService(Context.AUDIO_SERVICE);

    //Todo make an array name words

    final ArrayList<Word> words = new ArrayList<Word>();
    words.add(new Word("one", "lutti", R.drawable.number_one, R.raw.number_one));
    words.add(new Word("two", "otiiko", R.drawable.number_two, R.raw.number_two));
    words.add(new Word("three", "tolookosu", R.drawable.number_three, R.raw.number_three));
    words.add(new Word("four", "oyyisa", R.drawable.number_four, R.raw.number_four));
    words.add(new Word("five", "massokka", R.drawable.number_five, R.raw.number_five));
    words.add(new Word("six", "temmokka", R.drawable.number_six, R.raw.number_six));
    words.add(new Word("seven", "kenekaku", R.drawable.number_seven, R.raw.number_seven));
    words.add(new Word("eight", "kawinta", R.drawable.number_eight, R.raw.number_eight));
    words.add(new Word("nine", "wo’e", R.drawable.number_nine, R.raw.number_nine));
    words.add(new Word("ten", "na’aacha", R.drawable.number_ten, R.raw.number_ten));

    // Create an {@link ArrayAdapter}, whose data source is a list of Strings. The
    // adapter knows how to create layouts for each item in the list, using the
    // simple_list_item_1.xml layout resource defined in the Android framework.
    // This list item layout contains a single {@link TextView}, which the adapter will set to
    // display a single word.

// LinearLayout ln = (LinearLayout) this.findViewById(R.id.linear_layout);
// ln.setBackground(Drawable.createFromPath(getResources().getString(R.color.category_numbers)));

    WordAdapter itemsAdapter = new WordAdapter(getActivity(),R.layout.list_item, words, R.color.category_numbers);


    // Find the {@link ListView} object in the view hierarchy of the {@link Activity}.
    // There should be a {@link ListView} with the view ID called list, which is declared in the
    // word_list.xml file.
    ListView listView = (ListView) rootView.findViewById(R.id.list);

    // Make the {@link ListView} use the {@link ArrayAdapter} we created above, so that the
    // {@link ListView} will display list items for each word in the list of words.
    // Do this by calling the setAdapter method on the {@link ListView} object and pass in
    // 1 argument, which is the {@link ArrayAdapter} with the variable name itemsAdapter.
    listView.setAdapter(itemsAdapter);

    listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
        @Override
        public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) {
            // Release the media player if it currently exists because we are about to
            // play a different sound file
            releaseMediaPlayer();

            Word word = words.get(i);

            // Request audio focus so in order to play the audio file. The app needs to play a
            // short audio file, so we will request audio focus with a short amount of time
            // with AUDIOFOCUS_GAIN_TRANSIENT.
            int result = mAudioManager.requestAudioFocus(mOnAudioFocusChangeListener,
                    AudioManager.STREAM_MUSIC, AudioManager.AUDIOFOCUS_GAIN_TRANSIENT);

            if (result == AudioManager.AUDIOFOCUS_REQUEST_GRANTED) {
                // We have audio focus now.

                mMediaPlayer = MediaPlayer.create(getActivity(), word.getAudioResourceId());

                mMediaPlayer.start();
                // Setup a listener on the media player, so that we can stop and release the
                // media player once the sound has finished playing.
                mMediaPlayer.setOnCompletionListener(mCompletionListener);
            }
        }


    });

    return rootView;
}
private void releaseMediaPlayer() {
    // If the media player is not null, then it may be currently playing a sound.
    if (mMediaPlayer != null) {
        // Regardless of the current state of the media player, release its resources
        // because we no longer need it.
        mMediaPlayer.release();

        // Set the media player back to null. For our code, we've decided that
        // setting the media player to null is an easy way to tell that the media player
        // is not configured to play an audio file at the moment.
        mMediaPlayer = null;

        // Regardless of whether or not we were granted audio focus, abandon it. This also
        // unregisters the AudioFocusChangeListener so we don't get anymore callbacks.
        mAudioManager.abandonAudioFocus(mOnAudioFocusChangeListener);
    }
}

@Override
public void onStop() {
    super.onStop();
    releaseMediaPlayer();
}

}
`

This is the which works for me

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment