Open nt4f04uNd opened 3 years ago
I think it did do something on older version of Android, where if the media session is no longer active and the user clicks the media button, then the OS will route the click through to the app. But simply overriding click
is not enough because the click won't be routed through unless we register with the OS that we want it to be in this inactive state. Things have definitely changed in Android 11 and I don't have an easy way of testing this anymore but I would probably wait a bit before phasing this out.
android 9 - does nothing androrid q and 11 same
But simply overriding click is not enough because the click won't be routed through unless we register with the OS that we want it to be in this inactive state
i believe you gotta drop the media session or something like that to do so. agree this is not quite important for now
Some relevant information:
https://developer.android.com/guide/topics/media-apps/mediabuttons#restarting-inactive-mediasessions
Yeah, it seems that my application is indeed being restarted in the background when a media button on the headphone is pressed (this is Android 10, not 11),while the app is not in the task list, without the notification. I use my app as a daily driver and I have noticed this multiple times. Is it somehow related?
@chengyuhui it could be interesting to experiment with that option to see if it does anything, but from memory I didn't have much success with it when I originally implemented that code for the old version of audio_service which ran the background audio task in a separate isolate. In the multi-isolate approach there were technical roadblocks preventing me from relaunching the background FlutterEngine to wake up the media session anyway, which is part of the reason for this new one-isolate
design. But this new one-isolate
design also coincided with the release of Android 11, and having upgraded my device, that's really now the only Android OS version I'm testing.
If people still need to test Android 10, I may rely on those of you who use it to report whether it supports this feature, and perhaps also contribute pull requests to fix any Android 10 behaviours.
Just caught this on my debugging app:
04-20 22:28:41.319 1947 8533 D MediaSessionService: Sending KeyEvent { action=ACTION_DOWN, keyCode=KEYCODE_MEDIA_PLAY, scanCode=0, metaState=0, flags=0x0, repeatCount=0, eventTime=0, downTime=0, deviceId=-1, source=0x0, displayId=0 } to the last known PendingIntent PendingIntent{4961a06: PendingIntentRecord{67b18c7 com.santiego.vtbmusic.debug broadcastIntent}}
04-20 22:28:41.321 8071 8436 V Avrcp_ext: Exit handleMessage
04-20 22:28:41.322 8071 8071 V Avrcp_ext: recordKeyDispatched: KeyEvent { action=ACTION_DOWN, keyCode=KEYCODE_MEDIA_PLAY, scanCode=0, metaState=0, flags=0x0, repeatCount=0, eventTime=0, downTime=0, deviceId=-1, source=0x0, displayId=0 } dispatched to com.santiego.vtbmusic.debug
04-20 22:28:41.322 8071 8071 V Avrcp_ext: Player 8 package: com.santiego.vtbmusic.debug
04-20 22:28:41.322 8071 8071 W Avrcp_ext: Trigger setAddressedMediaSessionPkg recordKeyDispatchcom.santiego.vtbmusic.debug
04-20 22:28:41.344 8071 8163 W bt_btif : handle_rc_passthrough_cmd: Send fake play release command
04-20 22:28:41.347 8071 8163 D Avrcp_ext: Enter handlePassthroughCmdRequestFromNative
04-20 22:28:41.349 8071 8163 D Avrcp_ext: Exit handlePassthroughCmdRequestFromNative
04-20 22:28:41.351 8071 8163 D bt_btif : btif_av_state_opened_handler event:BTA_AV_REMOTE_CMD_EVT flags 0 peer_sep 1 and index 0 reconfig_event: 0
04-20 22:28:41.352 8071 8163 D bt_btif : btif_rc_handler: event: BTA_AV_REMOTE_CMD_EVT
04-20 22:28:41.352 8071 8163 W bt_btif : BTHF: btif_hf_check_if_sco_connected(): No SCO connection up
04-20 22:28:41.352 8071 8163 W bt_btif : BTHF: btif_hf_check_if_sco_connected(): No SCO connection up
04-20 22:28:41.352 8071 8163 W bt_btif : handle_rc_passthrough_cmd: Ignore release command
04-20 22:28:41.355 8071 8436 V Avrcp_ext: AvrcpMessageHandler: received message=13
04-20 22:28:41.356 8071 8436 V Avrcp_ext: MSG_NATIVE_REQ_PASS_THROUGH: id=68 st=0
04-20 22:28:41.359 8071 8436 V Avrcp_ext: MSG_NATIVE_REQ_PASS_THROUGH 9E:BF:8C:9F:DC:EC
04-20 22:28:41.360 8071 8436 I Avrcp_ext: device found at index 0
04-20 22:28:41.361 8071 8436 D Avrcp_ext: passthrough from device: 9E:BF:8C:9F:DC:EC
04-20 22:28:41.363 805 8320 I vendor.qti.bluetooth@1.0-ibs_handler: ProcessIbsCmd: Received IBS_SLEEP_IND: 0xFE
04-20 22:28:41.364 8071 8436 D Avrcp_ext: Active device: 9E:BF:8C:9F:DC:EC
04-20 22:28:41.367 8071 8436 D Avrcp_ext: ignore_play: false
04-20 22:28:41.368 8071 8436 D Avrcp_ext: Avrcp current play state: 2 isMusicActive: false A2dp state: 11 Cached passthrough command: 126
04-20 22:28:41.369 8071 8436 D BATService: getBATService(): service is NULL
04-20 22:28:41.370 8071 8436 D Avrcp_ext: cached passthrough: 126current passthrough: 126
04-20 22:28:41.372 1947 8533 D MediaSessionService: Sending KeyEvent { action=ACTION_UP, keyCode=KEYCODE_MEDIA_PLAY, scanCode=0, metaState=0, flags=0x0, repeatCount=0, eventTime=0, downTime=0, deviceId=-1, source=0x0, displayId=0 } to the last known PendingIntent PendingIntent{4961a06: PendingIntentRecord{67b18c7 com.santiego.vtbmusic.debug broadcastIntent}}
04-20 22:28:41.380 8071 8436 V Avrcp_ext: Exit handleMessage
04-20 22:28:41.384 8071 8071 V Avrcp_ext: recordKeyDispatched: KeyEvent { action=ACTION_UP, keyCode=KEYCODE_MEDIA_PLAY, scanCode=0, metaState=0, flags=0x0, repeatCount=0, eventTime=0, downTime=0, deviceId=-1, source=0x0, displayId=0 } dispatched to com.santiego.vtbmusic.debug
04-20 22:28:41.384 8071 8071 V Avrcp_ext: Player 8 package: com.santiego.vtbmusic.debug
04-20 22:28:41.384 8071 8071 W Avrcp_ext: Trigger setAddressedMediaSessionPkg recordKeyDispatchcom.santiego.vtbmusic.debug
04-20 22:28:41.398 705 705 D Zygote : Forked child process 19261
04-20 22:28:41.400 704 29185 D OemNetd : setPidForPackage: packageName=com.santiego.vtbmusic.debug, pid=19261, pid=10414
04-20 22:28:41.400 1947 2063 I ActivityManager: Start proc 19261:com.santiego.vtbmusic.debug/u0a414 for broadcast {com.santiego.vtbmusic.debug/com.ryanheise.audioservice.MediaButtonReceiver} caller=com.santiego.vtbmusic.debug
04-20 22:28:41.424 19261 19261 I .vtbmusic.debu: Late-enabling -Xcheck:jni
04-20 22:28:41.470 19261 19261 E .vtbmusic.debu: Unknown bits set in runtime_flags: 0x8000
04-20 22:28:41.512 1947 8533 D CompatibilityInfo: mCompatibilityFlags - 0
04-20 22:28:41.512 1947 8533 D CompatibilityInfo: applicationDensity - 440
04-20 22:28:41.512 1947 8533 D CompatibilityInfo: applicationScale - 1.0
04-20 22:28:41.516 1947 8533 D CompatibilityInfo: mCompatibilityFlags - 0
04-20 22:28:41.516 1947 8533 D CompatibilityInfo: applicationDensity - 440
04-20 22:28:41.516 1947 8533 D CompatibilityInfo: applicationScale - 1.0
04-20 22:28:41.519 1947 2356 I MiuiNetworkPolicy: updateUidState uid = 10414, uidState = 12
04-20 22:28:41.651 19261 19261 I Perf : Connecting to perf service.
04-20 22:28:41.723 19261 19261 I FeatureParser: can't find polaris.xml in assets/device_features/,it may be in /system/etc/device_features
04-20 22:28:41.749 19261 19261 E libc : Access denied finding property "ro.vendor.df.effect.conflict"
04-20 22:28:41.750 19261 19261 E libc : Access denied finding property "ro.vendor.knock.type"
04-20 22:28:41.771 19261 19261 D MediaBrowserCompat: Connecting to a MediaBrowserService.
04-20 22:28:41.775 539 539 E SELinux : avc: denied { find } for interface=vendor.qti.hardware.servicetracker::IServicetracker sid=u:r:system_server:s0 pid=1947 scontext=u:r:system_server:s0 tcontext=u:object_r:default_android_hwservice:s0 tclass=hwservice_manager permissive=0
04-20 22:28:41.781 1947 8533 D CompatibilityInfo: mCompatibilityFlags - 0
04-20 22:28:41.781 1947 8533 D CompatibilityInfo: applicationDensity - 440
04-20 22:28:41.781 1947 8533 D CompatibilityInfo: applicationScale - 1.0
04-20 22:28:41.782 539 539 E SELinux : avc: denied { find } for interface=vendor.qti.hardware.servicetracker::IServicetracker sid=u:r:system_server:s0 pid=1947 scontext=u:r:system_server:s0 tcontext=u:object_r:default_android_hwservice:s0 tclass=hwservice_manager permissive=0
04-20 22:28:41.793 19261 19261 I System.out: ### onCreate
04-20 22:28:41.827 19261 19283 E Perf : Fail to get file list com.santiego.vtbmusic.debug
04-20 22:28:41.829 19261 19283 E Perf : getFolderSize() : Exception_1 = java.lang.NullPointerException: Attempt to get length of null array
04-20 22:28:41.829 19261 19283 E Perf : Fail to get file list oat
04-20 22:28:41.829 19261 19283 E Perf : getFolderSize() : Exception_1 = java.lang.NullPointerException: Attempt to get length of null array
04-20 22:28:41.834 1947 8533 D MediaSessionService: Media button session is changed to com.santiego.vtbmusic.debug/media-session (userId=0)
04-20 22:28:41.835 8071 8071 V Avrcp_ext: Set active media session com.santiego.vtbmusic.debug
04-20 22:28:41.835 8071 8071 D HeadsetService: getHeadsetService(): returning com.android.bluetooth.hfp.HeadsetService@5be0acf
04-20 22:28:41.836 8071 8071 D HeadsetService: isAudioOn: The number of audio connected devices 0
04-20 22:28:41.836 8071 8071 D HeadsetService: isScoOrCallActive(): Call Active:falseCall is Ringing:falseSCO is Active:false
04-20 22:28:41.836 8071 8071 D HeadsetService: isAudioOn: The number of audio connected devices 0
04-20 22:28:41.836 8071 8071 W Avrcp_ext: playState object null, sending STOPPED
04-20 22:28:41.836 8071 8071 V Avrcp_ext: isBrowseSupported for com.santiego.vtbmusic.debug: true
04-20 22:28:41.837 8071 8071 D Avrcp_ext: update #8:MediaPlayerInfo com.santiego.vtbmusic.debug (as 'VtuberMusic') Type = 1, SubType = 0, Status = 0 Feature Bits [40 41 42 44 45 47 48 58 59 62 65 67 68] Controller: MediaController (com.santiego.vtbmusic.debug@e510b14) null
04-20 22:28:41.837 8071 8071 V Avrcp_ext: updateNewIds: Addressed:8 to 8, Browse:0 to 0
04-20 22:28:41.837 8071 8071 D Avrcp_ext: updateCurrentController: null to MediaController (com.santiego.vtbmusic.debug@e510b14) null
04-20 22:28:41.839 8071 8071 V Avrcp_ext: updateCurrentMediaState: mMediaController: MediaController (com.santiego.vtbmusic.debug@e510b14) null
04-20 22:28:41.840 8071 8071 V Avrcp_ext: isMusicActive: false getBluetoothPlayState: 2
04-20 22:28:41.840 8071 8071 V Avrcp_ext: updateCurrentMediaState: isPlaying = false
04-20 22:28:41.840 8071 8071 D Avrcp_ext: updateCurrentMediaState: playState is null, mAudioManagerIsPlaying=false, isMusicActive=false
04-20 22:28:41.841 19261 19261 I System.out: ### AudioService will resume on click
04-20 22:28:41.841 8071 8071 V Avrcp_ext: updateCurrentMediaState: get media attributes:
04-20 22:28:41.842 8071 8071 I Avrcp_ext: device found at index 0
04-20 22:28:41.842 8071 8071 V Avrcp_ext: updateCurrentMediaState: addr: [B@f59ffbd
04-20 22:28:41.842 8071 8071 V Avrcp_ext: Media update: id -1➡-1? [MediaAttributes: none] : [MediaAttributes: none]
04-20 22:28:41.842 8071 8071 V Avrcp_ext: newPlayStatus:2mReportedPlayStatus:2
04-20 22:28:41.845 8071 8071 V Avrcp_ext: updatePlaybackState, state: PlaybackState {state=2, position=-1, buffered position=0, speed=0.0, updated=941659819, actions=0, custom actions=[], active item id=-1, error=null} device: null
04-20 22:28:41.846 19261 19261 I System.out: ### Creating new FlutterEngine
04-20 22:28:41.846 8071 8071 V Avrcp_ext: Device: Plus 5.0 : old state: PlaybackState {state=2, position=-1, buffered position=0, speed=0.0, updated=941006811, actions=0, custom actions=[], active item id=-1, error=null}
04-20 22:28:41.846 8071 8071 V Avrcp_ext: Device: no name:
04-20 22:28:41.846 8071 8071 V Avrcp_ext: Device: no name:
You can see that process 19261 is created by the system for our application from the receiver. The audio actually went on for a moment without notification before eventually being killed by the system.
I wonder why it got killed. Anything in the log about that? Maybe your app didn't trigger the commencement of the foreground service in time?
Upon further investigation I later see this:
04-20 22:29:10.718 19261 19261 E MethodChannel#com.ryanheise.audio_service.handler.methods: java.lang.IllegalStateException: Not allowed to start service Intent { cmp=com.santiego.vtbmusic.debug/com.ryanheise.audioservice.AudioService }: app is in background uid UidRecord{b62c7c7 u0a414 CEM idle change:cached procs:1 seq(0,0,0)}
04-20 22:29:10.718 19261 19261 E MethodChannel#com.ryanheise.audio_service.handler.methods: at android.app.ContextImpl.startServiceCommon(ContextImpl.java:1626)
04-20 22:29:10.718 19261 19261 E MethodChannel#com.ryanheise.audio_service.handler.methods: at android.app.ContextImpl.startService(ContextImpl.java:1581)
04-20 22:29:10.718 19261 19261 E MethodChannel#com.ryanheise.audio_service.handler.methods: at android.content.ContextWrapper.startService(ContextWrapper.java:679)
04-20 22:29:10.718 19261 19261 E MethodChannel#com.ryanheise.audio_service.handler.methods: at com.ryanheise.audioservice.AudioService.enterPlayingState(AudioService.java:530)
04-20 22:29:10.718 19261 19261 E MethodChannel#com.ryanheise.audio_service.handler.methods: at com.ryanheise.audioservice.AudioService.setState(AudioService.java:396)
04-20 22:29:10.718 19261 19261 E MethodChannel#com.ryanheise.audio_service.handler.methods: at com.ryanheise.audioservice.AudioServicePlugin$AudioHandlerInterface.onMethodCall(AudioServicePlugin.java:840)
04-20 22:29:10.718 19261 19261 E MethodChannel#com.ryanheise.audio_service.handler.methods: at io.flutter.plugin.common.MethodChannel$IncomingMethodCallHandler.onMessage(MethodChannel.java:233)
04-20 22:29:10.718 19261 19261 E MethodChannel#com.ryanheise.audio_service.handler.methods: at io.flutter.embedding.engine.dart.DartMessenger.handleMessageFromDart(DartMessenger.java:85)
04-20 22:29:10.718 19261 19261 E MethodChannel#com.ryanheise.audio_service.handler.methods: at io.flutter.embedding.engine.FlutterJNI.handlePlatformMessage(FlutterJNI.java:818)
04-20 22:29:10.718 19261 19261 E MethodChannel#com.ryanheise.audio_service.handler.methods: at android.os.MessageQueue.nativePollOnce(Native Method)
04-20 22:29:10.718 19261 19261 E MethodChannel#com.ryanheise.audio_service.handler.methods: at android.os.MessageQueue.next(MessageQueue.java:336)
04-20 22:29:10.718 19261 19261 E MethodChannel#com.ryanheise.audio_service.handler.methods: at android.os.Looper.loop(Looper.java:183)
04-20 22:29:10.718 19261 19261 E MethodChannel#com.ryanheise.audio_service.handler.methods: at android.app.ActivityThread.main(ActivityThread.java:7589)
04-20 22:29:10.718 19261 19261 E MethodChannel#com.ryanheise.audio_service.handler.methods: at java.lang.reflect.Method.invoke(Native Method)
04-20 22:29:10.718 19261 19261 E MethodChannel#com.ryanheise.audio_service.handler.methods: at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:539)
04-20 22:29:10.718 19261 19261 E MethodChannel#com.ryanheise.audio_service.handler.methods: at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:953)
04-20 22:29:10.734 19261 19288 E flutter : [ERROR:flutter/lib/ui/ui_dart_state.cc(186)] Unhandled Exception: PlatformException(error, Not allowed to start service Intent { cmp=com.santiego.vtbmusic.debug/com.ryanheise.audioservice.AudioService }: app is in background uid UidRecord{b62c7c7 u0a414 CEM idle change:cached procs:1 seq(0,0,0)}, null, java.lang.IllegalStateException: Not allowed to start service Intent { cmp=com.santiego.vtbmusic.debug/com.ryanheise.audioservice.AudioService }: app is in background uid UidRecord{b62c7c7 u0a414 CEM idle change:cached procs:1 seq(0,0,0)}
04-20 22:29:10.734 19261 19288 E flutter : at android.app.ContextImpl.startServiceCommon(ContextImpl.java:1626)
04-20 22:29:10.734 19261 19288 E flutter : at android.app.ContextImpl.startService(ContextImpl.java:1581)
04-20 22:29:10.734 19261 19288 E flutter : at android.content.ContextWrapper.startService(ContextWrapper.java:679)
04-20 22:29:10.734 19261 19288 E flutter : at com.ryanheise.audioservice.AudioService.enterPlayingState(AudioService.java:530)
04-20 22:29:10.734 19261 19288 E flutter : at com.ryanheise.audioservice.AudioService.setState(AudioService.java:396)
04-20 22:29:10.734 19261 19288 E flutter : at com.ryanheise.audioservice.AudioServicePlugin$AudioHandlerInterface.onMethodCall(AudioServicePlugin.java:840)
04-20 22:29:10.734 19261 19288 E flutter : at io.flutter.plugin.common.MethodChannel$IncomingMethodCallHandler.onMessage(MethodChannel.java:233)
04-20 22:29:10.734 19261 19288 E flutter : at io.flutter.embedding.engine.dart.DartMessenger.handleMessageFromDart(DartMessenger.java:85)
04-20 22:29:10.734 19261 19288 E flutter : at io.flutter.embedding.engine.FlutterJNI.handlePlatformMessage(FlutterJNI.java:818)
04-20 22:29:10.734 19261 19288 E flutter : at android.os.MessageQueue.nativePollOnce(Native Method)
04-20 22:29:10.734 19261 19288 E flutter : at android.os.MessageQueue.next(MessageQueue.java:336)
04-20 22:29:10.734 19261 19288 E flutter : at android.os.Looper.loop(Looper.java:183)
04-20 22:29:10.734 19261 19288 E flutter : at android.app.ActivityThread.main(ActivityThread.java:7589)
04-20 22:29:10.734 19261 19288 E flutter : at java.lang.reflect.Method.invoke(Native Method)
04-20 22:29:10.734 19261 19288 E flutter : at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:539)
04-20 22:29:10.734 19261 19288 E flutter : at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:953)
04-20 22:29:10.734 19261 19288 E flutter : )
04-20 22:29:10.734 19261 19288 E flutter : #0 StandardMethodCodec.decodeEnvelope (package:flutter/src/services/message_codecs.dart:581:7)
04-20 22:29:10.734 19261 19288 E flutter : #1 MethodChannel._invokeMethod (package:flutter/src/services/platform_channel.dart:158:18)
04-20 22:29:10.734 19261 19288 E flutter : <asynchronous suspension>
04-20 22:29:10.734 19261 19288 E flutter : #2 MethodChannelAudioService.setState (package:audio_service_platform_interface/method_channel_audio_service.dart:19:5)
04-20 22:29:10.734 19261 19288 E flutter : <asynchronous suspension>
04-20 22:29:10.734 19261 19288 E flutter : #3 AudioService.init.<anonymous closure> (package:audio_service/audio_service.dart:941:7)
04-20 22:29:10.734 19261 19288 E flutter : <asynchronous suspension>
04-20 22:29:10.734 19261 19288 E flutter :
04-20 22:29:10.838 19261 19261 W .vtbmusic.debu: Accessing hidden method Landroid/media/AudioTrack;->getLatency()I (greylist, reflection, allowed)
04-20 22:29:10.847 19261 19261 I ExoPlayerImpl: Init b8ff390 [ExoPlayerLib/2.13.1] [polaris, MIX 2S, Xiaomi, 29]
04-20 22:29:10.864 19261 19261 D AudioManager: getStreamVolume isRestricted mode = 0
Which explains a lot, as a foreground service can not appear from nowhere.
Playing is triggered via
04-20 22:29:10.651 19261 19261 I System.out: ### onMediaButtonEvent: KeyEvent { action=ACTION_DOWN, keyCode=KEYCODE_MEDIA_PLAY, scanCode=0, metaState=0, flags=0x0, repeatCount=0, eventTime=0, downTime=0, deviceId=-1, source=0x0, displayId=0 }
04-20 22:29:10.652 19261 19261 I System.out: ### listener = com.ryanheise.audioservice.AudioServicePlugin$AudioHandlerInterface@7f44e15
04-20 22:29:10.652 19261 19261 I System.out: ### calling onClick
04-20 22:29:10.653 19261 19261 I System.out: ### sending click map: {button=0}
04-20 22:29:10.654 19261 19261 I System.out: ### called onClick
04-20 22:29:10.657 19261 19288 I flutter : ### received click: {button: 0}
04-20 22:29:10.657 19261 19288 I flutter : button value is "0"
04-20 22:29:10.657 19261 19288 I flutter : type: int
04-20 22:29:10.657 19261 19288 I flutter : ### calling handler.click(MediaButton.media)
04-20 22:29:10.657 19261 19288 I flutter : ### Play
OK, this has to do with starting a foreground service from the background which is something I've not implemented yet since there are some restrictions on the context from which a foreground service can be started from the background. I guess as a consequence, that is tripping up the androidResumeOnClick
feature. Note that Android 11's media session resumption feature is able to start the foreground service directly which is why I think it doesn't run into the same limitation.
Anyway, in terms of fixing this, I came across this S/O post:
It indicates that the service can't be started in the foreground from the activity's onCreate
, it must wait until at least after onResume
.
I actually noticed that some requests related to my app's home page is being triggered, so something has certainly started.
However, the activity is never visible the whole time, is it ever considered foreground
so that we may start services?
So what is the full test scenario in terms of launching the app, clicking this and that, then running into the error?
Do we know if the activity is at least created, even if not visible?
KEYCODE_MEDIA_PLAY
automatically when it is put into my earIt looks like only the receiver and service are started, and the activity was nowhere to be found.
I expect this can be fixed by using startForegroundService
.
In AudioService.java
:
private boolean enterPlayingState() {
// CHANGE THIS TO startServiceForeground
startService(new Intent(AudioService.this, AudioService.class));
if (!mediaSession.isActive())
mediaSession.setActive(true);
acquireWakeLock();
mediaSession.setSessionActivity(contentIntent);
internalStartForeground();
return true;
}
Do you want to give it a try?
I will have a try tomorrow, as it's just past midnight here and I have no access to my workstation.
why did you not use startForegroundService in the first place?
Historical reasons which predate the announcement of the startForegroundService
API, combined with the fact that after it was introduced I didn't actually need it for my own use cases. I suppose attention to this was just waiting for someone such as yourself to come along and make it into an issue ;-)
Can confirm that the service is started normally with correct notification after this change.
Perfect! By the way, I'm happy for you to share that fix in the form of a pull request and merge it (if you'd like to). Otherwise, I can add the code myself.
I opted not to close this issue as the original problem seems to be still there.
we should move this into onStartCommand doing this - is dangerous, since service may be started before we startForeground, which will cause a crash with startForegroundService
I don't see any harm in replacing startService
by startForegroundService
, all else being equal.
In the current code startService
is always called before startForeground
, and there are no conceivable variations where sometimes things might not be called in the right order.
startForegroundService gets called before internalStartForeground if it happens that service's onStartCommand completes before startForeground, which we can't be sure won't happen, this wall cause a crash
there are no conceivable variations where sometimes things might not be called in the right order
i'm not sure what you mean
The only requirement I'm aware of is that you have an ANR's worth of time after calling startForegroundService
before you must call startForeground
, and we meet that requirement. I haven't read anywhere that it is tied to the completion of onStartCommand
, and the uamp sample app doesn't seem to code around such a requirement:
@ryanheise Sorry for touching this really old issue. I have found it from the source comments. It seems the androidResumeOnClick now should work as expected. At least on new Android devices. Can you please give your opinion on this? Maybe you have already fixed this issue.
I'm not sure if this option is useful on recent versions of Android since notifications associated with media sessions aren't handled by the OS as ordinary notifications, they appear in the carousel even after the media session is stopped, unless you go to the system settings to force those notifications to be cleared. So my understanding is that this is an option for older versions of Android.
The only comment I've left in the code is about whether we should be using STOP_FOREGROUND_DETACH instead of zero if we want that notification to persist as long as possible, but I'm not going to change it unless someone who is developing for an older version of Android comes with a use case to clarify how they would ideally want it to work.
Thank you very much for your explanation, @ryanheise!
Which API doesn't behave as documented, and how does it misbehave? as titled
Minimal reproduction project example project with androidResumeOnClick set to false
To Reproduce (i.e. user steps, not code) send hook key like this
Error messages no
Expected behavior should not resume (and by the way because notification buttons are handled via the MediaButtonReceiver, the notification should become unaccessible too)
Screenshots no
Runtime Environment (please complete the following information if relevant): see flutter doctor
Flutter SDK version
flutter doctor -v
``` [✓] Flutter (Channel master, 2.1.0-13.0.pre.386, on Microsoft Windows [Version 10.0.19041.867], locale ru-RU) • Flutter version 2.1.0-13.0.pre.386 at c:\dev\src\flutter • Framework revision 66af44c9fe (54 minutes ago), 2021-04-01 10:22:37 -0700 • Engine revision 9651d11fe8 • Dart version 2.13.0 (build 2.13.0-190.0.dev) [✓] Android toolchain - develop for Android devices (Android SDK version 30.0.2) • Android SDK at C:\Users\danya\AppData\Local\Android\sdk • Platform android-30, build-tools 30.0.2 • Java binary at: C:\Program Files\Android\Android Studio\jre\bin\java • Java version OpenJDK Runtime Environment (build 1.8.0_242-release-1644-b01) • All Android licenses accepted. [✓] Chrome - develop for the web • Chrome at C:\Program Files\Google\Chrome\Application\chrome.exe [✓] Visual Studio - develop for Windows (Visual Studio Community 2019 16.7.7) • Visual Studio at C:\Program Files (x86)\Microsoft Visual Studio\2019\Community • Visual Studio Community 2019 version 16.7.30621.155 • Windows 10 SDK version 10.0.19041.0 [✓] Android Studio (version 4.0) • Android Studio at C:\Program Files\Android\Android Studio • Flutter plugin version 50.0.1 • Dart plugin version 193.7547 • Java version OpenJDK Runtime Environment (build 1.8.0_242-release-1644-b01) [✓] IntelliJ IDEA Community Edition (version 2020.3) • IntelliJ at C:\Program Files\JetBrains\IntelliJ IDEA Community Edition 2020.3.3 • Flutter plugin can be installed from: 🔨 https://plugins.jetbrains.com/plugin/9212-flutter • Dart plugin can be installed from: 🔨 https://plugins.jetbrains.com/plugin/6351-dart [✓] VS Code (version 1.55.0) • VS Code at C:\Users\danya\AppData\Local\Programs\Microsoft VS Code • Flutter extension version 3.21.0 [✓] Connected device (3 available) • Windows (desktop) • windows • windows-x64 • Microsoft Windows [Version 10.0.19041.867] • Chrome (web) • chrome • web-javascript • Google Chrome 89.0.4389.90 • Edge (web) • edge • web-javascript • Microsoft Edge 89.0.774.63 • No issues found! ```Additional context i think this option should be removed, since we always can override
click
to achieve the same effect