2016-10-12 13 views
1

私は曲の再生を制御する音楽プレーヤーのアクティビティを持っています。私はオーディオフォーカスの管理についてのドキュメントを読んで、btnPlayplaySongの機能で実装しました。ここに私のコードは次のとおりです。オーディオフォーカスの変更が機能していません

public class MusicPlayerActivity extends Activity implements MediaPlayer.OnCompletionListener, SeekBar.OnSeekBarChangeListener { 

    private boolean notRunning = false; 
    private boolean wasRunning = false; 

    private BroadcastReceiver receiver; 
    private static final int NOTIFICATION_ID = 69; 
    private static final String TAG = "museNotification"; 


    private ImageButton btnPlay; 
    private ImageButton btnForward; 
    private ImageButton btnBackward; 
    private ImageButton btnNext; 
    private ImageButton btnPrevious; 
    private ImageButton btnPlaylist; 
    private ImageButton btnRepeat; 
    private ImageButton btnShuffle; 
    private SeekBar songProgressBar; 
    private TextView songTitleLabel; 
    private TextView songCurrentDurationLabel; 
    private TextView songTotalDurationLabel; 
    // Media Player 
    private static MediaPlayer mp; 
    // Handler to update UI timer, progress bar etc,. 
    private Handler mHandler = new Handler();; 
    private SongsManager songManager; 
    private Utilities utils; 
    private int seekForwardTime = 5000; // 5000 milliseconds 
    private int seekBackwardTime = 5000; // 5000 milliseconds 
    private int currentSongIndex = 6; 
    private boolean isShuffle = false; 
    private boolean isRepeat = false; 
    private ArrayList<HashMap<String, String>> songsList = new ArrayList<HashMap<String, String>>(); 
    private ViewPager viewPager; 
    private int remember = 223; 
    public static String songName="Choose a song"; 


