You are on page 1of 12

Kod za Android aplikaciju:

using Acr.UserDialogs;
using Android.App;
using Android.Content;
using Android.Content.PM;
using Android.OS;
using Android.Util;
using Android.Views;
using CarouselView.FormsPlugin.Android;
using Microsoft.AppCenter.Push;
using Microsoft.Identity.Client;
using Plugin.HtmlLabel.Android;
using Plugin.Permissions;
using TheBeat.Clients.Base.Helpers;
using TheBeat.Clients.Base.Services.Authentication;
using TheBeat.Clients.Base.ViewModels.Base;
using TheBeat.Clients.Droid.Services.Authentication;
using TheBeat.Clients.Droid.Services.CardEmulation;
using Xamarin.Forms;
using Xamarin.Forms.Platform.Android;

namespace TheBeat.Clients.Droid
{
[Activity(
Label = "theBeat.hr",
Icon = "@drawable/icon",
Theme = "@style/MainTheme",
MainLauncher = false,
ScreenOrientation = ScreenOrientation.Portrait)]
public class MainActivity : FormsAppCompatActivity
{
protected override void OnCreate(Bundle bundle)
{
TabLayoutResource = Resource.Layout.Tabbar;
ToolbarResource = Resource.Layout.Toolbar;

base.OnCreate(bundle);

HtmlLabelRenderer.Initialize();
Forms.Init(this, bundle);
CarouselViewRenderer.Init();
UserDialogs.Init(this);
Renderers.Calendar.Init();
Xamarin.FormsMaps.Init(this, bundle);

Push.SetSenderId("802023456231");

InitMessageCenterSubscriptions();
RegisterPlatformDependencies();
LoadApplication(new App());

App.AuthenticationClient.PlatformParameters =
new PlatformParameters(Forms.Context as Activity);

MakeStatusBarTranslucent(false);
InitNFCService();
}

private void InitNFCService()


{
//StartService(new Intent(this, typeof(CardService)));
//DisableNFCService();
//MessagingCenter.Subscribe<string>(this, MessengerKeys.SendNFCToken, EnableNFCService);
}

public override void OnRequestPermissionsResult(int requestCode, string[] permissions, Permission[] grantResults)


{
PermissionsImplementation.Current.OnRequestPermissionsResult(requestCode, permissions, grantResults);
}

protected override void OnActivityResult(int requestCode, Result resultCode, Intent data)


{
base.OnActivityResult(requestCode, resultCode, data);
AuthenticationAgentContinuationHelper.SetAuthenticationAgentContinuationEventArgs(
requestCode, resultCode, data);
}

private void InitMessageCenterSubscriptions()


{
MessagingCenter.Instance.Subscribe<StatusBarHelper, bool>(this,
StatusBarHelper.TranslucentStatusChangeMessage, OnTranslucentStatusRequest);
}

private void OnTranslucentStatusRequest(StatusBarHelper helper, bool makeTranslucent)


{
MakeStatusBarTranslucent(makeTranslucent);
}

private void MakeStatusBarTranslucent(bool makeTranslucent)


{
if (makeTranslucent)
{
SetStatusBarColor(Android.Graphics.Color.Transparent);

if (Build.VERSION.SdkInt >= BuildVersionCodes.Lollipop)


{
Window.DecorView.SystemUiVisibility = (StatusBarVisibility)(SystemUiFlags.LayoutFullscreen |
SystemUiFlags.LayoutStable);
}
}
else
{
using (var value = new TypedValue())
{
if (Theme.ResolveAttribute(Resource.Attribute.colorPrimaryDark, value, true))
{
var color = new Android.Graphics.Color(value.Data);
SetStatusBarColor(color);
}
}

if (Build.VERSION.SdkInt >= BuildVersionCodes.Lollipop)


{
Window.DecorView.SystemUiVisibility = StatusBarVisibility.Visible;
}
}
}

private static void RegisterPlatformDependencies()


{
Locator.Instance.Register<IBrowserCookiesService, BrowserCookiesService>();
}

private void DisableNFCService()


{
PackageManager pm = this.PackageManager;
pm.SetComponentEnabledSetting(
new ComponentName(this, CardService.ServiceName),
ComponentEnabledState.Disabled,
ComponentEnableOption.DontKillApp);
}

private void EnableNFCService(string message = "")


{
PackageManager pm = this.PackageManager;
pm.SetComponentEnabledSetting(
new ComponentName(this, CardService.ServiceName),
ComponentEnabledState.Enabled,
ComponentEnableOption.DontKillApp);
}
}
}

