Background Audio in Xamarin Forms - xamarin

I've got a Xamarin.Forms app. at one time, I had this working, but alas, something has happened and now it no longer works. In my Android project, I have a dependency service as shown below. I am just trying to play a sound on the local system in the background. Now, out of the blue, I am getting an error on compile saying that 'Resource' does not contain a definition for 'Raw'. I have no idea where this error came from or how to fix it. There is a directory in Resource folder called raw. In it, there is a file named flushing.mp3. the VS intellisense does indicate the file is there. Any ideas are appreciated. TIA
Here is my code for my dependency service:
[assembly: Dependency(typeof(Audio))]
namespace PooperAppMobile.Droid.DependencyServices
{
public class Audio : IAudio
{
private MediaPlayer _mediaPlayer;
public bool PlayFlush()
{
_mediaPlayer = MediaPlayer.Create(global::Android.App.Application.Context, Resource.Raw.flushing);
_mediaPlayer.Start();
return true;
}
}
}

Well to be quite honest this error was giving me quite a pain when I saw this solution on a GITHUB discussion now all you have to do is add this line in your project file i.e. the .csproj, in your debug property group something like this :
<PropertyGroup.......
<AndroidUseManagedDesignTimeResourceGenerator>False</AndroidUseManagedDesignTimeResourceGenerator>
....
</PropertyGroup>
And It will start working as expected,
Good luck!
In case of queries do revert.

Related

NativeScript: CocoaPod that works in Pod example does not expose symbols in plugin project

I am trying to understand the best ways in which to bring native library code into a NativeScript plugin for iOS. I've had success in past bringing in a CocoaPod and accessing the symbols from that. So I want to create my own.
I follow the process for pod lib create TestPod to generate my library project. (https://guides.cocoapods.org/making/using-pod-lib-create.html)
The 'library' is a trivial test: it simply creates a class with a function that returns
a recognizable greeting string.
The associated "Example app" demo produces a text label that displays this string.
This all works as expected, all running in pure iOS world (written in Swift).
At the Nativescript side, I'm using the Nativescript Plugin Seed and I'm declaring my Podfile in the src/platforms/iOS folder as directed. My "plugin" (trivial as it is as a test), has the iOS-specific parts in the pluginName.ios.js file. I have a separate test method in here that verifies I can reach and use native iOS platform symbols (e.g. NSMutableString) and that works as expected. I want to do the same thing with native code imported from my library.
But when I bring the Podfile into Nativescript, it builds okay, but I'm not able to see any of the symbols as I would expect to see.
I generate typings and I don't find them either, but I do find a "TestPod.d.ts" typings file that declares some version info and a mysterious class named "UITest" that I did not define and bears no resemblance to my "SimpleTest" class, which I can't find anywhere.
I'm sure I'm missing something here that is probably obvious to the knowledgeable. But I'm unable to guess what it is. Any ideas?
import Foundation
#objc public class SimpleTest : NSObject {
public func announce() -> String {
return "Greetings from Swift code in a library"
}
}
I'm calling it in the plugin using the following:
public testNativeLib() : string {
let str:string;
try {
const testClass = new SimpleTest()
str = testClass.announce()
} catch(e) {
str = e.message;
}
return str;
}
and what I get returned for str is the catch case error message: "Can't find variable: SimpleTest"
Without seeing the source to the pod file; the only guess would be that you didn't use the #objc on anything that you wanted exposed. Without you exposing anything with #objc (or descending from a native objc class, so it is tagged by swift automagically) NativeScript cannot see it.
Please note their are some types in Swift that currently cannot be consumed by NativeScript (Or ObjC) and you have to write some wrapper code in swift around it using types that are compatible with ObjC so that NativeScript can use it.
Please see: https://docs.nativescript.org/guides/ios-source-code for more info on requirements...
The code needs to be:
import Foundation
public class SimpleTest : NSObject {
#objc public func announce() -> String {
return "Greetings from Swift code in a library"
}
}
Move the #objc to the actual property/function you want exposed. The NSObject will already cause the class to be exposed if it has exposed members.
The metadata generated:
A complete demo using a swift source file in a plugin is now located at
https://github.com/NathanaelA/demo-swift-plugin
If I have full control over the source, then I won't normally add another moving piece (i.e. cocoapod) to the mix; just let xcode compile the swift code and expose it, no need to add any additional places something can break.
However, if you want to see how to do an actual swift CocoaPod plugin; checkout any of these plugin repos that use swift code and cocoapod:
https://github.com/tomvardasca/nativescript-crypto
https://github.com/arpit2438735/nativescript-tglib
https://github.com/Daltron/NotificationBanner
In the case of an actual cocoapod; you need to have a valid Podfile, and a valid podspec file! Once you have those; when you build the application, you can open up xcode and verify that the cocoapod is linked in. If it isn't linked in then your podfile/podspec is messed up and has to do with a issue with Cocoapod and it is not a NativeScript issue. So in that case; you need to follow some Cocoapod tutorials to get it to work.
Please note; nuking your platform folder frequently while you are testing with cocoapods is highly recommended. Occasionally Nativescript does not detect the changes to Native code properly and so it then doesn't rebuild the xcode project/workspace files. So nuking your platforms folder will of course force it to rebuild them. If you don't you WILL waste a lot of time while messing around with cocoapods.
When running the sample project you will see this:
In addition, in the demo, the metadata generated from the code I saved in the demo/metadata folder so you can look at it.

