Splash Screen disappeared after Application.OnCreate was overridden - xamarin.android

Initial Issue
I need to register ProcessLifecycleOwner as described here Xamarin.Android Architecture Components in my Application.OnCreate method.
But it had resulted in the error with 6.2.2 version of MvvmCross:
MvvmCross.Exceptions.MvxIoCResolveException: Failed to resolve type MvvmCross.ViewModels.IMvxAppStart occurred
or just stuck on the Splash Screen with 6.2.3.
Fix
Those problems were fixed by advice from Xamarin.Android mvvmcross app crashes when launching with intent filter.
[Application]
public class App : MvxAndroidApplication<Setup, Core.App>
{
public App(IntPtr reference, JniHandleOwnership transfer) :
base(reference, transfer) { }
public override void OnCreate()
{
MvxAndroidSetupSingleton
.EnsureSingletonAvailable(ApplicationContext)
.EnsureInitialized();
base.OnCreate();
}
}
Current Issue
However Splash Screen dissapeared too, only blue background from default theme was left.
A workaround I've found:
public override void OnCreate()
{
Task.Run(() => MvxAndroidSetupSingleton
.EnsureSingletonAvailable(ApplicationContext)
.EnsureInitialized());
base.OnCreate();
}
But due to parallelism it is not reliable, sometimes works, sometimes crashes.
Question
How Splash Screen can be restored?

Your approach is most likely blocking on the UI thread which us causing the UI to block during the time that the expected splash screen is suppose to show.
Try using an async event handler to allow for a non blocking UI call
[Application]
public class App : MvxAndroidApplication<Setup, Core.App> {
public App(IntPtr reference, JniHandleOwnership transfer) :
base(reference, transfer) {
EnsureInitialized = onEnsureInitialized; //Subscribe to event
}
private event EventHandler EnsureInitialized = delegate { };
private async void onEnsureInitialized(object sender, EventArgs args) {
await Task.Run(() => MvxAndroidSetupSingleton.EnsureSingletonAvailable(ApplicationContext)
.EnsureInitialized());
}
public override void OnCreate() {
EnsureInitialized(this, EventArgs.Empty); //Raise event
base.OnCreate();
}
}

Related

How to display awarded ad in method OnAppearing() using Xamarin

I want to display awarded ad when app is starting.
I load ads under InitializeComponent(); with this code:
public MainPage()
{
InitializeComponent();
//Load Interestitial Ad
CrossMTAdmob.Current.LoadInterstitial("ca-app-pub-9688730828394396/1781454910");
//Load Rewarded Ad
CrossMTAdmob.Current.LoadRewardedVideo("ca-app-pub-9688730828394396/9667490273");
}
I have two buttons when users click on them different ads starting with this code:
private void ShowReward_OnClicked(object sender, EventArgs e)
{
CrossMTAdmob.Current.ShowRewardedVideo();
}
private void ShowInterstitial_OnClicked(object sender, EventArgs e)
{
CrossMTAdmob.Current.ShowInterstitial();
}
I try to put CrossMTAdmob.Current.ShowInterstitial(); from one button in my OnAppearing() method but when I start application, the ad does not appear with this code:
protected override void OnAppearing()
{
base.OnAppearing();
SetEvents();
CrossMTAdmob.Current.ShowInterstitial();
}
Can I get some example how to display my ad when app is starting ?
I'm the author of the plugin you are using.
You should check if the ads is actually loaded before trying to show it.
You can use
IsInterstitialLoaded()
And
IsRewardedVideoLoaded().
If these methods return true, then you can show the ads.
If the result is always false then you have to understand why they are not loaded, you can see in the output windows if you receive some error messages.
Most of the time the reason is a wrong Id.

How to get notified when Xamarin Native Android app goes to sleep or is terminated?

How to get notified when Xamarin Native Android app goes to sleep or is terminated?
When searching, I only found an answer for Xamarin.Forms where the Application object allows to override OnSleep.
The background of this question is that I want to save settings when the app either goes to background or is terminated.
Just like the OnSleep method of Xamarin Forms the OnPause method is called in Android Native when the app goes into the background.
You can override OnPause in both an Activity and a Fragment something like this:
protected override void OnPause()
{
base.OnPause();
// Add your code here
}
Update
You can do the same on application level by adding the Android Application class :
Add a new C# class file in your project called MainApplication.cs.
Then add the Application.IActivityLifecycleCallbacks interface where you can find the activity paused method with the activity context in which it was paused so you can add it and do the needful.
#if DEBUG
[Application(Debuggable = true)]
#else
[Application(Debuggable = false)]
#endif
public class MainApplication : Application , Application.IActivityLifecycleCallbacks
{
public MainApplication(IntPtr handle, JniHandleOwnership transer)
: base(handle, transer)
{
}
public void OnActivityPaused(Android.App.Activity activity)
{
base.OnCreate();
// Add some code
}
public override void OnTerminate()
{
base.OnTerminate();
UnregisterActivityLifecycleCallbacks(this);
}
public override void OnCreate()
{
base.OnCreate();
RegisterActivityLifecycleCallbacks(this);
}
}

How to exit the App in Xamarin Forms?

