onStop() ist ja nicht gleich onStop()

Was sollte ich für die geschilderte Problem benutzen?

  • MediaPlayer

    Stimmen: 0 0,0%
  • SoundPool

    Stimmen: 1 100,0%
  • ExoPlayer

    Stimmen: 0 0,0%
  • Andere

    Stimmen: 0 0,0%

  • Umfrageteilnehmer
    1
B

BraveSentry

Neues Mitglied
0
Hallo zusammen,

ich bastle an einer Gehörbildungs-App, die darauf beruht, dass ein Bordun-Ton die gesamte Zeit zu hören ist, in der die App im Vordergrund ist. Wenn die App verlassen wird, soll der Ton abbrechen und wenn die App wieder in den Vordergrund kommt, soll der Ton an der Stelle weiterspielen, an der er aufgehört hat.

Ich habe also eine .ogg mit genanntem Ton, der über 18 sekunden ein- und danch wieder ausfadet. Den lade ich so:

Code:
suspend fun playDelayed() {
        delay(18000)
        mPlayer = MediaPlayer.create(this, R.raw.cbordun)
        mPlayer.isLooping = true
        mPlayer.start()
    }

    fun playBordun() {
        mediaPlayer = MediaPlayer.create(this, R.raw.cbordun)
        mediaPlayer.isLooping = true
        mediaPlayer.start()

        GlobalScope.launch() {
            playDelayed()
        }
    }

Damit das Ganze wie gewünscht aufhört und wieder anfängt, benutze ich diesen Code:

Code:
override fun onStop() {
        super.onStop()
        mediaLength = mediaPlayer.currentPosition
        mLength = mPlayer.currentPosition
        mediaPlayer.pause()
        mPlayer.pause()
    }

    override fun onResume() {
        super.onResume()
        mediaPlayer.seekTo(mediaLength)
        mPlayer.seekTo(mLength)
        mediaPlayer.isLooping
        mPlayer.isLooping
        mediaPlayer.start()
        mPlayer.start()
    }
    override fun onDestroy() {
        super.onDestroy()
        mediaPlayer.stop()
        mPlayer.stop()
        mediaPlayer.reset()
        mPlayer.reset()
        mediaPlayer.release()
        mPlayer.release()
    }

Das Problem ist nun, dass onStop() ja auch passiert, wenn ich innerhalb der App auf eine andere Activity wechsle. Der Sound bricht dann trotzdem ab. Wenn ich aber den Code bei onStop() auskommentiere, spielt der Sound weiter, wenn ich die App per Home-Button verlasse, und bricht erst dann ab, wenn ich die App manuell aus den "recent apps" entferne.

Davon abgesehen: Ich habe öfters gelesen, dass man keine zwei MediaPlayer-Instanzen gleichzeitig laufen lassen soll, aber bisher nirgends herausgefunden, warum nicht.

Wenn jemand vorschlagen will, stattdessen SoundPool zu benutzen: Habe ich probiert. Hat nochmal ganz eigene Probleme. Dafür würde ich einen eigenen Thread eröffnen, wenn sicher ist, dass mein Vorhaben mit dem Media Player nicht machbar ist. Ich habe spaßeshalber mal eine Umfrage angehängt, um zu sehen, was ihr so benutzen würdet.

Vielen Dank schonmal
Paul
 
Hallo

Also ich würde es wohl in einem Service oder Thread packen. Außerdem würde ich das beenden nicht in der onStop sondern in der onPause machen. OnPause wird auf gerufen wenn die App in den Hintergrund tritt.

Wenn du einen Service oder Thread benutz musst du den auch stoppen beenden wenn du den Ton nicht mehr btrauchst.


Damit der Ton weiterläuft wenn du in eine andere Activity wechselst könntest du ein flag einsetzen damit in der die onPause der Thread, Service nicht beendet wird.


Beim Start einer neuen Activity wird ja die alte Activity beendet und somit wird deine onStopp, onPause Methode durchlaufen und der Ton wird beendet. Deshalb das flag das du vor dem Intent setzt und Und in der onPause mit einem if abfragst und das beenden somit überspringst.


Wenn die App verlassen wird, soll der Ton abbrechen und wenn die App wieder in den Vordergrund kommt, soll der Ton an der Stelle weiterspielen, [ /QUOTE]



genau dafür ist die onPause und onResume Methode besser geeignet als onStop

schaue im LifeCycle nach.

[doublepost=1548775204,1548773078][/doublepost]Bemerken möchte ich noch das wenn du zwei Töne zu gleich abspielen willst solltest du sie in einen eigenen Thread abspielen. Wenn du mehrere im UI Thread anspielst, belastest du den Main Thread sehr stark und riskiert somit einen App Absturz. Oder Verzögerungen bei der Steuerung.


