Ich verbringe bis jetzt ungefähr 20 Stunden und mein Problem ist immer noch. Ich erstelle eine Android-Anwendung, die mehrere Aktivitäten hat (Hauptmenü, AboutUs, Einstellung). Ich folgte der am besten beantworteten Verbindung unten und das war in Ordnung. Musik, die mit asyncTask abgespielt wird, stoppt nicht mit cancel
Wenn ich meine App starte (mein Code ist in mainActivity), beginnt die Musik und stoppt nicht, wenn Sie zu anderen Aktivitäten navigieren. Das ist GUT. Aber ich setze ein ToggleButton in meine setting_activity-Aktivität, mit der ich hoffe, dass dieser Button diese Musik startet und stoppt. JETZT ist meine Frage, wie kann ich die Musik von setting_activity aus stoppen und/oder neu starten?
in einer anderen Lösung: Ich erstelle eine Klasse MusicManager und nenne sie Start und Stop. Aber auch dies hatte einige Probleme:
Ich konnte die Musik von anderen Aktivitäten nicht stoppen. Zu diesem Zeitpunkt spiele ich Musik in mainMenua_ctivity als diese Zeilencodes:
MusicManager mm = new MusicManager(this, R.raw.background_sound);
mm.play();
Wie kann ich damit aufhören? 3. Die Musik wurde angehalten, wenn ich zu anderen Aktivitäten navigiere.
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);
}
}
Schließlich möchte ich bei allen Aktivitäten eine Hintergrundmusik ohne Stop/Start-Musik spielen. Wie kann ich das machen?
Sie könnten den Musik-Player in einen Dienst stellen. Dies würde es unabhängig von den Aktivitäten machen und Sie könnten die Wiedergabe weiterhin durch Absichten steuern.
Hier einige Codebeispiele dazu: https://stackoverflow.com/a/8209975/2804473 Der folgende Code wird von Synxmax hier bei StackOverflow geschrieben und im obigen Link behandelt:
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() {
}
}
Die beste Antwort ist richtig, Sie müssen den Dienst jedoch der Manifestdatei hinzufügen.
<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();
}
}
Die obige Antwort von Simon ist richtig. Ich hatte ein ähnliches Problem, bei dem ich Fragmente mit einem Musik-Player hatte und auf Knopfdruck zu dieser Benutzeroberfläche zurückkehren musste. Ihr Fall ist ähnlich, aber anstatt zur Benutzeroberfläche zurückzukehren, möchten Sie die Wiedergabe steuern. Folgendes habe ich für meine Bewerbung getan. Dies sorgt für die Wiedergabe der Audioliste, einschließlich der Funktionen zum Mischen und Wiederholen. Dadurch wird sichergestellt, dass Mediensteuerelemente auch in der Benachrichtigungsleiste angezeigt werden.
MusicPlayerService
mit folgendem Code:
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 { privater MediaPlayerService-Player; boolescher serviceBound = false; public static final String Broadcast_PLAY_NEW_AUDIO = "pkg_name.PlayNewAudio"; // Bindung dieses Clients an den AudioPlayer-Dienst Private ServiceConnection serviceConnection = new ServiceConnection () { @Override Public void onServiceConnected (Komponentenname, IBinder-Dienst) { // Wir haben an LocalService gebunden, den IBinder umgewandelt und die LocalService-Instanz abgerufen. MediaPlayerService.LocalBinder binder = (MediaPlayerService.LocalBinder) service; Player = binder.getService ( ); serviceBound = true; } @Override public void onServiceDisconnected (Komponentenname) { serviceBound = false ; } }; // Rufe diese Methode auf, um den Titel Abzuspielen. Public void playAudio (int audioIndex, ArrayList updatedList) { // Check Ist der Dienst aktiv? AudioList = UpdatedList; If (! ServiceBound) { Intent PlayerIntent = New Intent (dies, MediaPlayerService.class); StartService (PlayerIntent ); bindService (playerIntent, serviceConnection, Context.BIND_AUTO_CREATE); } else { // Dienst ist aktiv // Broadcast an den Dienst senden - > PLAY_NEW_AUDIO Intent broadcastIntent = new Intent (Broadcast_PLAY_NEW_AUDIO); SendBroadcast (broadcastIntent); } } // Zusätzliche Methoden zur Steuerung von Public void start () { Player.playMedia (); } public void pause () { player.pauseMedia (); } public boolean isPlaying () { if (player! = null && serviceBound) { Spieler zurückgeben.isPlaying (); } Falsch zurückgeben; } }
@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;
}
});
}