-
Notifications
You must be signed in to change notification settings - Fork 2
PictureChooser does not return #28
Comments
Posted directly since it is awaiting moderation in the Xamarin ForumsIf you have Xamarin Forms and MvvmCross, then the most likely cause of PictureChooserTask not returning is because the current ApplicationActivity dues not implement IMvxAndroidView and does not implement IMvxEventSourceActivity. Basically if your source looks like this: public class MvxFormsApplicationActivity
: FormsApplicationActivity {
protected override void OnCreate(Bundle bundle) {
base.OnCreate(bundle);
Xamarin.Forms.Forms.Init(this, bundle);
Acr.UserDialogs.UserDialogs.Init(this);
Mvx.RegisterSingleton<Acr.UserDialogs.IUserDialogs>(Acr.UserDialogs.UserDialogs.Instance);
Mvx.RegisterSingleton<Acr.Settings.ISettings>(Acr.Settings.Settings.CreateInstance("droid"));
Mvx.RegisterSingleton<IWaterMarkingService>(() => new ZueblinNM.Droid.Services.WaterMarkingService());
var mvxFormsApp = new MvxFormsApp();
LoadApplication(mvxFormsApp);
var presenter = Mvx.Resolve<IMvxViewPresenter>() as MvxFormsDroidPagePresenter;
presenter.MvxFormsApp = mvxFormsApp;
Mvx.Resolve<IMvxAppStart>().Start();
}
} Then you should create a class like this: using Android.App;
using Android.Content;
using Android.OS;
using Cirrious.CrossCore.Core;
using Cirrious.CrossCore.Droid.Views;
using Cirrious.MvvmCross.Droid.Views;
using Cirrious.MvvmCross.ViewModels;
using System;
using Xamarin.Forms.Platform.Android;
namespace EcoMerc.Xamarin.Droid {
public class MvxFormsAndroidEventApplicationActivity : FormsApplicationActivity, IMvxAndroidView, IMvxEventSourceActivity {
protected override void OnCreate(Bundle bundle) {
CreateWillBeCalled.Raise(this, bundle);
base.OnCreate(bundle);
CreateCalled.Raise(this, bundle);
this.AddEventListeners();
}
#region IMvxAndroidView (properties not implemented)
public void MvxInternalStartActivityForResult(Android.Content.Intent intent, int requestCode) {
StartActivityForResultCalled.Raise(this, new MvxStartActivityForResultParameters(intent, requestCode));
base.StartActivityForResult(intent, requestCode);
}
public IMvxViewModel ViewModel { get; set; }
public object DataContext { get; set; }
public Cirrious.MvvmCross.Binding.BindingContext.IMvxBindingContext BindingContext { get; set; }
#endregion
#region Overrides for Event Raising for IMvxEventSourceActivity
public override void OnConfigurationChanged(Android.Content.Res.Configuration newConfig) {
base.OnConfigurationChanged(newConfig);
}
protected override void OnDestroy() {
DestroyCalled.Raise(this);
base.OnDestroy();
}
protected override void OnNewIntent(Intent intent) {
base.OnNewIntent(intent);
NewIntentCalled.Raise(this, intent);
}
protected override void OnResume() {
base.OnResume();
ResumeCalled.Raise(this);
}
protected override void OnPause() {
PauseCalled.Raise(this);
base.OnPause();
}
protected override void OnStart() {
base.OnStart();
StartCalled.Raise(this);
}
protected override void OnRestart() {
base.OnRestart();
RestartCalled.Raise(this);
}
protected override void OnStop() {
StopCalled.Raise(this);
base.OnStop();
}
public override void StartActivityForResult(Intent intent, int requestCode) {
StartActivityForResultCalled.Raise(this, new MvxStartActivityForResultParameters(intent, requestCode));
base.StartActivityForResult(intent, requestCode);
}
public override void StartActivityForResult(Intent intent, int requestCode, Bundle options) {
StartActivityForResultCalled.Raise(this, new MvxStartActivityForResultParameters(intent, requestCode));
base.StartActivityForResult(intent, requestCode, options);
}
protected override void OnActivityResult(int requestCode, Result resultCode, Intent data) {
ActivityResultCalled.Raise(this, new MvxActivityResultParameters(requestCode, resultCode, data));
base.OnActivityResult(requestCode, resultCode, data);
}
protected override void OnSaveInstanceState(Bundle outState) {
SaveInstanceStateCalled.Raise(this, outState);
base.OnSaveInstanceState(outState);
}
protected override void Dispose(bool disposing) {
if (disposing) {
DisposeCalled.Raise(this);
}
base.Dispose(disposing);
}
#endregion
#region Events
public event EventHandler<MvxValueEventArgs<Bundle>> CreateWillBeCalled;
public event EventHandler<MvxValueEventArgs<Bundle>> CreateCalled;
public event EventHandler DestroyCalled;
public event EventHandler<MvxValueEventArgs<Intent>> NewIntentCalled;
public event EventHandler ResumeCalled;
public event EventHandler PauseCalled;
public event EventHandler StartCalled;
public event EventHandler RestartCalled;
public event EventHandler StopCalled;
public event EventHandler<MvxValueEventArgs<Bundle>> SaveInstanceStateCalled;
public event EventHandler<MvxValueEventArgs<MvxStartActivityForResultParameters>> StartActivityForResultCalled;
public event EventHandler<MvxValueEventArgs<MvxActivityResultParameters>> ActivityResultCalled;
public event EventHandler DisposeCalled;
#endregion
}
} |
Hi, thanks for pointing this out! Can you make a pull request, so it is easier to merge in? |
I ill be looking at this shortly. It may be more appropriate to make it an example with perhaps some additions to the presenters. |
@PeterBurke maybe you are right, However I feel it must be a bug that Mvx does not know the correct current activity. In the Mvvmcross-Forms sample I think (through som debugging) that it for the most part the current IMvxAndroidView is the splashscreen (even when inside active ViewModels). |
After a few hours of testing, if I turn on the kill Activities when they are not in focus (in developer mode) then there is an exception in the above code: In the OnDestroy() Even if I check if there is registered an eventhandler there seems to be a null reference exception somewhere inside MvvmCross. To tired to investigate more now. Additionally there should be some communicating with the ViewModels. Because they maybe closed and resumed and this class would have the capability of notifying them. Or maybe not and people needing it can implement it themselves? |
Just a small update quite a long time from discovery. The exception that is thrown from MvvmCross is a null reference exception
For what I can see everything is null checked so I cannot really see why this should fail. However wrapping everything in a try catch (bad bad developer) is does not die horribly: protected override void OnDestroy() {
try {
base.OnDestroy();
DestroyCalled?.Raise(this);
} catch (Exception ex) {
Android.Util.Log.Warn("mvvmcross", ex.ToString());
}
} |
This worked for me. Thanks! |
The current implementation of the MvxFormsApplicationActivity does not implement IMvxAndroidView nor IMvxEventSourceActivity and because of this the MvvmCross picture chooser plugin (when correctly implemented as a service) cannot return with an image to the viewmodel.
I have proposed a solution in the xamarin forum. But if needed I could probably find time to do a pull-request.
https://forums.xamarin.com/discussion/51135/mvvmcross-picture-chooser-not-working-with-the-take-picture-option
The text was updated successfully, but these errors were encountered: