2016-08-13 5 views
0

Je crée une application Music Player qui utilise des fragments d'onglets. Les composants Player (les méthodes qui chargent la liste de fichiers et lient les actions de lecture aux boutons) sont configurés dans une classe Player imbriquée qui se trouve dans une classe PlayerFragment.Erreur lors de l'instanciation des composants du lecteur audio dans une classe de fragmentation

J'ai l'intention de charger mon application et le premier fragment est le lecteur où une liste de fichiers apparaîtra et une fois qu'un utilisateur appuie sur un fichier dans la liste, il jouera. En ce moment, le problème que je rencontre est que j'essaie de créer une instance de Player, puis d'appeler la méthode initializeAllComponents() qui, comme son nom l'indique, va instancier la classe Player, permettant au Player de apparaissent dans la vue Fragment et permettent aux boutons d'utiliser leurs méthodes respectives.

J'ai cherché autour et je n'ai pas trouvé une réponse qui corrige le problème. Lorsque j'ouvre l'application, l'appel à initializeAllComponents() provoque la fermeture immédiate de l'application.

L'application est actuellement basée sur l'API Lite Music sous licence, mais elle sera modifiée beaucoup plus tard. C'est pourquoi le code est si similaire. En ce moment, je veux juste que le Fragment se charge correctement et contienne un Music Player fonctionnel avant de commencer à retravailler les boutons et les méthodes de MediaPlayer.

Les classes MainActivity et TabFragment (la classe FragmentPager dans ce cas) fonctionnent correctement, donc je ne les inclue pas. Ils permettent à l'application d'afficher une vue à onglets et de charger les fragments correctement lorsqu'ils ne contiennent pas d'appels dans OnCreateView, mais le composant PlayerFragment va interrompre l'application comme c'est le cas avec un appel dans la méthode OnCreateView.

Je sais également que la classe Player fonctionne correctement lorsqu'elle est configurée dans l'activité principale sans implémentation de fragment. Il semble donc que ce soit l'appel de player.initializeAllComponents() dans OnCreateView() qui casse tout, mais je ne sais pas pourquoi.

Y at-il un moyen d'appeler initializeAllComponents() qui gonfle le fragment correctement sans erreur? Est-ce que je n'instancie pas correctement la sous-classe Player correctement? Ou la sous-classe Player ne va-t-elle pas fonctionner à l'intérieur du fragment?

Toute aide serait appréciée.

Voici le code:

PlayerFragment.java

import android.content.DialogInterface; 
import android.media.AudioManager; 
import android.media.MediaPlayer; 
import android.os.AsyncTask; 
import android.os.Bundle; 
import android.os.Handler; 
import android.support.annotation.Nullable; 
import android.support.design.widget.Snackbar; 
import android.support.v4.app.Fragment; 
import android.support.v7.app.AlertDialog; 
import android.support.v7.app.AppCompatActivity; 
import android.support.v7.widget.AppCompatSeekBar; 
import android.view.LayoutInflater; 
import android.view.View; 
import android.view.ViewGroup; 
import android.widget.AdapterView; 
import android.widget.Button; 
import android.widget.LinearLayout; 
import android.widget.ListView; 
import android.widget.SeekBar; 
import android.widget.TextView; 

import java.io.IOException; 
import java.util.ArrayList; 
import java.util.Random; 

public class PlayerFragment extends Fragment { 

    @Nullable 
    @Override 
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { 
     Player.class.getMethods(); 

     Player player = new Player(); 
     player.initializeAllComponents(); 

     return inflater.inflate(R.layout.player_layout, null); 
    } 

    class Player extends AppCompatActivity implements MediaPlayer.OnCompletionListener, SeekBar.OnSeekBarChangeListener { 

     private View parent_view; 
     private LinearLayout lyt_main; 
     // playlist 
     private ListView listview; 
     private LinearLayout lyt_progress; 
     private LinearLayout lyt_list; 

