App.xaml.cs will run again unexpectedly in Debug mode - c#

I am using the APP to connect to a device in Xamarin debug mode.
When the system is trying to connect to the device(like the screenshot shows "Connecting to device..."), if I press the back button to home(desktop) and back to APP, I find that the code will run App.xaml.cs again, so I will see the screen will show Example_A_Page again and then show Example_B_Page afterward.
Then I tried again without the debug mode this time.
When I press the back button to home(desktop) and then back to APP, APP is still running Example_B_Page.
Does anybody know why this situation happened?
Here is the pseudo code
public partial class App : Application
{
public App()
{
InitializeComponent();
MainPage = new NavigationPage(new Example_A_Page());
}
}
public partial class Example_A_Page : ContentPage
{
public Example_A_Page()
{
InitializeComponent();
}
protected async override void OnAppearing()
{
await Navigation.PushPopupAsync(new Example_B_Page());
}
}
public partial class Example_B_Page : ContentPage
{
public Example_B_Page()
{
InitializeComponent();
}
private async void Button_Clicked(object sender, EventArgs e)
{
//Do the connection behavior...
//Connected to the device...
}
}

Related

Opening next file with the same instance of my app

I associated .pdf files with my C#.NET WPF app in Windows.
If I open the pdf file by clicking on it, array "param" is:
string[] param = Environment.GetCommandLineArgs();
Which contains two paths:
1) Path to my app (param[0])
2) Path to opened (param[1])
I have set in the C# code (app.xaml.cs) that only one instance of my app may be opened in Windows. If I try to open a second instance, the main window of the first instance is activated.
But now, if I open the next pdf file by click on it “param” contains the path to the first file logically, therefore I can not open the next file :0(.
How should I solve this problem? I don’t want to move to the next instance of the app!
Here is my app.xaml.code
public partial class App : Application
{
App()
{
InitializeComponent();
}
[STAThread]
static void Main()
{
SingleInstanceManager manager = new SingleInstanceManager();
manager.Run(new[] { "test" });
}
}
public class SingleInstanceManager : WindowsFormsApplicationBase
{
SingleInstanceApplication app;
public SingleInstanceManager()
{
this.IsSingleInstance = true;
}
protected override bool OnStartup(Microsoft.VisualBasic.ApplicationServices.StartupEventArgs e)
{
// First time app is launched
app = new SingleInstanceApplication();
app.Run();
return false;
}
protected override void OnStartupNextInstance(StartupNextInstanceEventArgs eventArgs)
{
// Subsequent launches
base.OnStartupNextInstance(eventArgs);
app.Activate();
}
}
public class SingleInstanceApplication : Application
{
protected override void OnStartup(System.Windows.StartupEventArgs e)
{
base.OnStartup(e);
// Create and show the application's main window
MainWindow window = new MainWindow();
window.Show();
}
public void Activate()
{
// Reactivate application's main window
this.MainWindow.WindowState = WindowState.Normal;
this.MainWindow.Activate();
((MainWindow)this.MainWindow).SpracujStartovacieParametre();
}
}
Here is my solution:
public partial class App : Application
{
App()
{
InitializeComponent();
}
[STAThread]
static void Main()
{
SingleInstanceManager manager = new SingleInstanceManager();
//manager.Run(new[] { "test" });
manager.Run(Environment.GetCommandLineArgs());
}
}
public class SingleInstanceManager : WindowsFormsApplicationBase
{
SingleInstanceApplication app;
public SingleInstanceManager()
{
this.IsSingleInstance = true;
}
protected override bool OnStartup(Microsoft.VisualBasic.ApplicationServices.StartupEventArgs e)
{
// First time app is launched
app = new SingleInstanceApplication();
app.Run();
return false;
}
protected override void OnStartupNextInstance(StartupNextInstanceEventArgs eventArgs)
{
// Subsequent launches
base.OnStartupNextInstance(eventArgs);
//MessageBox.Show("Event arguments:"+ eventArgs.ToString());
app.Activate(eventArgs.CommandLine.ToArray<string>());
}
}
public class SingleInstanceApplication : Application
{
protected override void OnStartup(System.Windows.StartupEventArgs e)
{
base.OnStartup(e);
// Create and show the application's main window
MainWindow window = new MainWindow();
window.Show();
}
public void Activate(string[] eventArgs)
{
((MainWindow)this.MainWindow).SpracujCommandLineArgs(eventArgs);
this.MainWindow.WindowState = WindowState.Maximized;
this.MainWindow.Activate();
}
}

Write to a .txt file using data from TextBox when UWP app is closed

When user closes the app, I believe the OnSuspending method in App.xaml.cs is called first before termination. So, I put my code in there in order to automatically save what the user wrote in the TextBox to a .txt file called TextFile1.txt. The program runs without errors but it doesn't save the user's data to the .txt file when app is closed.
Code in App.xaml.cs:
private MainPage mainFrame;
private async void OnSuspending(object sender, SuspendingEventArgs e)
{
var deferral = e.SuspendingOperation.GetDeferral();
await WriteTextToFile();
deferral.Complete();
}
private async Task WriteTextToFile()
{
try
{
string text = mainFrame.mainTextBox.Text;
StorageFile textFile = await StorageFile.GetFileFromApplicationUriAsync(new Uri("ms-appx:///TextFile1.txt"));
await FileIO.WriteTextAsync(textFile, text);
}
catch
{
}
}
Code in MainPage.xaml.cs:
public sealed partial class MainPage : Page
{
public TextBox mainTextBox => textBox;
public static MainPage rootPage;
public MainPage()
{
InitializeComponent();
if (rootPage != null)
{
rootPage = this;
}
}
}
Your code fails because it attempts to write to the app's installation folder. This folder is protected to ensure the integrity of the installation.
To make your scenario work, write the text file to your AppData location instead.
https://learn.microsoft.com/en-us/windows/uwp/design/app-settings/store-and-retrieve-app-data

Android Xamarin detect started from task manager

I am currently developing an android xamarin app (android 6 and above) and I have got a problem.
Our customer wants to secure the app by a pinpad. Whenever the app is started the user has to enter a four digit pin.
We have created an activity for the pinpad. This works pretty fine, but the problem is the following:
The pinpad just opens if the app was completely killed (e.g. by the task manager ) -> cold started.
How can I achive that the pinpad opens if the app was in the background and reopend by the task manager for example (user pressed home button and then wants to start app again) -> warm started.
I've tried to do this by OnResume(), OnStart(),. But unfortunately they trigger every time an another activity (e.g. open detail view of list item) is opened.
use IActivityLifecycleCallbacks to listen the status.
Application registration ActivityLifecycleCallbacks, such, when each activity in the app lifecycle occurs, the Application can be listening to. The number of public void onActivityStarted(activity activity) and public void onActivityStopped(activity activity) of an activity can be used to determine whether the app is in the foreground. Because when the app is in the foreground, an activity must have started onActivityStarted but not onActivityStopped, so the statistics of the number of activities opened in the app must be 1. When the app switches to the background, activityStartCount will be 0.
so write a Helper classes :
public class AppFrontBackHelper
{
public static OnAppStatusListener mOnAppStatusListener;
private LifecycleCallBack lifecycleCallBack;
public AppFrontBackHelper()
{
}
/**
* Register status listener, only used in Application
* #param application
* #param listener
*/
public void register(Application application, OnAppStatusListener listener)
{
mOnAppStatusListener = listener;
lifecycleCallBack = new LifecycleCallBack();
application.RegisterActivityLifecycleCallbacks(lifecycleCallBack);
}
public void unRegister(Application application) => application.UnregisterActivityLifecycleCallbacks(lifecycleCallBack);
public interface OnAppStatusListener
{
void onFront();
void onBack();
}
public class LifecycleCallBack : Java.Lang.Object, Application.IActivityLifecycleCallbacks
{
public int activityStartCount { get; private set; }
public void OnActivityCreated(Activity activity, Bundle savedInstanceState)
{
}
public void OnActivityDestroyed(Activity activity)
{
}
public void OnActivityPaused(Activity activity)
{
}
public void OnActivityResumed(Activity activity)
{
}
public void OnActivitySaveInstanceState(Activity activity, Bundle outState)
{
}
public void OnActivityStarted(Activity activity)
{
activityStartCount++;
//A value from 1 to 0 indicates cutting from the background to the foreground
if (activityStartCount == 1)
{
if (mOnAppStatusListener != null)
{
mOnAppStatusListener.onFront();
}
}
}
public void OnActivityStopped(Activity activity)
{
activityStartCount--;
//A value from 1 to 0 indicates cutting from the foreground to the background
if (activityStartCount == 0)
{
//从前台切到后台
if (mOnAppStatusListener != null)
{
mOnAppStatusListener.onBack();
}
}
}
}
}
then custom an Application and regist the listener :
[Application]
public class MyApplication : Application,AppFrontBackHelper.OnAppStatusListener
{
protected MyApplication(IntPtr javaReference, JniHandleOwnership transfer) : base(javaReference, transfer)
{
}
public override void OnCreate()
{
base.OnCreate();
AppFrontBackHelper appFrontBackHelper = new AppFrontBackHelper();
appFrontBackHelper.register(this, this);
}
public void onBack()
{
Toast.MakeText(this, "from front to back", ToastLength.Short).Show();
}
public void onFront()
{
Toast.MakeText(this, "from back to front", ToastLength.Short).Show();
}
}
you could do something in the onFront() callback.

AfterSessionComplete event not firing in Window Service(Debugging in Console). Fiddercore

My application is not firing the event AfterSessionComplete. Code Below
fiddler.cs
namespace proj
{
public static class Fiddler
{
public static void start()
{
startProxy();
}
public static void startProxy()
{
FiddlerApplication.AfterSessionComplete += FiddlerApplication_AfterSessionComplete;
FiddlerApplication.Startup(8888, true, true, true);
}
public static void FiddlerApplication_AfterSessionComplete(Session sess)
{
//Working aftersessioncomplete
}
}
}
Service1.cs
namespace Proj
{
public partial class Service1 : ServiceBase
{
public Service1()
{
InitializeComponent();
}
protected override void OnStart(string[] args)
{
Fiddler.start();
}
protected override void OnStop()
{
}
internal void TestStartupAndStop(string[] args)
{
this.OnStart(args); //use to debug
//For commandLine
}
}
}
program.cs
namespace Proj
{
static class Program
{
static void Main(string[] args)
{
if (Environment.UserInteractive)
{
Service1 service1 = new Service1();
service1.TestStartupAndStop(args);
}
else
{
}
}
}
}
I'm creating a windows service but I was facing a debugging issue, that's why I use the console application debug to check my code working or not.
I added break point at aftersessioncomplete event when I get to know that FiddlerApplication.AfterSessionComplete is not firing. It stops the application without going on public static void FiddlerApplication_AfterSessionComplete(Session sess)
Anyone can help? or faced same issue?
After Session cannot fire in window service because of the Certificate popup the certificate as for GUI which windows service cannot provide so the code stuck at certificate installation and not firing after session events.
To work out with this one keep in mind to use console app and hide console app after installation of certificate

Preload a Form in Another Thread

I am trying to preload server form in the constructor of client form, in a separate thread. My reason is that server load is time consuming.
Here's the client form, you can see in the constructor that I am calling Preload(). There's also a button, clicking on it should show the server, which should be fast since the server form is already preloaded:
public partial class Form1 : Form
{
ServerUser server = null;
public Form1()
{
InitializeComponent();
Preload();
}
public async void Preload()
{
await Task.Run(() =>
{
server = new ServerUser();
server.LoadDocument();
server.ShowDialog();
}
);
}
private void button1_Click(object sender, EventArgs e)
{
server.Show();
}
}
Here I try to preload form ServerUser in constructor of Form1 and if I click on button1 Server form show faster
And here's the server form:
public partial class ServerUser : Form
{
public ServerUser()
{
InitializeComponent();
}
public void LoadDocument()
{
ConfigureSource();
}
public void ConfigureSource()
{
InvokeUpdateControls();
}
public void InvokeUpdateControls()
{
UpdateControls();
}
private void UpdateControls()
{
richTextBox1.Rtf = Resource1.ReferatPPC_Bun___Copy;
}
}
You need to rethink your design. You should create all forms from the main UI thread, and offload the heavy lifting(non UI stuff) to the background threads. Calling UI methods from background threads results in undefined behavior or exceptions.
Also, I think you misunderstand what await does. You call Preload() synchronously even though it is an asynchronous method. This means that by the time server.Show(); is called, Server might still be running one of these methods:
server = new ServerUser(); //you should move this outside of Task.Run()
server.LoadDocument(); //implement this method using background threads
server.ShowDialog(); //this will actually throw an exception if called via Task.Run();
From your sample I suppose LoadDocument is the expensive operation. You should rewrite that method to run on a background thread and make ServerUser show a loading screen untill LoadDocument() completes. Make sure that all UI methods from LoadDocument are called via BeginInvoke
or proper async/await.
Send in constructor;
public partial class ServerUser : Form
{
public ServerUser(Form1 form1)
{
InitializeComponent();
form1.Preload();
}
public void LoadDocument()
{
ConfigureSource();
}
public void ConfigureSource()
{
InvokeUpdateControls();
}
public void InvokeUpdateControls()
{
UpdateControls();
}
private void UpdateControls()
{
richTextBox1.Rtf = Resource1.ReferatPPC_Bun___Copy;
}
}
public partial class Form1 : Form
{
ServerUser server = null;
public Form1()
{
InitializeComponent();
Preload();
}
public async void Preload()
{
await Task.Run(() =>
{
server = new ServerUser();
server.LoadDocument();
server.ShowDialog();
}
);
}
private void button1_Click(object sender, EventArgs e)
{
server=new ServerUser(this);// or whatever you want
server.Show();
}
}

Categories