I am developing .net maui app that measures sound volume and sends it with bluetooth to pc that logs data and makes graph as a hobby project. My problem is accesing microphone input. There seems to be no multiplatform way to do this in maui. So i tried to do it using platform specific android api, but when I tried so, it seemed like class that I needed was not fully implemented in maui Android namespace.
The part of my code I have trouble with is this:
using Android.Media;
using Java.Util;
public static class MicIn
{
static MediaRecorder mRecorder;
// Other functions
public static void startRecorder()
{
if (mRecorder == null)
{
mRecorder = new MediaRecorder();
mRecorder.SetAudioSource(MediaRecorder.AudioSource.MIC);
mRecorder.SetOutputFormat(MediaRecorder.OutputFormat.THREE_GPP);
mRecorder.SetAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);
mRecorder.SetOutputFile("/dev/null");
try
{
mRecorder.Prepare();
}
catch (Java.IO.IOException ioe)
{
Debug.WriteLine("IO exception");
}
catch (Java.Lang.SecurityException e)
{
Debug.WriteLine("Security exception");
}
try
{
mRecorder.Start();
}
catch (Java.Lang.SecurityException e)
{
Debug.WriteLine("Security exception");
}
}
}
}
Visual studio gives me errors on MediaRecorder.AudioSource.MIC, MediaRecorder.OutputFormat.THREE_GPP and MediaRecorder.AudioEncoder.AMR_NB
It says that these classes do not have definition for MIC, THREE_GPP and AMR_NB constants, even if they are in official android api documentation.
Do you have any ideas what might be error or other ways of taking microphone input in .net maui? Thank you for help.
according to the docs
AudioSource Mic
OutputFormat ThreeGpp
AudioEncoder AmrNb
Related
Using Xamarin.Forms I have my main application running Forms. But I have Mapbox Navigation which is Xamarin.Android that I am using, I ma trying to open the navigation from Forms so I am doing the following:
FORMS CODE
public interface INavigation
{
void StartNativeIntentOrActivity();
}
The void above is then called through DependencyService in Forms
XAMARIN.ANDROID Code
using Android.Content;
using MapleLMCApp.Classes;
using MapleLMCApp.Droid;
using MapleLMCApp.Droid.NavigationUI;
using System;
using Xamarin.Forms;
[assembly: Xamarin.Forms.Dependency(typeof(NavInitializer))]
namespace MapleLMCApp.Droid
{
class NavInitializer : INavigation
{
public void StartNativeIntentOrActivity()
{
//Begin Navigation Form
try
{
var intent = new Intent(Android.App.Application.Context, typeof(EmbeddedNavigationActivity));
intent.SetFlags(ActivityFlags.NewTask);
Android.App.Application.Context.StartActivity(intent);
}
catch (Exception ex)
{
LogFileCreation lg = new LogFileCreation();
lg.CreateLog(ex.ToString(), "NAV Initilizer Error");
}
}
}
}
The above works perfectly in the emulator for API <28 and API >28
The second I try the code above on my Huawei P30 Pro the second the new activity appears the App restarts itself or auto closes...
Any ideas on what might be causing this? some security setting or Manifest property that needs to be set or something along those lines?
There is a fetchRoute() event that starts as the new activity opens. This has an error on the P30 Pro due to culture variants on double parse...It was attempting to parse 27,33 as a double and needed to be 27.33
The form now opens without any issues
I would like to encrypt and decrypt files but this shows me an error "This request is not supported" and "Invalid descriptor".
Can you help me ?
I have two methods AddEncryption and RemoveEncryption which encrypts and decrypts the file passed in FileName.
public static void Main()
{
try
{
string FileName = "C:\Users\PORTABLEHP\Documents\a.txt";
Console.WriteLine("Encrypt" + FileName);
AddEncryption(FileName);
Console.WriteLine("Decrypt" + FileName);
RemoveEncryption(FileName);
Console.WriteLine("Done");
}
catch(Exception ex)
{
Console.WriteLine(ex);
}
Console.ReadLine();
}
public static void AddEncryption(string FileName)
{
File.Encrypt(FileName);
}
public static void RemoveEncryption(string FileName)
{
File.Decrypt(FileName);
}
The limitation of File.Encrypt method has been described at File.Encrypt
Important
This API is only supported on Windows platforms that are able to use
the NTFS Encrypting File System (EFS). Any attempt to use this on
non-Windows systems, Windows Home Edition systems, or non-NTFS drives
results in a PlatformNotSupportedException or NotSupportedException,
depending on the situation.
Use of this API in .NET Core is not recommended; it is included to
enable portability for applications that move to .NET Core but still
explicitly target Windows.
I want to make a USSD call in a xamarin crossplatform app using C# and i have no idea where to start. All the examples i have seen is done in java. Is it possible to successfully dial a USSD code like *270# within my app without opening the dialer? If yes, please how? I'll be very grateful for any help
To do it with Xamarin forms you have to create a custom renderer for android :
Create an interface in your shared project :
public interface IUssdRenderer
{
void StartTransaction();
}
then in your android project :
using System;
using Android.Content;
using Android.OS;
using ussd.Renderers;
[assembly: Xamarin.Forms.Dependency(typeof(IUssdRenderer))]
namespace ussd.Droid.Renderers
{
public class UssdRenderer : IUssdRenderer
{
public Android.Net.Uri createUriFromString(string ussd)
{
String uri = "tel:";
foreach (char c in ussd.ToCharArray())
{
if (c == '#')
{
uri += Android.Net.Uri.Encode("#");
}
else
{
uri += c;
}
}
return Android.Net.Uri.Parse(uri);
}
public void StartTransaction()
{
var intent = new Intent(Intent.ActionCall, createUriFromString("*270#"));
Context ctx = Xamarin.Forms.Forms.Context;
ctx.StartActivity(intent);
}
}
}
You'll also have to register you interface, I'm using prism :
public void RegisterTypes(IContainerRegistry containerRegistry)
{
containerRegistry.Register< IUssdRenderer, UssdRenderer>();
}
The last bit is to make sure you have Call permissions enabled :
Right click on Android Project > Options > Android application
make sure CallPhone is selected
You may use Xamarin.Essentials PhoneDialer, to make a call, note that since USSD contains '#' you need to URL-encode it. example:
string code = "*123#";
PhoneDialer.Open(HttpUtility.UrlEncode(code));
After collecting from left and right I finally found the solution to my question with CrossMessaging plugin.
The steps are as follow:
Create your project and give the name
Install from nuget Xam.Plugins.Messaging in your project
Add below line in Android project MainActivity's OnCreate method:
CrossMessaging.Current.Settings().Phone.AutoDial = true;
Add android.permission.CALL_PHONE to the manifest file.
Make calls as follow
try
{
var phonedialer = CrossMessaging.Current.PhoneDialer;
if (phonedialer.CanMakePhoneCall)
{
//Ussd call's
phonedialer.MakePhoneCall(HttpUtility.UrlEncode("#150#"));
//For normal calls
phonedialer.MakePhoneCall("9111111111")
}
}
catch (Exception exc)
{
await DisplayAlert("Error!!!!", exc.ToString(), "ok");
}
I am using Pencil.Gaming as the C# Wrapper for the OpenGL functions. I wanted to write a quite application to get the OpenGL renderer and version information but I can't seem to find the Macros for these (GL_RENDERER and GL_VERSION).
Has anyone used Pencil.Gaming or another C# wrapper before and used these or similar macros? Where are they located? Or is there another way to get this information with the wrapper?
Here's the code I have so far:
using System;
using Pencil.Gaming;
using Pencil.Gaming.Graphics;
using GLubyte = System.Byte;
namespace C_Sharp_OpenGL
{
class Program
{
static void Main(string[] args)
{
if (!Glfw.Init()){
Console.WriteLine("ERROR: Could not start GLFW3");
Console.WriteLine("Press Any Key to Continue...");
Console.ReadKey();
Environment.Exit(-1);
}
GlfwWindowPtr window = Glfw.CreateWindow(640, 480, "Hello Triangle", GlfwMonitorPtr.Null, GlfwWindowPtr.Null);
Glfw.MakeContextCurrent(window);
//Get Version Info
GLubyte renderer = GL.GetString(GL_RENDERER); //Doesn't Work
Glubyte version = GL.GetString(GL_VERSION); //Doesn't Work
}
}
}
Here is what I need.
I trying to write a application that will take over another application and intercept certain things that happens in it.
The idea is to monitor the application and take actions when some stuff happens.
After some research I found that Detours 2.1 from Ms Research, will help me, but I am having a hard time finding how to user it and integrate it in my domain of programming which is .NET.
Does anyone have any idea how I can do this without having to dig c\c++ books.
Thanks all
If your trying to hook another .NET application you could try .NET Hook Library.
If your talking about hooking system calls then there are actually lots of tools / libraries available. Checkout "Code Injection Tools" in the RCE tool library.
There was an API and a layer added in Windows to assist in enabling desktop applications for users with disabilities. I am not so sure about the current state of the API but I am quite sure equivalents exist in the .NET Framework. Check out this link and see if you can exploit the hooks built into this layer rather than going for lower level system calls. The information suggests that Windows Automation API 3.0 is the current standard for intercepting events and manipulating another application.
I recommend Deviare, the hook engine from our company where hooking is done trivially, injection and parameters parsing is done by the engine. This is for example a code in C# to intercept PrcStartDocPrinterW on spoolsv.exe.
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using Nektra.Deviare2;
namespace PrintLogger
{
public partial class PrintLogger : Form
{
private NktSpyMgr _spyMgr;
private NktProcess _process;
public PrintLogger()
{
InitializeComponent();
_spyMgr = new NktSpyMgr();
_spyMgr.Initialize();
_spyMgr.OnFunctionCalled += new DNktSpyMgrEvents_OnFunctionCalledEventHandler(OnFunctionCalled);
GetProcess("spoolsv.exe");
if (_process == null)
{
MessageBox.Show("Please start \"spoolsv.exe\" before!", "Error");
Environment.Exit(0);
}
}
private void PrintLogger_Load(object sender, EventArgs e)
{
NktHook hook = _spyMgr.CreateHook("spoolsv.exe!PrvStartDocPrinterW", (int)(eNktHookFlags.flgRestrictAutoHookToSameExecutable & eNktHookFlags.flgOnlyPreCall));
hook.Hook(true);
hook.Attach(_process, true);
}
private bool GetProcess(string proccessName)
{
NktProcessesEnum enumProcess = _spyMgr.Processes();
NktProcess tempProcess = enumProcess.First();
while (tempProcess != null)
{
if (tempProcess.Name.Equals(proccessName, StringComparison.InvariantCultureIgnoreCase) && tempProcess.PlatformBits > 0 && tempProcess.PlatformBits <= IntPtr.Size * 8)
{
_process = tempProcess;
return true;
}
tempProcess = enumProcess.Next();
}
_process = null;
return false;
}
private void OnFunctionCalled(NktHook hook, NktProcess process, NktHookCallInfo hookCallInfo)
{
string strDocument = "Document: ";
INktParamsEnum paramsEnum = hookCallInfo.Params();
INktParam param = paramsEnum.First();
param = paramsEnum.Next();
param = paramsEnum.Next();
if (param.PointerVal != IntPtr.Zero)
{
INktParamsEnum paramsEnumStruct = param.Evaluate().Fields();
INktParam paramStruct = paramsEnumStruct.First();
strDocument += paramStruct.ReadString();
strDocument += "\n";
}
Output(strDocument);
}
public delegate void OutputDelegate(string strOutput);
private void Output(string strOutput)
{
if (InvokeRequired)
BeginInvoke(new OutputDelegate(Output), strOutput);
else
textOutput.AppendText(strOutput);
}
}
}
There are many alternatives to Deviare, Microsoft Detours is one of them. The main scope of Deviare is doing hooking extremely easy and being a COM object it can be used in .NET too via an automatic created interop. It is also trivial to use it on every scripting language like VBScript or PowerShell.