mirror of
				https://github.com/NativeScript/NativeScript.git
				synced 2025-11-04 12:58:38 +08:00 
			
		
		
		
	
		
			
				
	
	
		
			553 lines
		
	
	
		
			19 KiB
		
	
	
	
		
			TypeScript
		
	
	
	
	
	
			
		
		
	
	
			553 lines
		
	
	
		
			19 KiB
		
	
	
	
		
			TypeScript
		
	
	
	
	
	
import { profile } from '../profiling';
 | 
						|
import { View } from '../ui/core/view';
 | 
						|
import { isEmbedded } from '../ui/embedding';
 | 
						|
import { AndroidActivityCallbacks, NavigationEntry } from '../ui/frame/frame-common';
 | 
						|
import { SDK_VERSION } from '../utils/constants';
 | 
						|
import type { AndroidApplication as IAndroidApplication } from './application';
 | 
						|
import { ApplicationCommon } from './application-common';
 | 
						|
import type { AndroidActivityBundleEventData, AndroidActivityEventData, ApplicationEventData } from './application-interfaces';
 | 
						|
 | 
						|
declare namespace com {
 | 
						|
	namespace tns {
 | 
						|
		class NativeScriptApplication extends android.app.Application {
 | 
						|
			static getInstance(): NativeScriptApplication;
 | 
						|
		}
 | 
						|
 | 
						|
		namespace embedding {
 | 
						|
			class ApplicationHolder {
 | 
						|
				static getInstance(): android.app.Application;
 | 
						|
			}
 | 
						|
		}
 | 
						|
	}
 | 
						|
}
 | 
						|
 | 
						|
declare class BroadcastReceiver extends android.content.BroadcastReceiver {
 | 
						|
	constructor(onReceiveCallback: (context: android.content.Context, intent: android.content.Intent) => void);
 | 
						|
}
 | 
						|
 | 
						|
let BroadcastReceiver_: typeof BroadcastReceiver;
 | 
						|
function initBroadcastReceiver() {
 | 
						|
	if (BroadcastReceiver_) {
 | 
						|
		return BroadcastReceiver_;
 | 
						|
	}
 | 
						|
 | 
						|
	@NativeClass
 | 
						|
	class BroadcastReceiverImpl extends android.content.BroadcastReceiver {
 | 
						|
		private _onReceiveCallback: (context: android.content.Context, intent: android.content.Intent) => void;
 | 
						|
 | 
						|
		constructor(onReceiveCallback: (context: android.content.Context, intent: android.content.Intent) => void) {
 | 
						|
			super();
 | 
						|
			this._onReceiveCallback = onReceiveCallback;
 | 
						|
 | 
						|
			return global.__native(this);
 | 
						|
		}
 | 
						|
 | 
						|
		public onReceive(context: android.content.Context, intent: android.content.Intent) {
 | 
						|
			if (this._onReceiveCallback) {
 | 
						|
				this._onReceiveCallback(context, intent);
 | 
						|
			}
 | 
						|
		}
 | 
						|
	}
 | 
						|
 | 
						|
	BroadcastReceiver_ = BroadcastReceiverImpl;
 | 
						|
	return BroadcastReceiver_;
 | 
						|
}
 | 
						|
 | 
						|
declare class NativeScriptLifecycleCallbacks extends android.app.Application.ActivityLifecycleCallbacks {}
 | 
						|
 | 
						|
let NativeScriptLifecycleCallbacks_: typeof NativeScriptLifecycleCallbacks;
 | 
						|
