web-dev-qa-db-ja.com

Android appのすべてのアクティビティでBGMを再生する

私は今まで約20時間過ごしましたが、まだ問題があります。いくつかのアクティビティ(mainMenu、aboutUs、setting)を持つAndroidアプリケーションを作成しています。以下のリンクのベストアンサーをたどりましたが、問題ありませんでした。 asyncTaskを使用して再生される音楽はありません。 tキャンセルを使用して停止

アプリを実行すると(コードはmainActivityにあります)、音楽が始まり、他のアクティビティに移動しても音楽が停止しません。これはいい 。しかし、setting_activityアクティビティにToggleButtonを入れて、このボタンがこの音楽を開始および停止することを願っています。今私の質問は、setting_activityから音楽を停止および/または再開するにはどうすればよいですか?

別の解決策では、クラスMusicManagerを作成し、それをstartとstopと呼びます。しかし、これもいくつかの問題でした:

  1. 音楽はmainMenu_activityで開始されましたが、約15秒間しか再生されず、その後停止しました。
  2. 私は他の活動から音楽を止めることができませんでした。この時点で私はこの行がコードするようにmainMenua_ctivityで音楽を再生します:

    MusicManager mm = new MusicManager(this, R.raw.background_sound);
    mm.play();
    

どうすればそれをやめることができますか? 3.他のアクティビティに移動すると、音楽が停止しました。

public class MusicManager implements OnPreparedListener {

    static MediaPlayer mPlayer;
    Context context;
    private int mySoundId;

    public MusicManager(Context ctx, int musicID) {
        context = ctx;
        mySoundId = musicID;
        mPlayer = MediaPlayer.create(context, mySoundId);
        mPlayer.setOnPreparedListener(this);
    }

    public void play() {
        mPlayer = MediaPlayer.create(context, mySoundId);

    }

    public void stop() {
        mPlayer.stop();
        mPlayer.release();
    }

    @Override
    public void onPrepared(MediaPlayer player) {
        player.start();
        mPlayer.setLooping(true);
        mPlayer.setVolume(25, 25);

    }

}

最後に、音楽を停止/開始せずに、すべてのアクティビティでバックグラウンドミュージックを再生したいと思います。どうすればいいですか?

8
Mojtaba

あなたは音楽プレーヤーをサービスに入れることができます。これにより、アクティビティから独立し、インテントを介して再生を制御できるようになります。

これに関するいくつかのコード例を次に示します。 https://stackoverflow.com/a/8209975/280447 以下のコードは、ここStackOverflowでSynxmaxによって作成され、上記のリンクでカバーされています。

public class BackgroundSoundService extends Service {
    private static final String TAG = null;
    MediaPlayer player;
    public IBinder onBind(Intent arg0) {

        return null;
    }
    @Override
    public void onCreate() {
        super.onCreate();
        player = MediaPlayer.create(this, R.raw.idil);
        player.setLooping(true); // Set looping
        player.setVolume(100,100);

    }
    public int onStartCommand(Intent intent, int flags, int startId) {
        player.start();
        return 1;
    }

    public void onStart(Intent intent, int startId) {
        // TO DO
    }
    public IBinder onUnBind(Intent arg0) {
        // TO DO Auto-generated method
        return null;
    }

    public void onStop() {

    }
    public void onPause() {

    }
    @Override
    public void onDestroy() {
        player.stop();
        player.release();
    }

    @Override
    public void onLowMemory() {

    }
}

一番上の答えは正しいですが、マニフェストファイルにサービスを追加する必要があります。

 <service Android:enabled="true" Android:name="BackgroundSoundService" />
0
MNadi Grant
public class serv extends Service{

