@@ -40,9 +40,11 @@ import {
4040 isA11yEnabled ,
4141 setA11yEnabled ,
4242} from '../accessibility/accessibility-common' ;
43- import { androidGetForegroundActivity , androidGetStartActivity , androidPendingReceiverRegistrations , androidRegisterBroadcastReceiver , androidRegisteredReceivers , androidSetForegroundActivity , androidSetStartActivity , androidUnregisterBroadcastReceiver , applyContentDescription } from './helpers' ;
43+ import { androidGetForegroundActivity , androidGetStartActivity , androidSetForegroundActivity , androidSetStartActivity , applyContentDescription } from './helpers' ;
4444import { getImageFetcher , getNativeApp , getRootView , initImageCache , setA11yUpdatePropertiesCallback , setApplicationPropertiesCallback , setAppMainEntry , setNativeApp , setRootView , setToggleApplicationEventListenersCallback } from './helpers-common' ;
4545import { getNativeScriptGlobals } from '../globals/global-utils' ;
46+ import type { AndroidApplication as IAndroidApplication } from './application' ;
47+ import lazy from '../utils/lazy' ;
4648
4749declare class NativeScriptLifecycleCallbacks extends android . app . Application . ActivityLifecycleCallbacks { }
4850
@@ -276,7 +278,36 @@ function initNativeScriptComponentCallbacks() {
276278 return NativeScriptComponentCallbacks_ ;
277279}
278280
279- export class AndroidApplication extends ApplicationCommon {
281+ interface RegisteredReceiverInfo {
282+ receiver : android . content . BroadcastReceiver ;
283+ intent : string ;
284+ callback : ( context : android . content . Context , intent : android . content . Intent ) => void ;
285+ id : number ;
286+ flags : number ;
287+ }
288+
289+ const BroadcastReceiver = lazy ( ( ) => {
290+ @NativeClass
291+ class BroadcastReceiverImpl extends android . content . BroadcastReceiver {
292+ private _onReceiveCallback : ( context : android . content . Context , intent : android . content . Intent ) => void ;
293+
294+ constructor ( onReceiveCallback : ( context : android . content . Context , intent : android . content . Intent ) => void ) {
295+ super ( ) ;
296+ this . _onReceiveCallback = onReceiveCallback ;
297+
298+ return global . __native ( this ) ;
299+ }
300+
301+ public onReceive ( context : android . content . Context , intent : android . content . Intent ) {
302+ if ( this . _onReceiveCallback ) {
303+ this . _onReceiveCallback ( context , intent ) ;
304+ }
305+ }
306+ }
307+ return BroadcastReceiverImpl ;
308+ } ) ;
309+
310+ export class AndroidApplication extends ApplicationCommon implements IAndroidApplication {
280311 static readonly activityCreatedEvent = 'activityCreated' ;
281312 static readonly activityDestroyedEvent = 'activityDestroyed' ;
282313 static readonly activityStartedEvent = 'activityStarted' ;
@@ -332,10 +363,13 @@ export class AndroidApplication extends ApplicationCommon {
332363
333364 this . _registerPendingReceivers ( ) ;
334365 }
335-
366+ private _registeredReceivers : Record < string , RegisteredReceiverInfo [ ] > = { } ;
367+ private _registeredReceiversById : Record < number , RegisteredReceiverInfo > = { } ;
368+ private _nextReceiverId : number = 1 ;
369+ private _pendingReceiverRegistrations : Omit < RegisteredReceiverInfo , 'receiver' > [ ] = [ ] ;
336370 private _registerPendingReceivers ( ) {
337- androidPendingReceiverRegistrations . forEach ( ( func ) => func ( this . context ) ) ;
338- androidPendingReceiverRegistrations . length = 0 ;
371+ this . _pendingReceiverRegistrations . forEach ( ( info ) => this . _registerReceiver ( this . context , info . intent , info . callback , info . flags , info . id ) ) ;
372+ this . _pendingReceiverRegistrations . length = 0 ;
339373 }
340374
341375 onConfigurationChanged ( configuration : android . content . res . Configuration ) : void {
@@ -414,18 +448,69 @@ export class AndroidApplication extends ApplicationCommon {
414448 // RECEIVER_EXPORTED (2)
415449 // RECEIVER_NOT_EXPORTED (4)
416450 // RECEIVER_VISIBLE_TO_INSTANT_APPS (1)
417- public registerBroadcastReceiver ( intentFilter : string , onReceiveCallback : ( context : android . content . Context , intent : android . content . Intent ) => void , flags = 2 ) : void {
418- androidRegisterBroadcastReceiver ( intentFilter , onReceiveCallback , flags ) ;
451+ public registerBroadcastReceiver ( intentFilter : string , onReceiveCallback : ( context : android . content . Context , intent : android . content . Intent ) => void , flags = 2 ) : ( ) => void {
452+ const receiverId = this . _nextReceiverId ++ ;
453+ if ( this . context ) {
454+ this . _registerReceiver ( this . context , intentFilter , onReceiveCallback , flags , receiverId ) ;
455+ } else {
456+ this . _pendingReceiverRegistrations . push ( {
457+ intent : intentFilter ,
458+ callback : onReceiveCallback ,
459+ id : receiverId ,
460+ flags,
461+ } ) ;
462+ }
463+ let removed = false ;
464+ return ( ) => {
465+ if ( removed ) {
466+ return ;
467+ }
468+ removed = true ;
469+ if ( this . _registeredReceiversById [ receiverId ] ) {
470+ const receiverInfo = this . _registeredReceiversById [ receiverId ] ;
471+ this . context . unregisterReceiver ( receiverInfo . receiver ) ;
472+ this . _registeredReceivers [ receiverInfo . intent ] = this . _registeredReceivers [ receiverInfo . intent ] ?. filter ( ( ri ) => ri . id !== receiverId ) ;
473+ delete this . _registeredReceiversById [ receiverId ] ;
474+ } else {
475+ this . _pendingReceiverRegistrations = this . _pendingReceiverRegistrations . filter ( ( ri ) => ri . id !== receiverId ) ;
476+ }
477+ } ;
478+ }
479+ private _registerReceiver ( context : android . content . Context , intentFilter : string , onReceiveCallback : ( context : android . content . Context , intent : android . content . Intent ) => void , flags : number , id : number ) : android . content . BroadcastReceiver {
480+ const receiver : android . content . BroadcastReceiver = new ( BroadcastReceiver ( ) ) ( onReceiveCallback ) ;
481+ if ( SDK_VERSION >= 26 ) {
482+ context . registerReceiver ( receiver , new android . content . IntentFilter ( intentFilter ) , flags ) ;
483+ } else {
484+ context . registerReceiver ( receiver , new android . content . IntentFilter ( intentFilter ) ) ;
485+ }
486+ const receiverInfo : RegisteredReceiverInfo = { receiver, intent : intentFilter , callback : onReceiveCallback , id : typeof id === 'number' ? id : this . _nextReceiverId ++ , flags } ;
487+ this . _registeredReceivers [ intentFilter ] ??= [ ] ;
488+ this . _registeredReceivers [ intentFilter ] . push ( receiverInfo ) ;
489+ this . _registeredReceiversById [ receiverInfo . id ] = receiverInfo ;
490+ return receiver ;
419491 }
420492
421493 public unregisterBroadcastReceiver ( intentFilter : string ) : void {
422- androidUnregisterBroadcastReceiver ( intentFilter ) ;
494+ const receivers = this . _registeredReceivers [ intentFilter ] ;
495+ if ( receivers ) {
496+ receivers . forEach ( ( receiver ) => {
497+ this . context . unregisterReceiver ( receiver . receiver ) ;
498+ } ) ;
499+ this . _registeredReceivers [ intentFilter ] = [ ] ;
500+ }
423501 }
424502
425503 public getRegisteredBroadcastReceiver ( intentFilter : string ) : android . content . BroadcastReceiver | undefined {
426- return androidRegisteredReceivers [ intentFilter ] ;
504+ return this . _registeredReceivers [ intentFilter ] ?. [ 0 ] . receiver ;
427505 }
428506
507+ public getRegisteredBroadcastReceivers ( intentFilter : string ) : android . content . BroadcastReceiver [ ] {
508+ const receiversInfo = this . _registeredReceivers [ intentFilter ] ;
509+ if ( receiversInfo ) {
510+ return receiversInfo . map ( ( info ) => info . receiver ) ;
511+ }
512+ return [ ] ;
513+ }
429514 getRootView ( ) : View {
430515 const activity = this . foregroundActivity || this . startActivity ;
431516 if ( ! activity ) {
0 commit comments