How to get DPI device to PCL in Xamarin. Forms? - Followup - forms

Using Xamarin Forms Visual Studio 2019.
I need to get the DPI of the device.
This post has a solution:
How to get DPI device to PCL in Xamarin. Forms?
Implementing the solution gave problems:
When applying the answer above I get this error message:
The type or namespace name 'DependencyAttribute' could not be found
(are you missing a using directive or an assembly reference?)
In your android implementation, add a new class:
[assembly: Dependency(typeof(DisplayInfo))]
namespace .....
--I solved this compiler problem by replacing with:
using Xamarin.Essentials;
[assembly: Xamarin.Forms.Dependency(typeof(DisplayInfo))]
However when I compile and run the code, it falls over when I try consume this in the Xamarin Core Code:
int dpi = DependencyService.Get<IDisplayInfo>().GetDisplayDpi();
I get this runtime error on the above line:
System.NullReferenceException: Object reference not set to an instance
of an object
Any ideas? I would have added this question as a comment on the original, but as a new user do not have the points to do this... If someone could drop a comment on the original question's solution pointing it to this URL that would be helpful too.

So the answer to my own question:
The solution original offered said do this:
In your android implementation, add a new class:
[assembly: Dependency(typeof(DisplayInfo))]
namespace YourAppNamespace.Droid
{
public class DisplayInfo : IDisplayInfo
{
public int GetDisplayWidth()
{
(int)Android.App.Application.Context.Resources.DisplayMetrics.WidthPixels;
}
public int GetDisplayHeight()
{
(int)Android.App.Application.Context.Resources.DisplayMetrics.HeightPixels;
}
public int GetDisplayDpi()
{
(int)Android.App.Application.Context.Resources.DisplayMetrics.DensityDpi;
}
}
}
The problem I did not see anywhere in the Android code that initialised this class, and I was unsure how best to do this really.
So I followed guidance for implementing the interface directly in the Android MainActivity.cs file, and this worked.. The video I watched to help me on that is here:
https://www.youtube.com/watch?v=lgcnYDb6cRQ&t=19s

Related

Unity google-play-core review issue

I added the google play core package as instructed in the repo, and added the code according to the documentation here
I receive the following error: CS0246: The type or namespace name 'PlayAsyncOperation<,>' could not be found (are you missing a using directive or an assembly reference?)
This error shows at _reviewManager.RequestReviewFlow(); and _reviewManager.LaunchReviewFlow(_playReviewInfo)
Any idea what could be the issue?
My full code:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using Google.Play.Review;
public class ReviewCodes : MonoBehaviour
{
private ReviewManager _reviewManager;
private PlayReviewInfo _playReviewInfo;
// Start is called before the first frame update
void Start()
{
StartCoroutine(RequestReviews());
}
// Update is called once per frame
void Update()
{
}
IEnumerator RequestReviews()
{
// Create instance of ReviewManager
_reviewManager = new ReviewManager();
var requestFlowOperation = _reviewManager.RequestReviewFlow();
yield return requestFlowOperation;
if (requestFlowOperation.Error != ReviewErrorCode.NoError)
{
// Log error. For example, using requestFlowOperation.Error.ToString().
yield break;
}
_playReviewInfo = requestFlowOperation.GetResult();
var launchFlowOperation = _reviewManager.LaunchReviewFlow(_playReviewInfo);
yield return launchFlowOperation;
_playReviewInfo = null; // Reset the object
if (launchFlowOperation.Error != ReviewErrorCode.NoError)
{
// Log error. For example, using requestFlowOperation.Error.ToString().
yield break;
}
// The flow has finished. The API does not indicate whether the user
// reviewed or not, or even whether the review dialog was shown. Thus, no
// matter the result, we continue our app flow.
}
}
"are you missing a using directive or an assembly reference?"
These are following situation which causes a compiler error:
Check if the name of the type or namespace is correct, as most of the time you can get this error when the compiler cannot find that namespace.
Check if you have added the reference to the assembly that contains the namespace. Ex: Your code can be in "using XYZ;"
but if your project does not reference assembly then you can get a CS0246 error.
Try: using Google.Play.Common;
the order might be your problem. You also not only have to import the Google Core Package. You also have to import the Google Review Plugin. The core plugin overrides assemblies and files which then can't be used by the review assembly.
Step-by-Step solution:
Import google-play-plugins-1.7.0.unitypackage
Import com.google.play.review-1.7.0.unitypackage
Make sure to restart your IDE or reload the code in your IDE after this steps.
In older versions in unity there was an option to download this packages with the help of the unity package manager. Now you have to use the official github repository from Google. See Downloading the plugins or just use the official provided .unitypackages from Google