function initNativeScriptLifecycleCallbacks() {
 | 
						|
	if (NativeScriptLifecycleCallbacks_) {
 | 
						|
		return NativeScriptLifecycleCallbacks_;
 | 
						|
	}
 | 
						|
 | 
						|
	@NativeClass
 | 
						|
	@JavaProxy('org.nativescript.NativeScriptLifecycleCallbacks')
 | 
						|
	class NativeScriptLifecycleCallbacksImpl extends android.app.Application.ActivityLifecycleCallbacks {
 | 
						|
		private activitiesCount: number = 0;
 | 
						|
		private nativescriptActivity: androidx.appcompat.app.AppCompatActivity;
 | 
						|
 | 
						|
		@profile
 | 
						|
		public onActivityCreated(activity: androidx.appcompat.app.AppCompatActivity, savedInstanceState: android.os.Bundle): void {
 | 
						|
			// console.log('NativeScriptLifecycleCallbacks onActivityCreated');
 | 
						|
			this.setThemeOnLaunch(activity);
 | 
						|
 | 
						|
			if (!Application.android.startActivity) {
 | 
						|
				Application.android.setStartActivity(activity);
 | 
						|
			}
 | 
						|
 | 
						|
			if (!this.nativescriptActivity && 'isNativeScriptActivity' in activity) {
 | 
						|
				this.nativescriptActivity = activity;
 | 
						|
			}
 | 
						|
 | 
						|
			this.notifyActivityCreated(activity, savedInstanceState);
 | 
						|
 | 
						|
			if (Application.hasListeners(Application.displayedEvent)) {
 | 
						|
				this.subscribeForGlobalLayout(activity);
 | 
						|
			}
 | 
						|
		}
 | 
						|
 | 
						|
		@profile
 | 
						|
		public onActivityDestroyed(activity: androidx.appcompat.app.AppCompatActivity): void {
 | 
						|
			// console.log('NativeScriptLifecycleCallbacks onActivityDestroyed');
 | 
						|
			if (activity === Application.android.foregroundActivity) {
 | 
						|
				Application.android.setForegroundActivity(undefined);
 | 
						|
			}
 | 
						|
 | 
						|
			if (activity === this.nativescriptActivity) {
 | 
						|
				this.nativescriptActivity = undefined;
 | 
						|
			}
 | 
						|
 | 
						|
			if (activity === Application.android.startActivity) {
 | 
						|
				Application.android.setStartActivity(undefined);
 | 
						|
 | 
						|
				// Fallback for start activity when it is destroyed but we have a known nativescript activity
 | 
						|
				if (this.nativescriptActivity) {
 | 
						|
					Application.android.setStartActivity(this.nativescriptActivity);
 | 
						|
				}
 | 
						|
			}
 | 
						|
 | 
						|
			Application.android.notify({
 | 
						|
				eventName: Application.android.activityDestroyedEvent,
 | 
						|
				object: Application.android,
 | 
						|
				activity,
 | 
						|
			} as AndroidActivityEventData);
 | 
						|
 | 
						|
			// TODO: This is a temporary workaround to force the V8's Garbage Collector, which will force the related Java Object to be collected.
 | 
						|
			gc();
 | 
						|
		}
 | 
						|
 | 
						|
		@profile
 | 
						|
		public onActivityPaused(activity: androidx.appcompat.app.AppCompatActivity): void {
 | 
						|
			// console.log('NativeScriptLifecycleCallbacks onActivityPaused');
 | 
						|
			if ('isNativeScriptActivity' in activity) {
 | 
						|
				Application.setSuspended(true, {
 | 
						|
					// todo: deprecate event.android in favor of event.activity
 | 
						|
					android: activity,
 | 
						|
					activity,
 | 
						|
				});
 | 
						|
			}
 | 
						|
 | 
						|
			Application.android.notify({
 | 
						|
				eventName: Application.android.activityPausedEvent,
 | 
						|
				object: Application.android,
 | 
						|
				activity,
 | 
						|
			} as AndroidActivityEventData);
 | 
						|
		}
 | 
						|
 | 
						|
		@profile
 | 
						|
		public onActivityResumed(activity: androidx.appcompat.app.AppCompatActivity): void {
 | 
						|
			// console.log('NativeScriptLifecycleCallbacks onActivityResumed');
 | 
						|
			Application.android.setForegroundActivity(activity);
 | 
						|
 | 
						|
			// NOTE: setSuspended(false) is called in frame/index.android.ts inside onPostResume
 | 
						|
			// This is done to ensure proper timing for the event to be raised
 | 
						|
 | 
						|
			Application.android.notify({
 | 
						|
				eventName: Application.android.activityResumedEvent,
 | 
						|
				object: Application.android,
 | 
						|
				activity,
 | 
						|
			} as AndroidActivityEventData);
 | 
						|
		}
 | 
						|
 | 
						|
		@profile
 | 
						|
		public onActivitySaveInstanceState(activity: androidx.appcompat.app.AppCompatActivity, bundle: android.os.Bundle): void {
 | 
						|
			// console.log('NativeScriptLifecycleCallbacks onActivitySaveInstanceState');
 | 
						|
 | 
						|
			Application.android.notify({
 | 
						|
				eventName: Application.android.saveActivityStateEvent,
 | 
						|
				object: Application.android,
 | 
						|
				activity,
 | 
						|
				bundle,
 | 
						|
			} as AndroidActivityBundleEventData);
 | 
						|
		}
 | 
						|
 | 
						|
		@profile
 | 
						|
		public onActivityStarted(activity: androidx.appcompat.app.AppCompatActivity): void {
 | 
						|
			// console.log('NativeScriptLifecycleCallbacks onActivityStarted');
 | 
						|
 | 
						|
			this.activitiesCount++;
 | 
						|
			if (this.activitiesCount === 1) {
 | 
						|
				Application.android.setInBackground(false, {
 | 
						|
					// todo: deprecate event.android in favor of event.activity
 | 
						|
					android: activity,
 | 
						|
					activity,
 | 
						|
				});
 | 
						|
			}
 | 
						|
 | 
						|
			Application.android.notify({
 | 
						|
				eventName: Application.android.activityStartedEvent,
 | 
						|
				object: Application.android,
 | 
						|
				activity,
 | 
						|
			} as AndroidActivityEventData);
 | 
						|
		}
 | 
						|
 | 
						|
		@profile
 | 
						|
		public onActivityStopped(activity: androidx.appcompat.app.AppCompatActivity): void {
 | 
						|
			// console.log('NativeScriptLifecycleCallbacks onActivityStopped');
 | 
						|
			this.activitiesCount--;
 | 
						|
			if (this.activitiesCount === 0) {
 | 
						|
				Application.android.setInBackground(true, {
 | 
						|
					// todo: deprecate event.android in favor of event.activity
 | 
						|
					android: activity,
 | 
						|
					activity,
 | 
						|
				});
 | 
						|
			}
 | 
						|
 | 
						|
			Application.android.notify({
 | 
						|
				eventName: Application.android.activityStoppedEvent,
 | 
						|
				object: Application.android,
 | 
						|
				activity,
 | 
						|
			} as AndroidActivityEventData);
 | 
						|
		}
 | 
						|
 | 
						|
		@profile
 | 
						|
		setThemeOnLaunch(activity: androidx.appcompat.app.AppCompatActivity) {
 | 
						|
			// Set app theme after launch screen was used during startup
 | 
						|
			const activityInfo = activity.getPackageManager().getActivityInfo(activity.getComponentName(), android.content.pm.PackageManager.GET_META_DATA);
 | 
						|
			if (activityInfo.metaData) {
 | 
						|
				const setThemeOnLaunch = activityInfo.metaData.getInt('SET_THEME_ON_LAUNCH', -1);
 | 
						|
				if (setThemeOnLaunch !== -1) {
 | 
						|
					activity.setTheme(setThemeOnLaunch);
 | 
						|
				}
 | 
						|
			}
 | 
						|
		}
 | 
						|
 | 
						|
		@profile
 | 
						|
		notifyActivityCreated(activity: androidx.appcompat.app.AppCompatActivity, bundle: android.os.Bundle) {
 | 
						|
			Application.android.notify({
 | 
						|
				eventName: Application.android.activityCreatedEvent,
 | 
						|
				object: Application.android,
 | 
						|
				activity,
 | 
						|
				bundle,
 | 
						|
			} as AndroidActivityBundleEventData);
 | 
						|
		}
 | 
						|
 | 
						|
		@profile
 | 
						|
		subscribeForGlobalLayout(activity: androidx.appcompat.app.AppCompatActivity) {
 | 
						|
			const rootView = activity.getWindow().getDecorView().getRootView();
 | 
						|
			// store the listener not to trigger GC collection before collecting the method
 | 
						|
			global.onGlobalLayoutListener = new android.view.ViewTreeObserver.OnGlobalLayoutListener({
 | 
						|
				onGlobalLayout() {
 | 
						|
					Application.android.notify({
 | 
						|
						eventName: Application.displayedEvent,
 | 
						|
						object: Application,
 | 
						|
						android: Application.android,
 | 
						|
						activity,
 | 
						|
					} as AndroidActivityEventData);
 | 
						|
					const viewTreeObserver = rootView.getViewTreeObserver();
 | 
						|
					viewTreeObserver.removeOnGlobalLayoutListener(global.onGlobalLayoutListener);
 | 
						|
				},
 | 
						|
			});
 | 
						|
			rootView.getViewTreeObserver().addOnGlobalLayoutListener(global.onGlobalLayoutListener);
 | 
						|
		}
 | 
						|
	}
 | 
						|
 | 
						|
	NativeScriptLifecycleCallbacks_ = NativeScriptLifecycleCallbacksImpl;
 | 
						|
	return NativeScriptLifecycleCallbacks_;
 | 
						|
}
 | 
						|
 | 
						|