using System;
using Android.App;
using Android.OS;
using Android.Runtime;
using Plugin.CurrentActivity;
namespace TheBeat.Clients.Droid
{
//You can specify additional application information in this attribute
[Application]
public class MainApplication : Application, Application.IActivityLifecycleCallbacks
{
public MainApplication(IntPtr handle, JniHandleOwnership transer)
:base(handle, transer)
{
}

public override void OnCreate()


{
base.OnCreate();
RegisterActivityLifecycleCallbacks(this);
//A great place to initialize Xamarin.Insights and Dependency Services!
}

public override void OnTerminate()


{
base.OnTerminate();
UnregisterActivityLifecycleCallbacks(this);
}

public void OnActivityCreated(Activity activity, Bundle savedInstanceState)


{
CrossCurrentActivity.Current.Activity = activity;
}

public void OnActivityDestroyed(Activity activity)


{
}

public void OnActivityPaused(Activity activity)


{
}

public void OnActivityResumed(Activity activity)


{
CrossCurrentActivity.Current.Activity = activity;
}

public void OnActivitySaveInstanceState(Activity activity, Bundle outState)


{
}

public void OnActivityStarted(Activity activity)


{
CrossCurrentActivity.Current.Activity = activity;
}

public void OnActivityStopped(Activity activity)


{
}
}
}

using Android.App;
using Android.Content;
using Android.Content.PM;
using Android.OS;
using Android.Support.V7.App;
using Android.Views;

namespace TheBeat.Clients.Droid
{
[Activity(
Label = "theBeat.hr",
Icon = "@drawable/icon",
Theme = "@style/SplashTheme",
MainLauncher = true,
NoHistory = true,
ScreenOrientation = ScreenOrientation.Portrait)]
public class SplashActivity : AppCompatActivity
{
protected override void OnCreate(Bundle bundle)
{
base.OnCreate(bundle);

if (Build.VERSION.SdkInt >= BuildVersionCodes.Lollipop)


{
Window.DecorView.SystemUiVisibility = StatusBarVisibility.Visible;
Window.SetStatusBarColor(Android.Graphics.Color.Transparent);
}

InvokeMainActivity();
}

private void InvokeMainActivity()


{
var mainActivityIntent = new Intent(this, typeof(MainActivity));
StartActivity(mainActivityIntent);
}
}
}

using Android.OS;
using Android.Webkit;
using TheBeat.Clients.Base.Services.Authentication;
using System.Threading.Tasks;

namespace TheBeat.Clients.Droid.Services.Authentication
{
public class BrowserCookiesService : IBrowserCookiesService
{
public Task ClearCookiesAsync()
{
var context = Plugin.CurrentActivity.CrossCurrentActivity.Current.Activity;

if (Build.VERSION.SdkInt >= BuildVersionCodes.LollipopMr1)


{
System.Diagnostics.Debug.WriteLine("Clearing cookies for API >= LollipopMr1");
CookieManager.Instance.RemoveAllCookies(null);
CookieManager.Instance.Flush();
}
else
{
System.Diagnostics.Debug.WriteLine("Clearing cookies for API < LollipopMr1");
CookieSyncManager cookieSyncMngr = CookieSyncManager.CreateInstance(context);
cookieSyncMngr.StartSync();
CookieManager cookieManager = CookieManager.Instance;
cookieManager.RemoveAllCookie();
cookieManager.RemoveSessionCookie();
cookieSyncMngr.StopSync();
cookieSyncMngr.Sync();
}

return Task.FromResult(true);
}
}
}

using System;
using System.Linq;
using System.Text;
using Android.OS;
using Android.Nfc.CardEmulators;
using TheBeat.Clients.Base;
using Xamarin.Forms;
using Android.App;