Du startest zwar den einen Ton in einer coroutine ( thread) den anderen im UI nur wo benutzt du die Methoden.


Wie hast du dir es gedacht von der neuen Activity auf den Thread und MP der alten Activiy zuzugreifen?

Bei Klotlin könntest du den Top Level Bereich nutzen. Oder „object“.



Auch SoundPool hat seine Berechtigung denn da hast du den Vorteil das dieser schon in einem eigenen Thread abläuft. Auch das Pausieren ist einfacher und der merkt sich auch die Position wo es weiter geht.
 
Zuletzt bearbeitet:
  • Danke
Reaktionen: BraveSentry
Erstmal vielen Dank für die Antwort.

jogimuc schrieb:
Wie hast du dir es gedacht von der neuen Activity auf den Thread und MP der alten Activiy zuzugreifen?

Bei Klotlin könntest du den Top Level Bereich nutzen. Oder „object“.

TL DR: Das ist gerade das, wo mit ich zu kämpfen habe. Alles andere läuft ganz gut.

Ich habe die beiden MediaPlayer jetzt in einen Service gepackt, den ich von der MainActivity aus starte. Dabei habe ich mich größtenteils an das erste Beispiel hieraus https://developer.android.com/reference/android/app/Service gehalten - natürlich auf kotlin übersetzt und meine eigenen Prozesse eingefügt.

Dann hab ich den service an die MainActivity gebunden und
Code:
    override fun onUserLeaveHint() {
        super.onUserLeaveHint()
        unbindService(myConnection)
    }
gesetzt, damit die Musik aufhört, wenn die Aktivität verlassen wird. Auf alle Intents habe ich dann FLAG_ACTIVITY_NO_USER_ACTION gesetzt, damit die Musik bei Intents weiterspielt. Das Problem ist jetzt tatsächlich, wie ich das mache, wenn ich in einer detr folgenden Activities auf den Home-Button drücke. Stand jetzt ist, dass die Musik weiterspielt. Soll sie aber nicht. Ich werde mal nachschauen, wie ich mit dem Top Level und mit "object" umgehen kann und melde mich wieder, wenn ich damit absolut nicht klarkomme.

PS: Das ist mein erstes Projekt überhaupt, das mehr ist als "Hello World". Von daher bitte ich um Nachsicht, wenn ich nicht alle Basics immer auf dem Schirm habe.
 
Zuletzt bearbeitet:
Ich möchte dir nur noch mitgeben. wenn du einen Service an eine Activity Bindest dieser beim beenden der Activity auch beendet wird also nicht weiterläuft.
 
  • Danke
Reaktionen: BraveSentry und deek
Das kommt drauf an wie man bindet.

Wenn man nur ein bindService macht (was dann den Service auch startet) wird das unbind den Service beenden. Das ist korrekt.
Wenn man das ganze aber in zwei SChritten macht. Service starten und danach auf den laufenden Service binden sollte dieser weiterlaufen auch wenn der Binder stirbt oder unbindet.
 
  • Danke
Reaktionen: BraveSentry
Hier mal ein einfaches Beispiel.

Code:
class MainActivity : AppCompatActivity() {
    var flag = true

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        button.setOnClickListener{
          flag = false
          val intent = Intent(this, Activity2::class.java)
          startActivity(intent)
      }
    }


    override fun onPause() {
        super.onPause()
        if(flag) {
            var sIntent = Intent(this@MainActivity, MyServiceTon::class.java)
            sIntent.putExtra("Pause", "Ein")
            startService(sIntent)
        }
    }

    override fun onResume() {
        super.onResume()
        var sIntent = Intent(this@MainActivity, MyServiceTon::class.java)
        sIntent.putExtra("Play", "Ein")
        startService(sIntent)

    }

    override fun onDestroy() {
        super.onDestroy()
        if (flag) {
            val sIntent = Intent(this@MainActivity, MyServiceTon::class.java)
            sIntent.putExtra("Stop", "Ein")
            startService(sIntent)
        }
    }
}
Code:
@Suppress("UNREACHABLE_CODE")
class MyServiceTon : Service() {

    lateinit var mPlayer: MediaPlayer
    private var mLength = 0

    override fun onBind(intent: Intent): IBinder? {
        return null
    }

    override fun onCreate() {
        super.onCreate()
        mPlayer = MediaPlayer.create(this, R.raw.salamisound)
    }