     // player 
     private Button bt_play; 
     private Button bt_next; 
     private Button bt_prev; 
     private Button btn_repeat; 
     private Button btn_shuffle; 
     private AppCompatSeekBar seek_song_progressbar; 
     private TextView tv_song_title; 
     private TextView tv_song_current_duration; 
     private TextView tv_song_total_duration; 

     // Media Player 
     private MediaPlayer mp; 
     // Handler to update UI timer, progress bar etc,. 
     private Handler mHandler = new Handler(); 

     //private SongsManager songManager; 
     private MusicUtils utils; 

     private int currentSongIndex = 0; 
     private boolean isShuffle = false; 
     private boolean isRepeat = false; 

     // the items (songs) we have queried 
     private ArrayList<MusicItem> mItems = new ArrayList<MusicItem>(); 
     private MusicItem cur_music = null; 
     private DatabaseHandler db; 

     public void initializeAllComponents() { 
      parent_view = findViewById(R.id.main_content); 

      db = new DatabaseHandler(getApplicationContext()); 
      lyt_main = (LinearLayout) findViewById(R.id.lyt_main); 

      initPlaylistComponents(); 
      initPlayerComponents(); 

     } 

     private void initPlayerComponents() { 
      // All player buttons 
      bt_play = (Button) findViewById(R.id.bt_play); 
      bt_next = (Button) findViewById(R.id.bt_next); 
      bt_prev = (Button) findViewById(R.id.bt_prev); 
      btn_repeat = (Button) findViewById(R.id.btn_repeat); 
      btn_shuffle = (Button) findViewById(R.id.btn_shuffle); 
      seek_song_progressbar = (AppCompatSeekBar) findViewById(R.id.seek_song_progressbar); 
      tv_song_title = (TextView) findViewById(R.id.tv_song_title); 
      tv_song_title.setSelected(true); 
      tv_song_current_duration = (TextView) findViewById(R.id.tv_song_current_duration); 
      tv_song_total_duration = (TextView) findViewById(R.id.tv_song_total_duration); 

      // Media Player 
      mp = new MediaPlayer(); 
      //songManager = new SongsManager(); 
      utils = new MusicUtils(); 
      // Listeners 
      seek_song_progressbar.setOnSeekBarChangeListener(this); // Important 
      mp.setOnCompletionListener(this); // Important 

      // Getting all songs list songsList = songManager.getPlayList(); 
      buttonPlayerAction(); 
     } 

     private void initPlaylistComponents() { 

      listview = (ListView) findViewById(R.id.list_main); 
      lyt_progress = (LinearLayout) findViewById(R.id.lyt_progress); 
      lyt_list = (LinearLayout) findViewById(R.id.lyt_list); 
      lyt_progress.setVisibility(View.GONE); 


      mItems.clear(); 
      mItems = db.getAllMusicFiles(); 
      listview.setAdapter(new MusicFileListAdapter(Player.this, mItems)); 
      listview.setOnItemClickListener(new AdapterView.OnItemClickListener() { 
       @Override 
       public void onItemClick(AdapterView<?> arg0, View arg1, int arg2, long arg3) { 
        playSong(mItems.get(arg2)); 
       } 
      }); 
     } 