namespace TheBeat.Clients.Droid.Services.CardEmulation
{
[Service(
Exported = true,
Enabled = true,
Name = ServiceName,
Permission = "android.permission.BIND_NFC_SERVICE"),
IntentFilter(new[] { "android.nfc.cardemulation.action.HOST_APDU_SERVICE" },
Categories = new[] { "android.intent.category.DEFAULT" }),
MetaData("android.nfc.cardemulation.host_apdu_service",
Resource = "@xml/apduservice")]
public class CardService : HostApduService
{
public const string ServiceName = "theBeat.clients.droid.services.cardEmulation.cardService";

// "OK" status word sent in response to SELECT AID command (0x9000)


private static readonly byte[] SELECT_OK_SW = HexStringToByteArray("9000");

// "UNKNOWN" status word sent in response to invalid APDU command (0x0000)


private static readonly byte[] UNKNOWN_CMD_SW = HexStringToByteArray("0000");

private static String _messageValue;

public CardService()
{
MessagingCenter.Subscribe<string>(this, MessengerKeys.SendNFCToken, StartNFCService);
}

public override byte[] ProcessCommandApdu(byte[] commandApdu, Bundle extras)


{
if (!string.IsNullOrEmpty(_messageValue))
{
return ConcatArrays(Encoding.UTF8.GetBytes(_messageValue), SELECT_OK_SW);
}
else
{
return UNKNOWN_CMD_SW;
}
}

public override void OnDeactivated(DeactivationReason reason)


{
}

private static byte[] HexStringToByteArray(string hex)


{
return Enumerable.Range(0, hex.Length)
.Where(x => x % 2 == 0)
.Select(x => Convert.ToByte(hex.Substring(x, 2), 16))
.ToArray();
}

private static byte[] ConcatArrays(byte[] first, byte[] rest)


{
byte[] result = new byte[first.Length + rest.Length];
first.CopyTo(result, 0);
rest.CopyTo(result, first.Length);
return result;
}

private void StartNFCService(string message)


{
_messageValue = message;
}
}
}

using Android.Views.InputMethods;
using Plugin.CurrentActivity;
using TheBeat.Clients.Base.Services.DismissKeyboard;
using TheBeat.Clients.Droid.Services.DismissKeyboard;

[assembly: Xamarin.Forms.Dependency(typeof(DismissKeyboardService))]
namespace TheBeat.Clients.Droid.Services.DismissKeyboard
{
public class DismissKeyboardService : IDismissKeyboardService
{
public void DismissKeyboard()
{
InputMethodManager inputMethodManager =
InputMethodManager.FromContext(CrossCurrentActivity.Current.Activity.ApplicationContext);

inputMethodManager.HideSoftInputFromWindow(
CrossCurrentActivity.Current.Activity.Window.DecorView.WindowToken, HideSoftInputFlags.NotAlways);
}
}
}

using Android.App;
using Android.Nfc;
using TheBeat.Clients.Base.Services.NFC;
using TheBeat.Clients.Droid.Services.NFC;

[assembly: Xamarin.Forms.Dependency(typeof(NfcService))]
namespace TheBeat.Clients.Droid.Services.NFC
{
public class NfcService : INfcService
{
private NfcAdapter _nfcDevice;

public NfcService()
{
var activity = Xamarin.Forms.Forms.Context as Activity;
_nfcDevice = NfcAdapter.GetDefaultAdapter(activity);
}

public bool IsAvailable


{
get
{
return _nfcDevice?.IsEnabled == true && _nfcDevice.IsNdefPushEnabled;
}
}
}
}

using System.Collections.Generic;
using Android.Runtime;
using Xamarin.Forms.Platform.Android;
using TheBeat.Clients.Base.Controls;
using Android.Graphics.Drawables;
using System.Threading.Tasks;
using Xamarin.Forms;
using TheBeat.Clients.Droid.Renderers;
using Android.Graphics;

[assembly: ExportRenderer(typeof(CalendarButton), typeof(CalendarButtonRenderer))]