    override fun onStartCommand(intent: Intent, flags: Int, startId: Int): Int {

        if (intent.hasExtra("Play")) {
            mPlayer.seekTo(mLength)
            mPlayer.isLooping
            mPlayer.start()
        }


        if (intent.hasExtra("Pause")) {
            mLength = mPlayer.currentPosition
            mPlayer.pause()
        }

        if (intent.hasExtra("Stop")) {
           stopSelf()
        }
        return super.onStartCommand(intent, flags, startId)
    }

    override fun onDestroy() {
        super.onDestroy()
        mPlayer.stop()
        mPlayer.reset()
        mPlayer.release()
    }
}
 
  • Danke
Reaktionen: BraveSentry
EDIT: Ich habe eine Lösung gefunden. Steht im nächsten Post.
------------------------------------

Ich habe mal versucht, dein Beispiel auf mein Projekt anzuwenden. Klappt auch alles ganz gut, aber einen Bug habe ich: Immer wenn ich die App per BackButton verlasse, starten sich die beiden sounds nochmal neu, und ich habe keine Ahnung von wo aus oder warum. Wenn ich über die recent apps zur App zurückkehre, starten sich die beiden Sounds erneut, sodass ich insgesamt vier sounds höre. Wenn ich das Ganze nochmal mache, kommen nochmal zwei sounds dazu, aber die ersten beiden werden beendet. Irgendeine Idee, woran das liegen könnte?
Das Ganze hört übrigens erst auf, wenn ich die App aus der recent apps liste entferne.

Hier mein Service:

Code:
@Suppress("UNREACHABLE_CODE")
class LocalService : LifecycleService() {

        lateinit var mPlayer: MediaPlayer
        private var mLength = 0
        lateinit var mediaPlayer: MediaPlayer
        private var mediaLength = 0

    fun playBordun() {
        if (mediaPlayer.isLooping or mPlayer.isLooping) {
        } else {
            mediaPlayer?.seekTo(mediaLength)
            mPlayer?.seekTo(mLength)
            mediaPlayer?.isLooping
            mPlayer?.isLooping
            mediaPlayer?.start()
            mPlayer?.start()
        }
    }
        override fun onBind(intent: Intent): IBinder? {
            super.onBind(intent)
            return null
        }

        override fun onCreate() {
            mediaPlayer = MediaPlayer()
            mPlayer = MediaPlayer()
            suspend fun playDelayed() {
                mPlayer = MediaPlayer.create(this, R.raw.cping)
                mPlayer?.isLooping = true
                mPlayer?.start()
            }

            suspend fun playBordun() {
                mediaPlayer = MediaPlayer.create(this, R.raw.cbordun)
                mediaPlayer?.isLooping = true
                mediaPlayer?.start()

            }
            GlobalScope.launch {
                playBordun()
                playDelayed()
            }
            super.onCreate()
        }

        override fun onStartCommand(intent: Intent, flags: Int, startId: Int): Int {

            if (intent.hasExtra("Play")) {
                playBordun()
            }

            if (intent.hasExtra("Pause")) {
                mLength = mPlayer.currentPosition
                mediaLength = mediaPlayer.currentPosition
                        mPlayer?.pause()
                mediaPlayer?.pause()
                stopSelf()
            }

            if (intent.hasExtra("Stop")) {
                mLength = mPlayer.currentPosition
                mediaLength = mediaPlayer.currentPosition
                mPlayer?.pause()
                mediaPlayer?.pause()
                mPlayer.stop()
                mPlayer.release()
                mediaPlayer.stop()
                mediaPlayer.release()
                stopSelf()
            }

            return super.onStartCommand(intent, flags, startId)
        }

   override fun onDestroy() {
     super.onDestroy()
       stopSelf()
   }
}

Das passiert in der MainActivity:

Code:
    override fun onDestroy() {
        super.onDestroy()
        if (flag) {
            val sIntent = Intent(this@MainActivity, LocalService::class.java)
            sIntent.putExtra("Stop", "Ein")
            startService(sIntent)
        }
    }

    override fun onBackPressed() {
        flag = true
        val sIntent = Intent(this@MainActivity, LocalService::class.java)
        sIntent.putExtra("Stop", "Ein")
        startService(sIntent)
        super.onBackPressed()
    }


Hier die Logcat nach dem Verlassen der App per BackButton:

