单击android中的后退按钮时,MusicPlayer崩溃

时间:2017-08-26 08:22:32

标签: java android audio-player android-music-player

我制作了一个简单的音乐播放器,可以在后台播放一些歌曲。转到主屏幕并通过通知重新打开应用程序。我唯一的问题是,当音乐播放完成后,如果我在音乐播放器活动中按下后退按钮(转到父活动),我的应用程序崩溃了。如何解决此问题?

playmusic.java

@Override
public void onDestroy() {

    currentSongIndex = -1;
    mHandler.removeCallbacks(mUpdateTimeTask);
    Log.d("Player Service", "Player Service Stopped");
    if (mp != null) {
        if (mp.isPlaying()) {
            mp.stop();
        }
        mp.release();
    }

    if (phoneStateListener != null) {
        telephonyManager.listen(phoneStateListener,
                PhoneStateListener.LISTEN_NONE);
    }
    // --Unregister headsetReceiver
    unregisterReceiver(headsetReceiver);

    super.onDestroy();
}

playerservice

 @Override
protected void onDestroy() {
    // TODO Auto-generated method stub

    if (!PlayerService.mp.isPlaying()) {
        stopService(playerService);



    }
    super.onDestroy();
}
E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.example.kaveh.googleplay2, PID: 29453
java.lang.RuntimeException: Unable to start service com.example.kaveh.googleplay2.PlayerService@527b4da4 with null: java.lang.NullPointerException
    at android.app.ActivityThread.handleServiceArgs(ActivityThread.java:2705)
    at android.app.ActivityThread.access$2100(ActivityThread.java:135)
    at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1293)
    at android.os.Handler.dispatchMessage(Handler.java:102)
    at android.os.Looper.loop(Looper.java:136)
    at android.app.ActivityThread.main(ActivityThread.java:5001)
    at java.lang.reflect.Method.invokeNative(Native Method)
    at java.lang.reflect.Method.invoke(Method.java:515)
    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:785)
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:601)
    at dalvik.system.NativeStart.main(Native Method)
Caused by: java.lang.NullPointerException
    at com.example.kaveh.googleplay2.PlayerService.initUI(PlayerService.java:311)
    at com.example.kaveh.googleplay2.PlayerService.onStartCommand(PlayerService.java:142)
    at android.app.ActivityThread.handleServiceArgs(ActivityThread.java:2688)
    at android.app.ActivityThread.access$2100(ActivityThread.java:135) 
    at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1293) 
    at android.os.Handler.dispatchMessage(Handler.java:102) 
    at android.os.Looper.loop(Looper.java:136) 
    at android.app.ActivityThread.main(ActivityThread.java:5001) 
    at java.lang.reflect.Method.invokeNative(Native Method) 
    at java.lang.reflect.Method.invoke(Method.java:515) 
    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:785) 
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:601) 
    at dalvik.system.NativeStart.main(Native Method) 
08-25 13:37:06.274 543-29470/system_process D/dalvikvm: GC_FOR_ALLOC freed 1760K, 28% free 10140K/14056K, paused 10ms, total 10ms
08-25 13:37:07.326 543-590/system_process D/MobileDataStateTracker: default: setPolicyDataEnable(enabled=true)
08-25 13:37:07.694 29453-29453/com.example.kaveh.googleplay2 I/Process: Sending signal. PID: 29453 SIG: 9
08-25 13:37:07.694 543-590/system_process D/MobileDataStateTracker: default: setPolicyDataEnable(enabled=true)

修改 PlayerService.java