     /** 
     * Play button click event plays a song and changes button to pause image 
     * pauses a song and changes button to play image 
     */ 
     private void buttonPlayerAction() { 
      bt_play.setOnClickListener(new View.OnClickListener() { 

       @Override 
       public void onClick(View arg0) { 
        if (mItems.size() > 0) { 
         // check for already playing 
         if (mp.isPlaying()) { 
          if (mp != null) { 
           mp.pause(); 
           // Changing button image to play button 
           bt_play.setBackgroundResource(R.drawable.btn_play); 
          } 
         } else { 
          // Resume song 
          if (mp != null) { 
           mp.start(); 
           // Changing button image to pause button 
           bt_play.setBackgroundResource(R.drawable.btn_pause); 
          } 
         } 
        } else { 
         Snackbar.make(parent_view, "Song not found", Snackbar.LENGTH_SHORT).show(); 
        } 

       } 
      }); 


      /** 
      * Next button click event 
      * Plays next song by taking currentSongIndex + 1 
      * */ 
      bt_next.setOnClickListener(new View.OnClickListener() { 

       @Override 
       public void onClick(View arg0) { 
        // check if next song is there or not 
        if (currentSongIndex < (mItems.size() - 1)) { 
         playSong(mItems.get(currentSongIndex + 1)); 
         currentSongIndex = currentSongIndex + 1; 
        } else { 
         // play first song 
         playSong(mItems.get(0)); 
         currentSongIndex = 0; 
        } 

       } 
      }); 

      /** 
      * Back button click event 
      * Plays previous song by currentSongIndex - 1 
      * */ 
      bt_prev.setOnClickListener(new View.OnClickListener() { 

       @Override 
       public void onClick(View arg0) { 
        if (currentSongIndex > 0) { 
         playSong(mItems.get(currentSongIndex - 1)); 
         currentSongIndex = currentSongIndex - 1; 
        } else { 
         // play last song 
         playSong(mItems.get(mItems.size() - 1)); 
         currentSongIndex = mItems.size() - 1; 
        } 

       } 
      }); 

      /** 
      * Button Click event for Repeat button 
      * Enables repeat flag to true 
      * */ 
      btn_repeat.setOnClickListener(new View.OnClickListener() { 

       @Override 
       public void onClick(View arg0) { 
        if (isRepeat) { 
         isRepeat = false; 
         Snackbar.make(parent_view, "Repeat is OFF", Snackbar.LENGTH_SHORT).show(); 
         btn_repeat.setBackgroundResource(R.drawable.btn_repeat); 
        } else { 
         // make repeat to true 
         isRepeat = true; 
         Snackbar.make(parent_view, "Repeat is ON", Snackbar.LENGTH_SHORT).show(); 
         // make shuffle to false 
         isShuffle = false; 
         btn_repeat.setBackgroundResource(R.drawable.btn_repeat_focused); 
         btn_shuffle.setBackgroundResource(R.drawable.btn_shuffle); 
        } 
       } 
      }); 

      /** 
      * Button Click event for Shuffle button 
      * Enables shuffle flag to true 
      * */ 
      btn_shuffle.setOnClickListener(new View.OnClickListener() { 
       @Override 
       public void onClick(View arg0) { 
        if (isShuffle) { 
         isShuffle = false; 
         Snackbar.make(parent_view, "Shuffle is OFF", Snackbar.LENGTH_SHORT).show(); 
         btn_shuffle.setBackgroundResource(R.drawable.btn_shuffle); 
        } else { 
         // make repeat to true 
         isShuffle = true; 
         Snackbar.make(parent_view, "Shuffle is ON", Snackbar.LENGTH_SHORT).show(); 
         // make shuffle to false 
         isRepeat = false; 
         btn_shuffle.setBackgroundResource(R.drawable.btn_shuffle_focused); 
         btn_repeat.setBackgroundResource(R.drawable.btn_repeat); 
        } 
       } 
      }); 

     } 

     /** 
     * Function to play a song 
     */ 
     public void playSong(MusicItem msc) { 
      // Play song 
      try { 
       mp.reset(); 
       mp.setAudioStreamType(AudioManager.STREAM_MUSIC); 
       mp.setDataSource(getApplicationContext(), msc.getURI()); 
       mp.prepare(); 
       mp.start(); 
       cur_music = msc; 
       // Displaying Song title 
       String songTitle = msc.getTitle(); 
       tv_song_title.setText(songTitle); 
       // Changing Button Image to pause image 
       bt_play.setBackgroundResource(R.drawable.btn_pause); 

       // set Progress bar values 
       seek_song_progressbar.setProgress(0); 
       seek_song_progressbar.setMax(100); 

       // Updating progress bar 
       updateProgressBar(); 
      } catch (IllegalArgumentException e) { 
       e.printStackTrace(); 
      } catch (IllegalStateException e) { 
       e.printStackTrace(); 
      } catch (IOException e) { 
       e.printStackTrace(); 
      } 

     } 

