【问题标题】:Error while Instantiating Music Player Components inside a Fragment Class在片段类中实例化音乐播放器组件时出错
【发布时间】:2016-08-13 23:29:50
【问题描述】:

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

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

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

我已经四处搜索,但没有找到解决问题的答案。

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

该应用目前基于 Lite Music API 并获得许可,但稍后会进行大量修改。这就是代码看起来如此相似的原因。现在我只希望片段能够正确加载并包含一个正常工作的音乐播放器,然后再开始修改按钮和 MediaPlayer 方法。

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

我还知道,当在没有 Fragment 实现的主 Activity 中设置 Player 类时,它可以正常工作。所以看来一定是 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>

【问题讨论】:

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


    【解决方案1】:

    我也在尝试开发相同类型的应用程序,是的,您可以通过使用带有标签的片段并使用服务类通过服务器在片段中播放歌曲来做到这一点。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多