namespace TheBeat.Clients.Droid.Renderers
{
[Preserve(AllMembers = true)]
public class CalendarButtonRenderer : ButtonRenderer
{
protected override void OnElementChanged(ElementChangedEventArgs<Button> e)
{
base.OnElementChanged(e);
if (Control == null) return;
Control.TextChanged += (sender, a) =>
{
var element = Element as CalendarButton;
if (Control.Text == element.TextWithoutMeasure || (string.IsNullOrEmpty(Control.Text) &&
string.IsNullOrEmpty(element.TextWithoutMeasure))) return;
Control.Text = element.TextWithoutMeasure;
};
Control.SetPadding(0, 0, 0, 0);
Control.ViewTreeObserver.GlobalLayout += (sender, args) => ChangeBackgroundPattern();
}
protected override async void OnElementPropertyChanged(object sender,
System.ComponentModel.PropertyChangedEventArgs e)
{
base.OnElementPropertyChanged(sender, e);
var element = Element as CalendarButton;
if (e.PropertyName == nameof(element.TextWithoutMeasure) || e.PropertyName == "Renderer")
{
Control.Text = element.TextWithoutMeasure;
}

if (e.PropertyName == nameof(Element.TextColor) || e.PropertyName == "Renderer")


{
Control.SetTextColor(Element.TextColor.ToAndroid());
}

if (e.PropertyName == nameof(Element.BorderWidth) || e.PropertyName == nameof(Element.BorderColor) ||


e.PropertyName == nameof(Element.BackgroundColor) || e.PropertyName == "Renderer")
{
if (element.BackgroundPattern == null)
{
if (element.BackgroundImage == null)
{
var drawable = new GradientDrawable();
drawable.SetShape(ShapeType.Rectangle);
drawable.SetStroke((int)Element.BorderWidth, Element.BorderColor.ToAndroid());
drawable.SetColor(Element.BackgroundColor.ToAndroid());
Control.SetBackground(drawable);
}
else
{
await ChangeBackgroundImageAsync();
}
}
else
{
ChangeBackgroundPattern();
}
}

if (e.PropertyName == nameof(element.BackgroundPattern))
{
ChangeBackgroundPattern();
}

if (e.PropertyName == nameof(element.BackgroundImage))
{
if (element.BackgroundImage == null)
{
var drawable = new GradientDrawable();
drawable.SetShape(ShapeType.Rectangle);
drawable.SetStroke((int)Element.BorderWidth, Element.BorderColor.ToAndroid());
drawable.SetColor(Element.BackgroundColor.ToAndroid());
Control.SetBackground(drawable);
}
else
{
await ChangeBackgroundImageAsync();
}
}
}

protected async Task ChangeBackgroundImageAsync()


{
var element = Element as CalendarButton;
if (element == null || element.BackgroundImage == null) return;

var d = new List<Drawable>();


var image = await GetBitmap(element.BackgroundImage);
d.Add(new BitmapDrawable(image));
var layer = new LayerDrawable(d.ToArray());
layer.SetLayerInset(d.Count - 1, 0, 0, 0, 0);
Control?.SetBackground(layer);
}

protected void ChangeBackgroundPattern()


{
var element = Element as CalendarButton;
if (element == null || element.BackgroundPattern == null || Control.Width == 0) return;
var d = new List<Drawable>();
for (var i = 0; i < element.BackgroundPattern.Pattern.Count; i++)
{
d.Add(new ColorDrawable(element.BackgroundPattern.Pattern[i].Color.ToAndroid()));
}
var drawable = new GradientDrawable();
drawable.SetShape(ShapeType.Rectangle);
drawable.SetStroke((int)Element.BorderWidth, Element.BorderColor.ToAndroid());
drawable.SetColor(Android.Graphics.Color.Transparent);
d.Add(drawable);
var layer = new LayerDrawable(d.ToArray());
for (var i = 0; i < element.BackgroundPattern.Pattern.Count; i++)
{
var l = (int)(Control.Width * element.BackgroundPattern.GetLeft(i));
var t = (int)(Control.Height * element.BackgroundPattern.GetTop(i));
var r = (int)(Control.Width * (1 - element.BackgroundPattern.Pattern[i].WidthPercent)) - l;
var b = (int)(Control.Height * (1 - element.BackgroundPattern.Pattern[i].HightPercent)) - t;
layer.SetLayerInset(i, l, t, r, b);
}
layer.SetLayerInset(d.Count - 1, 0, 0, 0, 0);
Control.SetBackground(layer);
}

Task<Bitmap> GetBitmap(FileImageSource image)


{
var handler = new FileImageSourceHandler();
return handler.LoadImageAsync(image, this.Control.Context);
}
}

public static class Calendar


{
public static void Init()
{
var d = string.Empty;
}
}
}