declare class NativeScriptComponentCallbacks extends android.content.ComponentCallbacks2 {}
 | 
						|
 | 
						|
let NativeScriptComponentCallbacks_: typeof NativeScriptComponentCallbacks;
 | 
						|
function initNativeScriptComponentCallbacks() {
 | 
						|
	if (NativeScriptComponentCallbacks_) {
 | 
						|
		return NativeScriptComponentCallbacks_;
 | 
						|
	}
 | 
						|
 | 
						|
	@NativeClass
 | 
						|
	@JavaProxy('org.nativescript.NativeScriptComponentCallbacks')
 | 
						|
	class NativeScriptComponentCallbacksImpl extends android.content.ComponentCallbacks2 {
 | 
						|
		@profile
 | 
						|
		public onLowMemory(): void {
 | 
						|
			gc();
 | 
						|
			java.lang.System.gc();
 | 
						|
 | 
						|
			Application.notify({
 | 
						|
				eventName: Application.lowMemoryEvent,
 | 
						|
				object: Application,
 | 
						|
				android: this,
 | 
						|
			} as ApplicationEventData);
 | 
						|
		}
 | 
						|
 | 
						|
		@profile
 | 
						|
		public onTrimMemory(level: number): void {
 | 
						|
			// TODO: This is skipped for now, test carefully for OutOfMemory exceptions
 | 
						|
		}
 | 
						|
 | 
						|
		@profile
 | 
						|
		public onConfigurationChanged(newConfiguration: android.content.res.Configuration): void {
 | 
						|
			Application.android.onConfigurationChanged(newConfiguration);
 | 
						|
		}
 | 
						|
	}
 | 
						|
 | 
						|
	NativeScriptComponentCallbacks_ = NativeScriptComponentCallbacksImpl;
 | 
						|
	return NativeScriptComponentCallbacks_;
 | 
						|
}
 | 
						|
 | 
						|
