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>
Pouvez-vous nous montrer le code nécessaire? –