onStart android titanium module not called - appcelerator

I want to add a hookup to the rootactivity onStart event because I am using an intent filter that opens my app. I added this block to my module but it never gets called.
#Override
public void onStart(Activity activity)
{
// This method is called when the module is loaded and the root context is started
Log.d(TAG, "[MODULE LIFECYCLE EVENT] start");
super.onStart(activity);
}
I Also tried to add this on my index.js but it is intermittently working .
most of the time it is not called.
Ti.Android.currentActivity.onStart = function(e){
Ti.API.info('onStart' + JSON.stringify(e));
// //when activity is created
};

For Titanium part, you will have to add onStart method after the window is completely opened:
To do so, let's say if your window's id is Win_1 in Alloy, the do it this way:
$.Win_1.addEventListener('open', function () {
$.Win_1.activity.onStart = function(e){
Ti.API.info('onStart' + JSON.stringify(e));
// //when activity is created
};
});
You can do it similarly in classic titanium. The point is that in Titanium an activity is only available after a window is opened and so you must listen to window's onOpen event

Related

Detect Back Arrow Press Of The NavigationPage in Xamarin Forms

Is there any way to detect the press of the back button of the Navigation Page in Xamarin forms?
You can override your navigation page "OnBackButtonPressed" method:
protected override bool OnBackButtonPressed()
{
Device.BeginInvokeOnMainThread(async () =>
{
if (await DisplayAlert("Exit?", "Are you sure you want to exit from this page?", "Yes", "No"))
{
base.OnBackButtonPressed();
await App.Navigation.PopAsync();
}
});
return true;
}
If you are using the shell, you can override the Shell's OnNavigating event:
void OnNavigating(object sender, ShellNavigatingEventArgs e)
{
// Cancel back navigation if data is unsaved
if (e.Source == ShellNavigationSource.Pop && !dataSaved)
{
e.Cancel();
}
}
Update:
OnBackButtonPressed event will get fired ONLY on Android when user press the Hardware back button.
Seems like you are more interested to implement when any page get disappeared you want to do something!
In that case:
You have the page's two methods -
protected override void OnAppearing()
{
base.OnAppearing();
Console.WriteLine("Hey, Im coming to your screen");
}
protected override void OnDisappearing()
{
base.OnDisappearing();
Console.WriteLine("Hey, Im going from your screen");
}
You can override those 2 methods on any page to track when they appear and disappear.
Recent updates to Xamarin forms mean you can now do this in an application made with Shell Navigation for navigation back arrow on both platforms.
Use the Shell.SetBackButtonBehavior method, for example running this code in the constructor of your page object will allow the back navigation to take place only when the bound viewmodel is not busy:
Shell.SetBackButtonBehavior(this, new BackButtonBehavior
{
Command = new Command(async() =>
{
if (ViewModel.IsNotBusy)
{
await Shell.Current.Navigation.PopAsync();
}
})
});
In the body of the Command you can do whatever you need to do when you are intercepting the click of the back button.
Note that this will affect only the navigation back button, not the Android hardware back button - that will need handling separately as per the answers above. You could write a shared method called from both the back button pressed override and the command on shell back button behaviour places to share the logic.
You must override native navigationbar button behavior with custom renderer. OnBackButtonPressed triggers only physical device button. You can read good article how to achive this here

How to navigate to a particular page when user taps on a Local Notification in Xamarin Forms app?