Null exception namespace App in Xamarin for UWP

I am developing UWP app in xamarin. The application works on IOS, Mac , Android, Windows. I have created UWP project in it according to the tutorial given in developer.xamarin.com. But it giving error saying Accessibility.App namespace not found.
Here is my code:
namespace Accessibility.UWP
{
public sealed partial class MainPage
{
public MainPage()
{
this.InitializeComponent();
this.LoadApplication(new Accessibility.App());
}
}
}
According to your description, the app can't see Accessibility.App. As you claim that Android and iOS projects work there are two things that can cause the problem:
you don't have the reference to your Shared/PCL project in your UWP project (most likely).
you have possibly changed the namespace / class name in the Shared/PCL project to something else than Accessibility.App
This is usually caused by missing reference to the shared project or class library where Xamarin.Forms App class resides. From the description this project should be called Accessibility.
Right-click the UWP project select Add, Reference... then in Solution tab select the Accessibility project.
Also it might happen that the UWP project didn't pick up on the reference, so restarting Visual Studio might help as well.
If all fails, you can try to use class name binding with using. On top of the source code file add:
using FormsApp = Accessibility.App;
And then in code use:
this.LoadApplication(new FormsApp());

Xamarin Android Binding Library Custom Namespace Not Recognized

I am creating a Xamarin Android binding library for an existing JAR that contains a single class and following the Xamarin binding library documentation, I am able to successfully rename the namespace using:
<attr path="/api/package[#name='com.company.blah']" name="managedName">Company.Blah</attr>
I also confirmed the namespace is changed in the generated class in the 'obj/Debug' folder:
namespace Company.Blah {
// Metadata.xml XPath class reference: path="/api/package[#name='com.company.blah']/class[#name='NativeClass']"
[global::Android.Runtime.Register ("com/sprylab/android/widget/TextureVideoView", DoNotGenerateAcw=true)]
public partial class NativeClass
{
...
}
}
I face two problems:
I am unable to reference NativeClass from a sample Android project. It's like to doesn't see the namespace at all. The binding project built successfully without errors.
If I remove the package namespace rename setting, it also builds successfully and I am then able to reference it in my sample project but it requires that I fully qualify the class name anywhere it is used:
private com.company.blah.NativeClass nativeClass;
I'm hoping if I can fix #1, then #2 will not show up again. If so, I'm also curious how you prevent fully qualified class names from showing up?
Going into the project settings of the binding library project and clearing the box to the right of the assembly name seemed to do the trick. Looking inside the csproj directly, it is the root namespace.

Xamarin.Forms - InitializeComponent doesn't exist when creating a new page