     /** 
     * Update timer on seekbar 
     */ 
     public void updateProgressBar() { 
      mHandler.postDelayed(mUpdateTimeTask, 100); 
     } 

     /** 
     * Background Runnable thread 
     */ 
     private Runnable mUpdateTimeTask = new Runnable() { 
      public void run() { 
       long totalDuration = mp.getDuration(); 
       long currentDuration = mp.getCurrentPosition(); 

       // Displaying Total Duration time 
       tv_song_total_duration.setText("" + utils.milliSecondsToTimer(totalDuration)); 
       // Displaying time completed playing 
       tv_song_current_duration.setText("" + utils.milliSecondsToTimer(currentDuration)); 

       // Updating progress bar 
       int progress = (int) (utils.getProgressPercentage(currentDuration, totalDuration)); 
       seek_song_progressbar.setProgress(progress); 

       // Running this thread after 100 milliseconds 
       mHandler.postDelayed(this, 100); 
      } 
     }; 


     public class loadFiles extends AsyncTask<String, String, String> { 
      MusicRetriever mRetriever; 
      String status = "success"; 

      public loadFiles() { 
       mRetriever = new MusicRetriever(getContentResolver()); 
      } 

      @Override 
      protected void onPreExecute() { 
       mItems.clear(); 
       lyt_progress.setVisibility(View.VISIBLE); 
       lyt_list.setVisibility(View.GONE); 
       super.onPreExecute(); 
      } 

      @Override 
      protected String doInBackground(String... params) { 
       try { 
        Thread.sleep(1000); 
        mRetriever.prepare(); 
        mItems = mRetriever.getAllItem(); 
        status = "success"; 
       } catch (Exception e) { 
        status = "failed"; 
       } 
       return null; 
      } 

      @Override 
      protected void onPostExecute(String result) { 
       if (!status.equals("failed")) { 
        lyt_progress.setVisibility(View.GONE); 
        lyt_list.setVisibility(View.VISIBLE); 
        listview.setAdapter(new MusicFileListAdapter(Player.this, mItems)); 
        //if(musicfiles.size()>0){ 
        db.truncateTableScan(); 
        db.addMusicFiles(mItems); 
       } 
       super.onPostExecute(result); 
      } 
     } 

     // 2.0 and above 
     @Override 
     public void onBackPressed() { 
      moveTaskToBack(true); 
     } 


     @Override 
     public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) { 
      // TODO Auto-generated method stub 

     } 

     @Override 
     public void onStartTrackingTouch(SeekBar seekBar) { 
      // remove message Handler from updating progress bar 
      mHandler.removeCallbacks(mUpdateTimeTask); 
     } 

     @Override 
     public void onStopTrackingTouch(SeekBar seekBar) { 
      mHandler.removeCallbacks(mUpdateTimeTask); 
      int totalDuration = mp.getDuration(); 
      int currentPosition = utils.progressToTimer(seekBar.getProgress(), totalDuration); 

      // forward or backward to certain seconds 
      mp.seekTo(currentPosition); 

      // update timer progress again 
      updateProgressBar(); 
     } 