Hi am developing a Xamarin Forms app. i have implemented local notifications in the app. When the notification has fired, upon clicking the notification it has to navigate to a particular page.
In iOS project in Appdelegate.cs i wrote this method
public async override void ReceivedLocalNotification(UIApplication application, UILocalNotification notification)
which will fire when the user taps on the notification. here i need to navigate to a page. Here i wrote the below line of code
App.Current.MainPage = new NavigationPage(new FavoritesPage());
It is navigating to the Favorites page but it is just displaying a blank page. OnNavigatedTo method is not calling for the FavoritesViewModel and in the Onnavigated to am calling a method which takes id(this id comes from the notification) as parameter to get a particular favorite
Here two questions
1) How to navigate to a Specific page
2) How to pass a parameter along with the page navigation.
Can someone please help me to solve this issue.
For 1:
You want to push to a new Page, but what you did is replacing the app's MainPage. please try PushAsync. You can subscribe a MessagingCenter in App:
public App ()
{
InitializeComponent();
MainPage = new NavigationPage(new MainPage());
MessagingCenter.Subscribe<object, string>(this, "Push", async (sender, favoriteID) =>
{
var favorite = new FavoritesPage();
favorite.FavoriteID = favoriteID;
await (MainPage as NavigationPage).PushAsync(favorite, true);
});
}
This Lambda will fire when you call MessagingCenter.Send<object, string>(this, "Push", "01");
The string 01 here is the ID what I want to push.
For 2:
Before I push to a new page, I define a property called FavoriteID in this page, then I pass the string using method above.
Use MessagingCenter, set ContentPage type or url for MessagingCenter.Send, then MessagingCenter.Subscribe & load

Calling Naviation.PushAsync from CustomMapRenderer when clicked on a marker

I am working on a xamarin project for ios aswel as android where we are showing custom markers on the Xamarin.Forms maps, we want the user to navigate to another view when he clicks on a custom marker.
We are using Navigation.PushAsync to navigate through the views. this is done from the viewmodels from the non platform specific code, and navigation.PushAsync can only be used there and not from the platformspecific code. Wich is where the customMapRenderers are and where the onlclick for the markers is handled.
So my question is how can i navigate to another view from these onClick Events.
underneath are the methods that catch the onclick.
Android:
private void OnMarkerClick(object sender, GoogleMap.MarkerClickEventArgs e)
{
Toast.MakeText(MainApplication.Context, "Button Pressed", ToastLength.Long).Show();
}
iOS:
private void OnDidSelectAnnotationView(object sender, MKAnnotationViewEventArgs e)
{
UIAlertView alert = new UIAlertView()
{
Title = "Event",
Message = "Button Clicked"
};
alert.AddButton("Oke");
alert.Show();
}
As Yuri said, you can implement this by using Messenger, here is a sample about how to use Messenger. You can use it in custom renderer onClick Events, When send a message in renderer, the Page will received Message. So you can navigate to another view in your Page's MessagingCenter.Subscribe method.
Page:
MessagingCenter.Subscribe<MainPage>(this, "Navigation", async (sender) =>
{
var page1 = new Page1();
await Navigation.PushModalAsync(page1);
});
Custom Renderer:
MessagingCenter.Send<MainPage>(MainPage.getInstance(), "Navigation");

JavaFX button event triggers only once

So i have this JavaFX application, which contains a button, that is supposed to open the DirectoryChooser onclick. When i trigger it once, it does what it was supposed to do, perfectly fine. As soon as i close the DirectoryChooser Dialog, the button doesn't do anything anymore. I was searching the web for some "event resetting" or something similar, because i thought maybe the Event was still "active" and therefore doesn't trigger anymore, but without any results:
// first attempt
button.addEventFilter(MouseEvent.MOUSE_CLICKED,
new EventHandler<MouseEvent>() {
public void handle(MouseEvent e) {
// dirChooser.setTitle("Select Directory:");
file = dirChooser.showDialog(primaryStage);
// just incase only the DirectoryChooser wasn't opening
System.out.println("asdf");
// updates the application view with the new selected path
update();
// not sure, if this affects anything
// found it while looking for resetting of events
e.consume();
};
}
);
// secont attempt
button.setOnAction(new EventHandler<ActionEvent>() {
#Override public void handle(ActionEvent e) {
DirectoryChooser dirChooser = new DirectoryChooser();
dirChooser.setTitle("Select Directory:");
file = dirChooser.showDialog(primaryStage);
update();
}
});
Not sure if this is just a complete wrong approach, or if i'm missing something important there. I hope you guys can figure it out.
So after the help of Uluk Biy, i got the problem. In the update routine, the button is newly created and therefore it's event handler is not existent anymore. I added the button to the attributes so I don't need to replace it everytime when calling the update routine, and the event handler is still existent.