    MediaPlayer mp;
    @Override
    public IBinder onBind(Intent intent) {
        // TODO Auto-generated method stub
        return null;
    }
    public void onCreate()
    {   
        mp = MediaPlayer.create(this, R.raw.b);
        mp.setLooping(false);
    }
    public void onDestroy()
    {       
        mp.stop();
    }
    public void onStart(Intent intent,int startid){

        Log.d(tag, "On start");
        mp.start();
    }
}
0
mahesh talaviya

上記のサイモンの答えは正しいです。音楽プレーヤーのあるフラグメントがあり、ボタンをクリックしてそのUIに戻る必要があるという同様の問題がありました。あなたのケースも同様ですが、UIに戻る代わりに、再生を制御したいと考えています。これが私のアプリケーションのために私がしたことです。これにより、シャッフルおよびリピート機能を含むオーディオリストの再生が処理されます。これにより、通知バーにメディアコントロールが表示されるようになります。

  1. 次のコードでサービスMusicPlayerServiceを作成します。


    public class MediaPlayerService extends Service implements MediaPlayer.OnCompletionListener,
            MediaPlayer.OnPreparedListener, MediaPlayer.OnErrorListener, MediaPlayer.OnSeekCompleteListener,
            MediaPlayer.OnInfoListener, MediaPlayer.OnBufferingUpdateListener,

            AudioManager.OnAudioFocusChangeListener {


        public static final String ACTION_PLAY = "pkg_name.ACTION_PLAY";
        public static final String ACTION_PAUSE = "pkg_name.ACTION_PAUSE";
        public static final String ACTION_PREVIOUS = "pkg_name.ACTION_PREVIOUS";
        public static final String ACTION_NEXT = "pkg_name.ACTION_NEXT";
        public static final String ACTION_STOP = "pkg_name.ACTION_STOP";

        private MediaPlayer mediaPlayer;

        //MediaSession
        private MediaSessionManager mediaSessionManager;
        private MediaSessionCompat mediaSession;
        private MediaControllerCompat.TransportControls transportControls;

        //AudioPlayer notification ID
        private static final int NOTIFICATION_ID = 101;

        //Used to pause/resume MediaPlayer
        private int resumePosition;

        // Binder given to clients
        private final IBinder iBinder = new LocalBinder();

        //List of available Audio files
        private ArrayList audioList;
        private int audioIndex = -1;


        //Handle incoming phone calls
        private boolean ongoingCall = false;
        private PhoneStateListener phoneStateListener;
        private TelephonyManager telephonyManager;
        private Bitmap albumArtBitmap;
        private boolean shuffle = false;
        private boolean repeat = false;
        private Random Rand;

        /**
         * Service lifecycle methods
         */
        @Override
        public IBinder onBind(Intent intent) {
            return iBinder;
        }

        @Override
        public void onCreate() {
            super.onCreate();
            // Perform one-time setup procedures

            // Manage incoming phone calls during playback.
            // Pause MediaPlayer on incoming call,
            // Resume on hangup.
            callStateListener();
            //ACTION_AUDIO_BECOMING_NOISY -- change in audio outputs -- BroadcastReceiver
            registerBecomingNoisyReceiver();
            //Listen for new Audio to play -- BroadcastReceiver
            register_playNewAudio();
            Rand = new Random();
            StorageUtil storage = new StorageUtil(getApplicationContext());
            shuffle = storage.loadShuffleRepeat("Shuffle");
            repeat = storage.loadShuffleRepeat("Repeat");
        }

        //The system calls this method when an activity, requests the service be started
        @Override
        public int onStartCommand(Intent intent, int flags, int startId) {
            try {

                //Load data from SharedPreferences
                StorageUtil storage = new StorageUtil(getApplicationContext());
                audioList = storage.loadAudio();
                audioIndex = storage.loadAudioIndex();

                if (audioIndex != -1 && audioIndex  ready to receive media commands
            mediaSession.setActive(true);
            //indicate that the MediaSession handles transport control commands
            // through its MediaSessionCompat.Callback.
            mediaSession.setFlags(MediaSessionCompat.FLAG_HANDLES_TRANSPORT_CONTROLS);

            //Set mediaSession's MetaData
            updateMetaData();

            // Attach Callback to receive MediaSession updates
            mediaSession.setCallback(new MediaSessionCompat.Callback() {
                // Implement callbacks
                @Override
                public void onPlay() {
                    super.onPlay();
                    resumeMedia();
                }

                @Override
                public void onPause() {
                    super.onPause();
                    pauseMedia();
                }
            });
        }

        private void updateMetaData() {
            fetchBitmapOfAlbum();
            // Update the current metadata
            mediaSession.setMetadata(new MediaMetadataCompat.Builder()
                    .putBitmap(MediaMetadataCompat.METADATA_KEY_ALBUM_ART, albumArtBitmap)
                    .putString(MediaMetadataCompat.METADATA_KEY_ARTIST, "")
                    .putString(MediaMetadataCompat.METADATA_KEY_ALBUM, activeAudio.getAlbumName())
                    .putString(MediaMetadataCompat.METADATA_KEY_TITLE, activeAudio.getTrackName())
                    .build());
        }

        private Target target = new Target() {
            @Override
            public void onBitmapLoaded(Bitmap bitmap, Picasso.LoadedFrom from) {
                albumArtBitmap = bitmap;
            }

            @Override
            public void onBitmapFailed(Exception e, Drawable errorDrawable) {

            }

            @Override
            public void onPrepareLoad(Drawable placeHolderDrawable) {
            }
        };

        private void fetchBitmapOfAlbum() {
            Picasso.get().load(activeAudio.getAlbumArt())
                    .placeholder(R.drawable.rotate_animation)
                    .error(R.drawable.ic_blank)
                    .into(target);
        }

        private void buildNotification(PlaybackStatus playbackStatus) {

            int notificationAction = Android.R.drawable.ic_media_pause;//needs to be initialized
            PendingIntent play_pauseAction = null;

            //Build a new notification according to the current state of the MediaPlayer
            if (playbackStatus == PlaybackStatus.PLAYING) {
                notificationAction = Android.R.drawable.ic_media_pause;
                //create the pause action
                play_pauseAction = playbackAction(1);
            } else if (playbackStatus == PlaybackStatus.PAUSED) {
                notificationAction = Android.R.drawable.ic_media_play;
                //create the play action
                play_pauseAction = playbackAction(0);
            }

                fetchBitmapOfAlbum(); //replace with your own image
                String channelId = "";
                if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
                    channelId = "APP_MUSIC";
                }
                // Create a new Notification
                NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(this, channelId)
                        // Hide the timestamp
                        .setShowWhen(false)
                        // Set the Notification style
                        .setStyle(new androidx.media.app.NotificationCompat.MediaStyle()
                                // Attach our MediaSession token
                                .setMediaSession(mediaSession.getSessionToken())
                                // Show our playback controls in the compat view
                                .setShowActionsInCompactView(0, 1, 2))
                        // Set the Notification color
                        .setColor(ContextCompat.getColor(this.getApplicationContext(), R.color.colorAccent))
                        // Set the large and small icons
                        .setLargeIcon(albumArtBitmap)
                        .setSmallIcon(R.drawable.ic_stat_notifications)
                        // Set Notification content information
                        .setContentText(activeAudio.getTrackName())
                        .setTicker(activeAudio.getAlbumName() + "-" + activeAudio.getTrackName())
                        .setOngoing(true)
                        .setContentTitle(activeAudio.getAlbumName())
                        .setContentInfo(activeAudio.getTrackName())
                        // Add playback actions
                        .addAction(notificationAction, "pause", play_pauseAction)

                ((NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE)).notify(NOTIFICATION_ID, notificationBuilder.build());
        }


        private PendingIntent playbackAction(int actionNumber) {
            Intent playbackAction = new Intent(this, MediaPlayerService.class);
            switch (actionNumber) {
                case 0:
                    // Play
                    playbackAction.setAction(ACTION_PLAY);
                    return PendingIntent.getService(this, actionNumber, playbackAction, 0);
                case 1:
                    // Pause
                    playbackAction.setAction(ACTION_PAUSE);
                    return PendingIntent.getService(this, actionNumber, playbackAction, 0);
                default:
                    break;
            }
            return null;
        }

        private void removeNotification() {
            NotificationManager notificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
            notificationManager.cancel(NOTIFICATION_ID);
        }

        private void handleIncomingActions(Intent playbackAction) {
            if (playbackAction == null || playbackAction.getAction() == null) return;

            String actionString = playbackAction.getAction();
            if (actionString.equalsIgnoreCase(ACTION_PLAY)) {
                transportControls.play();
            } else if (actionString.equalsIgnoreCase(ACTION_PAUSE)) {
                transportControls.pause();
            } 
        }        
        /**
         * Play new Audio
         */
        private BroadcastReceiver playNewAudio = new BroadcastReceiver() {
            @Override
            public void onReceive(Context context, Intent intent) {

                //Get the new media index form SharedPreferences
                audioIndex = new StorageUtil(getApplicationContext()).loadAudioIndex();
                if (audioIndex != -1 && audioIndex 
  1. Add the service to your manifest <service Android:name=".service.MediaPlayerService" /></ code>
  2. MainActivityでサービスをバインドし、サービスを呼び出すメソッドを宣言します
 
 public class MainActivity {
 private MediaPlayerService player; 
 boolean serviceBound = false; 
 public static final String Broadcast_PLAY_NEW_AUDIO = "pkg_name.PlayNewAudio"; 
 //このクライアントをAudioPlayerサービスにバインドする
 private ServiceConnection serviceConnection = new ServiceConnection(){
 @Override 
 public void onServiceConnected(ComponentName name、IBinder service) {
 // LocalServiceにバインドし、IBinderをキャストして、LocalServiceインスタンスを取得しました
 MediaPlayerService.LocalBinderバインダー=(MediaPlayerService.LocalBinder)サービス; 
 player =バインダー.getService( ); 
 serviceBound = true; 
} 
 
 @ Override 
 public void onServiceDisconnected(ComponentName name){
 serviceBound = false ; 
 } 
}; 
 
 //このメソッドを呼び出してトラックを再生します
 public void playAudio(int audioIndex、ArrayListupdatedList){
 //チェックサービスはアクティブです
 audioList = updateList; 
 if(!serviceBound){
 Intent playerIntent = new Intent(this、MediaPlayerService.class); 
 startService(playerIntent ); 
 bindService(playerIntent、serviceConnection、Context.BIND_AUTO_CREATE); 
} else {
 //サービスはアクティブです
 //サービスにブロードキャストを送信します- > PLAY_NEW_AUDIO 
インテントbroadcastIntent = new Intent(Broadcast_PLAY_NEW_AUDIO); 
 sendBroadcast(broadcastIntent); 
} 
 
} 
 // control 
 public void start(){
 player.playMedia(); 
} 
 public void pause(){
 player.pauseMedia(); 
} 
 public boolean isPlaying(){
 if(player! = null && serviceBound){
 return player.isPlaying(); 
} 
 return false; 
} 
} 
 
0
Deepak Dhamuria
 @Override
    public void onCreate (){
      super.onCreate();

       Player = MediaPlayer.create(this, R.raw.jingle);
       mPlayer.setOnErrorListener(this);

       if(mPlayer!= null)
        {
            mPlayer.setLooping(true);
            mPlayer.setVolume(100,100);
        }


        mPlayer.setOnErrorListener(new OnErrorListener() {

      public boolean onError(MediaPlayer mp, int what, int
          extra){

            onError(mPlayer, what, extra);
            return true;
        }
          });
    }
0
mahesh talaviya