     @Override 
     public void onCompletion(MediaPlayer arg0) { 

      // check for repeat is ON or OFF 
      if (isRepeat) { 
       // repeat is on play same song again 
       playSong(mItems.get(currentSongIndex)); 
      } else if (isShuffle) { 
       // shuffle is on - play a random song 
       Random rand = new Random(); 
       currentSongIndex = rand.nextInt((mItems.size() - 1) - 0 + 1) + 0; 
       playSong(mItems.get(currentSongIndex)); 
      } else { 
       // no repeat or shuffle ON - play next song 
       if (currentSongIndex < (mItems.size() - 1)) { 
        playSong(mItems.get(currentSongIndex + 1)); 
        currentSongIndex = currentSongIndex + 1; 
       } else { 
        // play first song 
        playSong(mItems.get(0)); 
        currentSongIndex = 0; 
       } 
      } 
     } 

     // stop player when destroy 
     @Override 
     public void onDestroy() { 
      super.onDestroy(); 
      mp.release(); 
     } 

     @Override 
     protected void onResume() { 
      if (mp.isPlaying()) { 
       updateProgressBar(); 
       bt_play.setBackgroundResource(R.drawable.btn_pause); 
      } else { 
       bt_play.setBackgroundResource(R.drawable.btn_play); 
      } 
      if(!Tools.isAllPermissionGranted(this)){ 
       showDialogPermission(); 
      }else{ 
       if(db.getAllMusicFiles().size()==0){ 
        new loadFiles().execute(""); 
       } 
      } 

      super.onResume(); 
     } 

     private void showDialogPermission(){ 
      AlertDialog.Builder builder = new AlertDialog.Builder(this); 
      builder.setTitle(getString(R.string.dialog_title_permission)); 
      builder.setMessage(getString(R.string.dialog_content_permission)); 
      builder.setCancelable(false); 
      builder.setPositiveButton("OK", new DialogInterface.OnClickListener() { 
       @Override 
       public void onClick(DialogInterface dialogInterface, int i) { 
        dialogInterface.dismiss(); 
        Tools.goToPermissionSettingScreen(Player.this); 
       } 
      }); 
      builder.show(); 
     } 

    } 

} 

player_layout.xml