using Android.Gms.Maps;
using Android.Gms.Maps.Model;
using TheBeat.Clients.Base.Controls;
using TheBeat.Clients.Base.Helpers;
using TheBeat.Clients.Base.Models;
using TheBeat.Clients.Droid.Renderers;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using Xamarin.Forms;
using Xamarin.Forms.Maps;
using Xamarin.Forms.Maps.Android;

[assembly: ExportRenderer(typeof(CustomMap), typeof(CustomMapRenderer))]


namespace TheBeat.Clients.Droid.Renderers
{
public class CustomMapRenderer : MapRenderer
{
private const int EventResource = Resource.Drawable.pushpin_01;
private const int RestaurantResource = Resource.Drawable.pushpin_02;

private BitmapDescriptor _pinIcon;


private List<CustomMarkerOptions> _tempMarkers;
private bool _isDrawnDone;

public CustomMapRenderer()
{
_tempMarkers = new List<CustomMarkerOptions>();
_pinIcon = BitmapDescriptorFactory.FromResource(EventResource);
}

protected override void OnElementPropertyChanged(object sender, PropertyChangedEventArgs e)


{
base.OnElementPropertyChanged(sender, e);

var androidMapView = (MapView)Control;


var formsMap = (CustomMap)sender;

if(e.PropertyName.Equals("CustomPins") && !_isDrawnDone)


{
ClearPushPins(androidMapView);

NativeMap.MyLocationEnabled = formsMap.IsShowingUser;

AddPushPins(androidMapView, formsMap.CustomPins);

PositionMap();

_isDrawnDone = true;
}
}

protected override void OnLayout(bool changed, int l, int t, int r, int b)


{
base.OnLayout(changed, l, t, r, b);

if (changed)
{
_isDrawnDone = false;
}
}

private void ClearPushPins(MapView mapView)


{
NativeMap.Clear();
}

private void AddPushPins(MapView mapView, IEnumerable<CustomPin> pins)


{
foreach (var formsPin in pins)
{
var markerWithIcon = new MarkerOptions();

markerWithIcon.SetPosition(new LatLng(formsPin.Position.Latitude, formsPin.Position.Longitude));


markerWithIcon.SetTitle(formsPin.Label);
markerWithIcon.SetSnippet(formsPin.Address);

switch (formsPin.Type)
{
case SuggestionType.Event:
_pinIcon = BitmapDescriptorFactory.FromResource(EventResource);
markerWithIcon.SetIcon(_pinIcon);
break;
case SuggestionType.Restaurant:
_pinIcon = BitmapDescriptorFactory.FromResource(RestaurantResource);
markerWithIcon.SetIcon(_pinIcon);
break;
default:
markerWithIcon.SetIcon(BitmapDescriptorFactory.DefaultMarker());
break;
}

NativeMap.AddMarker(markerWithIcon);

_tempMarkers.Add(new CustomMarkerOptions
{
Id = formsPin.Id,
MarkerOptions = markerWithIcon
});
}
}

private void PositionMap()


{
var myMap = this.Element as CustomMap;
var formsPins = myMap.CustomPins;

if (formsPins == null || formsPins.Count() == 0)


{
return;
}
var centerPosition = new Position(formsPins.Average(x => x.Position.Latitude), formsPins.Average(x =>
x.Position.Longitude));

var minLongitude = formsPins.Min(x => x.Position.Longitude);


var minLatitude = formsPins.Min(x => x.Position.Latitude);

var maxLongitude = formsPins.Max(x => x.Position.Longitude);


var maxLatitude = formsPins.Max(x => x.Position.Latitude);

var distance = MapHelper.CalculateDistance(minLatitude, minLongitude,


maxLatitude, maxLongitude, 'M') / 2;

myMap.MoveToRegion(MapSpan.FromCenterAndRadius(centerPosition, Distance.FromMiles(distance)));
}
}

public class CustomMarkerOptions


{
public int Id { get; set; }
public MarkerOptions MarkerOptions { get; set; }
}
}

using Android.Support.V7.Widget;
using TheBeat.Clients.Base.Views;
using TheBeat.Clients.Droid.Renderers;
using Xamarin.Forms;
using Xamarin.Forms.Platform.Android;
using Xamarin.Forms.Platform.Android.AppCompat;
using AView = Android.Views.View;