Code:
2019-02-01 11:24:47.972 30210-30210/com.example.asdasd.soulfetch W/MediaPlayer: mediaplayer went away with unhandled events
2019-02-01 11:24:47.972 30210-30210/com.example.asdasd.soulfetch W/MediaPlayer: mediaplayer went away with unhandled events
2019-02-01 11:24:47.972 30210-30210/com.example.asdasd.soulfetch W/MediaPlayer: mediaplayer went away with unhandled events
2019-02-01 11:24:47.977 30210-30210/com.example.asdasd.soulfetch W/MediaPlayer: mediaplayer went away with unhandled events
2019-02-01 11:24:48.038 30210-30210/com.example.asdasd.soulfetch E/MediaPlayer: error (-38, 0)
2019-02-01 11:24:48.039 30210-30210/com.example.asdasd.soulfetch E/MediaPlayer: error (-38, 0)
2019-02-01 11:24:48.039 30210-30210/com.example.asdasd.soulfetch E/MediaPlayer: pause called in state 0, mPlayer(0x0)
2019-02-01 11:24:48.040 30210-30210/com.example.asdasd.soulfetch E/MediaPlayer: pause called in state 0, mPlayer(0x0)
2019-02-01 11:24:48.074 30210-30210/com.example.asdasd.soulfetch E/MediaPlayer: Error (-38,0)
2019-02-01 11:24:48.074 30210-30210/com.example.asdasd.soulfetch E/MediaPlayer: Error (-38,0)
2019-02-01 11:24:48.113 30210-30227/com.example.asdasd.soulfetch D/EGL_emulation: eglMakeCurrent: 0xa061ffc0: ver 3 0 (tinfo 0x933f7960)
2019-02-01 11:24:48.153 30210-30228/com.example.asdasd.soulfetch D/MediaPlayer: setSubtitleAnchor in MediaPlayer
2019-02-01 11:24:48.154 30210-30210/com.example.asdasd.soulfetch D/MediaPlayer: setSubtitleAnchor in MediaPlayer
2019-02-01 11:24:48.206 30210-30210/com.example.asdasd.soulfetch D/MediaPlayer: setSubtitleAnchor in MediaPlayer
2019-02-01 11:24:48.209 30210-30228/com.example.asdasd.soulfetch D/MediaPlayer: setSubtitleAnchor in MediaPlayer
2019-02-01 11:24:48.397 30210-30210/com.example.asdasd.soulfetch E/MediaPlayer: error (-38, 0)
2019-02-01 11:24:48.397 30210-30210/com.example.asdasd.soulfetch E/MediaPlayer: error (-38, 0)
2019-02-01 11:24:48.397 30210-30210/com.example.asdasd.soulfetch E/MediaPlayer: pause called in state 0, mPlayer(0x0)
2019-02-01 11:24:48.397 30210-30210/com.example.asdasd.soulfetch E/MediaPlayer: pause called in state 0, mPlayer(0x0)
2019-02-01 11:24:48.397 30210-30210/com.example.asdasd.soulfetch E/MediaPlayer: stop called in state 0, mPlayer(0x0)
2019-02-01 11:24:48.398 30210-30210/com.example.asdasd.soulfetch E/MediaPlayer: stop called in state 0, mPlayer(0x0)
2019-02-01 11:24:48.402 30210-30210/com.example.asdasd.soulfetch W/MediaPlayer: mediaplayer went away with unhandled events
2019-02-01 11:24:48.402 30210-30210/com.example.asdasd.soulfetch W/MediaPlayer: mediaplayer went away with unhandled events
2019-02-01 11:24:48.420 30210-30228/com.example.asdasd.soulfetch D/MediaPlayer: setSubtitleAnchor in MediaPlayer
2019-02-01 11:24:48.420 30210-30210/com.example.asdasd.soulfetch D/MediaPlayer: setSubtitleAnchor in MediaPlayer
2019-02-01 11:24:48.448 30210-30210/com.example.asdasd.soulfetch D/MediaPlayer: setSubtitleAnchor in MediaPlayer
2019-02-01 11:24:48.450 30210-30228/com.example.asdasd.soulfetch D/MediaPlayer: setSubtitleAnchor in MediaPlayer
 
Zuletzt bearbeitet:
Vielen Dank nochmal für die Antworten! Anscheinend musste ich nur einen Haufen Code im Service von onCreate nach onStartCommand verschieben:

Code:
@Suppress("UNREACHABLE_CODE")
class LocalService : LifecycleService() {

    lateinit var mPlayer: MediaPlayer
        private var mLength = 0
        lateinit var mediaPlayer: MediaPlayer
        private var mediaLength = 0

        override fun onBind(intent: Intent): IBinder? {
            super.onBind(intent)
            return null
        }

        override fun onCreate() {
                    mediaPlayer = MediaPlayer.create(this, R.raw.cbordun)
            mPlayer = MediaPlayer.create(this, R.raw.cping)

            super.onCreate()
        }