My project is built with master-detail navigation.
There are totally three pages in the list named as Resources, Contacts, and Login.
Everything works fine in iOS, but when the user presses the Droid/WinPhone devices hardware back button, the app should exit.
Is there any app-exit mechanism for Xamarin Forms which will work on all the devices.? (I mean native code not platform dependent)
Thanks in advance.
I did that on this way
In xamarin forms I added interface
public interface INativeHelper
{
void CloseApp();
}
In android project I made implementation of INativeHelper
public class NativeHelper : INativeHelper
{
public void CloseApp()
{
Android.OS.Process.KillProcess(Android.OS.Process.MyPid());
}
}
Implementation of INativeHelper in IOS
public class NativeHelper : INativeHelper
{
public void CloseApp()
{
Process.GetCurrentProcess().CloseMainWindow();
Process.GetCurrentProcess().Close();
}
}
And then just override method OnBackButtonPressed in page in Xamarin.Forms project
protected override bool OnBackButtonPressed()
{
INativeHelper nativeHelper = null;
nativeHelper = DependencyService.Get<INativeHelper>();
if (nativeHelper != null)
{
nativeHelper.CloseApp();
}
return base.OnBackButtonPressed();
}
I didn't made implementation for WinPhone, but it should be similar.
You can use a DepedencyService for closing an app when your physical back button is pressed:
In your UI (PCL), do the following:
protected override bool OnBackButtonPressed()
{
if (Device.OS == TargetPlatform.Android)
DependencyService.Get<IAndroidMethods>().CloseApp();
return base.OnBackButtonPressed();
}
Now implement the Android-specific logic in your Android project:
[assembly: Xamarin.Forms.Dependency(typeof(AndroidMethods))]
namespace Your.Namespace
{
public class AndroidMethods : IAndroidMethods
{
public void CloseApp()
{
Android.OS.Process.KillProcess(Android.OS.Process.MyPid());
}
}
}
Also create an Interface (in your UI PCL):
public interface IAndroidMethods
{
void CloseApp();
}
As far as I know there is no native way to exit the app in Xamarin application.
The only way is to use dependency service. Override OnBackButtonPressed function in your ContentPage and check it is the last page:
protected override bool OnBackButtonPressed()
{
if(navigation.NavigationStack.Count == 1)//navigation is MainPage.Navigation
DependencyService.Get<YourDependencyInterface>().CloseApp();
}
For Android in YourAndroidDependency class:
public void CloseApp()
{
(Xamarin.Forms.Forms.Context as Activity).Finish();
}
As for WinPhone I'm not sure but I believe it can be done in same way - dependency service.
Having experimented with all the above, I found that none of the above worked on a Google Pixel 3a, with latest version of Android
The command that came closest was
Android.OS.Process.KillProcess(Android.OS.Process.MyPid());
However it left the remains of the app still visible in the background.
The following worked for me when called from the Android Main Activity
public void ExitApp()
{
this.FinishAndRemoveTask();
Android.OS.Process.KillProcess(Android.OS.Process.MyPid());
}
The first line FinishAndRemoveTask removes the app from both the foreground and the background, however the Application process is still active, hence the need for the second command.
This is the more easy way found:
public void QuitApp(object sender, EventArgs args)
{
Process.GetCurrentProcess().CloseMainWindow();
Process.GetCurrentProcess().Close();
}
PS: Tested in android
You can use Environment.Exit(0);

Blackberry splash screen wait issue

I'm trying to launch a splash screen for a few seconds and then close it and launch the second screen.
For some reason, the code executes the "sleep" before showing the splash page and the splash page appears only for a fraction of a second and the second screen appears immediately. In other words when I click on the app icon, it waits for 2 seconds, then shows and immediately hides splash and jumps to HomeScreen.
I've tried many different combinations including invokeAndWait(), call backs and threads inside the Splash class but to no avail.
I've gone through many posts on SO as well.
Please note that I do not want the splash page to open the next screen; the launcher of the splash page (AppStart) should launch the next screen.
Please suggest a solution.
Code:
public class AppStart extends UiApplication
{
public static void main(String[] args) {
AppStart app = new AppStart();
app.enterEventDispatcher();
}
public AppStart() {
final Splash splashscreen = new Splash();
UiApplication.getUiApplication().invokeLater(new Runnable() {
public void run() {
UiApplication.getUiApplication().pushScreen(splashscreen);
}
});
Thread waitthread = new Thread()
{
public void run()
{
try {
sleep(2000);
} catch (InterruptedException e) {
}
finally
{
UiApplication.getUiApplication().invokeLater(new Runnable() {
public void run() {
UiApplication.getUiApplication().popScreen(splashscreen);
}
});
UiApplication.getUiApplication().invokeLater(new Runnable() {
public void run() {
UiApplication.getUiApplication().pushScreen(new HomeScreen());
}
});
}
}
};
waitthread.run();
}
}
Splash
public class Splash extends MainScreen {
public Splash()
{
Bitmap bgImg = Bitmap.getBitmapResource("480x320-SplashScreen.png");
Background bg = BackgroundFactory.createBitmapBackground(bgImg);
getMainManager().setBackground(bg);
}
}
waitthread.run();
That is the problem. You are not starting a new thread, but hogging the main thread instead by callyng a method that sleeps it. Replace that line with this one:
waitthread.start();
And it should work.

Blackberry foreground after background

When my app is running in background and I click its icon, it comes from background to foreground. Which function is triggered at first? I searched, after coming from background it triggers the public void activate() in the class which is extended by Application.
Now I have a GUI class, lets say Login.java, which extends UiApplication. What should I write in this class to see that Application has come from background to foreground?
And when going to Background I use this code
public boolean onClose() {
UiApplication.getUiApplication().invokeAndWait(new Runnable() {
public void run() {
MyScreen.setBackgroundFlag("true");
UiApplication.getUiApplication().requestBackground();
};
});
//Application.getApplication().requestForeground();
//System.exit(0);
return true;
}

Resources