From 3efc06ed986b114e7ff52764e3cb78c07ad7c8c9 Mon Sep 17 00:00:00 2001 From: Eddy Verbruggen Date: Wed, 3 Apr 2019 10:06:14 +0200 Subject: [PATCH] feat(android): implement a 'activityNewIntent' event --- tests/app/app/app.ts | 4 ++ .../application/application.android.ts | 5 ++- tns-core-modules/application/application.d.ts | 22 ++++++++++- tns-core-modules/ui/frame/activity.android.ts | 5 +-- tns-core-modules/ui/frame/frame.android.ts | 38 ++++++++++++++++--- tns-core-modules/ui/frame/frame.d.ts | 21 ++++++---- 6 files changed, 77 insertions(+), 18 deletions(-) diff --git a/tests/app/app/app.ts b/tests/app/app/app.ts index a0e348269..4e6e9330a 100644 --- a/tests/app/app/app.ts +++ b/tests/app/app/app.ts @@ -135,6 +135,10 @@ if (application.android) { console.log("Event: " + args.eventName + ", Activity: " + args.activity); // Set args.cancel = true to cancel back navigation and do something custom. }); + + application.android.on(application.AndroidApplication.activityNewIntentEvent, function (args: application.AndroidActivityNewIntentEventData) { + console.log("Event: " + args.eventName + ", Activity: " + args.activity + ", Intent: " + args.intent); + }); } var time; diff --git a/tns-core-modules/application/application.android.ts b/tns-core-modules/application/application.android.ts index 14ff82693..f0588976d 100644 --- a/tns-core-modules/application/application.android.ts +++ b/tns-core-modules/application/application.android.ts @@ -1,6 +1,6 @@ import { AndroidActivityBundleEventData, AndroidActivityEventData, ApplicationEventData, OrientationChangedEventData, - AndroidApplication as AndroidApplicationDefinition, + AndroidApplication as AndroidApplicationDefinition, AndroidActivityNewIntentEventData, AndroidActivityResultEventData, AndroidActivityBackPressedEventData, AndroidActivityRequestPermissionsEventData } from "."; @@ -25,6 +25,7 @@ const ActivityStopped = "activityStopped"; const SaveActivityState = "saveActivityState"; const ActivityResult = "activityResult"; const ActivityBackPressed = "activityBackPressed"; +const ActivityNewIntent = "activityNewIntent"; const ActivityRequestPermissions = "activityRequestPermissions"; export class AndroidApplication extends Observable implements AndroidApplicationDefinition { @@ -37,6 +38,7 @@ export class AndroidApplication extends Observable implements AndroidApplication public static saveActivityStateEvent = SaveActivityState; public static activityResultEvent = ActivityResult; public static activityBackPressedEvent = ActivityBackPressed; + public static activityNewIntentEvent = ActivityNewIntent; public static activityRequestPermissionsEvent = ActivityRequestPermissions; public paused: boolean; @@ -119,6 +121,7 @@ export interface AndroidApplication { on(event: "saveActivityState", callback: (args: AndroidActivityBundleEventData) => void, thisArg?: any); on(event: "activityResult", callback: (args: AndroidActivityResultEventData) => void, thisArg?: any); on(event: "activityBackPressed", callback: (args: AndroidActivityBackPressedEventData) => void, thisArg?: any); + on(event: "activityNewIntent", callback: (args: AndroidActivityNewIntentEventData) => void, thisArg?: any); on(event: "activityRequestPermissions", callback: (args: AndroidActivityRequestPermissionsEventData) => void, thisArg?: any); } diff --git a/tns-core-modules/application/application.d.ts b/tns-core-modules/application/application.d.ts index 346680879..f85972e8b 100644 --- a/tns-core-modules/application/application.d.ts +++ b/tns-core-modules/application/application.d.ts @@ -187,7 +187,7 @@ export function off(eventNames: string, callback?: any, thisArg?: any); /** * @deprecated use application.run() instead. - * + * * Call this method to start the application. Important: All code after this method call will not be executed! */ export function start(entry?: NavigationEntry | string); @@ -371,6 +371,16 @@ export interface AndroidActivityResultEventData extends AndroidActivityEventData intent: any /* android.content.Intent */; } +/** + * Data for the Android activity newIntent event. + */ +export interface AndroidActivityNewIntentEventData extends AndroidActivityEventData { + /** + * The intent. + */ + intent: any /* android.content.Intent */; +} + /** * Data for the Android activity back pressed event. */ @@ -480,6 +490,11 @@ export class AndroidApplication extends Observable { */ on(event: "activityBackPressed", callback: (args: AndroidActivityBackPressedEventData) => void, thisArg?: any); + /** + * This event is raised when the Android app was launched by an Intent with data. + */ + on(event: "activityNewIntent", callback: (args: AndroidActivityNewIntentEventData) => void, thisArg?: any); + /** * This event is raised when the Android activity requests permissions. */ @@ -530,6 +545,11 @@ export class AndroidApplication extends Observable { */ public static activityBackPressedEvent: string; + /** + * String value used when hooking to activityNewIntent event. + */ + public static activityNewIntentEvent: string; + /** * String value used when hooking to requestPermissions event. */ diff --git a/tns-core-modules/ui/frame/activity.android.ts b/tns-core-modules/ui/frame/activity.android.ts index 946ca63df..9a4b9ce84 100644 --- a/tns-core-modules/ui/frame/activity.android.ts +++ b/tns-core-modules/ui/frame/activity.android.ts @@ -26,12 +26,11 @@ class NativeScriptActivity extends android.support.v7.app.AppCompatActivity { setActivityCallbacks(this); } - this._callbacks.onCreate(this, savedInstanceState, super.onCreate); + this._callbacks.onCreate(this, savedInstanceState, this.getIntent(), super.onCreate); } public onNewIntent(intent: android.content.Intent): void { - super.onNewIntent(intent); - super.setIntent(intent); + this._callbacks.onNewIntent(this, intent, super.setIntent, super.onNewIntent); } public onSaveInstanceState(outState: android.os.Bundle): void { diff --git a/tns-core-modules/ui/frame/frame.android.ts b/tns-core-modules/ui/frame/frame.android.ts index f3f2decbe..1bf5e396d 100644 --- a/tns-core-modules/ui/frame/frame.android.ts +++ b/tns-core-modules/ui/frame/frame.android.ts @@ -944,11 +944,17 @@ class ActivityCallbacksImplementation implements AndroidActivityCallbacks { } @profile - public onCreate(activity: android.support.v7.app.AppCompatActivity, savedInstanceState: android.os.Bundle, superFunc: Function): void { + public onCreate(activity: android.support.v7.app.AppCompatActivity, savedInstanceState: android.os.Bundle, intentOrSuperFunc: android.content.Intent | Function, superFunc?: Function): void { if (traceEnabled()) { traceWrite(`Activity.onCreate(${savedInstanceState})`, traceCategories.NativeLifecycle); } + const intent: android.content.Intent = superFunc ? intentOrSuperFunc : undefined; + + if (!superFunc) { + superFunc = intentOrSuperFunc; + } + // If there is savedInstanceState this call will recreate all fragments that were previously in the navigation. // We take care of associating them with a Page from our backstack in the onAttachFragment callback. // If there is savedInstanceState and moduleLoaded is false we are restarted but process was killed. @@ -966,6 +972,15 @@ class ActivityCallbacksImplementation implements AndroidActivityCallbacks { } } + if (intent && intent.getAction()) { + application.android.notify({ + eventName: application.AndroidApplication.activityNewIntentEvent, + object: application.android, + activity, + intent + }); + } + this.setActivityContent(activity, savedInstanceState, true); moduleLoaded = true; } @@ -982,6 +997,19 @@ class ActivityCallbacksImplementation implements AndroidActivityCallbacks { outState.putInt(ROOT_VIEW_ID_EXTRA, rootView._domId); } + @profile + public onNewIntent(activity: android.support.v7.app.AppCompatActivity, intent: android.content.Intent, superSetIntentFunc: Function, superFunc: Function): void { + superFunc.call(activity, intent); + superSetIntentFunc.call(activity, intent); + + application.android.notify({ + eventName: application.AndroidApplication.activityNewIntentEvent, + object: application.android, + activity, + intent + }); + } + @profile public onStart(activity: any, superFunc: Function): void { superFunc.call(activity); @@ -1188,7 +1216,7 @@ class ActivityCallbacksImplementation implements AndroidActivityCallbacks { if (shouldCreateRootFrame) { const extras = intent.getExtras(); let frameId = -1; - + // We have extras when we call - new Frame().navigate(); // savedInstanceState is used when activity is recreated. // NOTE: On API 23+ we get extras on first run. @@ -1196,17 +1224,17 @@ class ActivityCallbacksImplementation implements AndroidActivityCallbacks { if (extras) { frameId = extras.getInt(INTENT_EXTRA, -1); } - + if (savedInstanceState && frameId < 0) { frameId = savedInstanceState.getInt(INTENT_EXTRA, -1); } - + if (!rootView) { // If we have frameId from extras - we are starting a new activity from navigation (e.g. new Frame().navigate())) // Then we check if we have frameId from savedInstanceState - this happens when Activity is destroyed but app was not (e.g. suspend) rootView = getFrameByNumberId(frameId) || new Frame(); } - + if (rootView instanceof Frame) { rootView.navigate(mainEntry); } else { diff --git a/tns-core-modules/ui/frame/frame.d.ts b/tns-core-modules/ui/frame/frame.d.ts index ec3793fee..5983e9aa1 100644 --- a/tns-core-modules/ui/frame/frame.d.ts +++ b/tns-core-modules/ui/frame/frame.d.ts @@ -16,7 +16,7 @@ export * from "../page"; export class Frame extends View { /** * @deprecated - * + * * String value used when hooking to androidOptionSelected event (prefix `android` states that this event is available only in Android). */ public static androidOptionSelectedEvent: string; @@ -33,7 +33,7 @@ export class Frame extends View { canGoBack(): boolean; /** - * Navigates to a Page instance as described by the module name. + * Navigates to a Page instance as described by the module name. * This method will require the module and will check for a Page property in the exports of the module. * @param pageModuleName The name of the module to require starting from the application root. * For example if you want to navigate to page called "myPage.js" in a folder called "subFolder" and your root folder is "app" you can call navigate method like this: @@ -175,7 +175,7 @@ export class Frame extends View { /** * A basic method signature to hook an event listener (shortcut alias to the addEventListener method). - * @param eventNames - String corresponding to events (e.g. "propertyChange"). Optionally could be used more events separated by `,` (e.g. "propertyChange", "change"). + * @param eventNames - String corresponding to events (e.g. "propertyChange"). Optionally could be used more events separated by `,` (e.g. "propertyChange", "change"). * @param callback - Callback function which will be executed when event is raised. * @param thisArg - An optional parameter which will be used as `this` context for callback execution. */ @@ -210,7 +210,7 @@ export function goBack(); /** * @deprecated use getFrameById() if you want to retrieve a frame different than the topmost one - * + * * Gets the frames stack. */ export function stack(): Array; @@ -264,7 +264,7 @@ export interface NavigationEntry extends ViewEntry { transitionAndroid?: NavigationTransition; /** - * True to record the navigation in the backstack, false otherwise. + * True to record the navigation in the backstack, false otherwise. * If the parameter is set to false then the Page will be displayed but once navigated from it will not be able to be navigated back to. */ backstackVisible?: boolean; @@ -350,7 +350,7 @@ export interface BackstackEntry { } /** - * Represents the data passed to the androidOptionSelected event. + * Represents the data passed to the androidOptionSelected event. * This event is raised by the Android OS when an option in the Activity's action bar has been selected. */ export interface AndroidOptionEventData extends EventData { @@ -398,7 +398,7 @@ export interface AndroidFrame extends Observable { /** * @deprecated this property is not used internally - * + * * Gets or sets whether the page UI will be cached when navigating away from the page. */ cachePagesOnNavigate: boolean; @@ -413,8 +413,12 @@ export interface AndroidFrame extends Observable { export interface AndroidActivityCallbacks { getRootView(): View; resetActivityContent(activity: any): void; - + + /** + * @deprecated use onCreate(activity, savedInstanceState, intent, superFunc) instead. + */ onCreate(activity: any, savedInstanceState: any, superFunc: Function): void; + onCreate(activity: any, savedInstanceState: any, intent: any, superFunc: Function): void; onSaveInstanceState(activity: any, outState: any, superFunc: Function): void; onStart(activity: any, superFunc: Function): void; onStop(activity: any, superFunc: Function): void; @@ -423,6 +427,7 @@ export interface AndroidActivityCallbacks { onBackPressed(activity: any, superFunc: Function): void; onRequestPermissionsResult(activity: any, requestCode: number, permissions: Array, grantResults: Array, superFunc: Function): void; onActivityResult(activity: any, requestCode: number, resultCode: number, data: any, superFunc: Function); + onNewIntent(activity: any, intent: any, superSetIntentFunc: Function, superFunc: Function): void; } export interface AndroidFragmentCallbacks {