        override fun onStartCommand(intent: Intent, flags: Int, startId: Int): Int {
            if (intent.hasExtra("Play")) {
                playBordun()
            }
            if (intent.hasExtra("Pause")) {
                mLength = mPlayer.currentPosition
                mediaLength = mediaPlayer.currentPosition
                mPlayer.pause()
                mediaPlayer.pause()
                stopSelf()
            }
            if (intent.hasExtra("Stop")) {
                mLength = mPlayer.currentPosition
                mediaLength = mediaPlayer.currentPosition
                mPlayer.pause()
                mediaPlayer.pause()
                mPlayer.stop()
                mPlayer.release()
                mediaPlayer.stop()
                mediaPlayer.release()
                stopSelf()
            }
            return super.onStartCommand(intent, flags, startId)
        }

   override fun onDestroy() {
     super.onDestroy()
       stopSelf()
   }

fun playBordun() {
        if (mediaPlayer.isLooping or mPlayer.isLooping) {
        } else {
            mediaPlayer = MediaPlayer()
            mPlayer = MediaPlayer()
            suspend fun playDelayed() {
                mPlayer = MediaPlayer.create(this, R.raw.cping)
                mPlayer?.isLooping = true
                mPlayer?.start()
            }

            suspend fun playBordun() {
                mediaPlayer = MediaPlayer.create(this, R.raw.cbordun)
                mediaPlayer?.isLooping = true
                mediaPlayer?.start()
            }
            GlobalScope.launch {
                playBordun()
                playDelayed()
            }
        }
    }
}

Was ich bei aber beim Verlassen per BackButton immer noch bekomme, ist dieses Log:

Code:
2019-02-01 15:53:46.104 17682-17698/com.example.asdasd.soulfetch D/EGL_emulation: eglMakeCurrent: 0x9e70c860: ver 3 0 (tinfo 0x9e71ba30)
2019-02-01 15:53:46.373 17682-17682/com.example.asdasd.soulfetch D/MediaPlayer: setSubtitleAnchor in MediaPlayer
2019-02-01 15:53:46.390 17682-17682/com.example.asdasd.soulfetch D/MediaPlayer: setSubtitleAnchor in MediaPlayer
2019-02-01 15:53:46.393 17682-17682/com.example.asdasd.soulfetch E/MediaPlayer: pause called in state 8, mPlayer(0x933e4b00)
2019-02-01 15:53:46.393 17682-17682/com.example.asdasd.soulfetch E/MediaPlayer: error (-38, 0)
2019-02-01 15:53:46.393 17682-17682/com.example.asdasd.soulfetch E/MediaPlayer: pause called in state 8, mPlayer(0xa068ede0)
2019-02-01 15:53:46.393 17682-17682/com.example.asdasd.soulfetch E/MediaPlayer: error (-38, 0)
2019-02-01 15:53:46.393 17682-17682/com.example.asdasd.soulfetch E/MediaPlayer: stop called in state 0, mPlayer(0x933e4b00)
2019-02-01 15:53:46.393 17682-17682/com.example.asdasd.soulfetch E/MediaPlayer: error (-38, 0)
2019-02-01 15:53:46.395 17682-17682/com.example.asdasd.soulfetch E/MediaPlayer: stop called in state 0, mPlayer(0xa068ede0)
2019-02-01 15:53:46.395 17682-17682/com.example.asdasd.soulfetch E/MediaPlayer: error (-38, 0)
2019-02-01 15:53:46.400 17682-17682/com.example.asdasd.soulfetch W/MediaPlayer: mediaplayer went away with unhandled events
2019-02-01 15:53:46.400 17682-17682/com.example.asdasd.soulfetch W/MediaPlayer: mediaplayer went away with unhandled events
2019-02-01 15:53:46.400 17682-17682/com.example.asdasd.soulfetch W/MediaPlayer: mediaplayer went away with unhandled events
2019-02-01 15:53:46.401 17682-17682/com.example.asdasd.soulfetch W/MediaPlayer: mediaplayer went away with unhandled events
2019-02-01 15:53:46.401 17682-17682/com.example.asdasd.soulfetch W/MediaPlayer: mediaplayer went away with unhandled events
2019-02-01 15:53:46.401 17682-17682/com.example.asdasd.soulfetch W/MediaPlayer: mediaplayer went away with unhandled events

Heißt das, der MediaPlayer nimmt weiter Ressourcen in Anspruch?
Oder anders gefragt: Muss ich wegen diesen Meldungen irgendwas tun - solange im UI-Flow alles läuft wie es soll?
 
Hallo