public class PlayerService extends Service implements
    OnClickListener, MediaPlayer.OnInfoListener,
    SeekBar.OnSeekBarChangeListener, MediaPlayer.OnBufferingUpdateListener
    , OnPreparedListener, MediaPlayer.OnErrorListener, MediaPlayer.OnSeekCompleteListener
    , MediaPlayer.OnCompletionListener {

private WeakReference<ImageView> btnPlay, btnForward, btnBackward;
private WeakReference<SeekBar> songProgressBar;
private WeakReference<TextView> songCurrentDurationLabel;
private WeakReference<TextView> songTotalDurationLabel;
public static MediaPlayer mp;
   // Handler to update UI timer, progress bar etc,.
static Handler mHandler = new Handler();
   // private SongsManager songManager;
private Utility utils;
private int seekForwardTime = 5000; // 5000 milliseconds
private int seekBackwardTime = 5000; // 5000 milliseconds
public static int currentSongIndex = -1;
public static int songindexForPause = 0;
   // Set up broadcast identifier and intent
public static final String BROADCAST_BUFFER = "com.9android.net.broadcastbuffer";
Intent bufferIntent;

private boolean isPausedInCall = false;
private PhoneStateListener phoneStateListener;
private TelephonyManager telephonyManager;
private static final String TAG = "TELEPHONESERVICE";


Notification status;
private final String LOG_TAG = "NotificationService";


         /**
           * 29 * The BroadCast Receiver is used to listen system broadcast intent when
           * 30 * headsets gets unplugged. If headset gets unplugged, stop music and
          * 31 * service.
            * 32
            */
private int headsetSwitch = 1;
private BroadcastReceiver headsetReceiver = new BroadcastReceiver() {
    private boolean headsetConnected = false;

    @Override
    public void onReceive(Context context, Intent intent) {
        // TODO Auto-generated method stub
        // Log.v(TAG, "ACTION_HEADSET_PLUG Intent received");
        if (intent.hasExtra("state")) {
            if (headsetConnected && intent.getIntExtra("state", 0) == 0) {
                headsetConnected = false;
                headsetSwitch = 0;
            } else if (!headsetConnected
                    && intent.getIntExtra("state", 0) == 1) {
                headsetConnected = true;
                headsetSwitch = 1;
            }

        }
        switch (headsetSwitch) {
            case (0):
                headsetDisconnected();
                break;
            case (1):
                break;
        }
    }
};

@Override
public void onCreate() {
    // TODO Auto-generated method stub
    mp = new MediaPlayer();
    mp.setOnCompletionListener(this);
    mp.setOnErrorListener(this);
    mp.setOnPreparedListener(this);
    mp.setOnBufferingUpdateListener(this);
    mp.setOnSeekCompleteListener(this);
    mp.setOnInfoListener(this);
    mp.reset();
    mp.setAudioStreamType(AudioManager.STREAM_MUSIC);//
    utils = new Utility();
    // Instantiate bufferIntent to communicate with Activity for progress
    // dialogue
    bufferIntent = new Intent(BROADCAST_BUFFER);
    // Register headset receiver
    registerReceiver(headsetReceiver, new IntentFilter(
            Intent.ACTION_HEADSET_PLUG));
    super.onCreate();

}


@Override
public int onStartCommand(Intent intent, int flags, int startId) {
    initUI();
    Bundle extera = intent.getExtras();
    if (extera != null) {
        String songLink = extera.getString("songLink");
        Log.d("SongLink", "SongLink = " + songLink);
        if (songLink.compareTo("") != 0)
            playSong(songLink);


        telephonyManager = (TelephonyManager)   getSystemService(Context.TELEPHONY_SERVICE);
        phoneStateListener = new PhoneStateListener() {
            @Override
            public void onCallStateChanged(int state, String incomingNumber) {

                Log.v(TAG, "Starting CallStateChange");
                switch (state) {
                    case TelephonyManager.CALL_STATE_OFFHOOK:
                    case TelephonyManager.CALL_STATE_RINGING:// incoming call
                        if (mp != null) {
                            pauseMedia();
                            isPausedInCall = true;
                        }
                        break;
                    case TelephonyManager.CALL_STATE_IDLE:// call finish

                        if (mp != null) {
                            if (isPausedInCall) {
                                isPausedInCall = false;
                                playMedia();
                            }
                        }
                        break;
                }
            }
        };

        telephonyManager.listen(phoneStateListener,
                PhoneStateListener.LISTEN_CALL_STATE);


        if (intent.getAction().equals(Constants.ACTION.STARTFOREGROUND_ACTION)) {
            showNotification();
            Toast.makeText(this, "Service Started", Toast.LENGTH_SHORT).show();

        }
    } else {

        if (intent.getAction().equals(Constants.ACTION.PREV_ACTION)) {
            Toast.makeText(this, "Clicked Previous", Toast.LENGTH_SHORT).show();
            Log.i(LOG_TAG, "Clicked Previous");
        } else if (intent.getAction().equals(Constants.ACTION.PLAY_ACTION)) {
            Toast.makeText(this, "Clicked Play", Toast.LENGTH_SHORT).show();
            Log.i(LOG_TAG, "Clicked Play");
            if (mp.isPlaying()) {
                if (mp != null) {
                    mp.pause();



                    btnPlay.get().setImageResource(R.drawable.play);
                    Log.d("Player Service", "Pause");

                }
            } else {
                // Resume song
                if (mp != null) {
                    mp.start();
                    RemoteViews views = new RemoteViews(getPackageName(),
                            R.layout.status_bar);
                    RemoteViews bigViews = new RemoteViews(getPackageName(),
                            R.layout.status_bar_expanded);

                    views.setImageViewResource(R.id.status_bar_play,
                            R.drawable.apollo_holo_dark_play);
                    bigViews.setImageViewResource(R.id.status_bar_play,
                            R.drawable.apollo_holo_dark_play);


                    // Changing button image to pause button
                    btnPlay.get().setImageResource(R.drawable.pause);
                }
            }

        }
            //            else if (intent.getAction().equals(Constants.ACTION.NEXT_ACTION)) {
            //                Toast.makeText(this, "Clicked Next", Toast.LENGTH_SHORT).show();
             //                Log.i(LOG_TAG, "Clicked Next");
        //            }
        else if (intent.getAction().equals(
                Constants.ACTION.STOPFOREGROUND_ACTION)) {
            Log.i(LOG_TAG, "Received Stop Foreground Intent");
            Toast.makeText(this, "Service Stoped", Toast.LENGTH_SHORT).show();
            stopForeground(true);
            stopSelf();
        }

    }       String songLink = intent.getExtras().getString("songLink");
  Log.d("SongLink", "SongLink = " + songLink);
    if (songLink.compareTo("") != 0)
        playSong(songLink);
    // Manage incoming phone calls during playback. Pause mp on incoming,
    // resume on hangup.
    // Get the telephony manager
    telephonyManager = (TelephonyManager) getSystemService(Context.TELEPHONY_SERVICE);
    phoneStateListener = new PhoneStateListener() {
        @Override
        public void onCallStateChanged(int state, String incomingNumber) {
            // String stateString = "N/A";
            Log.v(TAG, "Starting CallStateChange");
            switch (state) {
                case TelephonyManager.CALL_STATE_OFFHOOK:
                case TelephonyManager.CALL_STATE_RINGING:// incoming call
                    if (mp != null) {
                       pauseMedia();
                       isPausedInCall = true;
                   }                       break;
               case TelephonyManager.CALL_STATE_IDLE:// call finish
                   // Phone idle. Start playing.
                   if (mp != null) {
                       if (isPausedInCall) {
                            isPausedInCall = false;
                            playMedia();
                        }
                    }
                    break;
            }
        }
    };
    // Register the listener with the telephony manager
    telephonyManager.listen(phoneStateListener,
            PhoneStateListener.LISTEN_CALL_STATE);

    super.onStart(intent, startId);
    return START_STICKY;
}

          /**
 * 131 * @author 9Android.net
 * 132
 */


private void initUI() {
    songCurrentDurationLabel = new WeakReference(
            PlayMusic.songCurrentDurationLabel);
    songTotalDurationLabel = new WeakReference(
            PlayMusic.songTotalDurationLabel);

    btnPlay = new WeakReference(PlayMusic.btnPlay);
    btnForward = new WeakReference(PlayMusic.btnForward);
    btnBackward = new WeakReference(PlayMusic.btnBackward);


    btnPlay.get().setOnClickListener(this);
    btnForward.get().setOnClickListener(this);
    btnBackward.get().setOnClickListener(this);

    songProgressBar = new WeakReference(
            PlayMusic.songProgressBar);
    songProgressBar.get().setOnSeekBarChangeListener(this);
}

          // Send a message to Activity that audio is being prepared and buffering
        // started.
private void sendBufferingBroadcast() {
    // Log.v(TAG, "BufferStartedSent");
    bufferIntent.putExtra("buffering", "1");
    sendBroadcast(bufferIntent);
}

             // Send a message to Activity that audio is prepared and ready to start
              // playing.
private void sendBufferCompleteBroadcast() {
    bufferIntent.putExtra("buffering", "0");
    sendBroadcast(bufferIntent);
}

// -------------------------------------------------------------------------//
@Override
public void onClick(View v) {
    // TODO Auto-generated method stub
    switch (v.getId()) {
        case R.id.btn_play:
            if (mp.isPlaying()) {
                if (mp != null) {
                    mp.pause();
                    // Changing button image to play button

                    btnPlay.get().setImageResource(R.drawable.play);
                    Log.d("Player Service", "Pause");

                }
            } else {
                // Resume song
                if (mp != null) {
                    mp.start();
                    // Changing button image to pause button
                    btnPlay.get().setImageResource(R.drawable.pause);
                }
            }
            break;

        case R.id.btn_forward:

            // get current song position
            int currentPosition = mp.getCurrentPosition();
            // check if seekForward time is lesser than song duration
            if (currentPosition + seekForwardTime <= mp.getDuration()) { // forward song mp.seekTo(currentPosition + seekForwardTime); } else { // forward to end position mp.seekTo(mp.getDuration()); } break; case R.id.btn_backward: // get current song position int currentPosition2 = mp.getCurrentPosition(); // check if seekBackward time is greater than 0 sec if (currentPosition2 - seekBackwardTime >= 0) {
                // forward song
                mp.seekTo(currentPosition + seekBackwardTime);
            } else {
                // backward to starting position
                mp.seekTo(0);
            }
            break;

    }
}

// -------------------------------------------------------------//
public void playSong(String songPath) {
    mHandler.removeCallbacks(mUpdateTimeTask);
    mp.reset();
    if (!mp.isPlaying()) {
        try {
            mp.setDataSource(songPath);
            // Send message to Activity to display progress dialogue
            sendBufferingBroadcast();
            mp.prepareAsync();
            // Changing Button Image to pause image
            btnPlay.get().setImageResource(R.drawable.pause);
            // set Progress bar values
            songProgressBar.get().setProgress(0);
            songProgressBar.get().setMax(100);
        } catch (IllegalArgumentException e) {
            e.printStackTrace();
        } catch (IllegalStateException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

}

// Called when the media file is ready for playback.--------------------//
public void onPrepared(MediaPlayer mp) {
    // Send a message to activity to end progress dialogue
    sendBufferCompleteBroadcast();
    playMedia();
}

public void playMedia() {
    if (!mp.isPlaying()) {
        mp.start();
        updateProgressBar();
    }
}

// Add for Telephony Manager
public void pauseMedia() {
    // Log.v(TAG, "Pause Media");
    if (mp.isPlaying()) {
        mp.pause();
    }

}

public void stopMedia() {
    if (mp.isPlaying()) {
        mp.stop();
    }
}

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

            /**
            * 271 * Background Runnable thread
           * 272 *
            */
private Runnable mUpdateTimeTask = new Runnable() {
    public void run() {
        long totalDuration = 0;
        try {
            totalDuration = mp.getDuration();
        } catch (IllegalStateException e) {
            e.printStackTrace();
        }
        long currentDuration = 0;
        try {
            currentDuration = mp.getCurrentPosition();
        } catch (IllegalStateException e) {
            e.printStackTrace();
        }

        songTotalDurationLabel.get().setText(
                 "" + utils.milliSecondsToTimer(totalDuration));

        songCurrentDurationLabel.get().setText(
                "" + utils.milliSecondsToTimer(currentDuration));

        // Updating progress bar
        int progress = (int) (utils.getProgressPercentage(currentDuration,
                totalDuration));
        // Log.d("Progress", ""+progress);
        songProgressBar.get().setProgress(progress);
        // Running this thread after 100 milliseconds
        mHandler.postDelayed(this, 100);

    }
};

         /**
           * 306 * onProgressChanged
            * 307
            */
@Override
public void onProgressChanged(SeekBar seekBar, int progress,
                              boolean fromTouch) {
}

         /**
           * 314 * When user starts moving the progress handler
           * 315 *
          */
@Override
public void onStartTrackingTouch(SeekBar seekBar) {
    // remove message Handler from updating progress bar
    mHandler.removeCallbacks(mUpdateTimeTask);
}

          /**
        * 323 * When user stops moving the progress hanlder
        * 324 *
        */
@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();
}

       /**
          * 339 * On Song Playing completed if repeat is ON play same song again if shuffle
       * 340 * is ON play random song
       * 341 *
         */
@Override
public void onCompletion(MediaPlayer arg0) {
    mp.stop();
    mp.release();
}

@Override
public void onDestroy() {

    currentSongIndex = -1;
    mHandler.removeCallbacks(mUpdateTimeTask);
    Log.d("Player Service", "Player Service Stopped");
    if (mp != null) {
        if (mp.isPlaying()) {
            mp.stop();
        }
        mp.release();
    }

    if (phoneStateListener != null) {
        telephonyManager.listen(phoneStateListener,
                PhoneStateListener.LISTEN_NONE);
    }
    // --Unregister headsetReceiver
    unregisterReceiver(headsetReceiver);

    super.onDestroy();
}

@Override
public boolean onInfo(MediaPlayer mp, int what, int extra) {
    return false;
}

@Override
public void onSeekComplete(MediaPlayer mp) {
}

@Override
public void onBufferingUpdate(MediaPlayer mp, int percent) {
}

@Override
public boolean onError(MediaPlayer mp, int what, int extra) {
    return false;
}

     private void headsetDisconnected() {
    pauseMedia();
}

      @Override
        public IBinder onBind(Intent intent) {
    // TODO Auto-generated method stub
    return null;
}


        private void showNotification() {
          // Using RemoteViews to bind custom layouts into Notification
    RemoteViews views = new RemoteViews(getPackageName(),
            R.layout.status_bar);
    RemoteViews bigViews = new RemoteViews(getPackageName(),
            R.layout.status_bar_expanded);

          // showing default album image
    views.setViewVisibility(R.id.status_bar_icon, View.VISIBLE);
    views.setViewVisibility(R.id.status_bar_album_art, View.GONE);
    bigViews.setImageViewBitmap(R.id.status_bar_album_art,
            Constants.getDefaultAlbumArt(this));

    Intent notificationIntent = new Intent(this, PlayMusic.class);
    notificationIntent.setAction(Constants.ACTION.MAIN_ACTION);
    notificationIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK
            | Intent.FLAG_ACTIVITY_CLEAR_TASK);
    PendingIntent pendingIntent = PendingIntent.getActivity(this, 0,
            notificationIntent, 0);

                //        Intent previousIntent = new Intent(this, PlayerService.class);
      //        previousIntent.setAction(Constants.ACTION.PREV_ACTION);
        //        PendingIntent ppreviousIntent = PendingIntent.getService(this, 0,
        //                previousIntent, 0);

    Intent playIntent = new Intent(this, PlayerService.class);
    playIntent.setAction(Constants.ACTION.PLAY_ACTION);
    PendingIntent pplayIntent = PendingIntent.getService(this, 0,
            playIntent, 0);

    Intent nextIntent = new Intent(this, PlayerService.class);
    nextIntent.setAction(Constants.ACTION.NEXT_ACTION);
    PendingIntent pnextIntent = PendingIntent.getService(this, 0,
            nextIntent, 0);

    Intent closeIntent = new Intent(this, PlayerService.class);
    closeIntent.setAction(Constants.ACTION.STOPFOREGROUND_ACTION);
    PendingIntent pcloseIntent = PendingIntent.getService(this, 0,
            closeIntent, 0);

    views.setOnClickPendingIntent(R.id.status_bar_play, pplayIntent);
    bigViews.setOnClickPendingIntent(R.id.status_bar_play, pplayIntent);

    views.setOnClickPendingIntent(R.id.status_bar_next, pnextIntent);
    bigViews.setOnClickPendingIntent(R.id.status_bar_next, pnextIntent);

       //        views.setOnClickPendingIntent(R.id.status_bar_prev, ppreviousIntent);
       //        bigViews.setOnClickPendingIntent(R.id.status_bar_prev, ppreviousIntent);

    views.setOnClickPendingIntent(R.id.status_bar_collapse, pcloseIntent);
    bigViews.setOnClickPendingIntent(R.id.status_bar_collapse, pcloseIntent);

    views.setImageViewResource(R.id.status_bar_play,
            R.drawable.apollo_holo_dark_pause);
    bigViews.setImageViewResource(R.id.status_bar_play,
            R.drawable.apollo_holo_dark_pause);


         //        views.setTextViewText(R.id.status_bar_artist_name, "Artist Name");
        //        bigViews.setTextViewText(R.id.status_bar_artist_name, "Artist Name");
            //
             //        bigViews.setTextViewText(R.id.status_bar_album_name, "Album Name");

    status = new Notification.Builder(this).build();
    status.contentView = views;
    status.bigContentView = bigViews;
    status.flags = Notification.FLAG_ONGOING_EVENT;
    status.icon = R.drawable.ic_launcher;
    status.contentIntent = pendingIntent;
    startForeground(Constants.NOTIFICATION_ID.FOREGROUND_SERVICE, status);
}


 }

0 个答案:

没有答案