私は今まで約20時間過ごしましたが、まだ問題があります。いくつかのアクティビティ(mainMenu、aboutUs、setting)を持つAndroidアプリケーションを作成しています。以下のリンクのベストアンサーをたどりましたが、問題ありませんでした。 asyncTaskを使用して再生される音楽はありません。 tキャンセルを使用して停止
アプリを実行すると(コードはmainActivityにあります)、音楽が始まり、他のアクティビティに移動しても音楽が停止しません。これはいい 。しかし、setting_activityアクティビティにToggleButtonを入れて、このボタンがこの音楽を開始および停止することを願っています。今私の質問は、setting_activityから音楽を停止および/または再開するにはどうすればよいですか?
別の解決策では、クラスMusicManagerを作成し、それをstartとstopと呼びます。しかし、これもいくつかの問題でした:
私は他の活動から音楽を止めることができませんでした。この時点で私はこの行がコードするように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);
}
}
最後に、音楽を停止/開始せずに、すべてのアクティビティでバックグラウンドミュージックを再生したいと思います。どうすればいいですか?
あなたは音楽プレーヤーをサービスに入れることができます。これにより、アクティビティから独立し、インテントを介して再生を制御できるようになります。
これに関するいくつかのコード例を次に示します。 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" />
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();
}
}
上記のサイモンの答えは正しいです。音楽プレーヤーのあるフラグメントがあり、ボタンをクリックしてそのUIに戻る必要があるという同様の問題がありました。あなたのケースも同様ですが、UIに戻る代わりに、再生を制御したいと考えています。これが私のアプリケーションのために私がしたことです。これにより、シャッフルおよびリピート機能を含むオーディオリストの再生が処理されます。これにより、通知バーにメディアコントロールが表示されるようになります。
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
Add the service to your manifest <service Android:name=".service.MediaPlayerService" />
</ code>
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; } }
@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;
}
});
}