Z.EntityFramework.Plus.QueryCache.EF6 Requires QueryDeferred Library?

When trying to use the QueryCache library to do some L2 caching of a few entities, I am receiving a compiler error on .FromCache() indicating the QueryDeferred library is required. Documentation indicates QueryCache can be used as stand-alone.
using Z.EntityFramework.Plus;
namespace LookupValuesMap.Controllers
{
public class HomeController : Controller
{
public ActionResult Index()
{
LookupValueContext ctx = new LookupValueContext();
var companies = ctx.Companies.FromCache().ToList(); <-- error
Here is the error:
Error CS0012 The type 'QueryDeferred<>' is defined in an assembly that is not referenced. You must add a reference to assembly 'Z.EntityFramework.Plus.QueryDeferred.EF6, Version=1.6.8.0, Culture=neutral, PublicKeyToken=59b66d028979105b'.
Thank you in advance!
J Kent
Disclaimer: I'm the owner of the project Entity Framework Plus
Due to how the library has been built, some "standalone" features like this one may have the Z.EntityFramework.Plus.QueryDeferred.EF6 requirement.
You can download the version from: NuGet
We will eventually fix it for no longer having to have this dependence.

methodAccessException when passing variables from ViewModel to ViewModel on WP7 using anonymous object (MVVMCross)

I've created an app using MVVMCross, the IOS and Android versions are working but when I tried to "port" to WP7 and I ran into the following problem:
throw methodAccessException.MvxWrap("Problem accessing object - most likely this is caused by an anonymous object being generated as Internal - please see http://stackoverflow.com/questions/8273399/anonymous-types-and-get-accessors-on-wp7-1");
As mentioned in the answer to my other question about this (on Android) you have to set an InternalsVisibleTo attribute in the AssemblyInfo.cs for WP7. So I did:
[assembly: InternalsVisibleTo("Cirrious.MvvmCross.WindowsPhone")]
But this doesn't make any difference. I use the following code to send two variables form my BeckhoffViewModel to my BeckhoffSensorViewModel.
BeckhoffViewModel:
public IMvxCommand BeckhoffSensor1
{
get
{
return new MvxRelayCommand(kvpSens1);
}
}
private void kvpSens1()
{
RequestNavigate<BeckhoffSensorViewModel>(new { VarType = "short", Variable = ".countertest" });
}
BeckhoffSensorViewModel:
public BeckhoffSensorViewModel(string VarType, string Variable)
{
_vartype = VarType;
_variable = Variable;
}
Anything I'm overlooking? I also looked at the other stackoverflow topic mentioned in the exception but couldn't really understand it.
The anonymous class will most definitely be created as internal by the compiler - which is why you need the line [assembly: InternalsVisibleTo("Cirrious.MvvmCross.WindowsPhone")]
Can you check that the AssemblyInfo.cs file definitely being linked into the project (and that this is the project containing the ViewModel/anonymous-class code)?
If that is the case, can you check the methodAccessException to see what the message is?
If that doesn't help, can you use a tool like Reflector to check the internalVisible attribute is actually present on the core/application assembly?

EventLogInstaller Full Setup with Categories?

It appears the MSDN docs are broken concerning creating an Event Log completely along with a definitions file for messages. I am also lost on how to setup Categories (I have custom numbers in the 3000's for messages).
Can anyone point me to a link or show sample code on how to make this right?
You should start (if you haven't done so already) here:
EventLogInstaller Class (System.Diagnostics)
The sample provided there is the foundation for what you want to do. To sum it up, build a public class inheriting from System.Configuration.Install.Installer in an assembly (could be the same DLL where you have the rest of your application, a separate DLL, or an EXE file), decorate it with the RunInstaller attribute, and add your setup code in the constructor:
using System;
using System.Configuration.Install;
using System.Diagnostics;
using System.ComponentModel;
[RunInstaller(true)]
public class MyEventLogInstaller: Installer
{
private EventLogInstaller myEventLogInstaller;
public MyEventLogInstaller()
{
// Create an instance of an EventLogInstaller.
myEventLogInstaller = new EventLogInstaller();
// Set the source name of the event log.
myEventLogInstaller.Source = "NewLogSource";
// Set the event log that the source writes entries to.
myEventLogInstaller.Log = "MyNewLog";
// Add myEventLogInstaller to the Installer collection.
Installers.Add(myEventLogInstaller);
}
}
When you have your assembly compiled, you may use the InstallUtil tool available through the Visual Studio Command Prompt to run the installer code.
Regarding the message definition file (which includes category definitions), the MSDN documentation for EventLogInstaller.MessageResourceFile mentions that you should create an .mc file, compile it, and add it as a resource to your assembly. Digging around, I found an excellent post which should guide you to the end, here:
C# with .NET - Event Logging (Wayback Machine)

Eclipse RCP: How to access internal classes of plugins?

I want to use the default XML editor (org.eclipse.wst.xml.ui) of Eclipse in an RCP application. I need to read the DOM of the xml file currently open. The plugin doesn't offer any extension point, so I'm trying to access the internal classes. I am aware that the I should not access the internal classes, but I don't have another option.
My approach is to create a fragment and an extension point to be able to read data from the plugin. I'm trying not to recompile the plugin, that's why I thought that a fragment was necessary. I just want to load it and extract the data at runtime.
So, my question is: is there another way to access the classes of a plugin? if yes, how?
Any tutorial, doc page or useful link for any of the methods is welcome.
Since nobody answered my question and I found the answer after long searches, I will post the answer for others to use if they bump into this problem.
To access a plugin at runtime you must create and extension point and an extension attached to it into the plugin that you are trying to access.
Adding classes to a plugin using a fragment is not recommended if you want to access those classes from outside of the plugin.
So, the best solution for this is to get the plugin source from the CVS Repository and make the modifications directly into the source of the plugin. Add extension points, extensions and the code for functionality.
Tutorials:
Getting the plugin from the CVS Repository:
http://www.eclipse.org/webtools/community/tutorials/DevelopingWTP/DevelopingWTP.html
Creating extensions and extension points and accessing them:
http://www.vogella.de/articles/EclipseExtensionPoint/article.html
http://www.eclipsezone.com/eclipse/forums/t97608.rhtml
I ended up extending XMLMultiPageEditorPart like this:
public class MultiPageEditor extends XMLMultiPageEditorPart implements
IResourceChangeListener {
#Override
public void resourceChanged(IResourceChangeEvent event) {
// TODO Auto-generated method stub
setActivePage(3);
}
public Document getDOM() {
int activePageIndex = getActivePage();
setActivePage(1);
StructuredTextEditor fTextEditor = (StructuredTextEditor) getSelectedPage();
IDocument document = fTextEditor.getDocumentProvider().getDocument(
fTextEditor.getEditorInput());
IStructuredModel model = StructuredModelManager.getModelManager()
.getExistingModelForRead(document);
Document modelDocument = null;
try {
if (model instanceof IDOMModel) {
// cast the structured model to a DOM Model
modelDocument = (Document) (((IDOMModel) model).getDocument());
}
} finally {
if (model != null) {
model.releaseFromRead();
}
}
setActivePage(activePageIndex);
return modelDocument;
}
}
This is not a clean implementation, but it gets the job done.