I'm using Visual Studio to try out Xamarin.Forms. I'm trying to follow the guide:
http://developer.xamarin.com/guides/cross-platform/xamarin-forms/xaml-for-xamarin-forms/getting_started_with_xaml/
In short, I create a Xamarin.Forms solution using a PCL and then try to add a Forms XAML Page to the PCL-project.
The code-behind that gets created looks like this:
public partial class Page1 : ContentPage
{
public Page1()
{
InitializeComponent();
}
}
The problem here is that InitializeComponent(); is red.
When I try to build I get informed that The name 'InitializeComponent' does not exist in the current context
I've been looking around for solutions and even though others have had the same trouble, their solutions wont work for me. Here is one suggestion i tried to use:
http://blog.falafel.com/xamarin-error-initializecomponent-does-not-exist-in-the-current-context/
Please let me know if you have a solution for this problem. Thanks!
Update:
My PCL (which is where I also want to add my XAML-page) contains:
App.cs:
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!"
}
}
}
};
}
protected override void OnStart()
{
// Handle when your app starts
}
protected override void OnSleep()
{
// Handle when your app sleeps
}
protected override void OnResume()
{
// Handle when your app resumes
}
}
And my XAML-page:
<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="XamaTest.MyXamlPage">
<Label Text="{Binding MainText}" VerticalOptions="Center" HorizontalOptions="Center" />
</ContentPage>
Code-behind:
public partial class MyXamlPage : ContentPage
{
public MyXamlPage()
{
InitializeComponent();
}
}
UPDATE:
This error doesn't usually appear in VS 2015, if it does, here's my original answer:
Found the solution!
Right click on the .XAML file, select Properties.
You will see a Property called Custom Tool. Change its value from MSBuild:Compile to MSBuild:UpdateDesignTimeXaml
This will solve the problem.
Dont know about the downvote, but here's my screenshot:
UPDATE:
It reappears rarely. If it does, just open the Xaml and code behind files and save them. I know, its not the best solution, but it gets the job done.
I get this sometimes and here's the checklist that solved them so far:
Make sure the namespace in .xaml and .xaml.cs match
Inherit from the correct parent - ContentPage for a page and ContentView for a control
Set build action of the .xaml file to Embedded Resource if in the shared project.
As far as my observation is concerned, in Visual Studio 2015, XAML properties are already set as suggested by highly-voted answers here by default, specifically :
Custom Tool = MSBuild:UpdateDesignTimeXaml
Build Action = Embedded Resource
but the error still appears sometimes... (like in this other question).
Editing the corresponding XAML file and then hit CTRL+S should work fine, but you don't have to. A cleaner way to force Custom Tools to be run is by right-clicking on the XAML file and then click on "Run Custom Tool" context menu.
I have met this problem. It's associated with the encoding of XAML files in VS. I'm using VS2015.
I solved this problem as follows:
Open the *.xaml file in the project and click Save button. (There will be applying the correct encoding in VS2015).
Then reopen the project and rebuild it. Now there are no errors.
Updating the Xamarin.Forms NuGet package should do the job
This is probably not your case but I had similar problem and mine was xaml and code behind name missmatching. for example according to your sample,
if code behind namespace is XamaTest(name of your app in most cases) and class is called MyXamlPage, your xaml class name must be XamaTest.MyXamlPage ([namespace].[classname])
I was silly after creating an empty xaml with code behind, I changed name of the class in xaml and i was getting this error.
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="XamaTest.MyXamlPage">
<Label Text="{Binding MainText}" VerticalOptions="Center" HorizontalOptions="Center" />
</ContentPage>
Code-behind:
public partial class MyXamlPage : ContentPage
Try adding a x:Name="..." on the xaml page... Nothing else worked for me - but after adding the x:Name attribute on some of the elements on the page the error dissapeared (most of the times - I still get it sometimes). I use the latest build (1.5.0.6447) of Xamarin.Forms...
XAML don't work on shared projects - it only works in portable projects...
It looks like the (re)generation of the blah.xaml.g.cs files is actually the problem. I get this a LOT in shared projects (which is why I don't use them unless I have no other choice). It happens way more in Xamarin Studio than Visual Studio, for me, for some reason. I try not to use XS at all.
Often unloading one of the other platforms (e.g. if you're building droid, unload ios) and doing a clean and rebuild will fix it.
You can also try doing something like opening one of the offending .xaml files and changing some of the xaml markup (e.g. adding or changing an x:Name to one of the controls or views). This will force a regeneration of the xaml.g.cs file, and (for me at least) usually solves the problem.
This really shouldn't be a thing tho.
I came across this error when;
I removed a ContentPage-cs+xaml and the App-cs+xaml from the project without actually deleting it.
Re-added these to the project in another folder.
This was fixed by;
Select the .xaml file of the class in which the issue is present.
Right click and select properties.
In Build action select "Embedded Resource"
In Custom Tool type "MSBuild:UpdateDesignTimeXaml"
Clean and Build and it was gone.
Check page text x:Class="AppName.Page1". AppName must be your app name
If you get intellisense errors such InitializeComponent in your Xamarin.Forms pages but the project actually builds and runs fine, just add a new Forms page using the wizard to fix all errors...
Then you can delete that new page.
I had similar problem in Visual Studio 2013 update 4 environment and I tried all recommendations what I found on the web. Nothing solved my problem.
Then I tried workaround approach. I installed Visual Studio 2015 preview and create new blank app with xamarin forms project.
When I added new Xaml file everything was OK and issue with InitialComponent method disappeared.
I don t know where exactly is the reason of the problem but it seems to be issue around configuration settings.
A Clean and rebuild did the trick for me!
Right click *.xaml and click properties,and change "Custom Tool" value to "MSBuild:UpdateDesignTimeXaml", next change "Build Action" properties to "Embedded Resource",
build project works.
Very simple solution that worked for me:
Copy contents of the xaml/cs file
Delete the xaml/cs file
Create a new class and paste the contents
Now the InitializeComponent() function appears without red underline.
Hope this helps someone.
Check the class name properly.
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="{AppName}.{ClassName}">
</ContentPage>
The class name should be a combination of App name and partial class name
This problem appears when the projects of solution are referencing the version 1.4.0.0 of the dlls "Xamarin.Forms.Core", "Xamarin.Forms.Xaml" and "Xamarin.Forms.Platform" version 1.0.0.0.
To solve it I've had to downgrade to version 1.3.3.0 of the dlls but with this version Xamarin.Forms.Platform 1.0.0.0 don't exists.
Check the version of Xamarin.Forms package referenced in your project.
I have been having the same issue now and then, and this is what I have been doing to fix it: When in the PCL project, I add a new cross-platform XAML page to the project. Adding a new XAML page takes a few seconds for the references to "hook". After the new XAML page is successfully added to the project, the red underlines on the XAML Pages (with issues) will get cleared. Once the problem is solved, I simply delete the XAML file that I have just added. - So, in summary, adding a new XAML page then deleting it has been solving the issue for me.
I Just updated All packages, works fine.
Change Page properties to :
BuildAction => Embedded resource
CustomTools => MSBuild:UpdateDesignTimeXaml
I had a caching issue when I encountered this error.
To get this fixed, simply uninstall last version of Xamarin.Forms package and reinstall a previous working version.
When the rebuild is successful, then update the package again to the latest version.
It appears this is caused by many things so if you've read all of these and haven't resolved it yet:
Mine was caused by the Solution Configuration being set to Release. Changed to Debug and error resolved.
In my case the problem was the project path.
The generated code file gets a name including the absolute path encoded to make it a valid filename.
The path was "D:\Projekt C#\ProjectRootFolder\Project".
The filename generated by the build tool was "Project.Droid.D_.Projekt_C_. Namespace etc."
Moving the project to a path like "D:\project\ProjectRootFolder" helped in my case.
I'm using Visual Studio 2015, I got the same problem, and found none of the answers on the net was a full solution.
Here I'll explain what worked for me.
My primary goal here was to eliminate the red error message that kept coming up
The name InitializeComponent does not exist in the current context
Basically I created a function called InitializeComponent2() that does exactly the same thing as InitializeComponent() and used that instead, I literally copied the code for InitializeComponent().
Does the job.
It looks like this (and I'll explain):
[System.CodeDom.Compiler.GeneratedCodeAttribute("Xamarin.Forms.Build.Tasks.XamlG", "0.0.0.0")]
private void InitializeComponent2()
{
// Change to:
// this.LoadFromXaml(typeof(Page2)); // for Page2
// this.LoadFromXaml(typeof(Page3)); // for Page3
// and put
// using Xamarin.Forms.Xaml;
// at the top of each source file.
this.LoadFromXaml(typeof(Page1));
}
Put the function in the definition of each of your pages (.cs files) e.g.
public partial class Page1 : ContentPage
{
[System.CodeDom.Compiler.GeneratedCodeAttribute("Xamarin.Forms.Build.Tasks.XamlG", "0.0.0.0")]
private void InitializeComponent2()
{
// Change to:
// this.LoadFromXaml(typeof(Page2)); // for Page2
// this.LoadFromXaml(typeof(Page3)); // for Page3
// and put
// using Xamarin.Forms.Xaml;
// at the top of each source file.
this.LoadFromXaml(typeof(Page1));
}
}
Also you need to put using Xamarin.Forms.Xaml; at the top of each .cs page
where LoadFromXaml(..) is used.
And then of course change InitializeComponent() to
InitializeComponent2() to call the new function.
i.e. you have put the function into the same context as the page making the error go away. I can't imagine the real InitializeComponent function will get anything added to it as you modify your project but that is a possibility.
It's been fine for me so far.
I tried many things, changing the Build Action, the XAML namespace, restarting vs, cleaning+rebuilding, looking for NuGet package updates.
Basically, Visual Studio compiled and ran the program fine on my android device + emulator, but that error message wouldn't go away.
My solution is for Android, but it may also work for iOS etc.
I went back to the root of the problem InitializeComponent() The actual code for this function is generated in a file called <Your Project Name>.Page1.xaml.g.cs or Page2.xaml.g.cs for example. However, it (the file) is
only generated when a certain event gets fired. I was lucky to discover
it by typing text into "Custom Tool Namespace", which fired that event, for one of the xaml pages(a file ending in .xaml, not .cs - make sure you have .xaml file selected), type some text and press enter and the file will be created.
Then I had the great idea of making InitializeComponent2(), a function exactly the same as InitializeComponent() and putting it in each cs file so it exists
without having to generate the .xaml.g.cs every time you want the error to
go away.
I don't know if this is solved, but for me, the only thing I had to do is remove the first line of the XAML ("xml version="1.0" encoding="utf-8")
Sometimes source version control, tries to identify which type of file is and add this kind of stuff.
add using Xamarin.Forms.Xaml
tested on Visual Studio 2017
Select the App.xaml and MainPage.xaml file of the class in which the issue is present.
Right click and select properties.
In Build action select "Embedded Resource"
In Custom Tool type "MSBuild:UpdateDesignTimeXaml"
Clean and Build and it was gone.
Ultimate solution would be to edit the project file in a text editor and just copy the pattern from another non-conflicting file. This solution worked for me. Usually, you would look for this syntax:
<Compile Update="Your\Path\YourContentPage.xaml.cs">
<DependentUpon>YourContentPage.xaml</DependentUpon>
</Compile>
In Xaml Page Properties only set
Build Action = Embedded resource
It works in visual studio 2017.

MvvmCross, Xamarin Studio and ICommands

My issue was born in Does MvvmCross work in Xamarin Studio?. MvvmCross works fine in Visual Studio. However, I've been mandated to deploy this corporately using Xamarin Studio which is what their build server uses. I ran into the issue with System.Windows.Input.ICommand not being found by the compiler during my Xamarin Studio build. ICommands appear to be used quite extensively throughout MvvmCross for user commands (MvxCommand, which implements System.Windows.Input.ICommand). I've tried creating my own version of ICommand via the following code:
using System;
namespace Something.Common
{
public interface ICommand
{
event EventHandler CanExecuteChanged;
bool CanExecute(object parameter);
void Execute(object parameter);
}
}
All good, but still doesn't fix MvxCommand, because it implements the interface System.Windows.Input.ICommand. So I created my own version, MvxCommandEx, which is basically copied from Stuart's MvxCommand and implements my own ICommand (Something.Common.ICommand).
Lo and behold, it builds. It deploys. It got me all excited. But.... it didn't work. Any place I've bound a UI element to my custom ICommand just doesn't do anything. It's as if the binding from the Click event of the control to the view model's command is just not there anymore, whether I bind it in the .axml layout file... or use the CreateBindingSet method built-in to the view.
Now... I can get around this for some things... for instance, if I use a standard android Button, and invoke the view model's command manually from the built-in Click event, like:
btnAddScope.Click += (o, i) => { _ViewModel.RequestAddScope.Execute(null); };
it works, and I'm okay doing it this way in the interim until Xamarin releases their PCL support. But I'm using an MvxListView in another section of the app that was bound the old way using a syntax like:
lst.ItemClick = _ViewModel.RequestViewScope;
where lst is a MvxListView.
This won't work, however, because lst.ItemClick expects a System.Windows.Input.ICommand, and my ICommand isn't in that namespace.
Stuart provided explanations for this that supposedly are supposed to work. However, I'm feeling stupid for not being able to implement the ICommand in a way that actually works, when it feels like it should work... so before I go down a different avenue to address this, I wanted to see if anyone could shed light on what I'm doing wrong.
The easy solutions are:
either to provide your own implementation for the Xamarin version of System.Windows.Input.ICommand and to use this implementation
or to use the mvvmcross binaries which are built on the mac.
I'd recommend the first.
If you delete your Something.Common.ICommand code abd then put your MyCommand class implementation in the same project/assembly as your viewmodels, then they should build and run fine on both windows and on mac.

Resources