ja so sieht der Code besser aus bei der ersten Version hattest du den Ton einmal ohne und einmal in der Coroutine gestartet. Das der Service immer beendet wird nach pause wird die onCreate auch wieder aufgerufen und startet den ton neu.
Ich hatte leider noch keine Zeit um dir zu antworten haste ja auch super selber gemacht.


Zu deinem jetzigen Code warum erstellst du diese Instanzen ? in Zeile 54,55

mediaPlayer = MediaPlayer()
mPlayer = MediaPlayer()

brauchst du nicht wofür.



auch verstehe ich nicht warum du

mediaPlayer = MediaPlayer.create(this, R.raw.cbordun)
mPlayer = MediaPlayer.create(this, R.raw.cping)

in der onCrate machst und in den Coroutinen nochmal.
 
  • Danke
Reaktionen: BraveSentry
jogimuc schrieb:
Zu deinem jetzigen Code warum erstellst du diese Instanzen ? in Zeile 54,55

mediaPlayer = MediaPlayer()
mPlayer = MediaPlayer()

brauchst du nicht wofür.

Ich glaube, die hatte ich einfach nur vergessen zu bereinigen. Ich hatte sie glaub ich hingeschrieben, um den runtime error (siehe unten) zu verhindern. Wenn ich beides rauskommentiere, funktioniert immer noch alles.

auch verstehe ich nicht warum du

mediaPlayer = MediaPlayer.create(this, R.raw.cbordun)
mPlayer = MediaPlayer.create(this, R.raw.cping)

in der onCrate machst und in den Coroutinen nochmal.

Ich mache wenig über komplettes Verstehen, mehr über trial and error. Das passiert, wenn ichs anders mache:
Wenn ichs aus onCreate rauskommentiere, bekomme ich nen runtime error: "lateinit property mediaPlayer has not been initialized".
Wenn ichs aus den Coroutinen rauskommentiere, kommt kein sound.
Wenns in beidem drinsteht, klappt alles.

Die Logcat, wenn ich ich per zurückbutton aus der app rausgehe, zeigt aber immer noch dieselben Warnungen/Fehler. Muss ich da irgendwas gegen machen - so zum Schonen von Systemressourcen o.ä.?

Code:
2019-02-01 21:05:07.242 26150-26170/com.example.asdasd.soulfetch D/EGL_emulation: eglMakeCurrent: 0xace050c0: ver 3 0 (tinfo 0xace03360)
2019-02-01 21:05:07.524 26150-26150/com.example.asdasd.soulfetch D/MediaPlayer: setSubtitleAnchor in MediaPlayer
2019-02-01 21:05:07.544 26150-26150/com.example.asdasd.soulfetch D/MediaPlayer: setSubtitleAnchor in MediaPlayer
2019-02-01 21:05:07.548 26150-26150/com.example.asdasd.soulfetch E/MediaPlayer: pause called in state 8, mPlayer(0x91696760)
2019-02-01 21:05:07.548 26150-26150/com.example.asdasd.soulfetch E/MediaPlayer: error (-38, 0)
2019-02-01 21:05:07.548 26150-26150/com.example.asdasd.soulfetch E/MediaPlayer: pause called in state 8, mPlayer(0x91e120e0)
2019-02-01 21:05:07.548 26150-26150/com.example.asdasd.soulfetch E/MediaPlayer: error (-38, 0)
2019-02-01 21:05:07.548 26150-26150/com.example.asdasd.soulfetch E/MediaPlayer: stop called in state 0, mPlayer(0x91696760)
2019-02-01 21:05:07.548 26150-26150/com.example.asdasd.soulfetch E/MediaPlayer: error (-38, 0)
2019-02-01 21:05:07.550 26150-26150/com.example.asdasd.soulfetch E/MediaPlayer: stop called in state 0, mPlayer(0x91e120e0)
2019-02-01 21:05:07.552 26150-26150/com.example.asdasd.soulfetch E/MediaPlayer: error (-38, 0)
2019-02-01 21:05:07.559 26150-26150/com.example.asdasd.soulfetch W/MediaPlayer: mediaplayer went away with unhandled events
2019-02-01 21:05:07.559 26150-26150/com.example.asdasd.soulfetch W/MediaPlayer: mediaplayer went away with unhandled events
2019-02-01 21:05:07.559 26150-26150/com.example.asdasd.soulfetch W/MediaPlayer: mediaplayer went away with unhandled events
2019-02-01 21:05:07.559 26150-26150/com.example.asdasd.soulfetch W/MediaPlayer: mediaplayer went away with unhandled events
2019-02-01 21:05:07.559 26150-26150/com.example.asdasd.soulfetch W/MediaPlayer: mediaplayer went away with unhandled events
2019-02-01 21:05:07.559 26150-26150/com.example.asdasd.soulfetch W/MediaPlayer: mediaplayer went away with unhandled events
 