    @Override 
    public void onResume() { 
     super.onResume(); 
     NotificationManager notificationManager = (NotificationManager)getSystemService(Context.NOTIFICATION_SERVICE); 
     notificationManager.cancelAll(); 


     if (mp.isPlaying()) { 
      if (mp != null) { 
       btnPlay.setImageResource(R.drawable.btn_pause); 
      } 
      else { 
       if (mp != null) 
        btnPlay.setImageResource(R.drawable.btn_play);} 
     } 
     else 
      btnPlay.setImageResource(R.drawable.btn_play); 
    } 

    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.activity_music_player); 

     // All player buttons 
     btnPlay = (ImageButton) findViewById(R.id.btnPlay); 
     // btnForward = (ImageButton) findViewById(R.id.btnForward); 
     //btnBackward = (ImageButton) findViewById(R.id.btnBackward); 
     btnNext = (ImageButton) findViewById(R.id.btnNext); 
     btnPrevious = (ImageButton) findViewById(R.id.btnPrevious); 
     btnPlaylist = (ImageButton) findViewById(R.id.btnPlaylist); 
     btnRepeat = (ImageButton) findViewById(R.id.btnRepeat); 
     btnShuffle = (ImageButton) findViewById(R.id.btnShuffle); 
     songProgressBar = (SeekBar) findViewById(R.id.songProgressBar); 
     songTitleLabel = (TextView) findViewById(R.id.songTitle); 
     songCurrentDurationLabel = (TextView) findViewById(R.id.songCurrentDurationLabel); 
     songTotalDurationLabel = (TextView) findViewById(R.id.songTotalDurationLabel); 
     viewPager = (ViewPager)findViewById(R.id.viewPager); 
     // Mediaplayer 
     mp = new MediaPlayer(); 
     songManager = new SongsManager(); 
     utils = new Utilities(); 

     // Listeners 
     songProgressBar.setOnSeekBarChangeListener(this); // Important 
     mp.setOnCompletionListener(this); // Important 

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

     /** 
     * Play button click event 
     * plays a song and changes button to pause image 
     * pauses a song and changes button to play image 
     * */ 

     btnPlay.setOnClickListener(new View.OnClickListener() { 

      @Override 
      public void onClick(View arg0) { 


       // if (result == AudioManager.AUDIOFOCUS_REQUEST_GRANTED){ 
       // check for already playing 
       if (mp.isPlaying()) { 
        if (mp != null) { 
         mp.pause(); 
         // Changing button image to play button 
         btnPlay.setImageResource(R.drawable.btn_play); 

        } 
       } 
       else { 

        //RISH 

        Context mContext = getApplicationContext(); 
        AudioManager am = (AudioManager) mContext.getSystemService(Context.AUDIO_SERVICE); 

        AudioManager.OnAudioFocusChangeListener afChangeListener = new AudioManager.OnAudioFocusChangeListener() { 
         public void onAudioFocusChange(int focusChange) { 
          if (focusChange == AudioManager.AUDIOFOCUS_LOSS) { 
           notRunning = true; 
           mp.pause(); 
           length = mp.getCurrentPosition(); //lol 
          } 
         } 
        }; 

        // Request audio focus for playback 
        int result = am.requestAudioFocus(afChangeListener, 
          // Use the music stream. 
          AudioManager.STREAM_MUSIC, 
          // Request permanent focus. 
          AudioManager.AUDIOFOCUS_GAIN_TRANSIENT_EXCLUSIVE); 
        //RISH 
        // Resume song 
        if (mp != null) { 
         mp.start(); 
         // Changing button image to pause button 
         btnPlay.setImageResource(R.drawable.btn_pause); 
        } 
       } 
       //} 
      } 
     }); 

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

      @Override 
      public void onClick(View arg0) { 

       if(isShuffle){ 
        // shuffle is on - play a random song 
        Random rand = new Random(); 
        remember = currentSongIndex; 
        currentSongIndex = rand.nextInt((songsList.size() - 1) - 0 + 1) + 0; 
        playSong(currentSongIndex); 
       } else{ 
        // no repeat or shuffle ON - play next song 
        if(currentSongIndex < (songsList.size() - 1)){ 
         playSong(currentSongIndex + 1); 
         currentSongIndex = currentSongIndex + 1; 
        }else{ 
         // play first song 
         playSong(0); 
         currentSongIndex = 0; 
        } 
       } 

      } 
     }); 

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

      @Override 
      public void onClick(View arg0) { 
       if(isShuffle){ 
        if(remember!=223) 
        {currentSongIndex = remember; 
         remember=223;} 
        else 
        {Random rand = new Random(); 
         currentSongIndex = rand.nextInt((songsList.size() - 1) - 0 + 1) + 0; 
         playSong(currentSongIndex);} 
        playSong(currentSongIndex); 
       } 

       else { 
        if (currentSongIndex > 0) { 
         playSong(
           currentSongIndex - 1); 
         currentSongIndex = currentSongIndex - 1; 
        } else { 
         // play last song 
         playSong(songsList.size() - 1); 
         currentSongIndex = songsList.size() - 1; 
        } 

       } 
      } 
     }); 

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

      @Override 
      public void onClick(View arg0) { 
       if(isRepeat){ 
        isRepeat = false; 
        Toast.makeText(getApplicationContext(), "Repeat Turned OFF", Toast.LENGTH_SHORT).show(); 
        btnRepeat.setImageResource(R.drawable.btn_repeat); 
       }else{ 
        // make repeat to true 
        isRepeat = true; 
        Toast.makeText(getApplicationContext(), "Single Repeat Turned ON", Toast.LENGTH_SHORT).show(); 
        // make shuffle to false 
        isShuffle = false; 
        btnRepeat.setImageResource(R.drawable.btn_repeat_focused); 
        btnShuffle.setImageResource(R.drawable.btn_shuffle); 
       } 
      } 
     }); 

     /** 
     * Button Click event for Shuffle button 
     * Enables shuffle flag to true 
     * */ 
     btnShuffle.setOnClickListener(new View.OnClickListener() { 

      @Override 
      public void onClick(View arg0) { 
       if(isShuffle){ 
        isShuffle = false; 
        Toast.makeText(getApplicationContext(), "Shuffle is OFF", Toast.LENGTH_SHORT).show(); 
        btnShuffle.setImageResource(R.drawable.btn_shuffle); 
       }else{ 
        // make repeat to true 
        isShuffle= true; 
        Toast.makeText(getApplicationContext(), "Shuffle is ON", Toast.LENGTH_SHORT).show(); 
        // make shuffle to false 
        isRepeat = false; 
        btnShuffle.setImageResource(R.drawable.btn_shuffle_focused); 
        btnRepeat.setImageResource(R.drawable.btn_repeat); 
       } 
      } 
     }); 

     /** 
     * Button Click event for Play list click event 
     * Launches list activity which displays list of songs 
     * */ 
     btnPlaylist.setOnClickListener(new View.OnClickListener() { 

      @Override 
      public void onClick(View arg0) { 

       Intent i = new Intent(getApplicationContext(), MainActivity.class); 
       startActivity(i); 

       //viewPager.setCurrentItem(0); 
      } 
     }); 


     Bundle extras = getIntent().getExtras(); 
     if(extras!=null){ 
      mp.reset(); 
      currentSongIndex = extras.getInt("songPath"); 
      // play selected song 
      if(mp != null) 
       if(mp.isPlaying()) 
       { 
        mp.prepareAsync(); 
        mp.start(); 
        mp.seekTo(0); 
        // start your new song 
       }else{ 
        playSong(currentSongIndex); 
        // start your new song 
       } 
     } 

    } 
    /** 
    * Function to play a song 
    * */ 

    int length; 

    public void playSong(int songIndex){ 


     notRunning=false; 
     //Rish -- THIS BLOCK STOPS MUSIC IF ANOTHER APP GETS THE FOCUS OF MEDIAPLAYER 

     Context mContext = getApplicationContext(); 
     AudioManager am = (AudioManager)mContext.getSystemService(Context.AUDIO_SERVICE); 

     AudioManager.OnAudioFocusChangeListener afChangeListener = new AudioManager.OnAudioFocusChangeListener() { 
      public void onAudioFocusChange(int focusChange) { 
       if (focusChange == AudioManager.AUDIOFOCUS_LOSS_TRANSIENT){ 
        btnPlay.setImageResource(R.drawable.btn_play); 
        notRunning=true; 
        mp.pause(); 
        length = mp.getCurrentPosition(); //lol 
       } else if (focusChange == AudioManager.AUDIOFOCUS_GAIN) { 
        notRunning=false; 
        mp.seekTo(length);//lol 
        mp.start(); 

       } else if (focusChange == AudioManager.AUDIOFOCUS_LOSS) { 
        mp.pause(); 
        notRunning=true; 
        length = mp.getCurrentPosition(); //lol 
       } 
      } 
     }; 

     // Request audio focus for playback 
     int result = am.requestAudioFocus(afChangeListener, 
       // Use the music stream. 
       AudioManager.STREAM_MUSIC, 
       // Request permanent focus. 
       AudioManager.AUDIOFOCUS_GAIN); 

     if (result == AudioManager.AUDIOFOCUS_REQUEST_GRANTED) { 

      // Play song 
      try { 
       mp.reset(); 
       mp.setDataSource(songsList.get(songIndex).get("songPath")); 
       mp.prepare(); 
       mp.start(); 
       // Displaying Song title 
       String songTitle = songsList.get(songIndex).get("songTitle"); 
       songTitleLabel.setText(songTitle); 
       // setNotification(songTitle); 
       songName =songTitle; 
       // Changing Button Image to pause image 
       btnPlay.setImageResource(R.drawable.btn_pause); 

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

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

     //Setting miniPlayer that is displayed in the bottom of main activity 

     Intent i = new Intent(getApplicationContext(),MainActivity.class); 
     i.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK| Intent.FLAG_ACTIVITY_SINGLE_TOP); 
     i.putExtra("songTitle",songName); 
     i.setAction("dummy3"); 

     //Setting miniPlayer that is displayed in the bottom of main activity 


    } 



    //Rish 

    /** 
    * Update timer on seekbar 
    * */ 

    public void updateProgressBar() { 
     mHandler.postDelayed(mUpdateTimeTask, 100); 
    } 

    /** 
    * Background Runnable thread 
    * */ 
    private Runnable mUpdateTimeTask = new Runnable() { 
     public void run() { 
      if((mp != null)) { //Attempting to prevent app crash on swipe 
       long totalDuration = mp.getDuration(); 
       long currentDuration = mp.getCurrentPosition(); 

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

       // Updating progress bar 
       int progress = (int) (utils.getProgressPercentage(currentDuration, totalDuration)); 
       //Log.d("Progress", ""+progress); 
       songProgressBar.setProgress(progress); 

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

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

    } 

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

    /** 
    * When user stops moving the progress hanlder 
    * */ 
    @Override 
    public void onStopTrackingTouch(SeekBar seekBar) { 
     // mHandler.removeCallbacksAndMessages(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(); 
    } 

    /** 
    * On Song Playing completed 
    * if repeat is ON play same song again 
    * if shuffle is ON play random song 
    * */ 
    @Override 
    public void onCompletion(MediaPlayer arg0) { 

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


    /* 
     //The method below minimizes the app if Back key is pressed ; i.e same as the method below 
    public boolean onKeyDown(int keyCode, KeyEvent event) 
    { 
     setNotification(songName);//Notification start 
     Intent i = new Intent(getApplicationContext(), MainActivity.class); 
     startActivity(i); 
     return super.onKeyDown(keyCode, event); 
    } 

    */ 



    //Above method works same as this 
    @Override 
    public void onBackPressed(){ 
     Intent i = new Intent(getApplicationContext(), MainActivity.class); 
     startActivity(i); 
     //super.onBackPressed(); 
    } 


    @Override 
    public void onPause(){ 
     setNotification(songName); 
     startService(new Intent(this, MyService.class)); //trying to cancel notification on app swipe 
     super.onPause(); 
    } 


    @Override 
    public void onDestroy(){ 
     if (receiver != null) { 
      unregisterReceiver(receiver); 
      receiver = null; 
     } 
     super.onDestroy(); 

     mp.release(); 
    } 

    //NOTIFICATION START 
    static @SuppressWarnings("deprecation") 
    Notification notification = new Notification(R.drawable.ic_launcher, null, System.currentTimeMillis()); 

    @SuppressLint("NewApi") 
    public void setNotification(String songName) { 
     String ns = Context.NOTIFICATION_SERVICE; 
     NotificationManager notificationManager = (NotificationManager)getSystemService(ns); 


     RemoteViews notificationView = new RemoteViews(getPackageName(), R.layout.notification_mediacontroller); 
     notificationView.setTextViewText(R.id.textView1, songName); 


     Notification.Builder mNotifyBuilder = new Notification.Builder(this); 
     notification = mNotifyBuilder.setContentTitle("some string") 
       .setContentText("Slide down on note to expand") 
       .setSmallIcon(R.drawable.ic_launcher) 
//    .setAutoCancel(true) 
       // .setLargeIcon() 
       .build(); 

     notification.contentView = notificationView; 

     //the intent that is started when the notification is clicked (works) 
     Intent notificationIntent = new Intent(this, MusicPlayerActivity.class); 
     //set some dummy action on the Intent, otherwise extras are dropped And cause problems like unnecessary new instance of activity 
     notificationIntent.setAction("dummy"); 
     notificationIntent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOP); 
     PendingIntent pendingNotificationIntent = PendingIntent.getActivity(this, 0, notificationIntent, PendingIntent.FLAG_ONE_SHOT); 


     notification.contentView = notificationView; 
     notification.contentIntent = pendingNotificationIntent; 

     notification.flags |= Notification.FLAG_NO_CLEAR; 
     notification.flags |= Notification.PRIORITY_MAX; 
     notification.flags |= Notification.FLAG_ONGOING_EVENT;//Dont know why using this flag. 
     notification.flags |= Notification.FLAG_AUTO_CANCEL; 

     //this is the intent that is supposed to be called when the button is clicked 
     Intent switchIntent = new Intent("com.dmmet.musicplayer.ACTION_PLAY"); 
     PendingIntent pendingSwitchIntent = PendingIntent.getBroadcast(this, 0, switchIntent, PendingIntent.FLAG_UPDATE_CURRENT); 

     notificationView.setOnClickPendingIntent(R.id.btnPlay2, pendingSwitchIntent); 
     notificationManager.notify(TAG,NOTIFICATION_ID, notification); 

     Intent closeIntent = new Intent("com.dmmet.musicplayer.ACTION_CLOSE"); 
     PendingIntent pendingCloseIntent = PendingIntent.getBroadcast(this, 0, closeIntent, 0); 

     notificationView.setOnClickPendingIntent(R.id.btnClose, pendingCloseIntent); 
     notificationManager.notify(TAG,NOTIFICATION_ID, notification); 

     Intent nextIntent = new Intent("com.dmmet.musicplayer.ACTION_NEXT"); 
     PendingIntent pendingNextIntent = PendingIntent.getBroadcast(this, 0, nextIntent, 0); 

     notificationView.setOnClickPendingIntent(R.id.btnNext, pendingNextIntent); 
     notificationManager.notify(TAG,NOTIFICATION_ID, notification); 

     Intent previousIntent = new Intent("com.dmmet.musicplayer.ACTION_PREVIOUS"); 
     PendingIntent pendingPreviousIntent = PendingIntent.getBroadcast(this, 0, previousIntent, 0); 

     notificationView.setOnClickPendingIntent(R.id.btnPrevious, pendingPreviousIntent); 
     notificationManager.notify(TAG,NOTIFICATION_ID, notification); 

    } 
    //NOTIFICATION START 

    public static class MyService extends Service { 


     @Override 
     public void onCreate() 
     { 
      super.onCreate(); 
     } 

     @Override 
     public void onTaskRemoved(Intent rootIntent){ 

      NotificationManager notificationManager = (NotificationManager)getSystemService(Context.NOTIFICATION_SERVICE); 
      notificationManager.cancel(TAG,NOTIFICATION_ID); 
      notificationManager.cancelAll(); 
      // mp.release(); 
      mp = null; //Trying to avoid app crash on swipe 
      //stop service 
      stopSelf(); 

     } 

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


} 

他の音楽プレーヤーのように動作することになっている、すなわち:これらの規則は、次のとおりです。他のいくつかのアプリがオーディオを再生している場合 の1-ゲインオーディオフォーカスを。 2他のアプリが既にオーディオを再生しているときにオーディオを再生しようとすると、オーディオフォーカスが失われます。 新しい曲が再生されたときに前の再生曲を3つ停止します。 4-電話が鳴ったら、曲を一時停止します。

あなたがPhoneStateListenerを使用して通話状態の変化を聞くことができたときに電話が鳴る曲を一時停止するには...この問題を解決するために

答えて

2

を助けが必要です。あなたはTelephonyManagerにリスナを登録することができます

PhoneStateListener phoneStateListener = new PhoneStateListener() { 
    @Override 
    public void onCallStateChanged(int state, String incomingNumber) { 
     if (state == TelephonyManager.CALL_STATE_RINGING) { 
     //Incoming call: Pause music 
     } else if(state == TelephonyManager.CALL_STATE_IDLE) { 
     //Not in call: Play music 
     } else if(state == TelephonyManager.CALL_STATE_OFFHOOK) { 
     //A call is dialing, active or on hold 
     } 
    super.onCallStateChanged(state, incomingNumber); 
}}; 

TelephonyManager mgr = (TelephonyManager) getSystemService(TELEPHONY_SERVICE); 
if(mgr != null) { 
    mgr.listen(phoneStateListener, PhoneStateListener.LISTEN_CALL_STATE); 
} 

は、マニュアルのを見てみましょうhere

関連する問題