SQLite-net PCL and Xamarin.Forms - sqlite

I have a problem with this Nuget Package:
https://www.nuget.org/packages/sqlite-net-pcl/1.0.11
In my test Case I have a PCLLibrary called "PCL" with this NuGet Package. And an emtpy class which has
using SQLite;
namespace PCL
{
public class Test
{
}
}
Now I create a new Xamarin.Forms PCL Project and reference this Library
using System;
using Xamarin.Forms;
namespace PCL
{
public class App : Application
{
public App ()
{
// The root page of your application
MainPage = new ContentPage {
Content = new StackLayout {
VerticalOptions = LayoutOptions.Center,
Children = {
new Label {
XAlign = TextAlignment.Center,
Text = "Welcome to Xamarin Forms!"
}
}
}
};
var test = new Test();
}
}
}
Now I run my App in iOS Simulator and it gets killed ...
When i am not creating an instance of Test this App starts fine...
When I integrate this Package directly in my Forms Library, I can use it normally.
What can cause this?

Normally when you are dealing with NuGet packages on PCL's you need to add the NuGet package on the iOS project as well as the PCL. This is because it may have some platform specific code in it (will definitely be the case with a SQLite library).
When you add it to the iOS project it loads the specific assemblies for iOS that is needed. Its just something you need to be aware of.
Also I would recommend this package: https://www.nuget.org/packages/SQLite.Net-PCL/

Related

.Net Maui Class library Dependancy injection for Platform specific code plugin

I am trying to create a plugin using .Net Maui class libraries that use native Android and iOS code. I tried using the Dependency Service using the Interface, but I get a null point when I try to Register the Interface.
Shared code
public class MyPlugin
{
public static DisplayModel()
{
IDeviceOrientationService service =
DependencyService.Get<IMyPlugin>();
var model = service.GetDeviceName();
}
}
public Interface IMyPlugin
{
string GetDeviceName();
}
Android platform
[assembly: Dependency(typeof(MyPlugin))]
public class MyPlugin:IMyPlugin
{
public string GetDeviceName
{
return "From Android";
}
}
This is just an example. Please help me understand if I am not going about this the correct way and any suggestion would be appreciated.

Is it possible to integrate AdMob in an Android app using Uno Platform