Do code after OnNavigatedTo

I Have Code get IdUsers From Other Page
String IdUsers;
public Main_Wallets_Page()
{
InitializeComponent();
MessageBox.Show(IdUsers);
}
protected override void OnNavigatedTo(System.Windows.Navigation.NavigationEventArgs e)
{
String Id;
if (NavigationContext.QueryString.TryGetValue("IdUsers", out Id))
IdUsers = Id;
}
The MessageBox Alway be Null. I Want to MessageBox Show the "IdUsers" after OnNavigationTo (Do not put the MessageBox IN "OnNavigationTo").
How can i do it ?
You shouldn't use MessageBoxes in OnNavigatedTo because if the user does not press a button your app will crash since the framework thinks that navigation has failed. MessageBoxes in the constructor are equally as bad.
I can think of two options (I use #1 for these sorts of things):
Show the MessageBox in the Loaded event. But be careful it can be
fired more than once. In the constructor you might add the handler for the Loaded event and then in the handler you'd detach from the handler so that it is called only once.
Use Dispatcher.BeginInvoke around the MessageBox.Show call so that it does not block navigation. That might still block the Dispatcher thread. If you really wanted to go this route you could use ThreadPool.QueueUserWorkItem or a TPL Task.
I also have used OnLayoutUpdated in place of the Loaded event but I can't remember exactly why :) It seems like it might have been that the page hasn't yet displayed in Loaded and it has in the other event.
If this value was initialized, you can store it in application isolated storage. Then, when constructor is called, you can read it from there. In this case value of user ID will be initialized and MessageBox won't show you NULL.
DO NOT place MessageBox into OnNavigatedTo event.
Try to create an empty project with MainPage and Page2. Place button on MainPage to navigate to Page2. In Page2 place MessageBox in OnNavigatedTo event. Then everythig will work fine if you Start Debugging from VS. BUT if you deploy and run it you will see that when you navigate to Page2 you see MessageBox. Then don't do anything, just wait for about 15 sec. MessageBox will react as Canceled and APPLICATION WILL BE CRASHED! without any navigation to Page2 or MainPage. The same thing happens if you use Dispatcher.BeginInvoke around the MessageBox.Show.
I assume that OnNavigatedTo event has a timeout which works only when app is deployed. So you should run your MessageBox when Navigation is competed.
Everything works if you do
protected override void OnNavigatedTo(System.Windows.Navigation.NavigationEventArgs e) {
base.OnNavigatedTo(e);
var lcTimer = new DispatcherTimer { Interval = new TimeSpan(0, 0, 0, 0, 200) };
lcTimer.Tick += (s2, e2) => {
(s2 as DispatcherTimer).Stop();
if (MessageBoxResult.OK == MessageBox.Show("Test, don't push", "", MessageBoxButton.OKCancel))
MessageBox.Show("OK");
else
MessageBox.Show("Cancel");
};
lcTimer.Start();
}
Note: If you have some code in OnNavigatedTo run above code at the end of OnNavigatedTo.
I liked what Austin Thompson(upvote) has adviced with ThreadPool.QueueUserWorkItem. But note that with this approach you need to place MessageBox inside the Dispatcher.BeginInvoke otherwise you will receive cross-thread exception. So the code is the following
protected override void OnNavigatedTo(System.Windows.Navigation.NavigationEventArgs e) {
base.OnNavigatedTo(e);
ThreadPool.QueueUserWorkItem((stateInfo) => {
Dispatcher.BeginInvoke(() => {
if (MessageBoxResult.OK == MessageBox.Show("Test don't push", "", MessageBoxButton.OKCancel))
MessageBox.Show("OK");
else
MessageBox.Show("Cancel");
});
});
}

Resources