export class AndroidApplication extends ApplicationCommon implements IAndroidApplication {
 | 
						|
	static readonly activityCreatedEvent = 'activityCreated';
 | 
						|
	static readonly activityDestroyedEvent = 'activityDestroyed';
 | 
						|
	static readonly activityStartedEvent = 'activityStarted';
 | 
						|
	static readonly activityPausedEvent = 'activityPaused';
 | 
						|
	static readonly activityResumedEvent = 'activityResumed';
 | 
						|
	static readonly activityStoppedEvent = 'activityStopped';
 | 
						|
	static readonly saveActivityStateEvent = 'saveActivityState';
 | 
						|
	static readonly activityResultEvent = 'activityResult';
 | 
						|
	static readonly activityBackPressedEvent = 'activityBackPressed';
 | 
						|
	static readonly activityNewIntentEvent = 'activityNewIntent';
 | 
						|
	static readonly activityRequestPermissionsEvent = 'activityRequestPermissions';
 | 
						|
 | 
						|
	readonly activityCreatedEvent = AndroidApplication.activityCreatedEvent;
 | 
						|
	readonly activityDestroyedEvent = AndroidApplication.activityDestroyedEvent;
 | 
						|
	readonly activityStartedEvent = AndroidApplication.activityStartedEvent;
 | 
						|
	readonly activityPausedEvent = AndroidApplication.activityPausedEvent;
 | 
						|
	readonly activityResumedEvent = AndroidApplication.activityResumedEvent;
 | 
						|
	readonly activityStoppedEvent = AndroidApplication.activityStoppedEvent;
 | 
						|
	readonly saveActivityStateEvent = AndroidApplication.saveActivityStateEvent;
 | 
						|
	readonly activityResultEvent = AndroidApplication.activityResultEvent;
 | 
						|
	readonly activityBackPressedEvent = AndroidApplication.activityBackPressedEvent;
 | 
						|
	readonly activityNewIntentEvent = AndroidApplication.activityNewIntentEvent;
 | 
						|
	readonly activityRequestPermissionsEvent = AndroidApplication.activityRequestPermissionsEvent;
 | 
						|
 | 
						|
	private _nativeApp: android.app.Application;
 | 
						|
	private _context: android.content.Context;
 | 
						|
	private _packageName: string;
 | 
						|
 | 
						|
	// we are using these property to store the callbacks to avoid early GC collection which would trigger MarkReachableObjects
 | 
						|
	private lifecycleCallbacks: NativeScriptLifecycleCallbacks;
 | 
						|
	private componentCallbacks: NativeScriptComponentCallbacks;
 | 
						|
 | 
						|
	init(nativeApp: android.app.Application): void {
 | 
						|
		if (this.nativeApp === nativeApp) {
 | 
						|
			return;
 | 
						|
		}
 | 
						|
 | 
						|
		if (this.nativeApp) {
 | 
						|
			throw new Error('Application.android already initialized.');
 | 
						|
		}
 | 
						|
 | 
						|
		this._nativeApp = nativeApp;
 | 
						|
		this._context = nativeApp.getApplicationContext();
 | 
						|
		this._packageName = nativeApp.getPackageName();
 | 
						|
 | 
						|
		// we store those callbacks and add a function for clearing them later so that the objects will be eligable for GC
 | 
						|
		this.lifecycleCallbacks = new (initNativeScriptLifecycleCallbacks())();
 | 
						|
		this.nativeApp.registerActivityLifecycleCallbacks(this.lifecycleCallbacks);
 | 
						|
 | 
						|
		this.componentCallbacks = new (initNativeScriptComponentCallbacks())();
 | 
						|
		this.nativeApp.registerComponentCallbacks(this.componentCallbacks);
 | 
						|
 | 
						|
		this._registerPendingReceivers();
 | 
						|
	}
 | 
						|
 | 
						|
	private _registeredReceivers = {};
 | 
						|
	private _pendingReceiverRegistrations = new Array<(context: android.content.Context) => void>();
 | 
						|
	private _registerPendingReceivers() {
 | 
						|
		this._pendingReceiverRegistrations.forEach((func) => func(this.context));
 | 
						|
		this._pendingReceiverRegistrations.length = 0;
 | 
						|
	}
 | 
						|
 | 
						|
	onConfigurationChanged(configuration: android.content.res.Configuration): void {
 | 
						|
		this.setOrientation(this.getOrientationValue(configuration));
 | 
						|
		this.setSystemAppearance(this.getSystemAppearanceValue(configuration));
 | 
						|
	}
 | 
						|
 | 
						|
	getNativeApplication() {
 | 
						|
		let nativeApp = this.nativeApp;
 | 
						|
 | 
						|
		if (nativeApp) {
 | 
						|
			return nativeApp;
 | 
						|
		}
 | 
						|
 | 
						|
		// Try getting it from module - check whether application.android.init has been explicitly called
 | 
						|
		// check whether the com.tns.NativeScriptApplication type exists
 | 
						|
		if (com.tns.NativeScriptApplication) {
 | 
						|
			nativeApp = com.tns.NativeScriptApplication.getInstance();
 | 
						|
		}
 | 
						|
 | 
						|
		if (!nativeApp && isEmbedded()) {
 | 
						|
			nativeApp = com.tns.embedding.ApplicationHolder.getInstance();
 | 
						|
		}
 | 
						|
 | 
						|
		// the getInstance might return null if com.tns.NativeScriptApplication exists but is not the starting app type
 | 
						|
		if (!nativeApp) {
 | 
						|
			// TODO: Should we handle the case when a custom application type is provided and the user has not explicitly initialized the application module?
 | 
						|
			const clazz = java.lang.Class.forName('android.app.ActivityThread');
 | 
						|
			if (clazz) {
 | 
						|
				const method = clazz.getMethod('currentApplication', null);
 | 
						|
				if (method) {
 | 
						|
					nativeApp = method.invoke(null, null);
 | 
						|
				}
 | 
						|
			}
 | 
						|
		}
 | 
						|
 | 
						|
		// we cannot work without having the app instance
 | 
						|
		if (!nativeApp) {
 | 
						|
			throw new Error("Failed to retrieve native Android Application object. If you have a custom android.app.Application type implemented make sure that you've called the 'Application.android.init' method.");
 | 
						|
		}
 | 
						|
 | 
						|
		return nativeApp;
 | 
						|
	}
 | 
						|
 | 
						|
	get nativeApp(): android.app.Application {
 | 
						|
		return this._nativeApp;
 | 
						|
	}
 | 
						|
 | 
						|
	run(entry?: string | NavigationEntry): void {
 | 
						|
		if (this.started) {
 | 
						|
			throw new Error('Application is already started.');
 | 
						|
		}
 | 
						|
 | 
						|
		this.started = true;
 | 
						|
		this.mainEntry = typeof entry === 'string' ? { moduleName: entry } : entry;
 | 
						|
 | 
						|
		if (!this.nativeApp) {
 | 
						|
			const nativeApp = this.getNativeApplication();
 | 
						|
			this.init(nativeApp);
 | 
						|
		}
 | 
						|
	}
 | 
						|
 | 
						|
	private _startActivity: androidx.appcompat.app.AppCompatActivity;
 | 
						|
	private _foregroundActivity: androidx.appcompat.app.AppCompatActivity;
 | 
						|
 | 
						|
	get startActivity() {
 | 
						|
		return this._startActivity;
 | 
						|
	}
 | 
						|
 | 
						|
	get foregroundActivity() {
 | 
						|
		return this._foregroundActivity;
 | 
						|
	}
 | 
						|
 | 
						|
	setStartActivity(value: androidx.appcompat.app.AppCompatActivity) {
 | 
						|
		this._startActivity = value;
 | 
						|
	}
 | 
						|
 | 
						|
	setForegroundActivity(value: androidx.appcompat.app.AppCompatActivity) {
 | 
						|
		this._foregroundActivity = value;
 | 
						|
	}
 | 
						|
 | 
						|
	get paused(): boolean {
 | 
						|
		return this.suspended;
 | 
						|
	}
 | 
						|
 | 
						|
	get backgrounded(): boolean {
 | 
						|
		return this.inBackground;
 | 
						|
	}
 | 
						|
 | 
						|
	get context() {
 | 
						|
		return this._context;
 | 
						|
	}
 | 
						|
 | 
						|
	get packageName() {
 | 
						|
		return this._packageName;
 | 
						|
	}
 | 
						|
 | 
						|
	// Possible flags are:
 | 
						|
	// RECEIVER_EXPORTED (2)
 | 
						|
	// RECEIVER_NOT_EXPORTED (4)
 | 
						|
	// RECEIVER_VISIBLE_TO_INSTANT_APPS (1)
 | 
						|
	public registerBroadcastReceiver(intentFilter: string, onReceiveCallback: (context: android.content.Context, intent: android.content.Intent) => void, flags = 2): void {
 | 
						|
		const registerFunc = (context: android.content.Context) => {
 | 
						|
			const receiver: android.content.BroadcastReceiver = new (initBroadcastReceiver())(onReceiveCallback);
 | 
						|
			if (SDK_VERSION >= 26) {
 | 
						|
				context.registerReceiver(receiver, new android.content.IntentFilter(intentFilter), flags);
 | 
						|
			} else {
 | 
						|
				context.registerReceiver(receiver, new android.content.IntentFilter(intentFilter));
 | 
						|
			}
 | 
						|
			this._registeredReceivers[intentFilter] = receiver;
 | 
						|
		};
 | 
						|
 | 
						|
		if (this.context) {
 | 
						|
			registerFunc(this.context);
 | 
						|
		} else {
 | 
						|
			this._pendingReceiverRegistrations.push(registerFunc);
 | 
						|
		}
 | 
						|
	}
 | 
						|
 | 
						|
	public unregisterBroadcastReceiver(intentFilter: string): void {
 | 
						|
		const receiver = this._registeredReceivers[intentFilter];
 | 
						|
		if (receiver) {
 | 
						|
			this.context.unregisterReceiver(receiver);
 | 
						|
			this._registeredReceivers[intentFilter] = undefined;
 | 
						|
			delete this._registeredReceivers[intentFilter];
 | 
						|
		}
 | 
						|
	}
 | 
						|
 | 
						|
	public getRegisteredBroadcastReceiver(intentFilter: string): android.content.BroadcastReceiver | undefined {
 | 
						|
		return this._registeredReceivers[intentFilter];
 | 
						|
	}
 | 
						|
 | 
						|
	getRootView(): View {
 | 
						|
		const activity = this.foregroundActivity || this.startActivity;
 | 
						|
		if (!activity) {
 | 
						|
			return undefined;
 | 
						|
		}
 | 
						|
		const callbacks: AndroidActivityCallbacks = activity['_callbacks'];
 | 
						|
 | 
						|
		return callbacks ? callbacks.getRootView() : undefined;
 | 
						|
	}
 | 
						|
 | 
						|
	resetRootView(entry?: NavigationEntry | string): void {
 | 
						|
		super.resetRootView(entry);
 | 
						|
 | 
						|
		const activity = this.foregroundActivity || this.startActivity;
 | 
						|
		if (!activity) {
 | 
						|
			throw new Error('Cannot find android activity.');
 | 
						|
		}
 | 
						|
 | 
						|
		// this.mainEntry = typeof entry === 'string' ? { moduleName: entry } : entry;
 | 
						|
		const callbacks: AndroidActivityCallbacks = activity['_callbacks'];
 | 
						|
		if (!callbacks) {
 | 
						|
			throw new Error('Cannot find android activity callbacks.');
 | 
						|
		}
 | 
						|
		callbacks.resetActivityContent(activity);
 | 
						|
	}
 | 
						|
 | 
						|
	getSystemAppearance(): 'light' | 'dark' {
 | 
						|
		const resources = this.context.getResources();
 | 
						|
		const configuration = resources.getConfiguration();
 | 
						|
		return this.getSystemAppearanceValue(configuration);
 | 
						|
	}
 | 
						|
 | 
						|
	// https://developer.android.com/guide/topics/ui/look-and-feel/darktheme#configuration_changes
 | 
						|
	private getSystemAppearanceValue(configuration: android.content.res.Configuration): 'dark' | 'light' {
 | 
						|
		const systemAppearance = configuration.uiMode & android.content.res.Configuration.UI_MODE_NIGHT_MASK;
 | 
						|
 | 
						|
		switch (systemAppearance) {
 | 
						|
			case android.content.res.Configuration.UI_MODE_NIGHT_YES:
 | 
						|
				return 'dark';
 | 
						|
			case android.content.res.Configuration.UI_MODE_NIGHT_NO:
 | 
						|
			case android.content.res.Configuration.UI_MODE_NIGHT_UNDEFINED:
 | 
						|
				return 'light';
 | 
						|
		}
 | 
						|
	}
 | 
						|
 | 
						|
	getOrientation() {
 | 
						|
		const resources = this.context.getResources();
 | 
						|
		const configuration = <android.content.res.Configuration>resources.getConfiguration();
 | 
						|
		return this.getOrientationValue(configuration);
 | 
						|
	}
 | 
						|
 | 
						|
	private getOrientationValue(configuration: android.content.res.Configuration): 'portrait' | 'landscape' | 'unknown' {
 | 
						|
		const orientation = configuration.orientation;
 | 
						|
 | 
						|
		switch (orientation) {
 | 
						|
			case android.content.res.Configuration.ORIENTATION_LANDSCAPE:
 | 
						|
				return 'landscape';
 | 
						|
			case android.content.res.Configuration.ORIENTATION_PORTRAIT:
 | 
						|
				return 'portrait';
 | 
						|
			default:
 | 
						|
				return 'unknown';
 | 
						|
		}
 | 
						|
	}
 | 
						|
 | 
						|
	get android() {
 | 
						|
		// ensures Application.android is defined when running on Android
 | 
						|
		return this;
 | 
						|
	}
 | 
						|
}
 | 
						|
export * from './application-common';
 | 
						|
export const Application = new AndroidApplication();
 | 
						|
export const iOSApplication = undefined;
 |