I have a few UWP apps I would like to migrate to Android.
I already migrated some using Xamarin.Forms
I have discovered Uno Platform that seems to be great. But I didn't find any information about integration AdMob advertisement in an Android project using Uno Platform.
Has anyone done it already?
Yes, it is possible and I have been able to get it working in my Uno Platform app on Android and iOS. I am planning to write a blogpost about getting AdMob and AdSense running on Android, iOS and WASM, and publish a Uno Platform library on NuGet that will do all the heavy lifting for you, so stay tuned :-) .
For now, here is a unedited, raw version of the control I am using currently. It requires that you install the Google Play Services Ads NuGet packages in the Android project and in the iOS project.
Android
#if __ANDROID__
using Android.Gms.Ads;
using Android.Widget;
using System;
using System.Collections.Generic;
using System.Text;
using Uno.UI;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
namespace SmsTicket.Core.Controls
{
public partial class AdControl : ContentControl
{
public AdControl()
{
var adView = new AdView(ContextHelper.Current);
adView.AdSize = AdSize.SmartBanner;
adView.AdUnitId = "YOUR AD UNIT ID";
HorizontalContentAlignment = HorizontalAlignment.Stretch;
VerticalContentAlignment = VerticalAlignment.Stretch;
var adParams = new LinearLayout.LayoutParams(
LayoutParams.WrapContent, LayoutParams.WrapContent);
adView.LayoutParameters = adParams;
adView.LoadAd(new AdRequest.Builder().AddTestDevice("YOUR TEST DEVICE ID").Build());
Content = adView;
}
}
}
#endif
iOS
#if __IOS__
using Google.MobileAds;
using System;
using System.Collections.Generic;
using System.Text;
using UIKit;
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml;
using CoreGraphics;
namespace SmsTicket.Core.Controls
{
public partial class AdControl : ContentControl
{
public AdControl()
{
HorizontalContentAlignment = HorizontalAlignment.Stretch;
VerticalContentAlignment = VerticalAlignment.Stretch;
Background = SolidColorBrushHelper.Red;
Width = AdSizeCons.LargeBanner.Size.Width;
Height = AdSizeCons.LargeBanner.Size.Height;
Windows.UI.Xaml.Window.Current.Activated += Current_Activated;
}
private void LoadAd()
{
if (!(Content is BannerView))
{
var adView = new BannerView(AdSizeCons.LargeBanner)
{
AdUnitID = "YOUR AD UNIT ID",
RootViewController = GetVisibleViewController()
};
adView.LoadRequest(GetRequest());
Content = adView;
}
}
Request GetRequest()
{
var request = Request.GetDefaultRequest();
// Requests test ads on devices you specify. Your test device ID is printed to the console when
// an ad request is made. GADBannerView automatically returns test ads when running on a
// simulator. After you get your device ID, add it here
request.TestDevices = new[] { Request.SimulatorId.ToString(), "YOUR TEST DEVICE ID" };
return request;
}
UIViewController GetVisibleViewController()
{
UIViewController rootController;
if (UIApplication.SharedApplication.KeyWindow == null)
{
return null;
}
else
{
rootController = UIApplication.SharedApplication.KeyWindow.RootViewController;
}
if (rootController.PresentedViewController == null)
return rootController;
if (rootController.PresentedViewController is UINavigationController)
{
return ((UINavigationController)rootController.PresentedViewController).VisibleViewController;
}
if (rootController.PresentedViewController is UITabBarController)
{
return ((UITabBarController)rootController.PresentedViewController).SelectedViewController;
}
return rootController.PresentedViewController;
}
private void Current_Activated(object sender, Windows.UI.Core.WindowActivatedEventArgs e)
{
LoadAd();
}
}
}
#endif
Also make sure to include the Ad control only conditionally (as I have provided only Android and iOS version here).
Uno Platform won't block you from using any third party (especially not on mobile). If there is a xamarin binding you can use it as-is in your code, just like you would use it in a Xamarin.Forms app. If it's a library affecting the view you will most likely create a custom control and interact with the third-party classes via C#.
If there's no xamarin binding for a library, you can create one following microsoft documentation.
Good news! For admob there is a microsoft-supported binding nuget and it has been used in an uno application in the past.

How to use SqLite in Xamarin Froms?

Everyone.
I am using SqLite in Xamarin Forms. For that I am using SqLite - PCL nuget. Now the problem is, It works fine in Android. But in UWP I can't Access database file.
I am using Common code for both Platforms. It is as below :
database = new SQLiteConnection(Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Personal), "mydb.db"));
database.CreateTable<Item>();
The error I am getting in UWP app only.
Thank You.
the docs contain clear instructions on how to do this in UWP
using Windows.Storage;
...
[assembly: Dependency(typeof(FileHelper))]
namespace Todo.UWP
{
public class FileHelper : IFileHelper
{
public string GetLocalFilePath(string filename)
{
return Path.Combine(ApplicationData.Current.LocalFolder.Path, filename);
}
}
}

Keeping screen turned on for certain pages