<?xml version="1.0" encoding="utf-8"?> 
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" 
    android:orientation="vertical" android:layout_width="match_parent" 
    android:layout_height="match_parent" 
    android:id="@+id/main_content"> 

    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 
     xmlns:app="http://schemas.android.com/apk/res-auto" 
     android:layout_width="match_parent" 
     android:layout_height="match_parent" 
     android:orientation="vertical"> 

     <TextView 
      android:id="@+id/tv_song_title" 
      android:layout_width="match_parent" 
      android:layout_height="wrap_content" 
      android:ellipsize="marquee" 
      android:marqueeRepeatLimit="marquee_forever" 
      android:maxLines="1" 
      android:singleLine="true" 
      android:text="Song Title" 
      android:background="@color/orange" 
      android:textAppearance="@style/TextAppearance.AppCompat.Title" 
      android:textColor="@color/white" /> 

     <LinearLayout 
      android:id="@+id/lyt_main" 
      android:layout_width="match_parent" 
      android:layout_height="wrap_content" 
      android:background="@color/orange" 
      android:orientation="vertical"> 

      <LinearLayout 
       android:layout_width="match_parent" 
       android:layout_height="wrap_content" 
       android:layout_marginBottom="5dp" 
       android:layout_marginTop="5dp" 
       android:gravity="center_horizontal" 
       android:orientation="horizontal" 
       android:paddingLeft="10dp" 
       android:paddingRight="10dp"> 

       <Button 
        android:id="@+id/btn_repeat" 
        android:layout_width="35dp" 
        android:layout_height="35dp" 
        android:layout_margin="3dp" 
        android:background="@drawable/btn_repeat" /> 

       <LinearLayout 
        android:layout_width="0dp" 
        android:layout_height="match_parent" 
        android:layout_weight="1" 
        android:gravity="center" 
        android:orientation="horizontal"> 

        <Button 
         android:id="@+id/bt_prev" 
         android:layout_width="35dp" 
         android:layout_height="35dp" 
         android:background="@drawable/btn_previous" /> 

        <Button 
         android:id="@+id/bt_play" 
         android:layout_width="35dp" 
         android:layout_height="35dp" 
         android:layout_marginLeft="30dp" 
         android:layout_marginRight="30dp" 
         android:background="@drawable/btn_play" /> 

        <Button 
         android:id="@+id/bt_next" 
         android:layout_width="35dp" 
         android:layout_height="35dp" 
         android:background="@drawable/btn_next" /> 
       </LinearLayout> 

       <Button 
        android:id="@+id/btn_shuffle" 
        android:layout_width="35dp" 
        android:layout_height="35dp" 
        android:layout_margin="3dp" 
        android:background="@drawable/btn_shuffle" /> 

      </LinearLayout> 

      <LinearLayout 
       android:layout_width="match_parent" 
       android:layout_height="wrap_content" 
       android:layout_marginBottom="10dp" 
       android:layout_marginLeft="20dp" 
       android:layout_marginRight="20dp" 
       android:layout_marginTop="10dp" 
       android:gravity="center_vertical" 
       android:orientation="horizontal"> 

       <TextView 
        android:id="@+id/tv_song_current_duration" 
        android:layout_width="wrap_content" 
        android:layout_height="wrap_content" 
        android:text="0.00" 
        android:textColor="@color/white" /> 

       <android.support.v7.widget.AppCompatSeekBar 
        android:id="@+id/seek_song_progressbar" 
        android:layout_width="match_parent" 
        android:layout_height="match_parent" 
        android:layout_weight="1" 
        android:progress="0" 
        android:theme="@style/SeekBarStyle" /> 

       <TextView 
        android:id="@+id/tv_song_total_duration" 
        android:layout_width="wrap_content" 
        android:layout_height="wrap_content" 
        android:text="0.00" 
        android:textColor="@color/white" /> 
      </LinearLayout> 

      <LinearLayout 
       android:layout_width="wrap_content" 
       android:layout_height="wrap_content" 
       android:layout_marginRight="20dp" 
       android:layout_gravity="right" 
       android:gravity="center_vertical" 
       android:orientation="vertical"> 

       <TextView 
        android:layout_width="match_parent" 
        android:layout_height="wrap_content" 
        android:text="SONG INFO HERE"/> 

      </LinearLayout> 

     </LinearLayout> 

     <RelativeLayout 
      android:layout_width="match_parent" 
      android:layout_height="match_parent"> 

      <LinearLayout 
       android:id="@+id/lyt_progress" 
       android:layout_width="wrap_content" 
       android:layout_height="wrap_content" 
       android:layout_centerHorizontal="true" 
       android:layout_centerVertical="true" 
       android:gravity="center" 
       android:orientation="vertical"> 

       <ProgressBar 
        android:id="@+id/progress_loadfiles" 
        style="?android:attr/progressBarStyleLarge" 
        android:layout_width="wrap_content" 
        android:layout_height="wrap_content" /> 

       <TextView 
        android:layout_width="wrap_content" 
        android:layout_height="wrap_content" 
        android:text="Scanning" /> 
      </LinearLayout> 

      <LinearLayout 
       android:id="@+id/lyt_list" 
       android:layout_width="match_parent" 
       android:layout_height="match_parent" 
       android:orientation="vertical"> 

       <ListView 
        android:id="@+id/list_main" 
        android:layout_width="fill_parent" 
        android:layout_height="0dp" 
        android:layout_weight="1" 
        android:divider="@android:color/transparent" 
        android:dividerHeight="0dp" 
        android:paddingTop="5dp" /> 

      </LinearLayout> 
     </RelativeLayout> 
    </LinearLayout> 
</RelativeLayout> 

Répondre

1

Je suis également en train de développer le même genre d'application, oui vous pouvez le faire en utilisant des fragments avec des onglets et en utilisant la classe de service pour jouer de la chanson en fr Agment via le serveur.

+0

Pouvez-vous nous montrer le code nécessaire? –