在片段类中实例化音乐播放器组件时出错

时间:2016-08-13 23:29:51

标签: android android-fragments tabs audio-player android-music-player

我正在创建一个使用Tabbed Fragments的音乐播放器应用。 Player组件(将文件列表和链接回放操作加载到按钮的方法)设置在PlayerFragment类中的嵌套Player类中。

我打算加载我的应用程序,第一个片段是播放器,其中会出现一个文件列表,一旦用户按下列表中的文件,它就会播放。

现在,我遇到的问题是我正在尝试创建一个Player实例,然后调用方法initializeAllComponents(),顾名思义,它将实例化Player类,允许Player出现在片段视图中,允许按钮使用各自的方法。

我已经四处寻找,但我找不到能够解决问题的答案。

当我打开应用程序时,对initializeAllComponents()的调用会导致应用程序立即关闭。

该应用目前基于许可证下的Lite Music API,但稍后会对其进行大量修改。这就是代码看起来如此相似的原因。现在我只想在开始重新处理按钮和MediaPlayer方法之前,正确加载Fragment并包含一个有效的音乐播放器。

MainActivity和TabFragment(本例中为FragmentPager类)类正常工作,因此我不会包含它们。它们允许应用程序显示标签视图,并在OnCreateView中不包含调用时加载片段,但是PlayerFragment会破坏应用程序,就像现在在OnCreateView方法中调用一样。

我也知道Player类在没有Fragment实现的Main Activity中设置时正常工作。所以它似乎必须调用onCreateView()中的player.initializeAllComponents()来打破一切,但我不知道为什么。

有没有办法调用initializeAllComponents()来正确地膨胀Fragment而不会出错?我只是没有正确地实例化Player子类吗?或者Player子类是否无法在Fragment中工作?

任何帮助都将不胜感激。

以下是代码:

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>

1 个答案:

答案 0 :(得分:1)

我也在尝试开发相同类型的应用程序,是的,您可以通过使用带有选项卡的片段并使用服务类通过服务器在片段中播放歌曲来实现。