I am using a portable project so do not have direct access to native code.
I have an interface in my project that allows me to access native objects in the Android/iOS projects. We use this primarily for playing audio.
Android, for example, has things like
Window w = new Window();
w.SetFlags(WindowManagerFlags.Fullscreen, WindowManagerFlags.KeepScreenOn);
However the main issue would be accessing a Window object. I could pass a Xamarin.Forms.Page object to the native code, but there would be no way (I don't think) to cast it to a native Android Window object to access the flags.
Is there a way to do this with a portable project?
You can't do this without platform specific services or renderers. A portable project will have to call platform specific code in order to achieve this.
From that platform specific code, either as a DependencyService or Renderer, you can access the Window object through the Forms.Context. The Forms.Context is your Android Activity, through which you can reach the Window object.
On Android it works like this:
Android.Views.Window window = (Forms.Context as Activity).Window;
window.SetFlags(WindowManagerFlags.KeepScreenOn);
On iOS you can try this (Apple docs):
UIApplication.SharedApplication.IdleTimerDisabled = true;
Now there is a plugin doing exactly what Tim wrote
https://learn.microsoft.com/en-us/xamarin/essentials/screen-lock
simple source code is here
https://github.com/xamarin/Essentials/blob/main/Samples/Samples/ViewModel/KeepScreenOnViewModel.cs
using System.Windows.Input;
using Xamarin.Essentials;
using Xamarin.Forms;
namespace Samples.ViewModel
{
public class KeepScreenOnViewModel : BaseViewModel
{
public KeepScreenOnViewModel()
{
RequestActiveCommand = new Command(OnRequestActive);
RequestReleaseCommand = new Command(OnRequestRelease);
}
public bool IsActive => DeviceDisplay.KeepScreenOn;
public ICommand RequestActiveCommand { get; }
public ICommand RequestReleaseCommand { get; }
void OnRequestActive()
{
DeviceDisplay.KeepScreenOn = true;
OnPropertyChanged(nameof(IsActive));
}
void OnRequestRelease()
{
DeviceDisplay.KeepScreenOn = false;
OnPropertyChanged(nameof(IsActive));
}
}
}
For Xamarin Forms Android.
Renders file I included below code
Window window = (Forms.Context as Activity).Window;
window.AddFlags(WindowManagerFlags.KeepScreenOn);

Can't find a working example of SQLite.Net-PCL in Xamarin Forms

I can't seem to get off dead center with SQLite.Net-PCL; I have a Xamarin forms solution with a PCL proj, Droid proj, iOS proj, and Windows Universal project. I have installed the nuget packages for SQLite.Net-PCL and SQLite.Net.Core-PCL.
So, I go over to the github project to find some awesome examples to get started and none of them work; apparently you have to pass a platform into the database connection, but I get a reference error on them all (such as SQLitePlatformWin32).
Search the web for the references and... nothing. Search nuget for the platforms and... nothing.
What am I missing? (yes, I feel dumb)
An example they have is
public class Database : SQLiteConnection
{
public Database(string path) : base(new SQLitePlatformWin32(), path)
{
CreateTable<Stock>();
CreateTable<Valuation>();
}}
and I get a reference error that I can't resolve on the "new SQLitePlatformWin32" line.
For anyone else struggling, here is what you need to do.
Install the SQLite.Net-PCL, SQLite.Net.Core-PCL and SQLite.Net.Async-PCL nugets
Create an interface for ISQLite in your PCL:
public interface ISQLite
{
SQLiteConnection GetConnection();
}
Call GetConnection via DependencyService
PatientDatabase = DependencyService.Get<ISQLite>().GetConnection();
PatientDatabase.CreateTable<Patient>();
The above will create the connection based on your platform (i.e. android, ios). In each platform's project, you must have a GetConnection that is accessable via DependencyService such as this for Android
[assembly: Xamarin.Forms.Dependency(typeof(SQLite_Android))]
// ...
public class SQLite_Android : ISQLite
{
public SQLite_Android() { }
public SQLite.Net.SQLiteConnection GetConnection()
{
var sqliteFilename = "TodoSQLite.db3";
string documentsPath = System.Environment.GetFolderPath(System.Environment.SpecialFolder.Personal); // Documents folder
var path = Path.Combine(documentsPath, sqliteFilename);
// Create the connection
var conn = new SQLite.Net.SQLiteConnection(new SQLite.Net.Platform.XamarinAndroid.SQLitePlatformAndroid(), path);
// Return the database connection
return conn;
}
}
My problem was I was trying to create the connection in my PCL and I couldn't find the platforms, what you need to do is create the connection in each individual project.

Resources