[assembly: ExportRenderer(typeof(CustomNavigationPage), typeof(CustomNavigationPageRenderer))]


namespace TheBeat.Clients.Droid.Renderers
{
public class CustomNavigationPageRenderer : NavigationPageRenderer
{
IPageController PageController => Element as IPageController;

protected override void OnLayout(bool changed, int l, int t, int r, int b)


{
base.OnLayout(changed, l, t, r, b);

int containerHeight = b - t;

PageController.ContainerArea = new Rectangle(0, 0, Context.FromPixels(r - l),


Context.FromPixels(containerHeight));

for (var i = 0; i < ChildCount; i++)


{
AView child = GetChildAt(i);

if (child is Toolbar)
{
continue;
}

child.Layout(0, 0, r, b);
}
}
}
}

using TheBeat.Clients.Droid.Renderers;
using Xamarin.Forms;
using Xamarin.Forms.Platform.Android;

[assembly: ExportRenderer(typeof(Slider), typeof(CustomSliderRenderer))]


namespace TheBeat.Clients.Droid.Renderers
{
public class CustomSliderRenderer : SliderRenderer
{
protected override void OnElementChanged(ElementChangedEventArgs<Slider> e)
{
base.OnElementChanged(e);

Control?.SetPadding(0, 0, 0, 0);
}
}
}

using System.ComponentModel;
using TheBeat.Clients.Base.Controls;
using TheBeat.Clients.Droid.Renderers;
using Xamarin.Forms;
using Xamarin.Forms.Platform.Android;

[assembly: ExportRenderer(typeof(ExtendedEntry), typeof(ExtendedEntryRenderer))]


namespace TheBeat.Clients.Droid.Renderers
{
public class ExtendedEntryRenderer : EntryRenderer
{
public ExtendedEntry ExtendedEntryElement => Element as ExtendedEntry;

protected override void OnElementChanged(ElementChangedEventArgs<Entry> e)


{
base.OnElementChanged(e);

if (e.NewElement != null)
{
Control.InputType |= Android.Text.InputTypes.TextFlagNoSuggestions;
UpdateLineColor();
}
}

protected override void OnElementPropertyChanged(object sender, PropertyChangedEventArgs e)


{
base.OnElementPropertyChanged(sender, e);

if (e.PropertyName.Equals(nameof(ExtendedEntry.LineColorToApply)))
{
UpdateLineColor();
}
}

private void UpdateLineColor()


{
Control?.Background?.SetColorFilter(ExtendedEntryElement.LineColorToApply.ToAndroid(),
Android.Graphics.PorterDuff.Mode.SrcAtop);
}
}
}

/*
// Helpers/Settings.cs This file was automatically added when you installed the Settings Plugin. If you are not using a
PCL then comment this file back in to use it.
using Plugin.Settings;
using Plugin.Settings.Abstractions;

namespace TheBeat.Clients.Droid.Helpers
{
/// <summary>
/// This is the Settings static class that can be used in your Core solution or in any
/// of your client applications. All settings are laid out the same exact way with getters
/// and setters.
/// </summary>
public static class Settings
{
private static ISettings AppSettings
{
get
{
return CrossSettings.Current;
}
}

#region Setting Constants

private const string SettingsKey = "settings_key";


private static readonly string SettingsDefault = string.Empty;

#endregion

public static string GeneralSettings


{
get
{
return AppSettings.GetValueOrDefault(SettingsKey, SettingsDefault);
}
set
{
AppSettings.AddOrUpdateValue(SettingsKey, value);
}
}

}
}*/

using Android.Widget;
using TheBeat.Clients.Droid.Effects;
using Xamarin.Forms;
using Xamarin.Forms.Platform.Android;

[assembly: ExportEffect(typeof(UnderlineTextEffect), "UnderlineTextEffect")]


namespace TheBeat.Clients.Droid.Effects
{
public class UnderlineTextEffect : PlatformEffect
{
protected override void OnAttached()
{
var label = Control as TextView;

if (label != null)
{
label.PaintFlags |= Android.Graphics.PaintFlags.UnderlineText;
}
}

protected override void OnDetached()


{
}
}
}

You might also like