I have Xamarin.Forms with MvvmCross (version 5.5) and I want to connect to AppCenter.
I tried to call AppCenter.Start on many places but when I called
bool enabled = await Distribute.IsEnabledAsync();
in app, it always return false. I tried in project without MvvmCross and it return true.
Thanks for help.
EDIT
So finally I upgraded to MvvmCross 6.0.1
in splashScreen I am calling AppCenter.Start and it worked.
public class SplashScreen : MvxFormsSplashScreenActivity<Setup, MvxApp, FormsApp>
{
protected override void RunAppStart(Bundle bundle)
{
AppCenter.Start(
"android=xxx;",
typeof(Analytics),
typeof(Crashes),
typeof(Distribute));
StartActivity(typeof(FormsApplicationActivity));
base.RunAppStart(bundle);
}
}
Related
I am attempting to code an App in Xamarin Forms.
Upon startup, if the app is logged in the the user will be taken to the main shell with flyouts etc. If they are not logged in, then they will be taken to the signup/login page.
I have the following code in my App.xaml.cs
public App()
{
Instance = this;
InitializeComponent();
AssessStartupPage();
}
public void AssessStartupPage()
{
if (App.LoggedInUser == null)
{
SwitchToSignupPage_OTP();
return;
}
SwitchToShell();
}
public void SwitchToSignupPage_OTP() => SwitchMainView(new SignupPage_OTP());
public void SwitchToShell() => SwitchMainView(new AppShell());
When I attempt to switch to the shell from another Page (by calling App.Instance.SwitchToShell) the following exception is thrown:
Java.Lang.RuntimeException
Font asset not found sans-serif-medium
However if I change the AssessStartupPage() function which is called on startup to this:
public void AssessStartupPage()
{
SwitchToShell();
return;
}
The shell loads correctly at startup. However I need to be able to have the Signup page load at start if the user is not signed in and therefore need to be able to switch to the shell once signup is complete.
I have updated all the xamarin forms and xamarin essential libraries to the latest stable version but nothing seems to help.
The problem doesn't occur when I debug the app in UWP mode.
I'm trying to login with integration to social networks, more specifically to Google in .NET MAUI. I've done it with Xamarin Forms and it worked perfectly, however, in MAUI a standard error is occurring:
Error CS0246 The type or namespace name 'Android' could not be found (are you missing a using directive or an assembly reference?) LoginWithRedes (net6.0-ios), LoginWithRedes (net6.0-maccatalyst), LoginWithRedes (net6.0-windows10.0.19041) C:\MAUI\LoginWithRedes\LoginWithRedes\Platforms\Android\GoogleManager.cs
Libraries not being recognized
Packages I added to the project
Code of the GoogleManager.CS Class where the standard error occurs to me:
`[assembly: Dependency(typeof(GoogleManager))]
namespace LoginWithRedes.Platforms.Android
{
public class GoogleManager : Java.Lang.Object, IGoogleManager, GoogleApiClient.IConnectionCallbacks, GoogleApiClient.IOnConnectionFailedListener
{
public static GoogleApiClient _googleApiClient { get; set; }
public static GoogleManager Instance { get; private set; }
public bool IsLogedIn { get; set; }
Context _context;
public GoogleManager()
{
_context = global::Android.App.Application.Context;
Instance = this;
}
public void Login()
{
GoogleSignInOptions gso = new GoogleSignInOptions.Builder(GoogleSignInOptions.DefaultSignIn)
.RequestEmail()
.Build();
_googleApiClient = new GoogleApiClient.Builder((_context).ApplicationContext)
.AddConnectionCallbacks(this)
.AddOnConnectionFailedListener(this)
.AddApi(Auth.GOOGLE_SIGN_IN_API, gso)
.AddScope(new Scope(Scopes.Profile))
.Build();
Intent signInIntent = Auth.GoogleSignInApi.GetSignInIntent(_googleApiClient);
((MainActivity)Forms.Context).StartActivityForResult(signInIntent, 1);
_googleApiClient.Connect();
}
public void Logout()
{
var gsoBuilder = new GoogleSignInOptions.Builder(GoogleSignInOptions.DefaultSignIn).RequestEmail();
GoogleSignIn.GetClient(_context, gsoBuilder.Build())?.SignOut();
_googleApiClient.Disconnect();
}
public void OnAuthCompleted(GoogleSignInResult result)
{
if (result.IsSuccess)
{
IsLogedIn = true;
Application.Current.MainPage = new MainPage();
}
else
{
}
}`
OnActivityResult method that I implemented in MainActivity class
If anyone can help me with this error, I would be very grateful.
Note: I'm new to Xamarin and Maui.
Thank you very much in advance
I'm also new to Maui, and in my experience, these errors were caused by using native Xamarin libraries in Maui. Xamarin targets each platform separately using separate nuget packages. Maui's combined 1-project architecture means you need to use packages that work for both at once.
At least when I was getting started a few months ago, these weren't readily available. Firebase client was not yet released for .NET 6.0 (Multiplatform by default).
Things may have changed since then. But I had great success using Firebase with this plugin https://github.com/TobiasBuchholz/Plugin.Firebase. It wraps up the platform specific libraries into a single project API, with a really easy to use c# interface. You can use await and stuff as you would expect. Calling the native APIs was difficult, and required a lot of code duplication. This plugin saves a lot of time, and I haven't yet run into any problems.
The documentation on the plugin is a bit sparse, but hey, it's free and works.
I save some preferences in Application.Current.Properties for my Xamarin.Forms app and have a BroadcastReceiver that needs those preferences. The problem is that Xamarin.Forms is not initialized in the BroadcastReceiver so I need a way to access those variables in native Xamain.Android. Is that possible?
I need a way to access those variables in native Xamain.Android
you could use DependencyService ,this functionality enables Xamarin.Forms apps to do anything that a native app can do.
here is a sample for using Android's Toast to show message in shared code:
1.create a interface in shared code:
public interface IToast
{
void LongAlert(string message);//the parameter could pass to the native platform
void ShortAlert(string message);
}
2.Android Implementation:
[assembly: Dependency(typeof(ToastAndroid))]
namespace Demo.Droid
{
class ToastAndroid : IToast
{
public void LongAlert(string message)
{
Toast.MakeText(Android.App.Application.Context, message, ToastLength.Long).Show();
}
public void ShortAlert(string message)
{
Toast.MakeText(Android.App.Application.Context, message, ToastLength.Short).Show();
}
}
}
3.call in shared code:
DependencyService.Get<IToast>().ShortAlert("short toast);
DependencyService.Get<IToast>().LongAlert("long toast);
DependencyService
I found the solution myself.
I used the Xamarin.Forms source (found here) to write a function that reads the values from the same file as they are written to in the forms app. Works like a charm.
I'm currently building a Xamarin.Forms project using MVVMCross. In order to test my platform specific code I am using Nunit.Xamarin which features an app that run tests on device.
This test app is a forms app but doesn't use MVVMCross and I haven't had any luck setting it up to use MVVMCross due to the fact the Application class loads an App of type NUnit.Runner.App whereas MVVMCross requires MvxFormsApp.
I want to test this class the saves and loads user data from an SQLite Database:
public class DataStorageService : IDataStorageService
{
private readonly SQLiteConnection _connection;
public User UserData
{
get { return _connection.Table<User>().FirstOrDefault(); }
set { _connection.InsertOrReplace(value); }
}
public DataStorageService(IMvxSqliteConnectionFactory factory)
{
_connection = factory.GetConnection(DataStorageConstants.LocalDatabaseName);
_connection.CreateTable<User>();
}
}
I want to actually test that it saves and loads from a local SQLite database so I don't want to mock the IMvxSqliteConnectionFactory. I tried installing MVVMCross and the SQLite plugin into the project and then passing in the Android implementation of the connection factory but that repeatedly threw a typeloadexception.
Any ideas as to how I can set up this test with MVVMCross (or are there alternatives?) and dependency injection?
It is possible :) The important stuff happens in the MvxSplashScreenActivity. The MvxFormsApp is basically empty. So we don't have to care. Example Code: https://github.com/smstuebe/stackoverflow-answers/tree/master/mvx-android-test-app
Create a nunit Test app project
Install-Package MvvmCross.StarterPack -Version 4.1.4
Get rid of Views folder
Install the SQLite plugin
Reference your Core project
Install-Package MvvmCross.Forms.Presenter -Version 4.1.4
Remove MainLauncher = true from MainActivity
Adust Setup to return your core project's App
protected override IMvxApplication CreateApp()
{
return new MyApp.Core.App();
}
Change SplashScreen to (source)
[Activity(MainLauncher = true
, Theme = "#style/Theme.Splash"
, NoHistory = true
, ScreenOrientation = ScreenOrientation.Portrait)]
public class SplashScreen
: MvxSplashScreenActivity
{
public SplashScreen()
: base(Resource.Layout.SplashScreen)
{
}
private bool _isInitializationComplete;
public override void InitializationComplete()
{
if (!_isInitializationComplete)
{
_isInitializationComplete = true;
StartActivity(typeof(MainActivity));
}
}
protected override void OnCreate(Android.OS.Bundle bundle)
{
Forms.Init(this, bundle);
Forms.ViewInitialized += (object sender, ViewInitializedEventArgs e) =>
{
if (!string.IsNullOrWhiteSpace(e.View.StyleId))
{
e.NativeView.ContentDescription = e.View.StyleId;
}
};
base.OnCreate(bundle);
}
}
Write a test like
[TestFixture]
public class TestClass
{
[Test]
public void TestMethod()
{
var service = Mvx.Resolve<IDataStorageService>();
Assert.IsNull(service.UserData);
}
}
Enjoy the awesomeness of MvvmCross
I'm using the android toolbar at my MvvmCross 3.5.1 app but once I updated it to MvvmCross 4.0 databindings are broken. As long as there is no base appcompat activity I have to implement my own:
MvxActionBarEventSourceActivity : AppCompatActivity , IMvxEventSourceActivity
{
...
}
And then base bindable mvx activity:
MvxActionBarActivity : MvxActionBarEventSourceActivity, IMvxAndroidView
{
...
}
App starts just fine and I can see my toolbar but bindings are just "silent" and don't work. Same implementation works find for MvvmCross 3.5.
You can find full sample here:
https://dl.dropboxusercontent.com/u/19503836/MvvmCross4_Toolbar_Bindings.zip
Please advise.
You need to override OnCreateView and AttachBaseContext and use the MvxAppCompatActivityHelper to support bindings: https://github.com/MvvmCross/MvvmCross-AndroidSupport/blob/master/MvvmCross.Droid.Support.V7.AppCompat/MvxAppCompatActivity.cs#L78
public override View OnCreateView(View parent, string name, Context context, IAttributeSet attrs)
{
var view = MvxAppCompatActivityHelper.OnCreateView(parent, name, context, attrs);
return view ?? base.OnCreateView(parent, name, context, attrs);
}
protected override void AttachBaseContext(Context #base)
{
base.AttachBaseContext(MvxContextWrapper.Wrap(#base, this));
}
There is a sample available to implement Toolbar instead of Actionbar too: https://github.com/MvvmCross/MvvmCross-AndroidSupport/tree/master/Samples