using Android.App; using Android.Content; using Android.Content.PM; using Android.Gms.Common; using Android.OS; using Android.Speech.Tts; using Android.Util; using Android.Widget; using Newtonsoft.Json.Linq; using Plugin.DeviceInfo; using SQLite.Net; using SQLite.Net.Platform.XamarinAndroid; using System; using System.Collections.Generic; using System.IO; using System.Linq; using System.Net; using System.Net.Http; using System.Threading.Tasks; using Xamarin.Auth; using XLabs; using XLabs.Caching; using XLabs.Caching.SQLite; using XLabs.Enums; using XLabs.Forms; using XLabs.Forms.Services; using XLabs.Ioc; using XLabs.Platform.Device; using XLabs.Platform.Mvvm; using XLabs.Platform.Services; using XLabs.Platform.Services.Email; using XLabs.Platform.Services.Media; using XLabs.Serialization; using XLabs.Serialization.JsonNET; namespace ZicMoove.Droid { using Android.Runtime; using Android.Support.V4.App; using Android.Support.V4.Content; using ZicMoove.Interfaces; using Data; using Droid.OAuth; using Helpers; using Interfaces; using Model.Auth.Account; using static Android.Manifest; using Settings; using Model.Auth; using Com.Paypal.Android.Sdk.Payments; using Java.Math; using Org.Json; using Xamarin.Forms; using ViewModels.UserProfile; [Activity( Name = Constants.ApplicationName + ".MainActivity", Label = Constants.ApplicationLabel, Theme = "@style/MainTheme", Icon = "@drawable/icon", MainLauncher = true, ConfigurationChanges = ConfigChanges.ScreenSize | ConfigChanges.Orientation)] [IntentFilter(new[] { Intent.ActionMain }, Categories = new[] { Intent.CategoryLauncher }, Icon = "@drawable/icon")] public class MainActivity : // global::Xamarin.Forms.Platform.Android.FormsAppCompatActivity, XFormsCompatApplicationDroid, IPlatform, IComponentContext { private PayPalConfiguration config = new PayPalConfiguration() .Environment(PayPalConfiguration.EnvironmentSandbox) .MerchantName("Yavsc") .LanguageOrLocale("fr") .RememberUser(true) .AcceptCreditCards(true) // needs card.io // TODO .MerchantPrivacyPolicyUri(new Uri("http://")) // TODO .MerchantUserAgreementUri(new Uri("http://")) .ClientId(Constants.PaypalClientId) .SandboxUserPassword(Constants.PaypalClientSecret) ; protected override void OnCreate(Bundle bundle) { TabLayoutResource = Resource.Layout.Tabbar; ToolbarResource = Resource.Layout.Toolbar; base.OnCreate(bundle); XamSvg.Setup.InitSvgLib(); // FIXME usefull? SetPersistent(true); // global::Xamarin.Forms.Forms.SetTitleBarVisibility(Xamarin.Forms.AndroidTitleBarVisibility.Never); //var tb = FindViewById(ToolbarResource); // FIXME tb is null var stb = new Android.Support.V7.Widget.Toolbar(this); SetSupportActionBar(stb); var tb = new Toolbar(this); SetActionBar(tb); if (Build.VERSION.SdkInt >= BuildVersionCodes.Kitkat) { Android.Webkit.WebView.SetWebContentsDebuggingEnabled(true); } IXFormsApp app = null; if (!Resolver.IsSet) { var xfapp = new XFormsCompatAppDroid(); this.SetIoc(xfapp); } else { app = Resolver.Resolve() as IXFormsApp; if (app != null) app.AppContext = this; } global::Xamarin.Forms.Forms.Init(this, bundle); global::Xamarin.FormsMaps.Init(this, bundle); Xamarin.Forms.Forms.ViewInitialized += (sender, e) => { if (!string.IsNullOrWhiteSpace(e.View.StyleId)) { e.NativeView.ContentDescription = e.View.StyleId; } }; var fapp = new ZicMoove.App(this); LoadApplication(fapp); var componentName = StartService(new Intent(this, typeof(YavscChooserTargetService))); // TabLayoutResource = Resource.Layout.Tabbar; // ToolbarResource = Resource.Layout.Toolbar; /* base.OnCreate(bundle); global::Xamarin.Forms.Forms.Init(this, bundle); global::Xamarin.FormsMaps.Init(this, bundle); LoadApplication(new App(this)); /* var x = typeof(Themes.DarkThemeResources); x = typeof(Themes.LightThemeResources); x = typeof(Themes.Android.UnderlineEffect); */ var intent = new Intent(this, typeof(PayPalService)); intent.PutExtra(PayPalService.ExtraPaypalConfiguration, config); this.StartService(intent); } public override void OnRequestPermissionsResult(int requestCode, string[] permissions, [GeneratedEnum] Android.Content.PM.Permission[] grantResults) { base.OnRequestPermissionsResult(requestCode, permissions, grantResults); if (requestCode == Constants.AllowBeATarget) { if (grantResults.Length > 0) { if (grantResults[0] == Android.Content.PM.Permission.Granted) { // yay! } else { // Should we show an explanation? if (ActivityCompat.ShouldShowRequestPermissionRationale(this, Permission.BindChooserTargetService)) { //Show permission explanation dialog... // Show an expanation to the user *asynchronously* -- don't block // this thread waiting for the user's response! After the user // sees the explanation, try again to request the permission. throw new NotImplementedException(); } else { //Never ask again selected, or device policy prohibits the app from having that permission. //So, disable that feature, or fall back to another situation... } } } } } private SimpleContainer SetIoc(XFormsCompatAppDroid app) { var resolverContainer = new SimpleContainer(); app.Init(this); var documents = app.AppDataDirectory; var pathToDatabase = Path.Combine(documents, "xforms.db"); resolverContainer.Register(t => AndroidDevice.CurrentDevice) .Register(t => t.Resolve().Display) .Register(t => new FontManager(t.Resolve())) .Register() .Register() .Register() .Register(resolverContainer) .Register(app) .Register(t => new KeyVaultStorage(t.Resolve().Id.ToCharArray())) .Register() .Register( t => new SQLiteSimpleCache(new SQLitePlatformAndroid(), new SQLiteConnectionString(pathToDatabase, true), t.Resolve())) .RegisterSingle(); Resolver.SetResolver(resolverContainer.GetResolver()); return resolverContainer; } public bool EnablePushNotifications(bool enable) { if (enable) return StartNotifications(); else return StopNotifications(); } private string gCMStatusMessage = null; public string GCMStatusMessage { get { return gCMStatusMessage; } } public App AppContext { get; set; } bool StartNotifications() { if (IsPlayServicesAvailable(out gCMStatusMessage)) { var intent = new Intent(this, typeof(GcmRegistrationIntentService)); StartService(intent); return true; } return false; } bool StopNotifications() { return StopService(new Intent(this, typeof(GcmRegistrationIntentService))); } public void RevokeAccount(string userName) { var accStore = AccountStore.Create(this); var accounts = accStore.FindAccountsForService(Constants.ApplicationLabel); accStore.Delete( accounts.Where(a => a.Username == userName).FirstOrDefault() , Constants.ApplicationLabel); Toast.MakeText(this, Resource.String.yavscIdentRemoved , ToastLength.Short); } public void OpenWeb(string Uri) { var u = global::Android.Net.Uri.Parse(Uri); Intent i = new Intent(Intent.ActionView, u); StartActivity(i); } protected override void OnStart() { base.OnStart(); if (MainSettings.PushNotifications) StartNotifications(); long queryId = Intent.GetLongExtra("BookQueryId", 0); if (queryId > 0) { Task.Run(async () => { var query = DataManager.Instance.BookQueries.LocalGet(queryId); App.ShowBookQuery(query); }); } } public bool IsPlayServicesAvailable(out string msgText) { int resultCode = GoogleApiAvailability.Instance.IsGooglePlayServicesAvailable(this); if (resultCode != ConnectionResult.Success) { if (GoogleApiAvailability.Instance.IsUserResolvableError(resultCode)) msgText = GoogleApiAvailability.Instance.GetErrorString(resultCode); else { msgText = "Sorry, this device is not supported"; Finish(); } return false; } else { msgText = "Google Play Services is available."; return true; } } public async Task> GetAndroidAccounts() { return await Task.Run(() => { var manager = AccountStore.Create(this); return manager.FindAccountsForService(Constants.ApplicationLabel); }); } public void AddAccount() { var auth = new YaOAuth2Authenticator( clientId: Constants.APIKey, clientSecret: Constants.APISecret, scope: Constants.Scope, authorizeUrl: new Uri(Constants.AuthorizeUrl), redirectUrl: new Uri(Constants.RedirectUrl), accessTokenUrl: new Uri(Constants.AccessTokenUrl)); Intent loginIntent = auth.GetUI(this); var accStore = AccountStore.Create(this); auth.Completed += (sender, eventArgs) => { if (eventArgs.IsAuthenticated) { int expires_in = int.Parse(eventArgs.Account.Properties["expires_in"]); var tokens = new Tokens { AccessToken = eventArgs.Account.Properties["access_token"], RefreshToken = eventArgs.Account.Properties["refresh_token"], ExpiresIn = expires_in, TokenType = eventArgs.Account.Properties["token_type"] }; RunOnUiThread( async () => { using (var client = new HttpClient()) { // get me using (var request = new HttpRequestMessage(HttpMethod.Get, Constants.UserInfoUrl)) { request.Headers.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue("Bearer", tokens.AccessToken); using (var response = await client.SendAsync(request)) { response.EnsureSuccessStatusCode(); string userJson = await response.Content.ReadAsStringAsync(); JObject jactiveUser = JObject.Parse(userJson); Account acc = eventArgs.Account; var uid = jactiveUser["Id"].Value(); var username = jactiveUser["UserName"].Value(); var roles = jactiveUser["Roles"].Values().ToList(); var emails = jactiveUser["EMails"].Values().ToList(); var avatar = jactiveUser["Avatar"].Value(); var address = jactiveUser["Avatar"].Value(); var newuser = new User { UserName = username, EMails = emails, Roles = roles, Id = uid, YavscTokens = tokens, Avatar = avatar, Address = address }; MainSettings.SaveUser(newuser); accStore.Save(acc, Constants.ApplicationLabel); } } } }); } }; auth.Error += Auth_Error; StartActivity(loginIntent); } private void Auth_Error(object sender, AuthenticatorErrorEventArgs e) { // TODO handle } public T Resolve() { return (T)Resolver.Resolve(typeof(T)); } public object Resolve(Type t) { return Resolver.Resolve(t); } protected override void OnSaveInstanceState(Bundle outState) { // TODO Save instance base.OnSaveInstanceState(outState); } public override void OnStateNotSaved() { base.OnStateNotSaved(); } public override void OnRestoreInstanceState(Bundle savedInstanceState, PersistableBundle persistentState) { base.OnRestoreInstanceState(savedInstanceState, persistentState); } private void CheckSharing() { // .BIND_CHOOSER_TARGET_SERVICE // Here, thisActivity is the current activity if (ContextCompat.CheckSelfPermission(this, Permission.BindChooserTargetService) != Android.Content.PM.Permission.Granted) { ActivityCompat.RequestPermissions(this, new String[] { Permission.BindChooserTargetService }, Constants.AllowBeATarget); // Constants.AllowReadContacts is an // app-defined int constant. The callback method gets the // result of the request. } } public void Pay(double amount, PayMethod method, string name = null) { if (name == null) name = $"Votre commande {Constants.ApplicationLabel}"; var payment = new PayPalPayment(new BigDecimal(amount), "EUR", "the item", PayPalPayment.PaymentIntentOrder); var intent = new Intent(this, typeof(PaymentActivity)); intent.PutExtra(PayPalService.ExtraPaypalConfiguration, config); intent.PutExtra(PaymentActivity.ExtraPayment, payment); this.StartActivityForResult(intent, (int)RequestCode.PayImmediate); } protected override void OnActivityResult(int requestCode, Result resultCode, Intent data) { if (requestCode == (int)RequestCode.PayDelayed) if (resultCode == Result.Ok) { var confirm = data.GetParcelableExtra(PaymentActivity.ExtraResultConfirmation); if (confirm != null) { try { Log.Info("xam.paypal.test", confirm.ToString()); // TODO: send 'confirm' to your server for verification. // see https://developer.paypal.com/webapps/developer/docs/integration/mobile/verify-mobile-payment/ // for more details. } catch (JSONException e) { Log.Error("xam.paypal.test", "something went really wrong here: ", e); } } } else if (resultCode == Result.Canceled) { Log.Info("xam.paypal.test", "Canceled."); } else if ((int)resultCode == PaymentActivity.ResultExtrasInvalid) { Log.Info("xam.paypal.test", "Invalid Payment or PayPalConfiguration."); } } protected override void OnDestroy() { this.StopService(new Intent(this, typeof(PayPalService))); base.OnDestroy(); } enum RequestCode : int { PayImmediate = 1, PayDelayed } private static string imagesFolder = null; public static string ImagesFolder { get { if (imagesFolder != null) return imagesFolder; imagesFolder = Constants.ImagePath.GetSpecialFolder(); return imagesFolder; } } public void UpdateAppImages() { var images = ImagesFolder; using (var client = new HttpClient()) { client.BaseAddress = new Uri(Constants.YavscHomeUrl); var targets = DataManager.Instance.Activities.Select( a => new string[2] { a.Photo, a.Code } ).ToArray(); foreach (var photo in targets) { if (photo[0] != null) { var streamtask = client.GetStreamAsync(photo[0]); streamtask.Wait(); if (streamtask.IsCompleted) { using (streamtask.Result) { FileInfo fi = new FileInfo(Path.Combine(images, $"{photo[1]}.svg")); using (var ostr = fi.OpenWrite()) { streamtask.Result.CopyTo(ostr); } } } var acode = photo[1]; var act = DataManager.Instance.Activities.LocalGet(acode); act.LocalPhoto = Path.Combine(images, $"{acode}.svg"); } } DataManager.Instance.Activities.SaveEntity(); } } } }