Using NuGet I added Unity to my Xamarin.Forms Application.
In my App class constructor I want to newup a UnityContainer instance.
using Xamarin.Forms;
public class App : Application
{
public App ()
{
unityContainer = new UnityContainer();
// The root page of your application
this.MainPage = new NavigationPage(new HomePage());
}
private static IUnityContainer unityContainer;
}
Unfortunately a System.Reflection.TargetInvocationException. Is thrown on the line unityContainer = new UnityContainer(); as I start to run my app in the android emulator.
What could be the reason to this?
Related
I am not sure of the terminology for what I'm looking to do, so sorry in advance!
I've found a FilePicker plugin for Xamarin.Forms (https://github.com/Studyxnet/FilePicker-Plugin-for-Xamarin-and-Windows) that implements device-specific functionality for selecting files via the CrossFilePicker class.
The way to use leverage this functionality would be something like
CrossFilePicker.Current.OpenFile("Filename.txt");
The most important part of this for me is that CrossFilePicker.Current is static and can be accessible from anywhere in the shared layer of my Xamarin.Forms app.
I need to implement a class with the same characteristics. I want to leverage device Accessibility functionality (i.e. determining if a screen reader is enabled) and I need to be able to do so with a static class.
My eventual plan is to then wrap this static class so that I can use it for unit tests too.
I don't want to import device libraries into my shared project.
TLDR: I need a static class that implements device-specific functionality.
Any help would be greatly appreciated! Thank you :)
EDIT:
Here are the files I have currently implemented in my project
IAccessibilityService Located in the shared .NET project
namespace Bitspace.Services
{
public interface IAccessibilityService
{
public bool IsScreenReaderEnabled();
public void Announcement(string message);
public void NavigationAnnouncement(string message);
}
}
DeviceAccessibility.cs Located in the shared .NET project
using System;
namespace Bitspace.Services
{
public class DeviceAccessibility
{
private static Lazy<IAccessibilityService> Implementation = new Lazy<IAccessibilityService>(() => CreateAccessibilityService(), System.Threading.LazyThreadSafetyMode.PublicationOnly);
public static IAccessibilityService Current
{
get
{
var curr = Implementation.Value;
if (curr == null)
{
throw new Exception();
}
return curr;
}
}
private static IAccessibilityService CreateAccessibilityService()
{
return new DeviceAccessibilityImplementation();
}
}
}
DeviceAccessibilityImplementation.cs Located in the Android project
using Android.Runtime;
namespace Bitspace.Services
{
[Preserve (AllMembers = true)]
public class DeviceAccessibilityImplementation : IAccessibilityService
{
public bool IsScreenReaderEnabled()
{
return true;
}
public void Announcement(string message)
{
}
public void NavigationAnnouncement(string message)
{
}
}
}
If I try to build the project, I get an error on the return new DeviceAccessibilityImplementation(); line in DeviceAccessibility.cs that says DeviceAccessibility.cs(25, 24): [CS0246] The type or namespace name 'DeviceAccessibilityImplementation' could not be found (are you missing a using directive or an assembly reference?)
However, CTRL Clicking on that line takes me to the DeviceAccessibilityImplementation.cs
I am trying to build a Home Launcher App in Xamarin
Currently I have a Xamarin Forms App with Access to Xamarin Android through interfaces. In Xamarin Android I have a method to find all package Names on the device like this:
[assembly: Xamarin.Forms.Dependency(typeof(Launcher.Droid.GetLauncher))]
namespace Launcher.Droid
{
class GetLauncher : MainActivity,IGetLauncher
{
public string GetPackageName(int index)
{
var apps = Android.App.Application.Context.PackageManager
.GetInstalledApplications(PackageInfoFlags.MatchAll);
return apps[index].PackageName; ;
}
}
}
I can access this function from Xamarin Forms to get the package names.
Now I want to launch an App with a certain package Name:
I have tried the following code also in Xamarin Android accessed by an Interface from Xamarin Forms:
[assembly: Xamarin.Forms.Dependency(typeof(Launcher.Droid.GetLauncher))]
namespace Launcher.Droid
{
class GetLauncher : MainActivity,IGetLauncher
{
public void RunApp(int index)
{
var apps = Android.App.Application.Context
.PackageManager.GetInstalledApplications(PackageInfoFlags.MatchAll);
Intent intent =
PackageManager.GetLaunchIntentForPackage(apps[index].PackageName);
StartActivity(intent);
}
}
}
which results in the following error:
Java.Lang.NullPointerException
Nachricht = Attempt to invoke virtual method 'android.content.pm.PackageManager android.content.Context.getPackageManager()' on a null object reference
The Error occurs on the PackageManager.GetLaunchIntentForPackage Line.
I am testing on a physical device.
Any Help or hints would be highly appreciated.
Try to change your codes like below:
[assembly: Xamarin.Forms.Dependency(typeof(Launcher.Droid.GetLauncher))]
namespace Launcher.Droid
{
class GetLauncher : IGetLauncher
{
public void RunApp(int index)
{
var apps = Android.App.Application.Context.PackageManager.GetInstalledApplications(PackageInfoFlags.MatchAll);
Intent intent = Android.App.Application.Context.PackageManager.GetLaunchIntentForPackage(apps[index].PackageName);
Android.App.Application.Context.StartActivity(intent);
}
}
}
So I want to implement a twitter login into my Xamarin App, but if I follow the tutorial, the Portable App will not let me do this function:
var ui = auth.GetUI(this);
when auth is this:
var auth = new OAuth1Authenticator(
"DynVhdIjJDXXXXXXXXXXXXX",
"REvU5dCUQI4MvjV6aWwXXXXXXXXXXXXXXXXXXXXXXX",
new Uri("https://api.twitter.com/oauth/request_token"),
new Uri("https://api.twitter.com/oauth/authorize"),
new Uri("https://api.twitter.com/oauth/access_token"),
new Uri("http://twitter.com"));
So I need to add it into the Android Project, but how do I show the button from there?
Thanks for any help! :)
Based on OAuth1Authenticator and GetUI() I assume you use Xamarin.Auth.
Xamarin.Auth supports Xamarin.Forms with 2 implementations for GetUI(), so called Presenters (actually Dependency Service/Injection) and CustomRenderers. Presenters are more tested (thus more evidence of stabilty), but you can check the code in the repo.
Samples how to use Xamarin.Auth with the Xamarin.Forms:
https://github.com/moljac/Xamarin.Auth.Samples.NugetReferences/tree/master/Xamarin.Forms/Evolve16Labs
NOTE: this repo contains extracted samples from the main Xamarin.Auth repo, so the handling is easier and samples are updated more often.
Creating platform specific code in Xamarin?
You can use DependencyService to implement this function. Here is the document and example. The document explain that :
DependencyService allows apps to call into platform-specific functionality from shared code. This functionality enables Xamarin.Forms apps to do anything that a native app can do.
Create a ILogin interface in PCL :
public interface ILogin
{
void GetUI();
}
Implement the interface in Xamarin.Android :
[assembly: Xamarin.Forms.Dependency(typeof(TwitterLogin))]
namespace TwitterDemo.Droid
{
public class TwitterLogin : ILogin
{
public TwitterLogin()
{
}
public void GetUI()
{
var auth = new OAuth1Authenticator("DynVhdIjJDXXXXXXXXXXXXX", "REvU5dCUQI4MvjV6aWwXXXXXXXXXXXXXXXXXXXXXXX",
new Uri("https://api.twitter.com/oauth/request_token"),
new Uri("https://api.twitter.com/oauth/authorize"),
new Uri("https://api.twitter.com/oauth/access_token"),
new Uri("http://twitter.com"));
Intent intent = auth.GetUI(Android.App.Application.Context);
Forms.Context.StartActivity(intent);
}
}
}
Use it in Xamarin.Forms:
private void Button_Clicked(object sender, EventArgs e)
{
Xamarin.Forms.DependencyService.Register<ILogin>();
DependencyService.Get<ILogin>().GetUI();
}
In NativeScript world, is it possible to create a JS file that extends Android's TextView, and then call it natively from pre-existing Android project?
for example, I derived this custom TextView that extends android.widget.TextView:
var constructorCalled = false;
var CustomTextView = android.widget.TextView.extend({
//constructor
init: function() {
constructorCalled = true;
this.setText("set in javascript");
},
});
and now I try to use this class by calling:
CustomTextView customTextView = new CustomTextView();
in native Android project.
Note: I have gone over this documentation:
https://docs.nativescript.org/angular/integration-with-existing-ios-and-android-apps/extend-existing-android-app-with-ns-angular2.html
and got it worked, but this example is not enough for me to understand how to construct a custom class in JS and have Java use it freely.
Thanks to pkanev, you have pointed me to the right direction!
So I modified my JS defined class like so:
var constructorCalled = false;
var CustomTextView = android.widget.TextView.extend(
"com.Arzath.custom.CustomTextView",
{
//constructor
init: function() {
constructorCalled = true;
this.setText("set in javascript");
},
});
Next I rebuild my android platform with this command:
tns build android
That gives me a Java class, CustomTextView in my src folder.
It's important to note that in order to use it, do not forget to initiate the runtime like so:
com.tns.Runtime runtime = com.tns.RuntimeHelper.initRuntime(MainActivity.this.getApplication());
if (runtime != null) {
runtime.run();
}
I have been developing a number of Android activities in a project in Eclipse.
I am now following a tutorial to achieve push notifications and I need to create a new Android Application (extends Application in the code).
However, when trying to create this application it does not run properly. Does the class name need to be the same as the project title?
When trying to run this on my phone it crashes.
My code is below: (ApplicationLoader is not the name of the App/Project)
public class ApplicationLoader extends Application {
#Override
public void onCreate() {
super.onCreate();
//Configure your application
//
// This can be done in code as illustrated here,
// or you can add these settings to a properties file
// called airshipconfig.properties
// and place it in your "assets" folder
AirshipConfigOptions options = AirshipConfigOptions.loadDefaultOptions(this);
options.developmentAppKey = --my development app key
options.productionAppKey = --my production app key
options.inProduction = false; //determines which app key to use
Logger.logLevel = Log.VERBOSE;
// Take off initializes the services
UAirship.takeOff(this, options);
PushManager.enablePush();
PushPreferences prefs = PushManager.shared().getPreferences();
Logger.info("My Application onCreate - App APID: " + prefs.getPushId());
}
}
If your application name is ApplicationLoader (defined under application tag in your AndroidManifest) then Application Class name should also be ApplicationLoader
<application android:name="ApplicationLoader ">
public class ApplicationLoader extends Application