ich meinte nicht aus der onCreate sonder in den Coroutienen.
In der onCreate ist klar das du es dort brauchst ist in meinem Beispiel auch so.
 
@jogimuc Wie gesagt, wenn ich statt diesem hier:

Code:
fun playBordun() {
       if (mediaPlayer.isLooping or mPlayer.isLooping) {
       } else {
           suspend fun playDelayed() {
               mPlayer = MediaPlayer.create(this, R.raw.cping)
               mPlayer?.isLooping = true
               mPlayer?.start()
           }

           suspend fun playBordun() {
               mediaPlayer = MediaPlayer.create(this, R.raw.cbordun)
               mediaPlayer?.isLooping = true
               mediaPlayer?.start()
           }
           GlobalScope.launch {
               playBordun()
               playDelayed()
           }
       }

dieses hier benutze:

Code:
fun playBordun() {
       if (mediaPlayer.isLooping or mPlayer.isLooping) {
       } else {
           suspend fun playDelayed() {
       //        mPlayer = MediaPlayer.create(this, R.raw.cping)
               mPlayer?.isLooping = true
               mPlayer?.start()
           }

           suspend fun playBordun() {
          //     mediaPlayer = MediaPlayer.create(this, R.raw.cbordun)
               mediaPlayer?.isLooping = true
               mediaPlayer?.start()
           }
           GlobalScope.launch {
               playBordun()
               playDelayed()
           }
       }

Dann spielt kein Sound ab.
 
Habe es eben nochmal getestet du brauchst die variable nicht in der coroutiene nochmal setzen.

Dafür darfst du auch nicht die beiden Instanzen erzeugen. Damit machst du das was du in onCreat zugewiesen hast wieder zu Nichte.



Was mir auch aufgefallen ist das wenn du den Backbutton drückst der Sound beendet wird und danach wieder über die Pause nochmal aufgerufen wird und beendet.

Das liegt an der onPause in der Main die auch noch aufgerufen wird.

Setze das flag auf false in der onBackbutton und es wird kein zweites Mal gestartet.


Code:
@Suppress("UNREACHABLE_CODE")
class MyServiceTon : Service() {

    lateinit var mPlayer: MediaPlayer
    private var mLength = 0
    lateinit var mediaPlayer: MediaPlayer
    private var mediaLength = 0


    override fun onBind(intent: Intent): IBinder? {
          return null
    }



        override fun onCreate() {
            Log.i("Test","Service onCreate")
            mediaPlayer = MediaPlayer.create(this, R.raw.salamisound)
            mPlayer = MediaPlayer.create(this, R.raw.salamisound)
            super.onCreate()
        }



override fun onStartCommand(intent: Intent, flags: Int, startId: Int): Int {
    if (intent.hasExtra("Play")) {
        Log.i("Test","Service Play")
        playBordun()
    }
    if (intent.hasExtra("Pause")) {
        Log.i("Test","Service Pause")
        mLength = mPlayer.currentPosition
        mediaLength = mediaPlayer.currentPosition
        mPlayer.pause()
        mediaPlayer.pause()
        stopSelf()
    }
    if (intent.hasExtra("Stop")) {
        Log.i("Test","Service Stop")
        mLength = mPlayer.currentPosition
        mediaLength = mediaPlayer.currentPosition
        mPlayer.pause()
        mediaPlayer.pause()
        mPlayer.stop()
        mPlayer.release()
        mediaPlayer.stop()
        mediaPlayer.release()
        stopSelf()
    }
    return super.onStartCommand(intent, flags, startId)
}

override fun onDestroy() {
    Log.i("Test","Service onDestroy")
    super.onDestroy()
    stopSelf()
}

fun playBordun() {
    if (mediaPlayer.isLooping or mPlayer.isLooping) {
    } else {
        //mediaPlayer = MediaPlayer()
        //mPlayer = MediaPlayer()
        suspend fun playDelayed() {
            Log.i("Test","Service Suspend playDelayed")
            //mPlayer = MediaPlayer.create(this, R.raw.salamisound)
            mPlayer?.isLooping = true
            mPlayer?.start()
        }

        suspend fun playBordun() {
            Log.i("Test","Service Suspend playBordun")
            //mediaPlayer = MediaPlayer.create(this, R.raw.salamisound)
            mediaPlayer?.isLooping = true
            mediaPlayer?.start()
        }
        GlobalScope.launch {
            Log.i("Test","Service GlobalScore")
            playBordun()
            playDelayed()
        }
    }
}
}

Code:
 override fun onBackPressed() {
        flag= false
        val sIntent = Intent(this@MainActivity, MyServiceTon::class.java)
        sIntent.putExtra("Stop", "Ein")
        startService(sIntent)
        super.onBackPressed()
    }

bei mir wird der sound abgespielt
[doublepost=1549054586,1549053638][/doublepost]hast du mal gelesen was die Warnungen sagen?

wenn du den Player nur Stoppst bekommst du diese Meldungen nicht.

Code:
if (intent.hasExtra("Stop")) {
        Log.i("Test","Service Stop")
        //mLength = mPlayer.currentPosition
        //mediaLength = mediaPlayer.currentPosition
        //mPlayer.pause()
        //mediaPlayer.pause()
        mPlayer.stop()
        //mPlayer.release()
        mediaPlayer.stop()
        //mediaPlayer.release()
        stopSelf()
    }
 
Zuletzt bearbeitet:
  • Danke
Reaktionen: BraveSentry
Super! So funktionierts!

Ich hatte genau das vorher auch geändert, aber anders:

Code:
            if (intent.hasExtra("Stop")) {
                mLength = mPlayer.currentPosition
                mediaLength = mediaPlayer.currentPosition
                mPlayer.pause()
                mediaPlayer.pause()
                mPlayer.stop()
                mPlayer.reset()
                mPlayer.release()
                mediaPlayer.stop()
                mediaPlayer.reset()
                mediaPlayer.release()
            stopSelf()
        }

So hats aber auch funktioniert. Deine Lösung scheint mir aber sinnvoller, weil: Weniger Code.

Vielen Dank nochmal. Ich glaube, ich hätte da noch wesentlich länger gebraucht ohne deine Hilfe.
 
Ich mache wenig über komplettes Verstehen, mehr über trial and error.

Nur Probieren reicht da nicht etwas Grundlagenwissen sollte schon da sein. Und vorallen die Warnungen lesen deuten.

Wie so machst du immer das
mediaPlayer?.start() ich meine das Fragezeichen.

die Variable ist NotNullable lateinit var mPlayer: MediaPlayer

wenn du einen Compilerfehler bekommst dann mache nicht gleich das Fragezeichen rein sondern schaue erstmal warum das so ist.

so nun viel Spass

PS. du solltest auch das wieder entfernnen
@Suppress("UNREACHABLE_CODE")
das hatte ich nur zum Testen.
 
Zuletzt bearbeitet:
  • Danke
Reaktionen: BraveSentry
jogimuc schrieb:
Ich mache wenig über komplettes Verstehen, mehr über trial and error.

Nur Probieren reicht da nicht etwas Grundlagenwissen sollte schon da sein. Und vorallen die Warnungen lesen deuten.

Klar. Aber wenn man (wie ich vor ca. nem Monat) komplett ohne Grundlagenwissen startet, muss man schon noch gucken, was überhaupt die Grundlagen sind, die man für sein konkretes Projekt braucht.

Wie so machst du immer das
mediaPlayer?.start() ich meine das Fragezeichen.

die Variable ist NotNullable lateinit var mPlayer: MediaPlayer

wenn du einen Compilerfehler bekommst dann mache nicht gleich das Fragezeichen rein sondern schaue erstmal warum das so ist.

Ich hatte mal versucht die Bedingung für playBordun() daran zu knüpfen, ob (mPlayer == null and mediaPlayer == null). Die IDE hat mir dann gesagt, dass die beiden nicht nullable sind. Also hatte ich einfach statt der lateinit zeile dieses geschrieben: "var mPlayer: MediaPlayer? = null" Danach musste ich dann überall die ? anbringen und habe bisher noch nicht alle wieder entfernt.

so nun viel Spass

PS. du solltest auch das wieder entfernnen
@Suppress("UNREACHABLE_CODE")
das hatte ich nur zum Testen.

Mach ich.

Dir auch!
 
Das mit den = null solte man in kotlin nicht machen. In Java ist das was anderes.
Da giebt es keine Prüfung auf Null wie in kotlin das solltest du dir in kotlin nochmal genau anschauen. Die null Prüfung ist ein wichtiges Element in kotlin.

Auch ich binn erst vor 14 Tagen von Java zu Kotlin.
 

Ähnliche Themen

U
  • unerfahrenerAppEntwickler
Antworten
3
Aufrufe
704
swa00
swa00
M
  • maksimilian
Antworten
5
Aufrufe
857
maksimilian
M
Zurück
Oben Unten